シミュレーション専用モデルを書く

(1)学習の概要と目標

設計した回路の外側につながる部分を自分でつくることが出来ます。これをシミュレーションモデルといいますが、意外と簡単です。「ないものは自分でつくる」という精神が大事です。

概要
  • システムレベルの検証に利用できるシミュレーションモデルの作成例と利用例を学ぶ
目標

以下の項目を理解し説明できる

  • シミュレーションモデルとは
  • ROM シミュレーションモデル
  • RAM シミュレーションモデル
修了判定

サイコロカウンタのシミュレーションを行ない動作確認する

(2)シミュレーションモデルとは

回路記述を検証するための周辺回路の動作記述を「シミュレーションモデル」といいます。回路記述を検証するには通常、その回路に対する入力信号を含んだテストベンチを用意します。

もふねこ

もふねこ:
RTLの動作確認をするとき、CPUやメモリの「ダミー(シミュレーションモデル)」を自分でサクッと作れるようになると、デバッグがめちゃくちゃ楽になるよ🐾!
論理合成できない書き方(#遅延とか)もシミュレーションなら使い放題だから、色々工夫してみてね!

一般に設計対象の回路は CPU やメモリなどと共に製品を構成しています。これらの周辺回路を含んだ状態でシミュレーションを行えば簡単に検証ができます。つまり個々の入力信号を用意しなくても、CPU のプログラムを用意すればシステム全体の動作を確認できるのです。

  • 検証のための周辺回路の記述
  • CPU などの複雑な機能を持ったものは ASIC ベンダなどから購入
  • ROM・RAM などの RTL モデルは自作で十分
【システム全体のテストベンチ構成例】
テストベンチ内に「回路記述」「CPU」「ROM」「RAM」を配置し、バスで接続して検証する
graph TD subgraph テストベンチ (システムレベル検証) direction LR CPU[CPU モデル] RTL[設計した回路 RTL] ROM[ROM モデル
rom_data.hex] RAM[RAM モデル] BUS[システムバス] CPU <--> BUS RTL <--> BUS ROM --> BUS RAM <--> BUS end style CPU fill:#f3e5f5,stroke:#9c27b0; style RTL fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; style ROM fill:#e3f2fd,stroke:#1976d2; style RAM fill:#e3f2fd,stroke:#1976d2;

CPU などの複雑な機能を持ったものは ASIC ベンダや AP ベンダに供給してもらいます。遅延を考慮しない RTL シミュレーションに限れば、ROM や RAM などは自作で十分でしょう。

これらのシミュレーションモデルは論理合成することはないので、論理合成にあわせた記述をする必要はありません。HDL の記述能力を最大限生かして記述することが出来ます。

(3)ROMシミュレーションモデル

簡単な ROM シミュレーションモデルを紹介します。15 ビットの ADDR と 1 ビットの出力制御信号(OEB)が入力され、8 ビットの DATA が出力されます。

ROM モデルの仕様

  • 入力:ADDR[14:0]OEB
  • 出力:DATA[7:0]

※ROM のデータはあらかじめ別ファイル("rom_data.hex")に用意しておき、シミュレーション開始時に $readmemh で読み込みます。

// ROMシミュレーションモデル
module ROM ( ADDR, DATA, OEB );
input   [14:0]  ADDR;
input           OEB;
output  [7:0]   DATA;

reg     [7:0]   MEM [0:32767]; // レジスタ配列

// 読み出し遅延
parameter   RDELAY = 1500;

assign #RDELAY DATA = 
            (OEB==0) ? MEM[ADDR] : 8'hZZ;

// シミュレーション開始時にファイル読み込み
initial $readmemh( "rom_data.hex", MEM );

endmodule

ROM のデータはレジスタ配列 MEM に格納します。このデータはあらかじめ別ファイルに用意しておき、シミュレーションがはじまったときに読み込みます。シミュレーション開始後に initial 文が実行され、データの読み込みにはシステムタスクの $readmemh を使います。

データの読み出しは assign 文で行います。出力制御信号 OEB が 0 のときにアドレスに対応したメモリの内容が出力され、1 のときにはハイインピーダンス(8'hZZ)が出力されるように記述します。

RDELAY は読み出し遅延時間で、あらかじめ parameter で設定しておきます。RTL のシミュレーションであればこの遅延はなくてもかまいません。

アドレス・DATA の幅は使用するシステムに合わせて変えます。あまり大きすぎるとシミュレーション速度が低下するので注意しましょう。

graph LR subgraph ROMモデル ADDR1[ADDR 15bit] --> R[ROM] OEB1[OEB] --> R R --> DATA1[DATA 8bit] end style R fill:#e3f2fd,stroke:#1976d2;
graph LR subgraph RAMモデル ADDR2[ADDR 15bit] --> RM[RAM] CEB2[CEB] --> RM WEB2[WEB] --> RM OEB2[OEB] --> RM DATA2[DATA 8bit 双方向] <--> RM end style RM fill:#fff3e0,stroke:#f57c00;

(4)RAMシミュレーションモデル

簡単な RAM シミュレーションモデルを紹介します。15 ビットの ADDR と 1 ビットの制御信号 3 本(CEB、WEB、OEB)が入力され、8 ビットの DATA は入出力として宣言されています。

RAM モデルの仕様

  • 入力:ADDR[14:0]CEBWEBOEB
  • 入出力(双方向):DATA[7:0]

$readmemh, $writememh でメモリ内容のファイルアクセスが可能です。より正確な遅延付加には specify ブロックを使用します。

// RAMシミュレーションモデル
module RAM ( ADDR, DATA, CEB, WEB, OEB );
input   [14:0]  ADDR;
input           CEB, WEB, OEB;
inout   [7:0]   DATA;   // 双方向ポート

reg     [7:0]   MEM [0:32767];
wire            WRITE, READ;      // 内部制御信号

// 書き込み, 読み出し遅延
parameter   WDELAY = 1000, RDELAY = 1500;

always @( WRITE or DATA ) begin
    #WDELAY
    if ( WRITE==1'b1 )
        MEM[ADDR] <= DATA;
end

assign READ  = (OEB==1'b0) & (CEB==1'b0);
assign WRITE = (WEB==1'b0) & (CEB==1'b0);

assign #RDELAY DATA = READ ? MEM[ADDR] : 8'hZZ;

endmodule

入出力ポートはキーワード inout の後にビット幅、ポート名を書いて宣言します。RAM のデータはレジスタ配列 MEM に格納します。データの読み出しと書き込みの切り替えは 3 本の制御信号を使って行います。READ が 1 のときにデータ読み出し、WRITE が 1 のときにデータ書き込みになります。

データの読み出しは ROM と同様に、assign 文を使って記述します。データの書き込みは always 文を使用します。RAM の場合は値を記憶しなければならないので、フリップフロップかラッチの記述になります。RAM の動作はラッチに近いのでラッチと同じ書き方です。

この RAM の記述で注意しなければならないのは、入力と出力が衝突しないようにすることです。データポートは双方向です。データを読み出すとき以外はデータ端子をハイインピーダンスにしています。

書き込み遅延を WDELAY、読み出し遅延を RDELAY と定義して記述しています。これらの遅延は ROM の場合と同様に RTL のシミュレーションにはなくてもかまいません(より正確な遅延付加には specify ブロックを使います)。

このようなモデルをつかってシミュレーションを行うと、システムタスクの $readmemh$writememh を使用してメモリの内容を自由に読み書きできます。これらの機能はデバッグする上で非常に便利に使用できます。

(5)シミュレーションモデルの応用例

シミュレーションモデルの簡単な応用例を紹介します。サイコロカウンタの記述を作成し、シミュレーションする場合を考えてみます。

サイコロカウンタの仕様
  • 入力信号:CLK, RES, EN
  • 出力信号:LAMP[6:0](サイコロの目一個一個に対応)
  • EN=1 の時、サイコロ回転(目が変わる)
  • EN=0 の時、サイコロ停止
  • RES=1 の時、リセット(1の目を表示)

テストベンチを作成する場合、各入出力信号を表示させて動作のチェックを行うのが一般的です。しかし出力信号 LAMP の値を 1、0 で表示させてもサイコロのどの目が出ているのかすぐにはわかりません。

// 生の LAMP 出力のシミュレーション結果(判読が難しい)
       .
       .
   33500 CLK=0 RES=0 EN=1 LAMP=1110111
   34000 CLK=1 RES=0 EN=1 LAMP=0001000
   34500 CLK=0 RES=0 EN=1 LAMP=0001000
   35000 CLK=1 RES=0 EN=1 LAMP=1000001
   35500 CLK=0 RES=0 EN=1 LAMP=1000001
   36000 CLK=1 RES=0 EN=1 LAMP=0011100
   36500 CLK=0 RES=0 EN=1 LAMP=0011100
   37000 CLK=1 RES=0 EN=1 LAMP=1010101
   37500 CLK=0 RES=0 EN=1 LAMP=1010101
   38000 CLK=1 RES=0 EN=1 LAMP=1011101
   38500 CLK=0 RES=0 EN=1 LAMP=1011101
   39000 CLK=1 RES=0 EN=1 LAMP=1110111
   39500 CLK=0 RES=0 EN=1 LAMP=1110111
   40000 CLK=1 RES=0 EN=1 LAMP=0001000
   40500 CLK=0 RES=0 EN=1 LAMP=0001000
   41000 CLK=1 RES=0 EN=1 LAMP=1000001
   41250 CLK=1 RES=0 EN=0 LAMP=1000001
   41500 CLK=0 RES=0 EN=0 LAMP=1000001
   42000 CLK=1 RES=0 EN=0 LAMP=1000001
   42500 CLK=0 RES=0 EN=0 LAMP=1000001
   43000 CLK=1 RES=0 EN=0 LAMP=1000001
       .
       .

そこで出力 LAMP をエンコードして 1~6 を出力するシミュレーションモデル DISP_ENC を作成します。このシミュレーションモデルとサイコロカウンタの記述をテストベンチの中で接続します。そしてこのシミュレーションモデルの出力 DISP をみればサイコロの表示を一目で確認できます。

graph LR subgraph テストベンチ direction LR CLK[CLK] --> SAI[SAIKORO2] EN[EN] --> SAI SAI -->|LAMP 7bit| DISP1[DISP_ENC
数値化] SAI -->|LAMP 7bit| DISP2[DISP_ENC2
アスキーアート表示] EN --> DISP2 end style SAI fill:#e8f5e9,stroke:#388e3c; style DISP1 fill:#fff3e0,stroke:#f57c00; style DISP2 fill:#fff3e0,stroke:#f57c00;
// DISP 出力を追加したシミュレーション結果(判読しやすい)
       .
       .
   33500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6
   34000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1
   34500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1
   35000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2
   35500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2
   36000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3
   36500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3
   37000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4
   37500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4
   38000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5
   38500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5
   39000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6
   39500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6
   40000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1
   40500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1
   41000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2
   41250 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2
   41500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2
   42000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2
   42500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2
   43000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2
       .
       .

これは非常に簡単な例ですが、目で見て確認する場合には、大きな効果が期待できます。

サイコロカウンタであれば上記のようなシミュレーションで十分検証できますが、さらに一工夫して $display を使ったシミュレーションモデル DISP_ENC2 を記述すると、テキストベースの表示でもサイコロの絵を出すことが出来ます。制御信号 EN が 0 に変化したときだけサイコロの絵をだすようにすればシミュレーション結果も見やすくなります。

// ASCII アートによるサイコロ表示(EN=0 になった瞬間のみ表示)
       .
       .
   35500 CLK=0 RES=0 EN=1 LAMP=1000001
   36000 CLK=1 RES=0 EN=1 LAMP=0011100
   36500 CLK=0 RES=0 EN=1 LAMP=0011100
   37000 CLK=1 RES=0 EN=1 LAMP=1010101
   37500 CLK=0 RES=0 EN=1 LAMP=1010101
   38000 CLK=1 RES=0 EN=1 LAMP=1011101
   38500 CLK=0 RES=0 EN=1 LAMP=1011101
   39000 CLK=1 RES=0 EN=1 LAMP=1110111
   39500 CLK=0 RES=0 EN=1 LAMP=1110111
   40000 CLK=1 RES=0 EN=1 LAMP=0001000
   40500 CLK=0 RES=0 EN=1 LAMP=0001000
   41000 CLK=1 RES=0 EN=1 LAMP=1000001
  +-------+
  | @     |
  |       |
  |     @ |
  +-------+
   41250 CLK=1 RES=0 EN=0 LAMP=1000001
   41500 CLK=0 RES=0 EN=0 LAMP=1000001
   42000 CLK=1 RES=0 EN=0 LAMP=1000001
   42500 CLK=0 RES=0 EN=0 LAMP=1000001
   43000 CLK=1 RES=0 EN=0 LAMP=1000001

このように VerilogHDL の記述能力を活用するといろいろなことが出来ます。ぜひチャレンジしてみてください。ただしやりすぎにならないように注意しましょう。

(6)修了判定

設問

ワンポイント・アドバイスのサイコロカウンタのシミュレーションを実行してください。サイコロカウンタ、テストベンチ、シミュレーションモデルの内容を良く確認してください。

サイコロカウンタの表示と LAMP 出力
表示(目) LAMP [6:0] 表示(目) LAMP [6:0]
1 0001000 4 1010101
2 1000001 5 1011101
3 0011100 6 1110111

ファイル構成:saikoro2.v(本体)、saikoro2_test.v(テストベンチ)、disp_enc.vdisp_enc2.v(シミュレーションモデル)

1. サイコロカウンタ本体(saikoro2.v)

module SAIKORO2( CLK, RES, EN, LAMP );

input           CLK, RES, EN;
output  [6:0]   LAMP;
reg     [6:0]   LAMP;

reg     [6:0]   LAMP_NEXT;

always @( posedge CLK or posedge RES ) begin
    if ( RES==1'b1 )
        LAMP <= 7'b0001000;
    else
        LAMP <= LAMP_NEXT;
end

always @( EN or LAMP ) begin
    if ( EN==1'b1 )
        case ( LAMP )
            7'b0001000 : LAMP_NEXT <= 7'b1000001; // 1 -> 2
            7'b1000001 : LAMP_NEXT <= 7'b0011100; // 2 -> 3
            7'b0011100 : LAMP_NEXT <= 7'b1010101; // 3 -> 4
            7'b1010101 : LAMP_NEXT <= 7'b1011101; // 4 -> 5
            7'b1011101 : LAMP_NEXT <= 7'b1110111; // 5 -> 6
            7'b1110111 : LAMP_NEXT <= 7'b0001000; // 6 -> 1
            default    : LAMP_NEXT <= 7'bX;
        endcase
    else
        LAMP_NEXT <= LAMP;
end

endmodule

2. シミュレーションモデル1:数値エンコーダ(disp_enc.v)

module DISP_ENC( LAMP, DISP );

input   [6:0] LAMP;
output  [2:0] DISP;
reg     [2:0] DISP;

always @( LAMP ) begin
    case ( LAMP )
        7'b0001000 : DISP <= 3'd1;
        7'b1000001 : DISP <= 3'd2;
        7'b0011100 : DISP <= 3'd3;
        7'b1010101 : DISP <= 3'd4;
        7'b1011101 : DISP <= 3'd5;
        7'b1110111 : DISP <= 3'd6;
        default    : DISP <= 3'dX;
    endcase
end

endmodule

3. シミュレーションモデル2:アスキーアート表示(disp_enc2.v)

module DISP_ENC2( LAMP, EN );
input           EN;
input   [6:0]   LAMP;

// ENが0に立ち下がった瞬間(停止したとき)にサイコロを描画
always @(negedge EN) begin
    case (LAMP)
        7'b0001000 : begin
            $display("  +-------+  ");
            $display("  |       |  ");
            $display("  |   @   |  ");
            $display("  |       |  ");
            $display("  +-------+  "); end
        7'b1000001 : begin
            $display("  +-------+  ");
            $display("  | @     |  ");
            $display("  |       |  ");
            $display("  |     @ |  ");
            $display("  +-------+  "); end
        7'b0011100 : begin
            $display("  +-------+  ");
            $display("  |     @ |  ");
            $display("  |   @   |  ");
            $display("  | @     |  ");
            $display("  +-------+  "); end
        7'b1010101 : begin
            $display("  +-------+  ");
            $display("  | @   @ |  ");
            $display("  |       |  ");
            $display("  | @   @ |  ");
            $display("  +-------+  "); end
        7'b1011101 : begin
            $display("  +-------+  ");
            $display("  | @   @ |  ");
            $display("  |   @   |  ");
            $display("  | @   @ |  ");
            $display("  +-------+  "); end
        7'b1110111 : begin
            $display("  +-------+  ");
            $display("  | @   @ |  ");
            $display("  | @   @ |  ");
            $display("  | @   @ |  ");
            $display("  +-------+  "); end
        default    : begin
            $display("  +-------+  ");
            $display("  | ?   ? |  ");
            $display("  | ? ? ? |  ");
            $display("  | ?   ? |  ");
            $display("  +-------+  "); end
    endcase
end

endmodule

4. テストベンチ(saikoro2_test.v)

module SAIKORO2_TEST;
reg         CLK, RES, EN;
wire  [6:0] LAMP;
wire  [2:0] DISP;

parameter CYCLE = 1000;

// 本体とシミュレーションモデルのインスタンス化
SAIKORO2 SAIKORO (.CLK(CLK), .RES(RES), .EN(EN), .LAMP(LAMP));
DISP_ENC ENCODER (.LAMP(LAMP), .DISP(DISP));
DISP_ENC2 ENCODER2 (.LAMP(LAMP), .EN(EN));

always begin
          CLK = 1'b1;
#(CYCLE/2) CLK = 1'b0;
#(CYCLE/2);
end

initial begin
    RES = 1'b0;
    EN  = 1'b0;
    #(CYCLE/4);
    RES = 1'b1;
    #CYCLE;
    RES = 1'b0;
    #(CYCLE * 8);
    EN  = 1'b1;
    #(CYCLE * 11);
    EN  = 1'b0;
    #(CYCLE * 7);
    EN  = 1'b1;
    #(CYCLE * 14);
    EN  = 1'b0;
    #(CYCLE * 7);
    EN  = 1'b1;
    #(CYCLE * 19);
    EN  = 1'b0;
    #(CYCLE * 7);
    $finish;
end

initial begin
$monitor( $time, " CLK=%b RES=%b EN=%b LAMP=%b DISP=%d", CLK, RES, EN, LAMP, DISP );
end

endmodule

5. シミュレーション実行結果

テキストベースの表示でもサイコロの絵を出すことが出来ます。テストベンチによる詳細なシミュレーション出力は以下のようになります(図 14 ~ 18 の完全な文字起こし)。

0 CLK=1 RES=0 EN=0 LAMP=xxxxxxx DISP=x +-------+ | ? ? | | ? ? ? | | ? ? | +-------+ 250 CLK=1 RES=1 EN=0 LAMP=0001000 DISP=1 500 CLK=0 RES=1 EN=0 LAMP=0001000 DISP=1 1000 CLK=1 RES=1 EN=0 LAMP=0001000 DISP=1 1250 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 1500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 2000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 2500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 3000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 3500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 4000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 4500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 5000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 5500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 6000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 6500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 7000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 7500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 8000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 8500 CLK=0 RES=0 EN=0 LAMP=0001000 DISP=1 9000 CLK=1 RES=0 EN=0 LAMP=0001000 DISP=1 9250 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 9500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 10000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 10500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 11000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 11500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 12000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 12500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 13000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 13500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 14000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 14500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 15000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 15500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 16000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 16500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 17000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 17500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 18000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 18500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 19000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 19500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 20000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 +-------+ | @ @ | | @ @ | | @ @ | +-------+ 20250 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 20500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 21000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 21500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 22000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 22500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 23000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 23500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 24000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 24500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 25000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 25500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 26000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 26500 CLK=0 RES=0 EN=0 LAMP=1110111 DISP=6 27000 CLK=1 RES=0 EN=0 LAMP=1110111 DISP=6 27250 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 27500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 28000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 28500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 29000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 29500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 30000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 30500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 31000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 31500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 32000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 32500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 33000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 33500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 34000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 34500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 35000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 35500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 36000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 36500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 37000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 37500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 38000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 38500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 39000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 39500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 40000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 40500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 41000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 +-------+ | @ | | | | @ | +-------+ 41250 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 41500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 42000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 42500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 43000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 43500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 44000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 44500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 45000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 45500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 46000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 46500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 47000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 47500 CLK=0 RES=0 EN=0 LAMP=1000001 DISP=2 48000 CLK=1 RES=0 EN=0 LAMP=1000001 DISP=2 48250 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 48500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 49000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 49500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 50000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 50500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 51000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 51500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 52000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 52500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 53000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 53500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 54000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 54500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 55000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 55500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 56000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 56500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 57000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 57500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 58000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 58500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 59000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 59500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 60000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 60500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 61000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 61500 CLK=0 RES=0 EN=1 LAMP=0011100 DISP=3 62000 CLK=1 RES=0 EN=1 LAMP=1010101 DISP=4 62500 CLK=0 RES=0 EN=1 LAMP=1010101 DISP=4 63000 CLK=1 RES=0 EN=1 LAMP=1011101 DISP=5 63500 CLK=0 RES=0 EN=1 LAMP=1011101 DISP=5 64000 CLK=1 RES=0 EN=1 LAMP=1110111 DISP=6 64500 CLK=0 RES=0 EN=1 LAMP=1110111 DISP=6 65000 CLK=1 RES=0 EN=1 LAMP=0001000 DISP=1 65500 CLK=0 RES=0 EN=1 LAMP=0001000 DISP=1 66000 CLK=1 RES=0 EN=1 LAMP=1000001 DISP=2 66500 CLK=0 RES=0 EN=1 LAMP=1000001 DISP=2 67000 CLK=1 RES=0 EN=1 LAMP=0011100 DISP=3 +-------+ | @ | | @ | | @ | +-------+ 67250 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 67500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 68000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 68500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 69000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 69500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 70000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 70500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 71000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 71500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 72000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 72500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 73000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3 73500 CLK=0 RES=0 EN=0 LAMP=0011100 DISP=3 74000 CLK=1 RES=0 EN=0 LAMP=0011100 DISP=3

📌 まとめ

  • シミュレーションモデルは、設計対象の回路をテストするための「周辺回路の動作記述」である
  • ROM や RAM のシミュレーションモデルを作成することで、システム全体の動作確認が容易になる
  • ファイル読み書き($readmemh等)を活用することで、デバッグ効率が大幅に向上する
  • $display 等を用いた視覚的な出力(アスキーアートや変換された値)を用意することで、シミュレーション結果の判読性が飛躍的に高まる