シリアル経由でスプライト操作その3 で書いたソースでは回路規模が大きくなりすぎるので, FPGA内のメモリを使用するように修正しよう.
FPGA内のメモリには,ブロックRAMと分散RAMがある. あと通常のフリップフロップでメモリが構成される場合もあるようだ. このへんのことに関しては, なひたふ電子 の ブロックRAMの使い方 にソースコードも含めた詳しい説明がある. また FPGA活用チュートリアル 2006/2007年版 にも記事がある.
上の資料はどちらもVHDLで書いてあるのだけど, VerilogHDLでも配列としてメモリを確保すれば, 書き方に応じてブロックRAMや分散RAMが割り当てられるように思える. ただしメモリを扱うモジュールはメモリモジュールとして独立させる 必要があるようだ. シリアル経由でスプライト操作その3 のスプライトのソースコードは,イメージ用メモリをスプライトのソースコード中に ベタで組み込んでしまっているので,これを切り出して独立させる必要がある.
メモリモジュールの作成なのだけど, アドレスに値を設定してイネーブル線を有効化したときに, データのリード/ライトを行うように設計する. 動作はクロックと同期して行うので,おそらくブロックRAMが利用されることになる.
ついでに,ブロックRAMを使用することでせっかく回路規模を節約できるのだから, スプライト数を16個に拡張してみる.
スプライト側からメモリを利用する場合,最低でも1クロック必要になるので, 1クロックの中でメモリからリードして描画を行うことはできない. このため前もってメモリから値を読みだしておく必要があるので, HSYNCの際にメモリから値を読み出すように改良する (スプライト数が16なので,HSYNCのブランクの間に16クロックかけて 16個の値を読み出す). あと16個のスプライトの描画計算を1クロック内ですべて行うのは きついような気がするので,1クロックごとにスプライトの描画計算を順次行うように パイプライン化する.
で,作成したのがこんな感じ. ついでにシリアル受信モジュールは, クロックとボーレートを変更できるように修正した. あとキャラクタの左右がひっくり返っているのを修正した.
sprite.v
memory.v
rx.v
s3astarter.ucf
ちなみにメモリモジュールを独立させたら,論理合成にかかる時間が短くなった. ていうか今まで書いたスプライトのソースコードでは 論理合成にやたら時間がかかっていたのだけど,それが普通くらいの時間になった. ブロックRAMを使用することでフリップフロップの使用数が減り, 論理合成にかかる時間が短縮されたのだろうか. でもスプライト数を4個から16個に増やしたら, やっぱし論理合成にそれなりの時間がかかるようになってしまった.
テストプログラムも改良した(move.c).
まずスタータキットを起動してダウンロードし, この状態でFreeBSDのPC上で,move.c をコンパイルし実行する.
これは動かしてしばらくしたところ.ちゃんと動いていて感動.