ModelSimコマンドライン実行用シェルスクリプトのVerilogとVHDLのサンプル・データについて、テストベンチの記述を比較しました。
サンプル・データはgithubにあります。
テストベンチの概要
テストベンチは、大きく3つの部分で構成されています。
- クロック信号の生成
- リセット信号の生成
- 入力データの生成
クロック信号の生成
Verilog-HDL
initialとforeverの組み合わせでクロックを生成しています。クロック周期はlocalparamや`defineを使って定義することもできますが、ここでは直接値(5)を記述しています。
reg clk; initial begin clk = 1; forever begin #5 clk = ~clk; end end
VHDL
processでクロックを生成しています。クロック生成は、sim_endでクロックを停止します。クロックの停止は、シミュレータを終了させるために必要な処理です。
signal clk : std_logic; signal sim_end : boolean := false; constant CK_CYCLE : time := 10 ns; -- 100MHz clkg : process begin clk <= '0'; wait for CK_CYCLE/2; clk <= '1'; wait for CK_CYCLE/2; if (sim_end) then wait; end if; end process;
リセット信号の生成
Verilog-HDL
taskでリセット信号を生成しています。リセット信号rst_xは、taskの引数として渡していません。グローバルな信号としてtask内で直接値を設定しています。
reg rst_x; task reset; begin rst_x = 0; repeat (10) @(posedge clk); @(negedge clk); rst_x = 1; @(posedge clk); end endtask
VHDL
procedureでリセット信号を生成しています。リセット信号rst_xは、procedureに引数として与えています。
signal rst_x : std_logic := '0'; procedure reset(signal rst_x : out std_logic) is begin rst_x <= '0'; for i in 0 to 9 loop wait until clk'event and clk='1'; end loop; wait until clk'event and clk='0'; rst_x <= '1'; wait until clk'event and clk='1'; end reset;
入力データの生成
Verilog-HDL
デザイン(DUT: Design-Under-Test)の8ビット入力端子i_inに対して、ランダムな値を10回入力しています。ランダム値生成にはシステムタスク$randomを利用しています。
reg [7:0] i_in; integer i; initial begin $display("ModelSim simulation sample"); $dumpvars; // 波形(vcd)出力 reset; // リセット repeat (10) @(posedge clk); for (i=0;i<10;i=i+1) begin // 入力は10回 i_in = $random; // ランダムデータ入力 @(posedge clk); end repeat (10) @(posedge clk); $finish; end
VHDL
デザイン(DUT: Design-Under-Test)の8ビット入力端子i_inに対して、ランダムな値を10回入力しています。ランダム値生成はこちらのサイトを参考にさせていただきました。math.realパッケージに格納されている、uniformを利用してランダムデータを生成しています。uniformで生成したreal型のランダムデータを、まず255までの整数に変換し、次に8ビットのstd_logic_vectorに変換しています。続いて、データ入力を終了して10サイクル待ってからsim_endをtrueに設定しています。これによってクロックが停止し、シミュレータが停止します。
signal i_in : std_logic_vector(7 downto 0) := (others => '0'); main : process variable seed1, seed2: positive; variable rand: real; variable range_of_rand : real := 255.0; -- 0から255まで begin report "ModelSim simulation sample"; reset(rst_x); -- リセット report "reset end"; for i in 0 to 9 loop -- 入力は10回 uniform(seed1, seed2, rand); rand_num <= integer(rand*range_of_rand); i_in <= conv_std_logic_vector(rand_num, 8); --ランダムデータ入力 wait until clk'event and clk='1'; end loop; for i in 0 to 9 loop wait until clk'event and clk='1'; end loop; report "simulation finished."; sim_end <= true; wait; end process;
VerilogとVHDLの違いについて
テストベンチの内容について、実現方法の違いをまとめると次のようになります。
項目 | Verilog-HDL | VHDL |
クロックの立ち上がりを待つ | @(posedge clk); | wait until clk’event and clk=’1′; |
クロックの立ち下がりを待つ | @(negedge clk); | wait until clk’event and clk=’0′; |
シミュレーションの終了 | $finish | processのループ等、処理を全て終了させる |
ランダム値の生成 | $random | uniform等を使って生成する |
画面への文字表示 | $display | report |