Posts Tagged with "FPGA"

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.

Pongの開発

posted by sakurai on November 6, 2023 #690

Pong Game

強化学習のトライアルとして、ビデオゲームを題材に取り上げます。本来はインベーダーゲームを対象としたいのですが複雑であるため、比較的単純なPongとします。

Youtubeで動作画像を探すとこのような動画が見つかりました。

図%%.1
図690.1 CmodA7toPMODボード回路図

これを参考にしつつ、bsvによりプログラミングを行います。

Sound

強化学習本来の目的ではサウンドは不要ですが、ゲームとしての完成度のためにサウンドも実装します。サウンドコントローラであるSoundFSMやその周りの回路は開発済みなので、サウンド実装の工数はサウンド収集加工以外にはほとんどかかりません。そこでサウンドの収集から始めます。

サウンドフォーマット等の参考にする過去記事はこれです。

まずWindows+Gによりゲームバーを呼び出し上記動画の動画をキャプチャします。次にffmpegによりwaveに変換します。変換コマンドは次のとおりです。audacityはmp4を読み込めないため、ffmpegを用います。

\$ffmpeg -i input.mp4 output.wav

これをaudacityにより編集し以下の4つのサウンドを取得します。

表690.1 4種のサウンド
コード 種類
1 発射音
2 パドル
3
4 アウト

ffmpegを用いるとINFO等の余分な情報が削除できずハードウエアが読み込めません。よってaudacityでサウンドデータを開き、

  • 音量をノーマライズ。イフェクト⇒音量⇒ノーマライズとします。
  • メタデータを全て削除
  • 形式はwav (microsoft)
  • チャンネルはモノラル
  • サンプリングは11025 Hz
  • エンコーディングはUnsigned 8-bit PCM

としてエクスポートします。

ここで各ファイルサイズを見ると、

\$ ls -l s?.wav
-rwxrwx--- 1 root vboxsf 1610 10月 29 21:10 s1o.wav
-rwxrwx--- 1 root vboxsf 900 10月 29 21:10 s2o.wav
-rwxrwx--- 1 root vboxsf 872 10月 29 21:13 s3o.wav
-rwxrwx--- 1 root vboxsf 4388 10月 29 21:11 s4o.wav

以上からROMの構成表を作成すれば、

表690.2 ROM構成表
Code Sound Start Size [bytes] Entry=Start+16
1 発射音 0 1,610 0+16
2 パドル 1,610 900 1,610+16
3 1,610+900 872 (1,610+900)+16
4 アウト 1,610+900+872 4,388 (1,610+900+872)+16
合計 [bytes] (16KB ROM使用率) 7,770 (95%)

となります。各サウンドのエントリは表の黄色で示したアドレスであり、これを次のようにbsvでFSM内に記述します(次ページにFSMの全リストを掲載)。
         // Format decoding
         //
         action
            case (current)
               `SOUND1:  romaddr <=   0 + 16;
               `SOUND2:  romaddr <=  1610 + 16;
               `SOUND3:  romaddr <=  (1610 + 900) + 16;
               `SOUND4:  romaddr <=  (1610 + 900 + 872) +16;
            endcase
         endaction

左矢前のブログ 次のブログ右矢

Cmod A7の利用 (3)

posted by sakurai on October 26, 2023 #686

完成した回路図を図686.1に、レイアウト図を686.2に示します。ボードは仕様的に2層、80cm^2未満であるため、Eagleの無料版で設計することができました。

図%%.1
図686.1 CmodA7toPMODボード回路図

図%%.1
図686.2 CmodA7toPMODボードガーバー図

基板業者JLCPCBにおいて基板製造及び部品実装(PCBA)をオーダーしようと思いました。ところがSMT部品でないとアセンブリできないらしく、今回SMT部品が無いことから基板のみのサービスを利用しました。

表686.1 JLCPCB費用まとめ
内容 費用[USD]
基板製造費10枚 5.00
配送費(OCS) 1.98
合計 6.98

という結果でした。


左矢前のブログ 次のブログ右矢

