Posts Tagged with "Cmod A7"

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

Cmod A7の利用 (8)

posted by sakurai on November 29, 2023 #705

レベルダイアグラム

前稿のレベルダイアグラムを変数を用いて書き直したものが図705.1です。これに従いデータ変換器をBSVで開発します。ただし、前稿ではVRの開始角と使用角度範囲を105°, 90°と仮決めしましたが、試行錯誤で変更することを見越してパラメータ化したRTLとします。

図%%.1
図705.1 レベルダイアグラム

  • VRの全角度は300°
  • VRの使用角はパラメータ化し、開始角a[°]、範囲b[°]
  • VRの全角度の際のADC入力電圧はLTSpiceの結果より、0.2~0.94[V]

これらより、使用電圧は開始角の値を$V_\text{a}$、終了角の値を$V_\text{a+b}$として、

  • $V_\text{L}=0.2$, $V_\text{H}=0.94$
  • $V_\text{range}=V_\text{H}-V_\text{L}=0.74$
  • $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}=10.1a+819.2$
  • $D_\text{a+b}=4096V_\text{a+b}=10.1(a+b)+819.2$
  • $D_\text{range}=10.1b$

一方、y座標の制約は以下のとおりであり、上限$y_\text{top}$と下限$y_\text{bottom}$の値でクリッピングが必要。

  • $y_\text{bottom}=44$, $y_\text{top}=186$
  • $y_\text{range}=y_\text{top}-y_\text{bottom}=142$

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

  • $y=\frac{y_\text{range}}{D_\text{range}}(D-D_\text{a})+y_\text{bottom}=\frac{142}{10.1b}D-\frac{142}{b}a-\frac{142\cdot 819.2}{10.1b}+44\\ =\frac{224.9}{b\ll4}D-\frac{142}{b}a-\frac{11514}{b}+44=\frac{225D-2272a-184216}{b\ll4}+44$

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

  • $D_\text{a}=10.1a+819.2=(162a+13107)\gg4$
  • $D_\text{a+b}=10.1(a+b)+819.2=(162(a+b)+13107)\gg4$

以上より、完成したBSVコードは以下のとおりです。

 package FixedPointConverter;

    import Vector::*; // ベクター操作のためのモジュール

    interface ConverterIfc;
        method Bit#(12) convert(Bit#(12) adcValue);
    endinterface

    // ADCの値から座標に変換する演算器(固定小数点演算を使用)
    (* synthesize, always_ready, always_enabled, no_default_clock, no_default_reset *)
    module mkFixedPointConverter #(
        parameter Bit#(12) a,  // 角度の最小値
        parameter Bit#(12) b   // 角度範囲
    ) (ConverterIfc);

        method Bit#(12) convert(Bit#(12) adcValue);
            // パラメータの拡張
            Bit#(20) extendedA = zeroExtend(a);
            Bit#(20) extendedB = zeroExtend(b);

            // 座標の下限と上限に対応するADC値の計算
            Bit#(20) adcMinValue = (162 * extendedA + 13107) >>4;     // Min = 10.1A + 819.2
            Bit#(20) adcMaxValue = (162 * (extendedA + extendedB) + 13107) >> 4; // Max = 10.1(A+B) + 819.2
            // クリッピング処理
            Bit#(12) clippedAdcValue = (adcValue < truncate(adcMinValue)) ? truncate(adcMinValue) :
                                      (adcValue > truncate(adcMaxValue)) ? truncate(adcMaxValue) :
                                      adcValue;

              Bit#(24) coordinate = ((zeroExtend(clippedAdcValue) * 225
                                   - zeroExtend(extendedA) * 2272 - 184216)
                                   / zeroExtend(extendedB) >> 4) + 44;

            return truncate(coordinate);
        endmethod

    endmodule
endpackage: FixedPointConverter

これをVivadoに配置した図は以下のとおりで単なる組み合わせ回路です。

図%%.2
図705.2 変換器

