Xilinx社の FPGA の開発環境であるVivado MLが持つシミュレーション機能を用いて、Kria KV260のFPGAのプログラムのシミュレーションを実行します。

ここでは、「Vivado MLによるプログラムシミュレーション-ブロックデザインの作成」の継続作業となります。

最上位HDLラッパーの作成

Vivado MLによるKria KV260のFPGAのプログラム作成(その2)」の「最上位HDLラッパーの作成」に従って、Zynqとblinkの両方を含む最上位モジュールを作成します。

シミュレーション対象の選択

複数のテストベンチが存在した場合は、どのテストベンチをシミュレーションするか選択する必要があります。

シミュレーション対象を切り替えるには、テストベンチを右クリックし、「Set as Top」を選択します。選択中のテストベンチは「Sources」タブ内でモジュール名が太字になり、先頭に三点アイコンが追加されて最上位に表示されます。

シミュレーションの実行

シミュレーションを行うために、左側の「Flow Navigator」より「SIMULATION」の「Run Simulation」をクリックし、表示されたメニューで「Run Behavioral Simulaion」を選択します。

次の波形が表示されます。「CLK」は100MHzで、「XRST」にはリセットがかかってないようで、カウンターが不定になっています。

シミュレーション操作

シミュレーション操作に使用する操作ボタンを次に示します。

下位モジュールの信号を波形画面に追加したい場合は「Scope」タブ及び、「Objects」タブを使います。

モジュール階層が表示されている「Scope」タブで追加したい信号線を含むモジュールを選択すると、信号線が「Objects」タブに表示されるので、対象となる信号線を右側の波形グラフの項目にドラッグ&ドロップして最初からシミュレーションします。

リセット信号の入力

リセットがうまく入っていないため、カウンタ値が不定となっています。PSからのリセットはソフトで指示しないとかからないようなので、「design_1」を右クリックして、表示されたメニューから「Goto Source」を選択してコードを表示します。

25行目の、blinkモジュールのXRST端子をPSからのリセットを削除し、「~glbl.GSR」をつなぎます。glblモジュール*1 のGSRは100nsのみtrueとなる信号で、反転してXRST端子に入力します。

.XRST(zynq_ultra_ps_e_0_pl_resetn0));
     ↓
.XRST(~glbl.GSR));

*1 : モジュールは、デザインにグローバル セット/リセット信号とグローバル トライステート信号を接続します。Verilog シミュレーションでデザインを正しくリセットするには、glbl.v モジュールをデザインと共にコンパイルし、読み込む必要があります。

変更したコードを保存し、再コンパイルして実行します。「XRST」にリセットがかかり、カウンタが不定でなくなりました。

Tcl Consoleを用いたデバック

このままだとシミュレーション時間が非常にかかるため、Tcl Consoleを用いて、次に示すコマンドによりMAX値に近い値をロードした後にカウントを進めます。

add_force {/design_1_wrapper/design_1_i/blink_0/inst/count25/LD} -radix hex {1fffff8 0ns}
add_force {/design_1_wrapper/design_1_i/blink_0/inst/count25/TEST} -radix hex {1 0ns}
run 10 ns
add_force {/design_1_wrapper/design_1_i/blink_0/inst/count25/TEST} -radix hex {0 0ns}
run 200ns

Tclコンソールでは、ユーザーインターフェースを使用する代わりにTcl/Tkコマンドを入力して実行することができます。

なお、ファイル「count25.v」ではRTLの25bitカウンタを、TEST信号のtrueにより任意の値をロードできるようにすでに作成しています。

Tclコンソールから上記のコマンドを実行します。

波形が更新され、LEDカウンタが「02」に更新されました。

【 RTLの25bitカウンタにMAX値が設定されない理由 】
always 文で 、ノンブロッキングにより処理を行うと、下の構文も同時に実行されるので、25bitカウンタにmax値が設定されない。
・ブロッキング代入 (=) : シーケンシャル・ブロック内で上から順番に実行される
・ノンブロッキング代入 (<=) : シーケンシャル・ブロック内で、ステートメントの記述の順番に関係なく代入できる