シミュレーションの演習を進めます。
以下のプロジェクトに対して、シミュレーションを行いました。
gitにアップしているchapter2-3 になります。
一つ下の階層のSIMフォルダにある「pattern_tb.v」を使います
少し解説してみます
シミュレーションのクロック設定
/* クロック周期とSimクロック数を定義 */
localparam STEP = 8;
localparam CLKNUM = (800*525+12000)*5;
- シミュレーション時間単位でのクロック周期(8ns)を定義
- 結果としてクロック周波数は 1/8ns=125MHz
- CLKNUMはシミュレーションするクロック数を指定
- 800は1回の水平スキャンにかかるクロック数。
- 表示領域640クロック+フロントポーチ16+同期パルス96+バックポーチ48=800
- 同様に垂直スキャンの525は、表示領域480クロック+フロントポーチ10+同期パルス2+バックポーチ33=525
- 800×525 は 1フレームのピクセル数(VGA解像度:640×480 + ブランキング期間)
- +12000 は追加で余裕を持たせたクロック数
- もしテストベンチで波形が安定しない場合は、+12000 を +20000 や +420000 に増やしてもOK
- ×5 は5フレーム分シミュレーションするという意味
信号定義と DUT(Device Under Test)接続
/* 接続信号の宣言 */
reg CLK;
reg RST;
wire [7:0] VGA_R, VGA_G, VGA_B;
wire VGA_HS, VGA_VS, VGA_DE;
wire PCK;
/* パターン表示回路を接続 */
pattern pattern(
.CLK (CLK),
.RST (RST),
.VGA_R (VGA_R),
.VGA_G (VGA_G),
.VGA_B (VGA_B),
.VGA_HS (VGA_HS),
.VGA_VS (VGA_VS),
.VGA_DE (VGA_DE),
.PCK (PCK)
);
-
CLK: シミュレーション用クロック
-
RST: リセット信号
-
VGA_R, VGA_G, VGA_B: RGB 各8bitの出力
-
VGA_HS, VGA_VS: 水平・垂直同期信号
-
VGA_DE: Display Enable(描画タイミング信号)
-
PCK: Pixel Clock
-
pattern モジュールは被検証回路(DUT)で、上記の信号が接続されている。
クロック生成ブロック
/* クロックの生成 */
always begin
CLK = 0; #(STEP/2);
CLK = 1; #(STEP/2);
end
- 1周期(立上り、立下り)を作っている
リセットとシミュレーションの流れを以下で記載
/* 検証対象への入力を作成 */
initial begin
RST = 0;
#(STEP*600) RST = 1;
#(STEP*20) RST = 0;
#(STEP*CLKNUM);
$stop;
end
- RST = 0;: 最初はリセット解除状態
- #(STEP*600): 600クロック待機(=約4.8 µs)
- RST = 1;: リセットを1サイクルだけアサート
- #(STEP*20): 20クロック待機(160ns)
- RST = 0;: リセット解除
- #(STEP*CLKNUM): メインシミュレーション(約5フレーム分)
- $stop;: シミュレーション終了
シミュレーション波形解説
MMCMによるPCK生成開始部分
- 1us付近でPCKの生成が始まる
- 2us付近でlockedが1となり、MMCMが安定したことがわかる
- 5us付近でリセットし、不定(赤表示)だった信号の値が確定している
HCNTとVCNTの動作
- 波形選択➡radixで表示を変更できる。デフォルトはヘキサ。Unsigned Desimalに変更した
- HCNT=16、VCNT=10でVGA_HSとVGA_VSが同時に立ち下がっている
VGA_HSの周期計測
- 波形上で左クリックで黄色いカーソル。クリックしたまま移動させるとエッジで吸着する。
- shift+左クリックで2本目のカーソルを表示でき、1本目との時間を測定できる
- カーソル間は12.711us。これはEBAZ4205のSYSCLK=125MHzのため、正しい。
- 参考書の例はSYSCLK=50MHzなので31.778usとなる
VGA_R~VGA_Bの値
-
最終ライン(VCNT=524)では逆にR:G:B=00:00:00、00:00:ff...ff:ff:ffまで変化している