Cmod A7の利用 (2)

posted by sakurai on October 25, 2023 #685

Eagleライブラリの作成

同様にDC Jackを登録します。以下にその基盤図及び実体図を示します。基盤穴をグレーで塗っています。

図%%.1
図685.1 Cmod A7ボード

EAGLEでこれを登録するには基盤図をfootprintに入力する必要があり、ライブラリを次のように作成します。

(1) symbolの編集画面において、

  • 部品外形をLayer=94 Symbolsで記述。
  • 適宜論理ピンを設定。
  • textでLayer=95 Namesとして">NAME"を追加。
  • textでLayer=96 Valuesとして">VALUE"を追加。

(2) footprintの編集画面において、

  • textでLayer=25 tNamesとして">NAME"を追加。
  • textでLayer=27 tValuesとして">VALUE"を追加。
  • Layer=20 Dimensionとする。
  • Widthを0とする。
  • Gridをmmにする。
  • ラインコマンドをクリックする。
  • 入力窓に、"(x, y)"と点を打つ。

以下"(x, y)"の繰り返しで図形を描きます。"20 Dimension"は外形線ですが、外形線の囲む内部に外形線があれば、囲まれた領域が穴になるという仕様です。ただし、上図は背面から見た図なので、上面から見た図はその裏返しとなります。

さらに、表面から背面に貫通する端子を背面で+5Vと接続させるため、背面のソルダーレジストを禁止とします。そのためには

  • 禁止したい領域をLayer=30 bStopとして矩形で囲む。

(3) deviceの編集画面において、

  • Edit ⇒ Addで作成したsymbolの読み込み
  • Edit ⇒ Packageで作成したfootprintの読み込み
  • 論理ピンと物理ピン(pad)の接続
  • prefixをクリックしてJと入力 (J1, J2, としたい場合)

特にここで挙げたsymbol画面とfootprint画面からのdevice画面への読み込みが直感的ではないので注意してください。


左矢前のブログ 次のブログ右矢

Cmod A7の利用

posted by sakurai on October 24, 2023 #684

Cmod A7

Cmod A7とはDigilentから販売されているArtix 7シリーズのFPGAの評価ボードで、その特長は小さくて安いことにあります。最近の世界的なインフレにより各種FPGAボードが値上がりしている中で、USD 99と最安の部類に入ります。

図%%.1
図684.1 Cmod A7ボード

小さくて安いFPGAボードですが、Arty A7-35ボードと同じFPGAを採用しているため、Space Invadersが動作するはずです。

CmodA7toPMOD

しかしながらArty A7ボードがPMODインタフェースを4個搭載しておりそのままPMOD-VGAやPMOD-Audioボードを接続できるのに対し、このボードはPMODが1個しかないため、PMODインタフェースを設計する必要があります。ただし、Ultra96と異なり端子電圧が3.3VであるためPMODと直接インタフェースでき、レベル変換ICが不要です。

そのためには変換ボード上に

  • Cmod A7ボード
  • PMODピンソケットコネクタ x 4
  • ACアダプタコネクタ(MJ-179PH)
  • 5V-3.3V電圧降下コンバータ(NJU7223F33)

等の部品を搭載する必要があります。

Eagleライブラリの作成

EAGLEでこれらを使用するにはシンボル図や基盤図をライブラリに登録する必要があります。例として電圧降下コンバータNJU7223F33の外形図を図684.2に示します。

図%%.2
図684.2 NJU7223F33外形図

このシンボルとフットプリントを作成した図を以下に示します。

図%%.3
図684.3 NJU7223F33 symbol図

図%%.4
図684.4 NJU7223F33 footprint図

左矢前のブログ 次のブログ右矢

Ultra96toPMODの追加製造費用

posted by sakurai on May 29, 2023 #608

Ulta96toPMOD基板製造再見積り

JLCPCBがPCBA(PCB製造及び部品実装)のセールをやっているようなので, 以前掲載したUltra96toPMODボードのオーダー費を再度計算してみました。

