いよいよFPGAに実装
以下の本を読みつつ進めているFPGAでゲーム機をつくろう日記。今回は実際にサンプルコードをFPGAに組み込んで動かしてみる。VGAでの映像出力をやるが、長くなりそうなので2回に分ける。
開発環境
Windows 10
Vivado 2020.1
Zybo(Zynq-7000)
まずは小手調べでVGAで映像出力してみる
ゲーム機をつくるにあたり、まず実現しないといけないのは映像出力。今回は本の9章の内容をZyboに実装して動かしてみたいと思う。ちなみに7章のclock dividerと8章のbinary counterは基本的な内容なので読み流した。
私の手持ちのZyboには映像出力端子としてVGAとHDMIが搭載されている。ただ、最近のZyboはHDMI端子しかついてないようだ。
そういう意味ではHDMIで映像出力する方法を書いた方が良いとは思うのだが、VGAはHDMIより簡単に映像を出力することができるため、まずはVGAで映像を出力させてみる。そのうえで、VGAである程度ゲームが動いてきたら、HDMIでも試してみて日記に追記したいと思う。
同期信号の出力モジュール
VGAモニターに映像を出力するには、FPGAからRed/Green/Blueそれぞれの値と、水平同期信号(h-syncなどと呼ぶ)と垂直同期信号(v-syncなどと呼ぶ)を出力してやる必要がある。詳細は省くが、ググったら以下の長崎大学が公開している資料がわかりやすかったのでリンクを張っておく。
基本的なイメージとしては、モニターでは画面の左上から、左から右、上から下に順番に1pixelずつR/G/Bのデータを表示させていく。このような映像描写方式をラスタスキャンと言って、この考え方はHDMIなどのVideoインタフェースでも基本的には同じ。
かなり乱暴な説明だが、画面に表示される1枚の画をフレームと呼び、フレーム内の表示区間(Active期間)の部分が画面に表示されるので、この部分のRed/Blue/Greenの値を変化させて、絵を描画していくことになる。
この同期信号を生成するサンプルコードは、以下のものをそのまま使わせてもらった。
https://8bitworkshop.com/v3.6.0/?file=hvsync_generator.v&platform=verilog-vga
モニターに送るh-sync、v-syncと、現在のピクセルの位置を表示するhpos、vpos、Active領域のときにHighになるdisplay_onを出力している。この同期信号生成モジュールの信号を基準に、映像を表示させていく。IDEではタイミングチャートも右側に表示されるので、眺めればなんとなく動きはつかめると思う。
このモジュールは今後の日記でも使っていく。
テストパターンの出力モジュール
基本的には著者のサンプルコードを使えば良いのだが、今後いちいちサンプルコードに合わせてtopモジュールの変えると、input/outputのポート名も変わりピン制約などもいちいち修正する必要があって面倒なので、zybo_top.vというファイルをトップとして、そのサブモジュールとして、この本のサンプルコードを組み込んでいくことにする。
以下が今回私がつくったzybo_top.vファイル。
ここに、こちらのIDEページのサンプルコードtest_hsync.vをサブモジュールとして埋め込んでいる(サンプルコードはtest_hsync.vというファイル名だが、モジュール名はtest_hsync_topなので注意。私はzyboのプロジェクトに組みこむ時にはファイル名をmodule名と同じtest_hsync_top.vに変更した)。hvsync_generator.vはtest_hvsync.vで呼び出されている。
ちなみにVGA端子付きのZyboでは、Red/Blueが5bit、Greenが6bitで出力できるようになっているが、今回の場合はtest_hvsync.vのred/green/blueは1bitなので、bit拡張して接続している。
また、mmcmでZyboに入力されている125MHzのクロックから、25MHzを作っている。VGAのピンアサインと、mmcmのIP作成方法は次回の日記で書きたいと思う。また、プロジェクトもgithubで公開したい。
FPGAでゲーム機をつくろう日記まとめ
この日記は以下でまとめています。