Posts Tagged with "FPGA"

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

CmodA7toPMODの評価

posted by sakurai on January 5, 2024 #729

CmodA7toPMODV5/6のノイズ評価

それぞれのボードに部品を実装してノイズ評価を行いました。その結果以下のようなことが判明しました。

  • 改版後のV6でもV5と同様にノイズが乗る。主にXADCに供給していた100MHzクロックが原因のようだ。
  • 100MHzを落として8MHz程度にすると正しく動作し、かつスイッチONでのブー音が消えた。

図%%.1
図729.1 XADC外部クロックを8MHzに
  • スペースインベーダーはXADCを使用していないので、どちらのボードでも画面縞は発生しない。
  • 一方、XADCクロックを8MHzに落としても画面の斜め縞はV5/V6両方で発生する。
  • XADCへの供給クロックを8MHzに落とした(上記)だけではなく、XADCの内部動作クロック設定も8MHzにしたが、斜め画面縞は変わらず原因不明。

図%%.2
図729.2 XADC外部クロックを8MHzに

実験によるフィードバック

V6基板においてVRを実際にADCに接続してJTAG経由で測定したところ、ADC入力電圧値は0.208~0.9804Vとなりました。LTSpiceの値とほぼ一致する結果です。

設計計算の変化点をマーカで表示します。ピンク前記事との変化点であり、ブルーは最終結果としてソースコードに入れる値です。

  • VRの全角度は300°
  • VRの有効角はパラメータ化し、開始角a[°] (デフォルト値a=105)、範囲b[°] (デフォルト値b=90)
  • VRの全角度の際のADC入力電圧は測定結果より、0.2~0.98[V]

図%%.3
図729.3 レベルダイア

再設計計算

これらより、ADC入力電圧は開始角$a$の値を$V_\text{a}$、終了角$a+b$の値を$V_\text{a+b}$として、 $\require{color} \definecolor{pink}{rgb}{1.0,0.8,1.0} \definecolor{blue}{rgb}{0.8,0.8,1.0}$

  • $V_\text{L}=\colorbox{pink}{0.2}$, $V_\text{H}=\colorbox{pink}{0.98}$
  • $V_\text{range}=V_\text{H}-V_\text{L}=\colorbox{pink}{0.78}$
  • $V_\text{a}=\frac{V_\text{range}}{300}a+V_\text{L}$
  • $V_\text{a+b}=\frac{V_\text{range}}{300}(a+b)+V_\text{L}$

次にAD変換後のデータDは入力全範囲0~1[V]を4096分割する。開始角の値を$D_\text{a}$、終了角の値を$D_\text{a+b}$として

  • $D_\text{a}=4096V_\text{a}=\frac{4096V_\text{range}}{300}a+4096V_\text{L}=\colorbox{pink}{10.65}a+\colorbox{pink}{819.2}$
  • $D_\text{a+b}=4096V_\text{a+b}=\colorbox{pink}{10.65}(a+b)+\colorbox{pink}{819.2}$
  • $D_\text{range}=D_\text{a+b}-D_\text{a}=\colorbox{pink}{10.65}b$

一方、y座標の制約は以下のとおりであり、$y_\text{top}$(上限$y_\text{max}$+5%)と$y_\text{bottom}$(下限$y_\text{min}$-5%)の値でクリッピング。

  • $y_\text{min}=\colorbox{pink}{44}, y_\text{max}=\colorbox{pink}{219}, Paddle_\text{h}=\colorbox{pink}{26}$
  • $y_\text{bottom}=y_\text{min}-7=\colorbox{pink}{37}, y_\text{top}=(y_\text{max}-Paddle_\text{h})+7=\colorbox{pink}{200}$
  • $y_\text{range}=y_\text{top}-y_\text{bottom}=200-37=\colorbox{pink}{163}$

これらからy座標を求めると、ADCのデータを$D$とすれば、

  • $y=\frac{y_\text{range}}{D_\text{range}}(D-D_\text{a})+y_\text{bottom}=\frac{\colorbox{pink}{163}}{\colorbox{pink}{10.65}b}D-\frac{\colorbox{pink}{163}}{b}a-\frac{\colorbox{pink}{163}\cdot\colorbox{pink}{819.2}}{\colorbox{pink}{10.65}b}+\colorbox{pink}{37}\\ =\frac{\colorbox{pink}{244.9}}{b\ll4}D-\frac{\colorbox{pink}{163}}{b}a-\frac{\colorbox{pink}{12538}}{b}+\colorbox{pink}{37}=\frac{\colorbox{blue}{245}D-\colorbox{blue}{2608}a-\colorbox{blue}{200615}}{b\ll4}+\colorbox{blue}{37}$