前回と同様パープルとグリーン基板を10枚製造し、さらにICを2個/枚×10枚実装した場合の費用の内訳を示します。前回パープル基板はEconomyの有利な価格で基板が製造できず、Standardとなっていました。今回はパープルもグリーンと同じEconomy扱いに変更されています。

表608.1 Ultra96toPMOD Jlcpcbの費用構成
10枚製造時費用内訳 基板色[USD]
グリーン パープル
PCB Special Offer Price 5.00
Components(TXS0108EPWR --- 20個) 9.39
Extended Components 2.96
SMT Assembly 0.65
Setup fee 7.88
Stencil 1.48
合計 27.36
送料(OCS Express:6~8日) 11.68
総計 39.04

前回と比較してみると、部品(レベコンIC)代が若干安くなり、セットアップフィー、SMTアセンブリ、ステンシルがほんの少し安くなりました。一方、送料が上がりクーポンが使えないので、40.2%の値上げ(パープルは28.6%の値下げ)という結果になりました。

今回、再度BokTech及びSeeedFusion PCBの見積もりを取りましたが、それぞれこの2倍、4倍ほどの費用となりました。JLCPCBの安さが光ります。

PMODピンソケットコネクタの再オーダー

PMOD仕様の12ピンソケットの型格はSamtec製のSSW-106-02-T-D-RAです。

図%%.1
図608.1 SSW-106-02-T-D-RA

以前オーダーしたときはMouser から購入しました。この時は単価が141円と安く送料が無料なこともあり、総額が安かったのですが、今回見積もったら単価が258円とかなり値上がりしていたため、Arrowから購入しました。

再度調べたところ、以下のように最安はChip 1stopでした。単価的にはArrowと同じですが、送料が無料となることから、今後はChip 1stopで購入しようと思います。

  • Chip1stop 単価156.2 x 40(送料650)= 6,899円 (税込み) 最安
  • Arrow 単価156.2 x 40(送料3,080)= 9,330円 (税込み)
  • RSオンライン 単価254.9x 40 (送料無料) =10,199円 (税込み)
  • Mouser 単価263.6 x 40 (送料無料) =10,542円 (税込み)

図%%.2
図608.2 送付部品(SSW-106-02-T-D-RA)

本ピンソケット互換品でA2541HWR-2x6Pという製品があるようです。


左矢前のブログ 次のブログ右矢

Ultra96toPMODのBOM

posted by sakurai on May 26, 2023 #607

Ultra96toPMODのBOM

弊社作成のUltra96toPMODボードですが、BoMを掲載していなかったので、掲載します。

表607.1 Ultra96toPMODボードBoM
Degignator Value Qty MPN
C1, C2, C4, ..., C11 0.1u 10 Multilayer Ceramic Capacitor
C3 10u 1 47 µF 50 V Aluminum Electrolytic Capacitors Radial
J1, ..., J4 SSW-106-02-T-D-RA 4 SSW-106-02-T-D-RA
J100 MTMM-120-03-T-D-155 1 MTMM-120-03-T-D-155
LED1 TLLR4400 1 Red LED 3mm Through Hole
R1 470 1 Axial Carbon Film Resistor
R2, ..., R4, R6 3.3k 4 Axial Carbon Film Resistor
R5 10k 1 Axial Carbon Film Resistor
SW1 COUNT 1 4bit DIP SW
SW2 RESET 1 Tactile Push SW
TP1, ..., TP10 Test Pin 10 Test Pin
U1, U3 TXS0108EPWR-TSSOP20 2 Level Converter IC (SMD)
U2 DC DC Converter IC 1 PQ3RD23

Online-shopの開設

併せてオンラインショップを開設しました。

図%%.1
図607.1 オンラインショップ画面

左矢前のブログ 次のブログ右矢

PL UARTの接続とPCでの表示

posted by sakurai on May 17, 2023 #605

PL部UARTのPCへの出力

以前Space Invadersのゲーム実行中のVRAM画面の吸出しを実施しました。過去記事ではこれ等が相当します。これは、メモリダンプモジュールをBSVにより設計し、UARTの送信機能を用いてUART/USB変換ボードを経由してPCとUSBで接続し、PC上のPuttyでメモリダンプ情報を取得するというものです。