このモジュールをダブルクリックすると以下のパラメータ設定画面が表示されます。aとbがすでに設定されているのは、残念ながらbsvにデフォルト値の設定が無いのですが、生成されたverilogのパラメータ文を修正したものです。verilogを10進で修正したため、vivadoでも10進表示となっています。

図%%.3
図705.3 パラメータ設定画面

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

Cmod A7の利用 (7)

posted by sakurai on November 28, 2023 #704

レベルダイアグラム

アナログ回路では用いられる概念でレベルダイアグラムという概念があります。回路の各部分でどれだけのダイナミックレインジがあるかを示す図です。ここではアナログ入力についてダイナミックレインジを調べておきます。

VR角度[°] XADC入力電圧[V] XADC出力
0 0.2 820
300 0.94 3,852

使用VR角度[°] 変換器出力 画面可動域[pix]
105 1598 44
195 2498 186

  • VR回転角は0~300°
  • XADC入力は0~1.0Vであるが可変抵抗器出力のため、0.2~0.94V
  • XADCの変換後の出力はおよそ820~3852
  • 使用VR回転角は中心150°±45°=105~195°⇒調整により変更予定
  • 変換回路の出力は1598~2498⇒調整により変更予定
  • 画面の可動域(y座標)は44~186

読み出しシーケンス

読み出しだけなのでデータバスdi_in及びdwe_in入力は0とします。またアドレスはPin 15に対応するChannel 4(0x14)とし、den_inを1サイクルだけアサートします。すると変換データが準備されデータバスdo_outに出力されるので、それを読み込みます。この回路では変換終了信号eoc_outをden_inに接続しているため、連続的に変換が実行されます。

eoc_outをden_inに接続することにより、特に複雑なシーケンサを組まなくても連続的にADCが実行できるようです。

図%%.1
図704.1 XADC回路図

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

Cmod A7の利用 (6)

posted by sakurai on November 21, 2023 #699

DRPからアクセス可能な各種ステータスレジスタ及びコントロールレジスタを示します。

図%%.1
図699.1 XADC構造

次にDRPアクセスタイミングを示します。

図%%.2
図699.2 XADCのDRPアクセスタイミング

この仕様に従ってADCデータを読み出すFSMをBSVでプログラミングします。BSVではStmtFSMライブラリを用いることによりシーケンシャルな処理を実行するFSMが容易にかけるため、FSMの設計に何ら痛痒を感じません。ただし結果としてはEOC(End of conversion)をDEN(DRP Enable)に接続し、Continuousモードに設定するだけで連続的にADC値が出力されるため、シーケンサを組む必要はありませんでした。

