スプライトのソースを整理しよう.
てなわけで, シリアル経由でスプライト操作その2 でベタで書いたソースを,だいぶ書き直してみた. 実は動くようになるまで,デバッグでだいぶ苦労しているのだけど, そのへんはまあいいや.
まず,シリアル通信がなんかおかしいバグを修正した(rx.v). 受信信号を検知した際にクロックを合わせる動作がうまく動いて いなかったのが原因だった.ちなみに以下が rx.v の修正点.
--- sprite_rx2/rx.v Sun May 6 16:20:06 2007 +++ sprite_rx3/rx.v Wed May 9 23:31:47 2007 @@ -68,7 +68,7 @@ serclk_old <= serclk; if (rxd_old != rxd) begin - clk_reset <= 1'b1; + clk_reset <= ~clk_reset; rxd_old <= rxd; end else if ((serclk_old == 1'b1) && (serclk == 1'b0)) // negedge
sprite.v はだいぶ修正した.このへんはソースを直接参照してほしい. ただ,気を付けないと論理合成の際に「回路規模が大きすぎ」ということで エラーになってしまう. たぶん回路効率をあまり考えていないというか, イメージのビットマップ保存に何も考えずに配列を使用しているので, フリップフロップを湯水のように使ってしまっているのだと思われる. まあこのへんはいろいろ試行錯誤してみたのだけど, どうも以下のような感じのようだ.
reg [3:0] spbitmap[0:63][0:15];は(後述する回路規模は別として,文法的には)可だが,
reg [3:0] spbitmap[0:3][0:15][0:15];は文法的には不可. (VerilogHDLの文法的制限なのか,ISE WebPACK の制限なのかは不明)
reg [63:0] spbitmap[0:63];だと論理合成できるが,
reg [3:0] spbitmap[0:63][0:15];のように書き方を変えると論理合成できなくなったり, 回路規模オーバーでエラーになってしまったりする. 書き方によって回路の効率が変わってくるようだ. ブロックRAMとか分散RAMとかそのへんが関係しているのかもしれない. よくわからんけど.
で,テストプログラムも改良した(move.c). ソース中の MOVING の定義が無効な場合には左上に4つのキャラクタを 表示する.MOVING の定義が有効な場合には, サイズや移動速度をてきとうに変化させながら画面中を移動する.
まずスタータキットを起動してダウンロード.
ちょっとピンボケなのだけど, 前回と違ってリセット時にとくにイメージを設定していないので, 画面上に何も出ていない.
この状態でFreeBSDのPC上で,move.c の MOVING を無効にしてコンパイルし実行する.
4つのキャラクタがきちんと表示されている. ちなみに写真では,右上のキャラクタの紫の帯はやっぱり白になってしまっていて, 緑のボールも白くなってしまっている. 前回ちょっと気になっていた色の問題は,デジカメのせいだということだろうか.
次に,move.c の MOVING を有効にしてコンパイルし実行する.
写真ではわからないけど,キャラクタが適当に動いている.
キャラクタが重なったところ.
キャラクタの重なりを拡大.おお,スプライトっぽい!
拡大写真だと,色がきちんと出ているね.単に近付いて撮っているだけなのだけれど.
とりあえず動くようになった. ただ,上にも書いたように回路規模が大きくなりすぎているので, ブロックRAMを使用するように修正しないと. でないとこれ以上イメージやスプライト数を増やせないので.
あ,あとキャラクタの左右がひっくり返っているのを修正するのを忘れてた...