ところが、再度実行しようとしたところ、どうしてもUARTの出力の取得ができませんでした。前回は比較的簡単にできてしまったので、記事にはpin設定であるxdcの詳細は書いていませんでした。単にUART_TXに接続するとのみと書いており、端子番号は今は定かではありません。

こうなると基本から調べなければならないので、まずUltra96V2の回路図を見ると、なんとPS部からの接続となっているようです。

図%%.1
図605.1 Ultra96 UART部分回路図

UART/USB変換ボードのJ1の2 pinにUART_TXが接続されていますが、これはPS_MIO0のUART1_TXであり、PLからはPIN配置でエラーになるため、PS部であるBank 500のU4端子に接続することはできません。図605.2にUltra96-V2ハードウェアユーザーズガイドの抜粋を示しますが、やはりBank 500(PS部)のU4端子となっています。

図%%.2
図605.2 Ultra96 UART部分端子表

従って、最後の手段としてボード上に配線をハンダ付けし無理やりJ1に出力することを考えます。

まず図605.3はPL部UART_TXの引き出しを示す回路図です。

図%%.3
図605.3 UART_TX部回路図

このUART_TXを次のxdcによりG6端子に割り当てます。これはPL部の出力(Bank 26)です。

set_property PACKAGE_PIN G6 [get_ports {UART_TX}]

最後にUART_TXを割り着けた端子G6とJ1の2 pinの間に配線をハンダ付けし、ショートしてやります。レベル的に本来はTrのD側ではなくS側に接続すべきですが、3.3Vにpull upされているため、これでもVOHは満足しているようです。

このようにすることで921,600bpsにより、VRAM内容の送信がうまく動作しました。が、以前設定だけでできた理由は不明のままです。

PCへの出力結果の確認

以下に、得られたlogファイルを画像に変換するフィルタを再掲します。

log2ppm.c

#include <stdio.h>
void main() {
      char line[4096];
      char ch;
      printf("P3\n256 256\n255\n");
      for(int y = 0; y <= 255; y++) {
            fgets(line, sizeof(line), stdin);
            for(int x = 0; x <= 255; x++) {
                  ch = line[x] - 0x30;
                  if ((ch & 0x4) != 0) printf("255 ");    // R
                  else printf("0 ");
                  if ((ch & 0x2) != 0) printf("255 ");    // G
                  else printf("0 ");
                  if ((ch & 0x1) != 0) printf("255 ");    // B
                  else printf("0 ");
            }
            printf("\n");
      }
}

以下のコマンドによりフィルタを作成します。

$ gcc -O log2ppm.c -o log2ppm

これを下記のようにフィルターとして実行し、ログデータを画像ファイルに変換します。

$ ./log2ppm <putty.log >putty.ppm

生成されたppm図形を図605.4に示します。

図%%.3
図605.4 メモリダンプ図形

左矢前のブログ 次のブログ右矢

posted by sakurai on December 2, 2022 #561

画面の縦横の入れ替えの変更

過去記事において、本来VRAMの読み出しアドレスのxとyを入れ替えるつもりが、たまたまwrite側のアドレスマルチプレクサが目につき、それを流用しました。が、動作的な欠点が目立ちました。具体的には、画面書き換えの途中で切り替えると、縦図形と横図形が混在したり、初期画面を動的に準備する負担が大きくなっていました。

これを本来のread側アドレスマルチプレクサに変更します。ただし、write側マルチプレクサに追加してread側マルチプレクサの増設が必要になります。

write側アドレスマルチプレクサは名前をWriteMuxに変更しましたが、元の単なるセレクタに戻しました。新たにReadMuxモジュールを設置し、読み出し側アドレスのxとyを入れ替えます。実際にはyはx(a[7:0])をそのまま用い、xはy(a[15:8])を256から引いたものを用います。

