帰らざるMOS回路(28) Icarus Verilog、ライブラリのパラメータ化

Joseph Halfmoon

前回、モジュールファイルの置き場所を決めたりして、作成済の部品を呼び出して使うのが便利になりました。すると即座に不満な点が出てきました。部品が「8ビット用」とかキメウチで応用が効かないことです。今回はシフトレジスタを題材にパラメタライズ、呼び出し時にビット幅を決められるようにしてみます。

※フリーのVerilogの定番、Icarus Verilogの以下のバージョンで動作確認を行っております。

Icarus Verilog version 11.0 (devel) ()

ホームページが以下に。

Icarus Verilog

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)が代入できています。

シフトレジスタのクロックを動かしていくと、予定通りの値が入力できていることが分かります。vvp

念のため、gtkwave に vcd ファイルを表示してもらったものが冒頭のアイキャッチ画像に。シミュレーションしている感じが出てきたかも。

帰らざるMOS回路(27) Icarus Verilog小ネタ、ライブラリ、実行時パラメータ へ戻る

帰らざるMOS回路(29) Icarus Verilog、検証用テキストファイル出力 へ進む