y式中のシフトは固定小数点演算を行うために分母分子を16倍しているものです。さらに最小値$D_\text{a}$、最大値$D_\text{a+b}$で入力ADCデータのクリッピングを行います。

  • $D_\text{a}=\colorbox{pink}{10.65}a+\colorbox{pink}{819.2}=(\colorbox{blue}{170}a+\colorbox{blue}{13107})\gg4$
  • $D_\text{a+b}=\colorbox{pink}{10.65}(a+b)+\colorbox{pink}{819.2}=(\colorbox{blue}{170}(a+b)+\colorbox{blue}{13107})\gg4$

以上より、完成したBSVコードの変更点のみを以下に示します。

クリッピング値計算部分

            // 座標の下限-5%と上限+5%に対応するADC値の計算
            Bit#(20) adcMinValue = (170 * extendedA + 13107) >>4;     // Min = 10.65A + 819.2
            Bit#(20) adcMaxValue = (170 * (extendedA + extendedB) + 13107) >> 4; // Max = 10.65(A+B) + 819.2

ADCからy値計算部分

            Bit#(24) coordinate = ((zeroExtend(clippedAdcValue) * 245
                   - zeroExtend(extendedA) * 2608 - 200615 + 915)
                   / zeroExtend(extendedB) >> 4) + 37;

+915は途中計算がアンダーフローして値が最大値にならないように調整するものです。この例のように小数点演算において0をわずかに割った場合、負数は正の最大値となるため、非常に大きな誤差が起こります。

FSM中でのパドルの可動範囲$y_\text{min}=\colorbox{blue}{44}$、$y_\text{max}-Paddle_\text{h} + 1=219-26 + 1=\colorbox{blue}{194}$でクリッピングすることを忘れないように注意します。


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

posted by sakurai on December 13, 2023 #715

Hardware Description Language Advent Calendar 2023 の第11目として、「BSV (Bluespec System Verilog) によるPongの設計」と題する記事をQiitaに投稿しました。

図%%.1
図715.1 Qiita投稿

以下に目次を示します。

  • Pong Game
  • 強化学習の題材としてのPong
  • BSV
  • BSVをより深く知るためには
  • Cmod A7
  • CmodA7toPMODボードの設計
  • パドルコントロール
  • CmodA7toPMODボード回路
  • FPGA内部ブロック図
  • グラフィックサブシステム
  • ゲームサブシステム
  • ボール方向制御
  • ボール動作
  • ボール制御BSVコード
  • サウンドサブシステム
  • サウンドステートマシン
  • ADC
  • 設計計算例
  • 完成画面
  • 今後の予定や感想

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

Pongの開発 (16)

posted by sakurai on December 12, 2023 #714

CmodA7toPMODV6の実装

JLCPCBからV6基板が届いたので、早速実装して動作試験をしてみました。あいかわらず、スイッチを押すとブーという音が出ます。いろいろと試したところXADCのクロックが100MHz推奨であるものを1/10以下に落としたら、画面もきれいになりスイッチのブー音も消えました。ただし、依然として画面の斜め縞は出ており原因不明です。インベーダーゲームでは出現しないので、XADCを起動させると出ることは確かです。

一方、初めて基板厚を0.8mmと従来の半分にしてみましたが、DCジャックの足も折れ曲がり代が増え、こちらは良好です。

図%%.1
図714.1 CmodA7toPMODV6ボード基板

JLCPCB費用他

表714.1 JLCPCB費用まとめ
内容 費用[USD]
基板製造費(5枚) 2.00
部品代(15個) 5.48
基板実装費(5枚) 12.79
配送費(OCS) 9.0
クーポン ▲9.0
合計 20.27

時間としては基板製造と部品実装で2日間、最安のOCS配送が7日間で、計9日間で到着しました。


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

Pongの開発 (15)

posted by sakurai on December 11, 2023 #713

CmodA7toPMODの改版

CmodA7toPMODV5の実機評価の結果、数点ノイズが原因らしい問題点が発覚しました。原因は恐らくCmodA7ボードからコネクタを2回とおして遠くのスイッチまで伝送線路が伸びていることによるノイズと思われます。そのためUltra96toPMODボードと同様にバッファICを入れる改版を行います。以下に回路図を示します。

図%%.1
図713.1CmodA7toPMODV6ボード回路図

Ultra96toPMODで使用したときは1.8V信号と3.3V信号のレベル変換の必要上からTXS0108Eを使用しました。今回は3.3Vどうしでレベル変換は不要ですが、同ICをバッファとして使用しました。