$$ \begin{eqnarray} \left\{ \begin{array}{l} x&\Leftarrow&256-y \\ y&\Leftarrow&x \end{array} \right. \end{eqnarray} $$

図561.1に改造後のブロック図を示します。

図%%.1
図561.1 VRAMモジュール

以下にBSVソースを示します。処理はwrite側で実施した入れ替えとほとんど同様です。

ReadMux.bsv:

// アドレス型の定義
typedef Bit#(16) Addr_t;

// マルチプレクサのインタフェース定義
interface ReadMux_ifc;
   (* prefix="" *)
   // 出力アドレスを生成するメソッド
   method Addr_t outp(Bool sel, Addr_t a);
endinterface

// マルチプレクサの実装
(* synthesize, always_ready = "outp", no_default_clock, no_default_reset *)
module mkReadMux(ReadMux_ifc);

   // 出力アドレスを生成するメソッド
   method Addr_t outp(Bool sel, Addr_t a);
      // xa: aの下位8ビット
      Bit#(8) xa = a[7:0];
      // yax: aの上位8ビットから算出
      Int#(10) yax = 256 - signExtend(unpack(a[15:8]));
      // ya: yaxを8ビットにトリミング
      Bit#(8) ya = truncate(pack(yax));

      // selがTrueなら加工したアドレスを返す
      if (sel) return {xa, ya};
      // selがFalseなら元のアドレスをそのまま返す
      else return a; 
   endmethod

endmodule

この変更により、ボード上のdip swを切り替えることで、リアルタイムに画面の縦横変換ができるようになりました。


左矢前のブログ 次のブログ右矢

posted by sakurai on September 27, 2022 #517

完成したゲームのオープニングからのゲーム開始画面です。動画変換フレームレートの関係で、ゼロの点滅がハッキリと再生されませんが、実際にはきれいに点滅しています。

図%%.1
図517.1 オープニングアニメーションシーケンス

実行のシーケンス

  • 得点表(Score Advance Table)アニメーション表示
  • Fボタンを押す
  • "PUSH ONLY 1PLAYER BUTTON"を表示、CREDIT=01
  • Sボタンを押す
  • "PLAY PLAYER<1>"を表示、CREDIT=00、SCORE<1>をゼロにし、規定回数点滅
  • ゲームスタート

図513.5
図513.5 ボタン配置図

左矢前のブログ 次のブログ右矢

posted by sakurai on September 26, 2022 #516

Y字リプレースアニメーションのソース

Y字リプレースアニメーションのソースを示します。Y字リプレースアニメーションもFボタンにより中断するため、各所でFボタンを見ています。

function Stmt replaceY;
   return (seq
      // from right to left
      for (i <= 228; i >= 142; i <= i - 2) seq
         copyArea((pack(i)[1] == 1'b1) ? 68 : 84 , 32, i, 67, 10, 8);
         wait_timer(`TICK_WAIT3);
         if (fbutton) break;
      endseq // for
      if (fbutton) break;
      // from left to right
      for (i <= 136; i <= 226; i <= i + 2) seq
         copyArea((pack(i)[1] == 1'b1) ? 75 : 91 , 107, i, 67, 16, 8);
         wait_timer(`TICK_WAIT3);
         if (fbutton) break;
      endseq // for
      eraseArea(226, 67, 16, 8);
      wait_timer(`TICK_WAIT32);
      if (fbutton) break;
     // from right to left
     for (i <= 226; i >= 136; i <= i - 2) seq
        copyArea((pack(i)[1] == 1'b1) ? 77 : 93 , 117, i, 67, 16, 8);
        wait_timer(`TICK_WAIT3);
        if (fbutton) break;
      endseq // for
      wait_timer(`TICK_WAIT32);
      if (fbutton) break;
      eraseArea(141, 67, 9, 8);
      wait_timer(`TICK_WAIT32);
      if (fbutton) break;
   endseq);
endfunction

これだけでなく、タイマールーチンの中でもFボタンによる中断を見ていますが、ちょっとやり過ぎのようです。実際には多少間引いても体感に影響しないと思います。


左矢前のブログ 次のブログ右矢


ページ: