シミュレーションと論理合成を体験する
(1)ここで学ぶ内容
書いた回路が正しく動くか確認する「シミュレーション」と、回路図に変換する「論理合成」を体験するよ🐾
特に『テストベンチ』の書き方は、設計と同じくらい実務でよく使うから要チェック!
概要
目標
修了判定
- 動作を確認するための記述「テストベンチ」について学ぶ
- 疑似ツールを使ってシミュレーションと論理合成を体験する
目標
(1)以下の項目を理解し説明できる
- テストベンチ
- initial文
- parameter 宣言
- 代入文による入力信号の変化
- クロックの記述
(2)シミュレータと論理合成ツールを操作できる
修了判定
フルアダーを用いた加算回路をシミュレーションと論理合成する
(2)シミュレーションと論理合成
シミュレーションによる動作確認
Verilog-HDL シミュレータを用いて回路に適切な入力を与え、出力を確認する仕組みが必要
論理合成を行い回路を生成
論理合成の記述ファイルと合成対象の ASIC,FPGA のライブラリを用いて論理合成を行い回路を生成
(3)テストベンチ
テストベンチ adder_tp (検証対象の上の階層)
4ビット加算回路
graph LR
subgraph テストベンチ
subgraph 信号生成
R1[reg a]
R2[reg b]
end
ADD[adder
4ビット加算回路] subgraph 観測 W1[wire q] end R1 -->|4| ADD R2 -->|4| ADD ADD -->|4| W1 end style ADD fill:#e3f2fd,stroke:#1976d2,stroke-width:2px; style R1 fill:#fff9c4,stroke:#fbc02d; style R2 fill:#fff9c4,stroke:#fbc02d; style W1 fill:#e8f5e9,stroke:#388e3c;
4ビット加算回路] subgraph 観測 W1[wire q] end R1 -->|4| ADD R2 -->|4| ADD ADD -->|4| W1 end style ADD fill:#e3f2fd,stroke:#1976d2,stroke-width:2px; style R1 fill:#fff9c4,stroke:#fbc02d; style R2 fill:#fff9c4,stroke:#fbc02d; style W1 fill:#e8f5e9,stroke:#388e3c;
- 検証対象に対して上位階層を用意する
- 上位階層側で,テスト入力の印加,出力の観測を行う
(4)加算回路のテストベンチ
テストベンチ adder_tp
4ビット加算回路
graph LR
subgraph テストベンチ
subgraph 信号生成
R1[reg a]
R2[reg b]
end
ADD[adder
4ビット加算回路] subgraph 観測 W1[wire q] end R1 -->|4| ADD R2 -->|4| ADD ADD -->|4| W1 end style ADD fill:#e3f2fd,stroke:#1976d2,stroke-width:2px; style R1 fill:#fff9c4,stroke:#fbc02d; style R2 fill:#fff9c4,stroke:#fbc02d; style W1 fill:#e8f5e9,stroke:#388e3c;
4ビット加算回路] subgraph 観測 W1[wire q] end R1 -->|4| ADD R2 -->|4| ADD ADD -->|4| W1 end style ADD fill:#e3f2fd,stroke:#1976d2,stroke-width:2px; style R1 fill:#fff9c4,stroke:#fbc02d; style R2 fill:#fff9c4,stroke:#fbc02d; style W1 fill:#e8f5e9,stroke:#388e3c;
module adder_tp;
reg [3:0] a, b;
wire [3:0] q;
// 検証対象接続
adder A1( a, b, q );
// テスト入力
initial begin
a = 4'h0; b = 4'h0;
#1000 a = 4'h5; b = 4'ha;
#1000 a = 4'h7; b = 4'ha;
#1000 a = 4'h1; b = 4'hf;
#1000 a = 4'hf; b = 4'hf;
#1000 $finish;
end
// 表示
initial $monitor( $stime,
" a=%h b=%h q=%h", a, b, q );
endmodule
(5)シミュレーション時のファイル指定
シミュレータの起動
% verilog adder_tp.v adder.v
テストベンチ
module adder_tp;
reg [3:0] a, b;
wire [3:0] q;
. . .
// 検証対象接続
adder A1( a, b, q );
. . .
endmodule
回路記述
module adder( a, b, q );
input [3:0] a, b;
output [3:0] q;
assign q = a + b;
endmodule
(6)加算回路のシミュレーション
・シミュレータを起動して,加算回路のシミュレーションを実行してみよう
Verilog-HDLシミュレータ
_ □ ×
D:/tools/verisim/sample>
(7)クロックの記述
always 文によるクロックの記述
reg ck; ─→ クロック信号をreg宣言
always begin ─→ 無限ループ
ck = 1; ─→ ckを1に
#500; ─→ 500ユニットの遅延
ck = 0; ─→ ckを0に
#500; ─→ 500ユニットの遅延
end
ck ┊ 1 │┌────┐ ┌────┐ ┌────┐ ││ │ │ │ │ │ 0 ┼┴────┴────┴────┴────┴────┴──── 0 500 1000 1500 2000 2500 3000
(8)カウンタのテストベンチ
4ビット
バイナリカウンタ
graph LR
subgraph 4ビット・バイナリカウンタ
CNT[counter
► ck] end RES[res] --> CNT CK[ck] --> CNT CNT -->|4| Q[q
4bit] style CNT fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
► ck] end RES[res] --> CNT CK[ck] --> CNT CNT -->|4| Q[q
4bit] style CNT fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
module count_tp;
reg ck, res;
wire [3:0] q;
parameter STEP = 1000;
// 検証対象接続
counter C1 ( ck, res, q );
// クロック作成
always begin
ck = 0; #(STEP/2);
ck = 1; #(STEP/2);
end
// テスト入力
initial begin
res = 0;
#STEP res = 1;
#STEP res = 0;
#(STEP*20)
$finish;
end
// 表示
initial $monitor($stime,"ck=%b res=%b q=%h",ck,res,q );
endmodule
(9)カウンタのシミュレーション
・シミュレータを起動して,カウンタのシミュレーションを実行してみよう
Verilog-HDLシミュレータ
_ □ ×
D:/tools/verisim/sample>ls
. .. adder_tp.v adder.v adder_tp.vcd
adder_tp.sim
D:/tools/verisim/sample>ls -l
0 99/05/12 16:00 .
0 99/05/12 16:00 ..
478 99/05/12 16:10 adder_tp.v
142 99/05/12 16:10 adder.v
345 99/02/09 18:03 adder_tp.vcd
120 99/05/12 16:13 adder_tp.sim
D:/tools/verisim/sample>cd..
D:/tools/verisim/sample>ls -l
0 99/05/12 16:00 .
0 99/05/12 16:00 ..
0 99/05/12 16:00 sample
. .. adder_tp.v adder.v adder_tp.vcd
adder_tp.sim
D:/tools/verisim/sample>ls -l
0 99/05/12 16:00 .
0 99/05/12 16:00 ..
478 99/05/12 16:10 adder_tp.v
142 99/05/12 16:10 adder.v
345 99/02/09 18:03 adder_tp.vcd
120 99/05/12 16:13 adder_tp.sim
D:/tools/verisim/sample>cd..
D:/tools/verisim/sample>ls -l
0 99/05/12 16:00 .
0 99/05/12 16:00 ..
0 99/05/12 16:00 sample
(10)論理合成の実行
いよいよ「論理合成」!Verilogのコードが実際の回路(ゲートレベル)に変換される瞬間だよ🐾
シミュレーションは「ソフト上の確認」、論理合成は「ハードウェアへの翻訳」という違いを意識してみてね。
・論理合成ツールを起動して,加算回路とカウンタの論理合成を実行してみよう
論理合成
_ □ ×
⬆
➕
➖
SRC
SCR
NET
RPT
(11)修了判定
設問
フルアダーを用いた加算回路( E1ユニット )を,
・シミュレーション
・論理合成
する。
・シミュレーション
・論理合成
する。
🌸
たいへん
よく
できました
よく
できました
4ビット加算回路
graph LR
subgraph 4ビット加算回路
ADD[adder]
end
A[a
4bit] -->|4| ADD B[b
4bit] -->|4| ADD ADD -->|4| Q[q
4bit] style ADD fill:#e3f2fd,stroke:#1976d2,stroke-width:2px;
4bit] -->|4| ADD B[b
4bit] -->|4| ADD ADD -->|4| Q[q
4bit] style ADD fill:#e3f2fd,stroke:#1976d2,stroke-width:2px;
| テストベンチのファイル | : adder_tp2.v |
| 4ビット加算回路のファイル | : adder_ripple.v |
| フルアダーのファイル | : fulladd.v |
graph TD
a0[a 0] --> add0[add0
fulladd] b0[b 0] --> add0 add0 --> q0[q 0] a1[a 1] --> add1[add1
fulladd] b1[b 1] --> add1 add1 --> q1[q 1] a2[a 2] --> add2[add2
fulladd] b2[b 2] --> add2 add2 --> q2[q 2] a3[a 3] --> add3[add3
fulladd] b3[b 3] --> add3 add3 --> q3[q 3] cin[CIN 0] -.->|COUT0| add0 add0 -.->|COUT1| add1 add1 -.->|COUT2| add2 add2 -.->|COUT3| add3 add3 -.->|COUT4| cout[開放] style add0 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style add1 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style add2 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style add3 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
fulladd] b0[b 0] --> add0 add0 --> q0[q 0] a1[a 1] --> add1[add1
fulladd] b1[b 1] --> add1 add1 --> q1[q 1] a2[a 2] --> add2[add2
fulladd] b2[b 2] --> add2 add2 --> q2[q 2] a3[a 3] --> add3[add3
fulladd] b3[b 3] --> add3 add3 --> q3[q 3] cin[CIN 0] -.->|COUT0| add0 add0 -.->|COUT1| add1 add1 -.->|COUT2| add2 add2 -.->|COUT3| add3 add3 -.->|COUT4| cout[開放] style add0 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style add1 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style add2 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style add3 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
D:/exam/E_unit/E3_11>verilog adder_tp2.v adder_ripple.v fulladd.v
Verilog-HDL (faked) simulator
Copyright 1999-2002 hdLab, Inc.
Compiling source file "adder_tp2.v"
Compiling source file "adder_ripple.v"
Compiling source file "fulladd.v"
0 a=0 b=0 q=0
1000 a=5 b=a q=f
2000 a=7 b=a q=1
3000 a=1 b=f q=0
4000 a=f b=f q=e
End of simulation 15/09/03 15:26:06
|0 |1000 |2000 |3000 |4000
──────────┼──────────┼──────────┼──────────┼──────────┼──────────
a[3:0] |0 |5 |7 |1 |f
──────────┼──────────┼──────────┼──────────┼──────────┼──────────
b[3:0] |0 |a |f |
──────────┼──────────┼─────────────────────┼──────────┼──────────
q[3:0] |0 |f |1 |0 |e
──────────┼──────────┼──────────┼──────────┼──────────┼──────────
adder_ripple.v (論理合成後ネットリスト概要)
graph LR
subgraph adder_ripple.v 論理合成後ネットリスト
direction LR
A[入力 a]
B[入力 b]
FA0[fulladd add0]
FA1[fulladd add1]
FA2[fulladd add2]
FA3[fulladd add3]
Q0[出力 q0]
Q1[出力 q1]
Q2[出力 q2]
Q3[出力 q3]
A -->|a0| FA0
B -->|b0| FA0
FA0 --> Q0
A -->|a1| FA1
B -->|b1| FA1
FA1 --> Q1
A -->|a2| FA2
B -->|b2| FA2
FA2 --> Q2
A -->|a3| FA3
B -->|b3| FA3
FA3 --> Q3
CIN[logic 0] -->|CIN| FA0
FA0 -->|COUT| FA1
FA1 -->|COUT| FA2
FA2 -->|COUT| FA3
FA3 -->|COUT| OPEN[open]
end
style FA0 fill:#e8f5e9,stroke:#388e3c;
style FA1 fill:#e8f5e9,stroke:#388e3c;
style FA2 fill:#e8f5e9,stroke:#388e3c;
style FA3 fill:#e8f5e9,stroke:#388e3c;
※右に伝搬する carry (COUT -> CIN) を表現しています。
fulladd.v (論理合成後ゲートレベル)
graph LR
A[A] --> XOR1{{XOR}}
B[B] --> XOR1
XOR1 --> XOR2{{XOR}}
CIN[CIN] --> XOR2
XOR2 --> Q[Q]
A --> AND1{{AND}}
B --> AND1
XOR1 --> AND2{{AND}}
CIN --> AND2
AND1 --> NOR1{{NOR}}
AND2 --> NOR1
NOR1 --> NOT1{{NOT}}
NOT1 --> COUT[COUT]
style XOR1 fill:#e3f2fd,stroke:#1976d2;
style XOR2 fill:#e3f2fd,stroke:#1976d2;
style AND1 fill:#e8f5e9,stroke:#388e3c;
style AND2 fill:#e8f5e9,stroke:#388e3c;
style NOR1 fill:#fff3e0,stroke:#f57c00;
style NOT1 fill:#f3e5f5,stroke:#9c27b0;