ついでにアナログ入力が2chあるので、パドルを2個接続できるようにピンソケットを増設しました。以下に同ボードのBOM及びP&P表を示します。

図%%.2
図713.2 BOM表

図%%.3
図713.3 P&P表

PCBAはいつものように格安のJLCPCBに依頼しました。約20 USDで実装及び部品代込みです。

図%%.4
図713.4 Gerber図

今回DCジャックの足を折り曲げる必要からPCB厚を最安の費用の範囲内で最薄の0.8mmに変更しました。代償として基板色はグリーンしか選べませんでした。

図%%.5
図713.5 PCB厚

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

Pongの開発 (14)

posted by sakurai on December 8, 2023 #712

QSPIプログラミング

FPGAプログラミングにはVivadoやPCやUSBケーブル等が必要ですが、電源を投入してアプリケーションをすぐに動作させるためにはCmodA7ボード上のQSPI Flashに書き込む必要があります。基本的には過去記事:Artyで実施したのと同じ手順ですが、異なる点だけを示します。

  • Binファイルの作成: 過去記事どおりに実施します。
  • Binファイルの焼きこみ: 選択するFlashの型格に注意します。以下の図のとおり、mx25I3273f-spi-x1_x2_x4を選択します。間違えて異なる型格を指定すると、Vivadoがエラーを出力し正しい型各を教えてくれます。

図%%.1
図712.1 Flash選択画面

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

Pongの開発 (13)

posted by sakurai on December 7, 2023 #711

パドル動作

完成したADCとパドルVRの連携を以下の動画に示します。パドルの描画アルゴリズムは

  • 新しいADCの値を取得
  • ADCの値を要素8の移動平均化(フラつき防止のため)
  • 閾値4と移動値(ADC値-現在値)を比較し、閾値を超えていたら移動(フラつき防止のため)
  • 移動値を座標制限内にクリッピング
  • 移動の際には現在のパドル像を消去(ゴミ残り防止のため)
  • 前回値と同じであれば書き換えをしない(チラつき防止のため)

図%%.1
図711.1 パドル動作

ボール動作

ボールがパドルと衝突する判定は、ボール座標のVRAMデータを読み出して行います。右パドルのVRAMデータは3であるため、移動のたびにボール座標を読み出し3であれば衝突と判断します。

パドルのy座標範囲は0~25であり、これを①0~5,②6~12、③13~19、④20~25の4領域に分割します。①に衝突した場合は-45°の角度で反射し、②は約-18.4°の角度で反射します。これをxとyの増分であるdx, dyに変換すれば、-45度の場合はdx=1, dy=-1であり、-18.4度の場合はdx=3, dy=-1です。

図%%.2
図711.2 ボール衝突動作

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

Pongの開発 (12)

posted by sakurai on December 6, 2023 #710

実験によるフィードバック

VRを実際にADCに接続してJTAG経由で測定したところ、VRと付属回路の電圧値は0.158~0.711Vとなりました。LTSpiceの値と異なったのは手持ちの適当な抵抗を付けたからかもしれません。

また、パラメータ化したa, bはデフォルト値のa=105, b=90で特に違和感はありませんでした。特に可変範囲は90°としました。これは全回転角が300°でリニアの場合ですが実際にはそうではなく、使用角度bは45°くらいとなりました。

ADCの出力をちょうどy座標の動作範囲にクリップしていましたが、実験の結果、パドルが端にくっつかない問題がありました。そのためADCの出力を、動作範囲よりも5%ほど大きめにして座標計算でもクリップすることにします。

さらにパドル消去アルゴリズムを変更したため、パドルの大きさも多少変えました。従って、再度設計計算を行います。一度方式としては確定しているため、数値を少々変更するだけです。変化点をマーカで表示します。ピンク前記事との変化点であり、ブルーは最終結果としてソースコードに入れる値です。

  • VRの全角度は300°
  • VRの有効角はパラメータ化し、開始角a[°] (デフォルト値a=105)、範囲b[°] (デフォルト値b=90)
  • VRの全角度の際のADC入力電圧は測定結果より、0.16~0.71[V]

図%%.1
図710.1 レベルダイア

再設計計算

これらより、ADC入力電圧は開始角$a$の値を$V_\text{a}$、終了角$a+b$の値を$V_\text{a+b}$として、 $\require{color} \definecolor{pink}{rgb}{1.0,0.8,1.0} \definecolor{blue}{rgb}{0.8,0.8,1.0}$

  • $V_\text{L}=\colorbox{pink}{0.16}$, $V_\text{H}=\colorbox{pink}{0.71}$
  • $V_\text{range}=V_\text{H}-V_\text{L}=\colorbox{pink}{0.55}$
  • $V_\text{a}=\frac{V_\text{range}}{300}a+V_\text{L}$
  • $V_\text{a+b}=\frac{V_\text{range}}{300}(a+b)+V_\text{L}$