完成したADCソフトブロックを以下に示します。ADCの出力に接続しているのは、ADC値からy座標に変換する回路(#705で設計予定)です。

図%%.2
図699.3 ADCソフトブロック

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

Cmod A7の利用 (5)

posted by sakurai on November 17, 2023 #698

Artix 7シリーズFPGAのADCを利用するには、ただ読み込めば良い基板上のスイッチと異なりいろいろと制約があるようです。ADCのユーザーズガイド(UG480)に書かれていますが、DRP(Dynamic Reconfigure Register)経由で読み出すとのことです。

その日本語版 (UG480) のXADCの概要によれば、

XADC には、オンチップ電源電圧とダイ温度の測定をサポートするいくつかのオンチップ センサーも含まれています。ADC 変換データはステータス レジスタと呼ばれる専用レジスタに格納されます。これらのレジスタは、ダイナミック リコンフィギュレーション ポート (DRP) と呼ばれる 16 ビットの同期読み取り/書き込みポートを使用して、FPGA インターコネクト経由でアクセスできます。

とのことであり、以下にブロック図を示します。右下にDRPブロックがあります。

図%%.1
図698.1 XADC回路図

VivadoにおいてはXADC Wizardによりパラメータを設定してからインスタンスします。

  • Vivadoのブロックデザインエディタにおいて、右クリックからAdd IPをクリック、XADC Wizを開く。
  • Basicタブにおいて、Interface OptionをDRPとする。
  • Timing ModeはContinuous Mode
  • startup Channel SelectionはSingle Channel
  • DRP Timing Optionは無設定(DCLKは100MHzがデフォルト)
  • AXI4Sは無設定
  • Control/Status Portsは無設定
  • ADC Setupタブにおいて、全てを無設定、None、空欄とする。
  • Alarmsタブにおいても同様。
  • Single ChannelタブはChannel Enableにチェック

以上を設定のうえOKをクリックすると図のようなモジュールが生成されます。WizardではXADCが内部にインスタンスされたラッパーモジュールを生成します。

図%%.2
図698.2 生成されたXADCモジュール

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

Cmod A7の利用 (4)

posted by sakurai on November 15, 2023 #697

回路を修正し、基板版数をV5としました。修正箇所は

  • VRを追加
  • Micro USBの書き込みポートが干渉するため、逆向きにした。
  • ドリルホールが小さかったのを広げた

これにより基板サイズを多少大きくしました。回路図中に文字の重なりがあるのはEagleのバグのようです。

図%%.1
図697.1 CmodA7toPMODV5ボード回路図

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

再度JLCPCBに依頼しましたが、費用は以下のとおり変わりません。

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


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

Pongの開発 (7)

posted by sakurai on November 14, 2023 #696

可変抵抗器の作成

標準ではLTSpiceに可変抵抗器は存在しないようです。そこで可変抵抗器のモデルを作成してLTSpiceに組み込んでみました。参考にさせて頂いたのはこのページ(魚拓)です。

図%%.1
図696.1 可変抵抗器等価回路

図696.1のZo1-Zo2間に0-10kΩの可変抵抗を発生させる仕様であり、インピーダンスがゼロとならないよう、電源内部に1Ω抵抗を入れています。以下はこの部品のSpice記述です。

.SUBCKT ZX In1 In2 Z Zo1 Zo2
Eout Zo1 1 POLY(2) (In1,In2) (Z,0) 0 0 0 0 1
Fcopy 0 Z Vsense 1
Rin In1 In2 1G
Vsense 1 Zo2 0
.ENDS

これを用いたLTSpiceにおける部品の作成法を示します。

  • 上記記述をZX.subとしてC:\Users\ユーザ名\AppData\Local\LTspice\lib\subに配置
  • OpenによりZX.subを開くが拡張子が制約されており対象に出ないため、全ファイルを対象として開く
  • 1行目を右クリックしてCreate Symbolを行う

これを組み込んだ回路のシミュレーションを実施したので以下に回路と波形を示します。

図%%.2
図696.2 可変抵抗器使用回路

制御電圧$V_\text{1}$(グリーン)は実際には存在しない制御電圧で0~1.0Vです。Zo1とZo2の間がこれにより0~10KΩとなります。$V_\text{in}$(ブルー)は0.3~3.3Vとなり、CmodA7入力電圧$V_\text{1}$(マゼンタ)は0.3~3.2Vとなっています。ADCの入力電圧$V_\text{out1}$(ブルーグリーン)は0.07~0.94Vとなっています。ただし変化が急かもしれないので、その場合にはR5を例えば10KΩと大きくすることで調整します。

図%%.3
図696.3 可変抵抗器使用回路

R5を10KΩとした場合、ADCの入力電圧$V_\text{out1}$(ブルーグリーン)は0.2~0.94Vと下側が上がったものの、変化が穏やかになりました。

秋月の10KΩの可変抵抗器Bを見ると可変角は最大300°だそうで、使用感を考えると可変抵抗を最大まで使うよりも角度の一部を使ったほうが使いやすそうです。そのためADC入力電圧の下側を上げて47KΩとし、回転角の60~90°くらいを使用したほうが良いかもしれません。


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

Pongの開発 (6)

posted by sakurai on November 13, 2023 #695

エミッタフォロワ

インピーダンス変換のためにNPN Trでエミッタフォロワ回路を構成しました。

図%%.2
図695.1 エミッタフォロワ回路と波形

ところが、TrがOnしても電圧降下が約0.8Vもあり、エミッタ電圧$V_\text{Tr}$(マゼンタ)は約2.5V Max程度となり、さらにADCの入力電圧$V_\text{out1}$(グリーン)は約0.75V Maxとなっています。

改善はされましたが1V近くまでは上昇しませんでした。もっともパドルの制御なのでどうでもよいことかもしれません。


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

Pongの開発 (5)

posted by sakurai on November 10, 2023 #694

パドルコントロール

さて、Pongの実装で欲しくなるのがパドルコントロールのためのツマミです。一般には可変抵抗器で実装しているようです。幸いCmodA7にはアナログ入力があるので、可変抵抗器を接続すればよさそうです。

FPGAボード内のアナログ入力は以下のようになっています。外部の0~3.3Vの電圧を抵抗で分圧し、FPGAのADC入力は0~1Vの入力としています。入力インピーダンスが高いとは言えないので、外部回路の出力インピーダンスが高い場合問題になります。

図%%.1
図694.1 CmodA7 ADC入力回路

可変抵抗器は出力インピーダンスが変化するので、設計が案外面倒です。最大と最小のみの2点だけを考えれば良いのかもしれませんが、ここではアナログ回路シミュレータであるLTSpiceを使用してみます。

まず、可変抵抗器のシミュレーションをする前に、出力インピーダンスが高い場合にどうなるかを見てみます。出力インピーダンスが3.3Kとした場合の回路とシミュレーション波形です。浮遊容量を少し付加しています。

図%%.2
図694.2 出力インピーダンス3.3Kと波形

サイン波形を入れていますが、DC特性を見る目的です。

波形から明らかなように、基準電圧$V_\text{in}$(ブルー)は3.3Vまで上昇しているにも関わらず、出力インピーダンスが後段の入力インピーダンスと同程度であるため、CmodA7ボードの入力電圧$V_\text{1}$(レッド)は期待の3.3Vまで上昇せず1.6V Maxとなり、分圧したADCの入力電圧$V_\text{out1}$(グリーン)は0.5V Maxと半分しか上がりません。


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

Pongの開発 (3)

posted by sakurai on November 8, 2023 #692

ブロック図

以下にPongのデモ画面が動作するステートマシンを組み込んだブロック図を示します。

図%%.1
図692.1 Pongブロック図

これらのモジュールのうち、クロック系、デュアルポートRAMを含むグラフィクス系、1チャネルのサウンド系はほぼ流用です。新規設計はGameFSMのみであり、GameFSMとSoundFSMを連結するコマンドバッファもそのまま流用しています。 

完成画面

システムが動作している画面を示します。

図%%.2
図692.2 Pong動作画面

方向制御

パドルの縦位置はボールと同じにしてあるため、必ずボールは打ち返します。パドルでの反射は表692.1のとおり。

表692.1 2種類の乱数とボールの方向
乱数1 bcount 乱数2 dy
0 0 (45°) 0 (dx=1に対して)+1
1 (dx=1に対して)-1
1 3 (18.4°) 0 (dx=3に対して)+1
1 (dx=3に対して)-1

乱数1で傾きの逆数であるbcountを0または3とします。乱数2で方向がプラス+1かマイナスかを決定します。合わせると、bcount=0は右方向の場合速度ベクトルが(+1, +1)または(+1, -1)です。bcount=3の場合速度ベクトルが(+1, +1/3)または(+1, -1/3)です。

オリジナルゲームにはまっすぐ反射する反射もあったのですが、まっすぐ反射してもあまり面白くないので、カットしました。

上下の壁にボールが衝突するとy方向の速度dyの符号を反転させます。一方、左右のパドルに衝突するとx方向の速度であるdxの符号を反転させ、かつ上記の表により方向をランダムに変化させます。


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

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

という結果でした。


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


ページ: