前回、モジュールファイルの置き場所を決めたりして、作成済の部品を呼び出して使うのが便利になりました。すると即座に不満な点が出てきました。部品が「8ビット用」とかキメウチで応用が効かないことです。今回はシフトレジスタを題材にパラメタライズ、呼び出し時にビット幅を決められるようにしてみます。
※かえらざるMOS回路 投稿順 INDEX
※フリーのVerilogの定番、Icarus Verilogの以下のバージョンで動作確認を行っております。
Icarus Verilog version 11.0 (devel) ()
ホームページが以下に。
Verilog モジュールのパラメタライズ
Verilogのパラメタライズは難しくはないのですが、なぜか「とってつけた感」があります(個人の感想です。)
-
- parameterというキーワードがあるので、それを使って「定数的なパラメータ」を宣言し、モジュールを記述する(宣言時の既定値がある)
- 該当のモジュールを呼び出す(インスタンス)ときに何も指定しなければ上記で宣言している既定値が使われる
- 呼び出し時に #( xx ) という形で実パラメータを渡すと、こちらが優先される
そんな緩い理解で、デフォルト8ビット、パラメータ化することで任意のNビットになるはずのシフトレジスタ(入力シリアル、出力パラレル)を記述してみたものがこちら。
/** @file Nbit shift register */ `ifndef SHIFTER_N_V_ `define SHIFTER_N_V_ /** The shifterN module @param[in] CLK clock input @param[in] RST reset input @param[out] OUT [N-1:0] shifter parallel output */ module shifterN( CLK, RST, IN, OUT ); parameter N = 8; input CLK, RST, IN; output [N-1:0] OUT; reg [N-1:0] OUT; always @( posedge CLK or posedge RST) begin if ( RST==1'b1 ) OUT <= 0; else OUT <= { OUT , IN }; end endmodule `endif // SHIFTER_N_V_
上記ファイルは前回指定した「ライブラリ・モジュールのディレクトリ」に配置しました。ディレクトリ内にソースさえあれば、Icarus Verilogは呼び出されているモジュールを勝手に見つけてくれるのでお楽。
上記シフトレジスタのテストベンチ
上記のシフトレジスタを呼び出して動作確認するテストベンチがこちら。shifterNについてはデフォルト指定が8ビットでしたが短くして
4ビット
にしてみました。短い方が、シミュレーション確認が楽だし。
また前回、シミュレーション時にコマンドラインから入力値を代入する技を覚えました。今回はshifterへの入力値を与えてみます。これで、モデルを再ビルドせずとも、異なる値でシミュレーションできます。
/** @file shifterN Test bench */ `timescale 1 us / 100 ns module shiftReg_tb; parameter CYCLE = 100; parameter HALF_CYCLE = 50; parameter DELAY = 10; wire [3:0] SOUT; reg CLK, RST, IN; reg [3:0] SIN; shifterN #(4) dut( CLK, RST, IN, SOUT ); initial begin if (! $value$plusargs("SIN=%d", SIN)) begin $display("ERROR: +SIN=0..15 needed."); $finish; end $dumpfile("shiftReg_tb.vcd"); $dumpvars(-1, dut); $monitor("%d CLK=%b, RST=%b, IN=%b, SOUT=%d, SIN=%d", $stime, CLK, RST, IN, SOUT, SIN); end always begin CLK = 1'b1; #HALF_CYCLE CLK = 1'b0; #HALF_CYCLE; end // testbench actions initial begin RST = 1'b0; #DELAY RST = 1'b1; #CYCLE RST = 1'b0; IN = SIN[3]; #CYCLE IN = SIN[2]; #CYCLE IN = SIN[1]; #CYCLE IN = SIN[0]; #CYCLE $finish; end endmodule //shiftReg_tb
ビルド(エラボレーション)と実行
Icarus verilogのコマンドラインは以下です。 前回やったとおり-y の後に続くディレクトリ内にモジュールファイルを配置しています。
iverilog -o shiftReg_tb.out -yF:\pgm2\iverilog\vlib shiftReg_tb.v
シミュレーションは vvp コマンドで実行ですが、モデル(shiftReg_tb.out)の後に、+に続けて変数名とその値を指定しています。これによりモデル中の変数(ここではSIN)に値(ここでは5)が代入できています。
シフトレジスタのクロックを動かしていくと、予定通りの値が入力できていることが分かります。
念のため、gtkwave に vcd ファイルを表示してもらったものが冒頭のアイキャッチ画像に。シミュレーションしている感じが出てきたかも。