次にAD変換後のデータDは入力全範囲0~1[V]を4096分割する。開始角の値を$D_\text{a}$、終了角の値を$D_\text{a+b}$として

  • $D_\text{a}=4096V_\text{a}=\frac{4096V_\text{range}}{300}a+4096V_\text{L}=\colorbox{pink}{7.509}a+\colorbox{pink}{655.4}$
  • $D_\text{a+b}=4096V_\text{a+b}=\colorbox{pink}{7.509}(a+b)+\colorbox{pink}{655.4}$
  • $D_\text{range}=D_\text{a+b}-D_\text{a}=\colorbox{pink}{7.509}b$

一方、y座標の制約は以下のとおりであり、$y_\text{top}$(上限$y_\text{max}$+5%)と$y_\text{bottom}$(下限$y_\text{min}$-5%)の値でクリッピング。

  • $y_\text{min}=\colorbox{pink}{44}, y_\text{max}=\colorbox{pink}{219}, Paddle_\text{h}=\colorbox{pink}{26}$
  • $y_\text{bottom}=y_\text{min}-7=\colorbox{pink}{37}, y_\text{top}=(y_\text{max}-Paddle_\text{h})+7=\colorbox{pink}{200}$
  • $y_\text{range}=y_\text{top}-y_\text{bottom}=200-37=\colorbox{pink}{163}$

これらからy座標を求めると、ADCのデータを$D$とすれば、

  • $y=\frac{y_\text{range}}{D_\text{range}}(D-D_\text{a})+y_\text{bottom}=\frac{\colorbox{pink}{163}}{\colorbox{pink}{7.509}b}D-\frac{\colorbox{pink}{163}}{b}a-\frac{\colorbox{pink}{163}\cdot\colorbox{pink}{655.4}}{\colorbox{pink}{7.509}b}+\colorbox{pink}{37}\\ =\frac{\colorbox{pink}{347.3}}{b\ll4}D-\frac{\colorbox{pink}{163}}{b}a-\frac{\colorbox{pink}{14225}}{b}+\colorbox{pink}{37}=\frac{\colorbox{blue}{347}D-\colorbox{blue}{2608}a-\colorbox{blue}{227607}}{b\ll4}+\colorbox{blue}{37}$

y式中のシフトは固定小数点演算を行うために分母分子を16倍しているものです。さらに最小値$D_\text{a}$、最大値$D_\text{a+b}$で入力ADCデータのクリッピングを行います。

  • $D_\text{a}=\colorbox{pink}{7.509}a+\colorbox{pink}{655.4}=(\colorbox{blue}{120}a+\colorbox{blue}{10486})\gg4$
  • $D_\text{a+b}=\colorbox{pink}{7.509}(a+b)+\colorbox{pink}{655.4}=(\colorbox{blue}{120}(a+b)+\colorbox{blue}{10486})\gg4$

以上より、完成したBSVコードの変更点のみを以下に示します。

クリッピング値計算部分

            // 座標の下限-5%と上限+5%に対応するADC値の計算
            Bit#(20) adcMinValue = (120 * extendedA + 10486) >>4;     // Min = 7.509A + 655.4
            Bit#(20) adcMaxValue = (120 * (extendedA + extendedB) + 10486) >> 4; // Max = 7.509(A+B) + 655.4

ADCからy値計算部分

            Bit#(24) coordinate = ((zeroExtend(clippedAdcValue) * 347
                   - zeroExtend(extendedA) * 2608 - 227607)
                                   / zeroExtend(extendedB) >> 4) + 37;

変換器部分はこのとおりですが、FSM中でのパドルの可動範囲$y_\text{min}=\colorbox{blue}{44}$、$y_\text{max}-Paddle_\text{h}=219-26=\colorbox{blue}{193}$でクリッピングすることを忘れないように注意します。


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

Pongの開発 (11)

posted by sakurai on December 5, 2023 #709

CmodA7からPMODへのインタフェース基板のため、CmodA7toPMODV5と名付けました。そのGerber図が図709.1であり、JLCPCBに依頼していた基板が届きました(図709.2)。

図%%.1
図709.1 CmodA7toPMODV5ボードガーバー図

図%%.2
図709.2 CmodA7toPMODV5基板

