シミュレーションと論理合成を体験する

(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)加算回路のテストベンチ

テストベンチ 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;
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シミュレータ _ □ ×
ファイル(F) 編集(E) ヘルプ
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;
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シミュレータ _ □ ×
ファイル(F) 編集(E) ヘルプ
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

(10)論理合成の実行

もふねこ

いよいよ「論理合成」!Verilogのコードが実際の回路(ゲートレベル)に変換される瞬間だよ🐾
シミュレーションは「ソフト上の確認」、論理合成は「ハードウェアへの翻訳」という違いを意識してみてね。

・論理合成ツールを起動して,加算回路とカウンタの論理合成を実行してみよう

論理合成 _ □ ×
ファイル(F) 編集(E) ビュー(V) ツール(T) ヘルプ(H)
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;
テストベンチのファイル: 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;
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;