【FPGA】Racing GameのサンプルをZybo向けに変更して動かす(FPGA + Verilogでゲーム機をつくろう日記6日目)

投稿日:2021年1月5日
最終更新日:2021年5月24日

いよいよRacing Gameのサンプルを実装してゲームを動かす

以下の本を読みつつ進めているFPGAでゲーム機をつくろう日記。前回はtile graphicsというサンプルを実装して動かしてみた。今回はいよいよゲームを動かす。本の19章「Racing Game」の内容をZybo向けにカスタマイズして動かしてみた。

Designing Video Game Hardware in Verilog (English Edition)

前回と同様、先に動かしてみた動画をのっけておく。

今回のサンプルのプロジェクトは例のごとく以下で公開している。

https://github.com/WakkyFree/FpgaGameConsole/tree/master/RacingGame

tclファイルからプロジェクトを生成する方法はこちら。

Vivadoのプロジェクトをtclから生成する

いつものごとく、日記ではポイントだけ絞ってメモしていきます。

 

開発環境

Windows 10
Vivado 2020.1
Zybo(Zynq-7000)

 

hvsync_generator.v、detect_edge.v、MMCM IP、ピンアサインは前回と同じ

前回のMoving Ballのプロジェクトとhvsync_generator.v、detect_edge.v、mmcmのIP(clk_vga_25m)、ピンアサイン情報が記述された制約ファイル(game_console.xdc)は前回と同じ。今回変更&追加したのは

  • zybo_top.v
  • car_bitmap.v
  • racing_game_top.v
  • sprite_renderer.v

 

の4つのVerilogコード。今回はこちらのサンプルコードを利用している。car_bitmap.vとsprite_renderer.vはサンプルそのままで大丈夫だったが、racing_game_top.vには色々と手を加える必要がある。また、車の左右移動、加速を操作するためにzybo_top.vで3つのinput信号を定義して、Zybo上のタクトスイッチに割りあてることで操作ができるようにした。

 

zybo_top.vの変更ポイント

基本的には前回のtest_ram1_topのモジュールをracing_game_top.vに差し替えているが、Zybo上のタクトスイッチでプレイヤーの車を操作できるように、タクトスイッチ3つに割り当てるinputを追加した。

input         BTN0,
input         BTN1,
input         BTN2,

また、タクトスイッチのような機械的なスイッチを押すときのチャタリング(詳しくはググってください)により、うまく動かなくなることを防ぐためにチャタリング防止のコードを追加している。

wire w_btn0_rmv_chat;
wire w_btn1_rmv_chat;
wire w_btn2_rmv_chat;

reg [1:0] r_btn0;
reg [1:0] r_btn1;
reg [1:0] r_btn2;

always @(posedge clk_vga)
  begin
    r_btn0 <= {r_btn0[0], BTN0}; 
    r_btn1 <= {r_btn1[0], BTN1};
    r_btn2 <= {r_btn2[0], BTN2};
  end

assign w_btn0_rmv_chat = &r_btn0;
assign w_btn1_rmv_chat = &r_btn1;
assign w_btn2_rmv_chat = &r_btn2;

あとは、追加したinputを忘れずにピンアサインしておく。今回はinputをZybo上のBTN0(R18 pin)、BTN1(R16 pin)、BTN2(V16 pin)に割り当てた。game_console.xdcを見ると、前回までの記述に加えて以下が追加されていることがわかる。

set_property IOSTANDARD LVCMOS33 [get_ports BTN0]
set_property IOSTANDARD LVCMOS33 [get_ports BTN1]
set_property IOSTANDARD LVCMOS33 [get_ports BTN2]
set_property PACKAGE_PIN R18 [get_ports BTN0]
set_property PACKAGE_PIN P16 [get_ports BTN1]
set_property PACKAGE_PIN V16 [get_ports BTN2]

これでzybo_topの変更は完了。

 

racing_game_top.vの変更ポイント

ベースになっているのはエミュレータのracing_game_top.vというソースコード。そういえば今までの日記でちゃんと説明していなかった気もするが、エミュレータのソースコードは基本的に256 x 240pixelという解像度に合わせて作ってあるため、VGAで表示するにはRTLを640 x 480pixelに対応した解像度に書き換える必要がある。

そのため、hposやvpos、player_xとplayer_yなどは全て640 x 480pixelに対応できるようにbit長を長くしている。全部挙げてたらキリが無いので詳細はソースコードを見てください。

また、元々のコードでは車の横移動を操作する信号hpaddleは1つのinputになっていたが、どうもうまく動かなかったので、hpaddle_right、hpaddle_leftの2つのスイッチを押したら、左右の固定位置に移動するように変更した。

  input hpaddle_left, hpaddle_right, vpaddle;

さらに、表示されるコースのtrack_offside(緑の部分)、track_shoulder(白い部分)も適当な大きさに調整した。

  wire track_offside = (hpos[9:7]==3'b000) || (hpos[9:7]==3'b100); 
  wire track_shoulder = (hpos[9:4]==6'b000111) || (hpos[9:4]==6'b100000);
  wire track_gfx = (vpos[7:3]!=track_pos[7:3]) && track_offside;

かなりざっくりとした説明だが、おおまかなポイントはこのくらい。

 

動かしてみた

プロジェクトをいつものごとくsynthesisとimplementationしてGenerate bitstream後にFPGAに書き込んで動かすと、最初にのせた動画のようにZybo上のタクトスイッチで車を操作することができた。(写真とってなかったので最初のせた動画のスクショだけど…笑)

これで当初の目的であったFPGAでゲーム機をつくるという目的は達成できた。あとはスコア表示したり、別のゲームに挑戦したり、VGAで表示しているところをHDMIで表示したりなどやりたいことは色々とあるが、今回はひとまずここまで。

 

FPGAでゲーム機をつくろう日記まとめ

この日記は以下でまとめています。

【FPGA/HDL】FPGAでゲーム機をつくろう日記まとめ


投稿者: wakky

映画と旅行が大好きなエンジニア。お酒、ゲーム、読書も好き。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください