VerilogとVHDLの記述比較(テストベンチ)

設計

ModelSimコマンドライン実行用シェルスクリプトのVerilogとVHDLのサンプル・データについて、テストベンチの記述を比較しました。

サンプル・データはgithubにあります。

Kenji-Ishimaru/msim-sample-verilog
ModelSim verilog simulation environment sample. Contribute to Kenji-Ishimaru/msim-sample-verilog development by creating an account on GitHub.
Kenji-Ishimaru/msim-sample-vhdl
ModelSim VHDL simulation environment sample. Contribute to Kenji-Ishimaru/msim-sample-vhdl development by creating an account on 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-HDLVHDL
クロックの立ち上がりを待つ @(posedge clk); wait until clk’event and clk=’1′;
クロックの立ち下がりを待つ @(negedge clk); wait until clk’event and clk=’0′;
シミュレーションの終了$finish processのループ等、処理を全て終了させる
ランダム値の生成$random uniform等を使って生成する
画面への文字表示$displayreport
タイトルとURLをコピーしました