早速組み立てて動作させたところ、デバッグした後に正常に動作しました。図はPMODVGAインタフェース、PMOD I2Sオーディオインターフェース、PMODジョイスティックスイッチインターフェースの3つを接続した図です。外部電源5VでもUSBのみの電力でも動作するようです。

図%%.3
図709.3 CmodA7toPMODV5完成

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

Pongの開発 (10)

posted by sakurai on December 4, 2023 #708

You

AとBはゲームを試作してみないと決定できませんが、決める方法は?

Bluespec Expert
AとBがゲームの試作段階で決定されるというのは理解しました。AとBは、ゲームのデザインやユーザーインターフェースの要件に基づいて変わる可能性があるため、試作を通じてこれらの値を最適化するのは良いアプローチです。

試作段階では、さまざまなAとBの値を試して、ゲームプレイに最も適した設定を見つけることが重要です。この過程で以下の点を考慮すると良いでしょう:

 1. ユーザーインターフェース:
プレイヤーが可変抵抗器のツマミをどのように操作するか、そしてその操作がゲーム上でどのように反映されるかを考慮します。

 2. 応答性:
ツマミの操作に対するゲームの応答性を評価します。ツマミを少し回すだけで大きく座標が変化するか、またはより細かい調整が可能かを検討します。

 3, プレイの難易度:
AとBの設定はゲームの難易度に直接影響を与える可能性があります。簡単すぎるか難しすぎるかを評価し、プレイヤーにとって楽しく挑戦的なバランスを見つけます。

 4, テストとフィードバック:
実際のプレイヤーによるテストを行い、彼らのフィードバックをもとに、AとBの最適な値を決定します。

試作プロセスが完了し、AとBの値が決定されたら、提供された変換式を使用して、ADCの値からゲーム画面上の座標への変換を実装できます。これにより、ゲームの操作性とプレイヤーの体験を最適化することができるでしょう。


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

Pongの開発 (9)

posted by sakurai on December 1, 2023 #707

You

正解です。それではA°のときが画面上の座標44に相当し、A+B°のときが座標186のときに相当するとき、ある角度A+x°のときの座標を計算してください。

Bluespec Expert
与えられた条件に基づいて、角度A+x°のときの座標を計算するためには、角度と座標の間の線形関係を確立する必要があります。A°が座標44に、A+B°が座標186に対応するとします。この関係から、角度と座標の変換式を導き出し、それを使って任意の角度A+x°のときの座標を求めます。

  1. 角度と座標の変換係数の計算:

    • 角度の変化量は B、対応する座標の変化量は 186 - 44 です。
    • したがって、1°あたりの座標の変化量は (186 - 44) / B です。
  2. 任意の角度A+x°の座標の計算:

  • A°のときの座標は44なので、A+x°のときの座標は 44 + x * ((186 - 44) / B) となります。

この計算には、角度の増加量 x とBの具体的な値が必要です。しかし、これらの値が提供されていないため、具体的な座標を計算することはできません。もしこれらの値を提供いただければ、具体的な座標を計算することが可能です。

You

ゲーム中にxは毎秒変化するから具体的な値は与えられません。以上から、ADCの値から座標値へ変換する式を求めてください。

Bluespec Expert
ADCの値からゲーム画面上の座標値への変換式は以下の通りです:

$$座標 = 44 + ((((\text{adc_value} / 4096 - 0.2) / 0.74) * 300 - A) * ((186 - 44) / B))$$

この式では、まずADC値 (adc_value) から対応する角度への変換を行い、その後その角度を基にして座標値に変換しています。ただし、この式はBの具体的な値に依存します。Bは角度AからA+Bまでの変化量を示しており、これによって角度と座標の関係が決定されます。

You

事前に演算できる定数をまとめてください。

Bluespec Expert
確かに、定数同士の除算も事前に計算して定数として扱うことができます。式内のすべての定数同士の乗算と除算を事前に行い、式をさらに簡略化してみましょう。式は次のようになります:

$$座標 = 44 + \frac{\text{adc_value} \times 14.05}{B} - \frac{11513.36}{B} - \frac{A \times 142}{B}$$

これで、式は定数計算をすべて事前に行った状態で、より簡略化されています。これを使って、特定の $\text{adc_value}$、$A$、$B$ の値に対する座標を計算できます。


ChatGPTに計算してもらった式を固定小数点演算化するために分母分子を16倍します。すると、 $$座標 = 44 + \frac{\text{adc_value} \times 225}{16B} - \frac{184214}{16B} - \frac{A \times 2272}{16B}$$ となり、前記事の式と有効数字5桁で一致しました。


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


ページ: