Spartan-3A スタータキット

〜シリアル経由でスプライト操作〜


2007/04/30

あなたは 人目のお客様です.

スプライト表示ができたので, いろいろ機能を乗せてみたい.とりあえず,表示できるキャラクタ数を 増やしたいのと,いろんなパターンを表示できるように機能拡張したい.

しかしこれらのことをすべて押しボタンスイッチやスライドスイッチで 操作するのは無理があるので,スプライト機能をシリアル経由で 操作できるようにしてみよう.

具体的には, スプライト表示で作成したVerilogHDLソースに シリアル受信で作成したソースをモジュールとして 組み込んで,シリアル経由でPCからコマンドを送信し, Spartan3Aスタータキット側ではコマンドに応じてスプライトの設定内容を 変更するようにする. VGAへの出力はリアルタイムに行っているので,設定内容を変更すると, 即時に画面に反映されることになる. コマンドは手動で打ち込んでもいいし, コマンド生成するようなプログラムを書けば, 自動でコマンド発行してキャラクタを動かすこともできる.

とりあえず合体させたのがこんなかんじ. シリアル受信モジュール(rx.v)は, 文字を受信したら受信レジスタ(rch[7:0])に設定して, 受信フラグ(rcv)を反転させる. スプライト制御側では,受信フラグが変化したら 受信レジスタから受信文字を受け取り, コマンドに応じてスプライト用レジスタの内容を変更する.

sprite.v
rx.v
s3astarter.ucf

あいかわらずものすごく手抜き&ベタ書きの実装になっているので注意.

ちなみにコマンドのフォーマットは以下のように設計した.

たとえば座標を(10,10)に移動したいなら,
$dx00000a+$dy00000a+
をPC側からシリアル経由で送信してやればよい. 横方向に2倍に拡大したいならば
$mx0001+
を送信することになる.

で,実行してみた.まず VGA出力シリアル送信のときのように, VGAをテスト用液晶ディスプレイに, シリアルをPC(FreeBSD)に接続.んでFPGAにダウンロード.

起動すると,左上の隅にキャラクタが表示される. ディスプレイ側で同期がうまくとれないとまずいので, 外枠を表示するようにしている. しかし,キャラクタは左半分が切れてしまっている. あと外枠の左側と下側がうまく表示できていない. うーんタイミングがうまくとれていないようだ.まあこれはそのうち考えよう.

FreeBSDのPCでcuを起動し,シリアル接続する.このへんは シリアル送信を参照.

で,cuを起動した kterm 上で

$dx000100+
を入力することで,コマンドをスタータキットに送信できる. これはx座標を0x0100(10進数で64)に移動するコマンド.


x座標の設定コマンドを送信

横方向に移動できている.

次に,縦方向に移動してみよう.cu上で

$dy000100+
を入力.


y座標の設定コマンドを送信

縦方向に移動することで,画面中央に移動している.

次に横方向拡大.

$mx0001+
拡大率として0x01を設定すると,2倍に拡大することになる.


x方向の拡大率コマンドを送信

これもOK.

さらに拡大してみよう.

$mx0003+
拡大率として0x03を設定すると,8倍拡大することになる.


x方向の拡大率コマンドを送信

次に,縦方向にも拡大してみる.

$my0003+

y方向の拡大率コマンドを送信

横方向に8倍,縦方向に8倍に拡大することで, 最大サイズで表示できている.

さらに,左上隅に移動して位置を戻してみる.

$dx000000+$dy000000+

左上隅に移動できた. シリアル経由で問題なくコマンド操作できている.

最後に,適当に拡大率を変化させながら移動させるようなコマンドを発行する プログラムをCで書いてみた(move.c).

で,move.cを実行したときの画像が以下. キャラクタがサイズを変化させながら,左上から右下まで移動している. /dev/cuad0に書き込むので,cuで接続しているときには cuでの接続を切ってから実行するように注意. あと実行環境はFreeBSD-6.xなので,プログラム中では /dev/cuad0 を利用しているが, FreeBSD-4.xで実行する場合には /dev/cuaa0 を利用すること.

なお,書き忘れたけどロータリースイッチを押すことでリセットできる. またLEDにはシリアルで受信した文字が8bitで表示される.


ロータリースイッチ押下でリセット


LEDにはシリアル受信文字を表示


メールは kozos(アットマーク)kozos.jp まで