今回はMoving Ballのサンプルを動かす
以下の本を読みつつ進めているFPGAでゲーム機をつくろう日記。前回はVGAで画を出力してみた。前回は動きのない静止画を表示したのだが、今回は本の12章「A Moving Ball」の内容をZybo向けにカスタマイズして動かしてみた。
以下が実際に動かしてみた動画。ボールが画面上を動いて、端までいったら跳ね返るという単純なものだが、動きがつくと一気にゲームっぽくなる。なお、上のツイートの動画では本のRTLに基づいてやってみたのだが、これだと壁の反射の処理がうまくいかず。非同期の記述になっている部分を同期回路にしたところ、下の動画のようにちゃんと動いた。
元々のコードが非同期でメタステーブル起こってそうだったので、同期回路に書き換えたらうまく動いた。この本面白いけど、FPGA全く触ったこと無い人が実機で動かすのはちょっと厳しそうだな。そういう部分をブログで補足したら面白そうかも pic.twitter.com/W9AWiWwVqG
— Wakky (@wakky_free) September 13, 2020
前回同様、今回のサンプルのプロジェクトは以下で公開している。
https://github.com/WakkyFree/FpgaGameConsole/tree/master/MovingBallTest
tclファイルからプロジェクトを生成する方法はこちら。
日記ではポイントだけ絞ってメモしていきます。
開発環境
Windows 10
Vivado 2020.1
Zybo(Zynq-7000)
hvsync_generator.vやMMCM IP、ピンアサインは前回と同じ
VGAで映像を表示するのは前回と変わらないので、Verilogコードのうちhvsync_generator.v、mmcmのIP(clk_vga_25m)、ピンアサイン情報が記述された制約ファイル(game_console.xdc)は前回と同じ。今回変更&追加したのは
の3つのVerilogコード。ball_absolute_top.vのベースはこの本のサンプルコードだが、サンプルコードはあまり実機動かすことを考慮していない非同期のコードになっておりZyboではうまく動かなかったので、同期回路のコードに書き換えた。同期回路化する中で、hsyncとvsyncの立ち上がりのタイミングを検出するdetect_edge.vという簡単なmoduleをつくって追加した。
zybo_top.vの変更箇所
前回のVGAテストパターンのコードのtest_hvsync_topをball_absolute_topに変更しただけ。そのほかは変更なし。
ball_absolute_top.vのポイント
結論から言うと、これはそのまま本のRTLサンプルを使ってもうまく動かなかった。本のRTLサンプルでもなんとなく映像は出るのだが、ボールの動きがおかしかったり壁での跳ね返りの挙動がおかしい。RTLサンプルは非同期回路になっており、メタステーブルが起こってそうだったので同期回路に書きかえた。同期回路&非同期回路、メタステーブルについては詳細はググって頂きたいが、同一クロックの同一エッジに同期して動く回路のことを同期回路をという。今回は、すべてinputのclkに同期して動くようにRTLを書いた。
同期化の中で、vsyncの立ち上がりで動いていた部分を、vsyncの立ち上がりでclkに同期したpulse信号を出すdetect_edge.vというモジュールを作成して同期回路に変更した。
動かしてみた
プロジェクトをsynthesisとimplementationしてGenerate bitstream後にFPGAに書き込んで動かすと、最初にのせた動画のようにちゃんとボールが壁で跳ね返るようになった。
次回だが、本の13章、14章は実機でやってもあまり面白味がないのので、15章の「Tile Graphics」というサンプルをZyboで動かしてみようと思う。ただ、15章の内容を深く理解したなら13章、14章も読んでおいた方が良い。私もZybo向けにRTLを変更したり追加したりするまえに13章、14章を読んである程度内容を理解したうえで15章にうつった。
FPGAでゲーム機をつくろう日記まとめ
この日記は以下でまとめています。