... | ... | @@ -8,14 +8,14 @@ Verilogは、ハードウェア設計のための記述言語(HDL: Hardware De |
|
|
Verilogでの基本構成は以下のようになります:
|
|
|
|
|
|
- `module`:回路のブロック(部品)
|
|
|
- `input` / `output`:端子
|
|
|
- `input` / `output`:入出力端子
|
|
|
- `wire` / `reg`:信号を表現する変数(信号線やレジスタ)
|
|
|
- `wire` は常に接続されている線、と考えるとよいと思います、組み合わせ回路や、モジュール間の接続、ピンの入出力など、の用途に使います
|
|
|
- `reg` は記憶を持つ変数であり、フリップフロップ、状態変数など、クロックなどに応じて値が変化するような用途に使います
|
|
|
- `wire` は常に接続されている線、と考えるとよいと思います、モジュール間の接続、ピンの入出力など、の用途に使います
|
|
|
- `reg` は、主にフリップフロップ、状態変数など、クロックなどに応じて値が変化するような用途に使います。alwaysなどのブロックの中で代入します
|
|
|
- `assign`:**組み合わせ回路の論理式を記述するための代入文**。`wire` 型の信号に対して使用され、いつでも右辺の論理式に応じて出力が変化します。
|
|
|
- `always`:**条件に基づく処理(順序回路や条件に基づいた組み合わせ回路)を記述するブロック**。
|
|
|
- `always @(posedge clk)` などクロックを指定して、**順序回路**の動作を記述することができます。
|
|
|
- `always @(*)` のようにセンシティビティリストに `*` を使って、**条件に基づいた組み合わせ回路**を記述することができます。assignでは記述が難しい、複雑な条件分岐を伴う組み合わせ回路の記述に適しています。その際、出力信号の変数には`reg`を使います。
|
|
|
- `always @(*)` のようにセンシティビティリストに `*` を使って、**条件に基づいた組み合わせ回路**を記述することができます。その際、出力の変数としてはregを利用します。
|
|
|
|
|
|
```verilog
|
|
|
wire a, b, y;
|
... | ... | @@ -26,7 +26,7 @@ always @(posedge clk) begin |
|
|
state <= next_state; // クロックの立ち上がりに応じたregへの代入(順序回路)
|
|
|
end
|
|
|
|
|
|
reg [1:0] sel; // always @(*)を用いた組み合わせ回路の出力にはregを使う
|
|
|
reg [1:0] sel; // always @(*)内での使用に向けて2bitのreg変数を宣言
|
|
|
always @(*) begin
|
|
|
if (sel == 2'd0) begin
|
|
|
out = in0;
|
... | ... | @@ -44,7 +44,6 @@ end |
|
|
|
|
|
Verilog HDLでは`module`を使って回路ブロックを作成します。
|
|
|
|
|
|
#### 例:ANDゲート
|
|
|
```verilog
|
|
|
module and_gate (
|
|
|
input wire inA, // 1bitの入力信号
|
... | ... | @@ -63,7 +62,6 @@ endmodule |
|
|
|
|
|
テストベンチは、記述した回路が正しく動作するかを検証するためのVerilog HDLコードです。
|
|
|
|
|
|
### 例:ANDゲート用テストベンチ
|
|
|
```verilog
|
|
|
module testbench;
|
|
|
// パラメータ
|
... | ... | @@ -71,29 +69,30 @@ module testbench; |
|
|
parameter HALF_CYCLE = 500;
|
|
|
parameter DLY = 500;
|
|
|
|
|
|
// シグナル
|
|
|
// 信号の定義
|
|
|
reg clk;
|
|
|
reg inA, inB;
|
|
|
wire out_and_gate;
|
|
|
|
|
|
// テスト対象モジュール
|
|
|
// テスト対象モジュールのANDゲートをインスタンス化
|
|
|
and_gate and_gate_0 (
|
|
|
.inA(inA),
|
|
|
.inB(inB),
|
|
|
.out(out_and_gate)
|
|
|
);
|
|
|
|
|
|
// クロック生成
|
|
|
// クロック生成: HIGH/LOWを繰り返す
|
|
|
always begin
|
|
|
clk = 1'b1;
|
|
|
#(HALF_CYCLE) clk = 1'b0;
|
|
|
#(HALF_CYCLE);
|
|
|
#(HALF_CYCLE); // #によって時間遅延を表現できる、#のあとに指定した単位時間だけ待って次の処理に移る
|
|
|
end
|
|
|
|
|
|
// テストシナリオ
|
|
|
initial begin
|
|
|
inA = 1'b0; inB = 1'b0;
|
|
|
inA = 1'b0; inB = 1'b0; // 初期化
|
|
|
|
|
|
// 入力を変化させ、出力を表示
|
|
|
inA = 1'b0; inB = 1'b0;
|
|
|
#100 $display("inA=%b inB=%b out=%b", inA, inB, out_and_gate);
|
|
|
inA = 1'b1; inB = 1'b0;
|
... | ... | @@ -102,7 +101,7 @@ module testbench; |
|
|
#100 $display("inA=%b inB=%b out=%b", inA, inB, out_and_gate);
|
|
|
inA = 1'b1; inB = 1'b1;
|
|
|
#100 $display("inA=%b inB=%b out=%b", inA, inB, out_and_gate);
|
|
|
|
|
|
// クロックの立ち上がり10回待って終了
|
|
|
repeat(10) @(posedge clk); // 10回繰り返し
|
|
|
$finish;
|
|
|
end
|
... | ... | |