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 |

