スティミュラスの作成
CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 74/90。
Stimulus とは、設計が正しく動作するかどうかをテストするために、設計に対して印加する入力値のことです。入力値を変化させて出力を観察することで、設計が期待通りに動作することを確認できます。
機械のテストのように考えてみましょう。さまざまなボタンを押し(stimulus)、何が起こるかを観察します(outputs)。優れた stimulus を作成することは、testbench を記述する上で不可欠な部分です。
例えば、以下のテストベンチの刺激(stimulus)を見てみましょう:
module testbench;
reg a, b;
wire c;
and_gate dut (
.a(a),
.b(b),
.c(c)
);
initial begin
// スティミュラスここから開始
// テストケース1: 両方の入力が0
a = 0; b = 0; #10;
// テストケース2: a=0, b=1
a = 0; b = 1; #10;
// テストケース3: a=1, b=0
a = 1; b = 0; #10;
// テストケース4: 両方の入力が1
a = 1; b = 1; #10;
// スティミュラスここまで終了
$finish;
end
endmodule各刺激が適用された後、次の刺激の前に10時間単位(#10)待ちます。これにより、DUTが出力を生成する時間が確保されます。
STIMULUS を作成する方法
| 方法 | 最適な用途 | 例 |
|---|---|---|
| Sequential assignments | シンプルなテスト | a = 0; b = 0; #10; |
| For loop | すべての組み合わせのテスト | for (i = 0; i < 4; i++) |
| Repeat loop | パターンを繰り返す場合 | repeat (10) #5 clk = ~clk; |
| Forever loop | 連続信号 | forever #5 clk = ~clk; |
方法 1: シーケンシャル代入 (Sequential Assignments)
最もシンプルなテスト刺激 (stimulus) の作成方法です。ディレイを挟みながら値を1つずつ代入します。
initial begin
a = 0; b = 0; #10;
a = 0; b = 1; #10;
a = 1; b = 0; #10;
a = 1; b = 1; #10;
$finish;
end方法 2: For ループ
可能なすべての入力の組み合わせをテストしたい場合に便利です。
integer i;
initial begin
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i;
#10;
end
$finish;
endこれにより、00、01、10、11 をテストします。
方法 3: Repeat ループ
同じ `stimulus` を何回も繰り返すのに便利です。
initial begin
a = 0; b = 1;
repeat (10) begin
#10 a = ~a;
end
$finish;
end方法 4: Forever ループ
クロックのような連続した信号に便利です。
initial begin
clk = 0;
forever #5 clk = ~clk;
end重要なルール
| ルール | 説明 |
|---|---|
STIMULUSの代入(assign)間にディレイを使用する | #10により、dutが応答するための時間を確保します |
STIMULUS信号にはregを使用する | 時間とともに変化するためです |
最後に$finishを追加する | シミュレーションを終了(finish)させるためです |
チャレンジ
OR ゲートモジュールが与えられています。あなたのタスクは、結果を出力するための不足している stimulus と $display ステートメントを追加することです。
作業手順:
4 つの入力の組み合わせ (00, 01, 10, 11) すべてをテストするための stimulus を追加します:
- 各行で、
xとyの値を設定します - ディレイのために
#10を追加します - 結果を出力するために
$displayを追加します
$display は以下のようになります:
$display("%d %d | %d", x, y, z);自分で試してみよう
module or_gate (
input x,
input y,
output z
);
assign z = x | y;
endmodule
module testbench;
reg x, y;
wire z;
or_gate dut (
.x(x),
.y(y),
.z(z)
);
initial begin
$display("x y | z");
$display("---------");
// TODO: 0 0 の刺激と表示を追加
// TODO: 0 1 の刺激と表示を追加
// TODO: 1 0 の刺激と表示を追加
// TODO: 1 1 の刺激と表示を追加
$finish;
end
endmoduleこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。