FPGA内部でのLFSR(線形フィードバックシフトレジスタ) - VHDL & Verilogコード FPGA内部での線形フィードバックシフトレジスタの動作原理 LFSRはLinear Feedback Shift Registerの略で、FPGA内部で有用な設計手法です。LFSRは合成が容易で、比較的少ないリソースでFPGA内部에서非常に高いクロックレートで動作可能です。LFSRの恩恵を受けるアプリケーションは多岐にわたります。 カウンタ テストパターン生成器 データスクランブリング 暗号技術 線形フィードバックシフトレジスタは、FPGA内部でシフトレジスタとして配線された一連の
シングルポート同期RAMの設計 同期RAMは、クロックエッジで読み書き両方を制御するメモリです。アドレス幅ADDR_WIDTH、データ幅DATA_WIDTH、深さDEPTHをパラメータ化し、汎用的に使えます。入出力は双方向バスdata(inout)で、チップセレクトcs、書き込みイネーブルwe、出力イネーブルoeで制御します。 module single_port_sync_ram #( parameter ADDR_WIDTH = 4, parameter DATA_WIDTH = 32, parameter DEPTH = 16 )( input clk, inpu
フルアダーの概要 フルアダーは、2つの入力ビット(A, B)とキャリー入力(Cin)を加算し、和(Sum)とキャリー出力(Cout)を生成する組み合わせ回路です。プロセッサのALU、アドレス計算、ポインタ演算などの核となる基本ブロックです。 真理値表(1ビットフルアダー) ABCinCoutSum 00000 00101 01001 01110 10001 10110 11010 11111 設計:4ビットフルアダー(リップルキャリーアダー) 4ビット入力a, bと1ビットc_inを受け、5ビット結果(c_out + sum[3:0])を出力します。
マルチプレクサ(MUX)とは マルチプレクサは、N個の入力から選択信号selに基づいて1つを出力に通す組み合わせ回路です。4:1 MUXでは、2ビットのselで4つの入力(a, b, c, d)から1つを選択します。 選択真理値表 sel選択入力出力 00aa 01bb 10cc 11dd 実装方法1:assign文(継続代入) ネストした条件演算子(?:)で記述。組み合わせ回路として最もシンプルで、合成結果も最適化されやすい形式です。 module mux_4to1_assign ( input [3:0] a, b, c, d, input [1:
プライオリティエンコーダ(優先度付きエンコーダ/マルチプレクサ) 本設計は、4つの8ビット入力(a, b, c, d)から、2ビット選択信号selに基づいて1つを出力outに選択するマルチプレクサです。優先順位はselの値そのもの(00→a, 01→b, 10→c, 11→d)で固定されます。 設計 module pr_en ( input [7:0] a, input [7:0] b, input [7:0] c, input [7:0] d, input [1:0] sel, output reg [7:0] out ); always @(a or
シフトレジスタの基本 シフトレジスタは、フリップフロップをカスケード接続し、共通クロックで動作させることで、ビット列を1クロックごとに1ビットずつシフトさせる回路です。データ入力dから入力されたビットが順次伝播し、出力outから並列または直列に取り出せます。 設計:パラメータ化双方向シフトレジスタ ビット幅MSB、方向制御dir(0=右シフト、1=左シフト)、イネーブルen、アクティブローリセットrstnを備えた汎用設計です。 module shift_reg #( parameter MSB = 8 )( input d, // シリアルデータ入力 in
グレイコードとは グレイコード(反射2進コード)は、隣り合うコード語のビット差が常に1ビットのみとなる符号化方式です。通常のバイナリカウントでは複数ビットが同時に変化する(例:0111→1000で4ビット変化)ため、非同期クロックドメイン間での値受け渡しや、機械的エンコーダ、カーネルマップ簡略化などでグレイコードが用いられます。 バイナリ→グレイ変換の公式 nビットバイナリ値B[n-1:0]からグレイコードG[n-1:0]への変換: G[n-1] = B[n-1] G[i] = B[i+1] ^ B[i] (i = n-2 ... 0) Verilogでは連結演算子で簡潔に記述で
Mod-Nカウンタとは Mod-Nカウンタ(モジュロNカウンタ)は、0からN-1までカウントし、N-1の次に0へ戻るカウンタです。任意のカウント長Nをパラメータで指定できるため、任意の分周比やステートマシンの周期制御に最適です。 設計 2つのパラメータN(カウント最大値+1)とWIDTH(ビット幅)を持ち、out == N-1で次回0にクリアします。 module modN_ctr #( parameter N = 10, // モジュロ値(カウント数) parameter WIDTH = 4 // 出力ビット幅(N-1を表現できる最小幅) )( inp
ジョンソンカウンタ(ツイステッドリングカウンタ)とは ジョンソンカウンタは、シフトレジスタの最終出力を反転させて先頭にフィードバックする構造です。Nビットで2Nステートを持つため、リングカウンタ(Nステート)の2倍のカウント長を実現できます。出力パターンは「1つの1が左へ移動 → 全1 → 1つの0が左へ移動 → 全0」を繰り返します。 設計 リングカウンタとほぼ同一ですが、フィードバック時に~out[0](LSBの反転)をMSBに入力する点が異なります。 module johnson_ctr #( parameter WIDTH = 4 )( input clk, inpu
リングカウンタとは リングカウンタは、出力ビットを循環シフトさせるカウンタです。初期状態で1ビットのみが1(他は0)で、クロックごとに1が左(または右)に1ビットずつ移動し、端まで達したら反対側に戻ります。NビットならNクロックで元の状態に戻るため、N進カウンタとして機能します。 設計(ストレートリングカウンタ) パラメータWIDTHでビット幅を可変にし、リセット時はout = 1(LSBのみ1)で初期化します。クロックごとにMSBにLSBを、それ以外は右隣のビットをシフトインします。 module ring_ctr #( parameter WIDTH = 4 )( input
リップルカウンタとは リップルカウンタ(非同期カウンタ)は、最初のフリップフロップのみが共通クロックで駆動され、それ以降のフリップフロップは前段の出力でクロッキングされる構造です。クロックが段々に伝播(リップル)するためこの名があります。 特徴 メリット:回路がシンプル、クロック配線が容易、低消費電力 デメリット:伝播遅延が累積し、高速動作不向き、グリッチ発生しやすい、タイミング解析が複雑 設計 Tフリップフロップ(d = ~q)を4段カスケード接続し、各段のクロックを前段のq出力とします。出力はqn(反転出力)を並べてout = {qn3, qn2, qn1, qn0}としま
4ビットカウンタの概要 4ビットカウンタは4b0000から4h1111(0〜15)までインクリメントし、オーバーフロー時に4b0000にロールオーバーします。クロックが供給され、リセットが非アサート(High)の間、カウントを継続します。 ロールオーバーの仕組み 最大値4b1111(15)の次にカウントアップすると、5ビット目5b10000(16)になりますが、4ビットレジスタではMSBが捨てられ4b0000(0)になります。 0000 → 0001 → 0010 → ... → 1110 → 1111 → 0000 → 0001 → ... 設計 クロック立ち上がりエッジで動作し、ア
ラッチとフリップフロップの根本的な違い フリップフロップはクロックのエッジ(立ち上がり/立ち下がり)で入力を取り込み、次のエッジまで出力を保持します。クロックエッジ以降の入力変化は無視されます。 一方、ラッチはエッジではなくレベルで動作します。イネーブル信号(en)がアサートされている間、出力qは入力dを透過的に追従します。イネーブルが非アサートになると、その瞬間の値をラッチ(保持)します。 Dラッチの設計 3入力(データd、イネーブルen、アクティブローリセットrstn)、1出力(q)のポジティブラッチを実装します。 module d_latch ( input d, //
Tフリップフロップの設計 Tフリップフロップ(トグルフリップフロップ)は、入力tが1のときクロックエッジで出力を反転し、0のときは保持するシンプルな順序回路です。カウンタや分周器の基本構成要素として広く使われます。 module tff ( input clk, input rstn, // アクティブローリセット(同期) input t, // トグル入力 output reg q ); always @(posedge clk) begin if (!rstn) q <= 0; else if (t) q <
Dフリップフロップの基本 Dフリップフロップは、クロックの指定エッジ(立ち上がり/立ち下がり)で入力dの値を取り込み、出力qに反映する順序回路の基本要素です。 設計 #1:非同期アクティブローリセット リセット信号rstnがLow(0)になった瞬間に、クロックに関係なく即座に出力を0にクリアします。always @(posedge clk or negedge rstn)でクロック立ち上がりまたはリセット立ち下がりを感度リストに含めます。 module dff ( input d, input rstn, // アクティブローリセット input clk, out
JKフリップフロップの設計 JKフリップフロップは、JとKの2入力を持つ汎用的なフリップフロップです。クロック立ち上がりエッジで動作し、入力組み合わせに応じて保持・クリア・セット・トグルの4動作を行います。 module jk_ff ( input j, input k, input clk, output q ); reg q; always @(posedge clk) begin case ({j, k}) 2b00: q <= q; // 保持 2b01: q <= 0; // リセット(クリア)
最初のVerilogプログラム どんな言語でも最初は「Hello World」から始めるのが定石です。Verilogも例外ではありません。以下は最小限の構成でコンソールにメッセージを表示するモジュールです。 // 単一行コメントは // で始まる // Verilogのコードは常に module の中に書く // 各モジュールは何らかの機能を持つデジタルブロックを表す module tb; // initialブロックはシミュレーション開始時(時間0)に一度だけ実行される // 信号や変数の初期化、刺激生成などに使う initial // $displayはフォーマット付
VerilogにおけるファイルI/Oの概要 Verilogには、ファイルを開き、値をファイルに出力し、ファイルから値を読み取って変数に格納し、ファイルを閉じるためのシステムタスクおよび関数が用意されています。これらを活用することで、シミュレーション中のデータログ記録、テストベクタの外部ファイルからの読み込み、結果のファイル出力などが可能になります。 ファイルのオープンとクローズ ファイル操作の第一歩は、$fopenでファイルを開き、ファイルディスクリプタ(ハンドラ)を取得することです。処理が完了したら$fcloseで確実にクローズします。 module tb; integer fd;
デフォルトtimescale Verilogモジュールはモジュール前にtimescaleが定義されていることが期待されますが、シミュレータはデフォルトのtimescaleを挿入する場合があります。Verilog展開階層内の任意のスコープで実際に適用されるtimescaleは、スコープを引数として受け取るシステムタスク$printtimescaleで出力できます。 module tb; initial begin // このモジュールのtimescaleを出力 $printtimescale(tb); // $printtimescale($root); end
Verilogのtimescaleディレクティブは、シミュレーションの時間単位と精度を指定します。 Verilogの$timeformatシステム関数は、$displayや$strobeなどの表示文での%tフォーマット指定子の報告スタイルを指定します。 構文 $timeformat(<unit_number>, <precision>, <suffix_string>, <minimum field width>); unit_numberは、ソースコードで使用されているすべての`timescaleディレクティブの中で最小の時間精度 pr
Verilog