005回
テストベンチ

key :
テストベンチ ファイル出力


カウンタの動作確認のためのシミュレーション環境作り。
信号の入力もこちらで。
記述はVerilogで、通常の回路(RTL)の時では使えなかった記述方法が使える。
↑テストベンチは実際に回路化しないから

そんな訳で、RTLの記述とはちょっと違った記述を見てみましょう。

Verilog記述 解説

`timescale 1ns/1ns

module cnt_test;

wire [3:0] Q0,Q1,Q2;
reg clock,reset;
reg data_set;
reg [3:0] data0,data1,data2;

integer mcd;

parameter STEP = 10;

cnt_th cnt (clock,reset,Q0,Q1,Q2,data_set,data0,data1,data2);

always #(STEP/2) clock = ~clock;

initial begin
//initialize
 clock = 0; reset = 0;
 data_set = 1'h0;
 data0 = 4'h0; data1 = 4'h0; data2 = 4'h0;

 @(negedge clock);

 repeat(10) @(negedge clock);

 reset = 1;

 repeat(1200) @(negedge clock);

 data0 = 4'h8; data1 = 4'h3; data2 = 4'h7;

 repeat(10) @(negedge clock);

 data_set = 1'b1;
 @(negedge clock);
 data_set = 1'b0;

 repeat(100) @(negedge clock);

$finish;

end

initial $monitor ($stime, "ck=%b res=%b Q0=%h Q1=%h Q2=%h set=%b"
          ,clock,reset,Q0,Q1,Q2,data_set);

initial begin
 mcd = $fopen("cnt_th.dat");
end

always @(negedge clock) begin
$fdisplay(
      mcd,
      "ck=%b res=%b Q0=%h Q1=%h Q2=%h set=%b",
      clock,reset,Q0,Q1,Q2,data_set
      );
end

initial begin
 $shm_open("cnt_th.shm");
 $shm_probe("AS");
end

endmodule

`timescale 1ns/1ns
時間幅設定

wire
reg
ここがRTL記述とちょっとニュアンスが異なるところ。
input,outputの宣言がないので、これで入出力を決める。
wireが観測用信号で、出力に相当。
regが回路に入力する信号。

integer mcd;
後ほど説明。

parameter STEP = 10;
parameterはCで言う、#defineみたいな感じ。

cnt_th cnt (clock,reset,Q0,Q1,Q2,data_set,data0,data1,data2);
テスト対象呼び出し。
モジュール名 インスタンス名()

always #(STEP/2) clock = ~clock;
クロック作成。
STEP/2の時間が経過する度にclockが反転するという記述。
#を付けるとそこ入れられる数字 × 時間幅の時間が経過する。
この場合、5ns毎

initial begin 〜 end
この中に信号の入力タイミングを記述。

 repeat(10) @(negedge clock);
本来はrepeat(10) begin 〜〜 endって書くのだけれど1行の記述だとそれが要らない。
今回の記述は、10クロック分の時間を経過させると考える。

$finish;
beginのend前に絶対記述
これが無いとシミュレーションが終わらない。

initial $monitor ($stime, "ck=%b res=%b Q0=%h Q1=%h Q2=%h set=%b"
          ,clock,reset,Q0,Q1,Q2,data_set);
being〜end以降に記述。
モニターに直接出力。ちょっと動作を確認したい際には使う。
$stimeってのは観測する値が変化した際にモニターに出力するって意味


integer mcd;

initial begin
 mcd = $fopen("cnt_th.dat");
end
always @(negedge clock) begin
$fdisplay(
      mcd,
      "ck=%b res=%b Q0=%h Q1=%h Q2=%h set=%b",
      clock,reset,Q0,Q1,Q2,data_set
      );
end
Cで言うfprintf。

initial begin
 $shm_open("cnt_th.shm");
 $shm_probe("AS");
end
波形確認用の出力。
使ってるのはsignalscan。シェア


このテストベンチでは、最初に値の初期値を代入してresetをHに。そして1200ns程待ってからdataを入れる。⇒カウンタの確認
んで、10ns程待ってからdata_setをHにする。⇒時間のセットの確認
ただそれだけのこと。

一応、長い記述のcnt_10aと楽な記述のcnt_10b両方でこのテストベンチを試し、Linux使ってるので出力したファイルのdiffを取って動作のを確認。
異なる箇所が出なかったので、記述は違ってもちゃんと同じ動作をしてました。


正直な話、ここまで出来たらあとは応用でほとんどの回路&テストベンチが作れますよ。
あとちょっとだけ、テストベンチを簡易化する手法があるけれど、それはまた後ほど。


[<<前へ | ↑Topへ戻る↑ | 次へ>>]