Posts Tagged with "Ultra96"

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

改版中の基板図を図437.1及び2に示します。

図%%.1
図437.1 Ultra96toPMODV9ボード基板図(表面)

図%%.2
図437.2 Ultra96toPMODV9ボード基板図(裏面)


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

posted by sakurai on September 20, 2021 #436

基板が到着しました。今回も実装が安いBokTechに依頼しました。

図%%.1
図436.1 Ultra96toPMODV8基板

部品を並べたものが図436.2です。

図%%.2
図436.2 Ultra96toPMODV8ボード及び部品

組み立てたものが図436.3です。

図%%.3
図436.3 Ultra96toPMODV8ボード完成

正常に動作したものの、デバッグ途中で修正箇所を発見したため、改版中です。具体的には、

  • Dip SWの入力がレベル変換ICにより1.8Vに変換されて入力されていた(Dip SWはスタティック信号のため、レベル変換ICの必要無し)⇒Dip SWの電源を1.8Vに変更し、ダイレクト入力に変更
  • Joy SWの入力が3.3Vダイレクト入力だった⇒1.8Vにレベル変換して入力(ラッチアップの可能性有るため)

Joy SWはV3において、1.8Vへのレベル変換ICを通すように変更したのですが、その際にSW信号が水平・垂直同期信号に悪影響を与えたため、V4以降で元に戻したものです。ただし動作しているとはいえ、1.8V入力に3.3Vを加えています。今回は再度V3と同様に修正します。ちなみにV3での悪影響の理由は、レベル変換ICで混信したのではなく、図436.4のように、レイアウト上同期信号がSW信号の間を通っていたためのようです。

図%%.4
図436.4 V3でのHSYNC/VSYNCのSWとの混信

V9ではV3と同様、再度JoySW信号を1.8Vへのレベル変換ICに入れるように修正しました。合わせて、レイアウト上SWの間を水平・垂直同期信号が通らないように注意して配線しています。


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

posted by sakurai on September 3, 2021 #434

Qiitaに「BSVによるSpaceInvaderのソースを公開」という記事を書きましたが、それに合わせてUltra96toPMOD基板の再設計(V8)を実施しました。現行のV7との変更点は、以下の2点です。

  • UltraZedボードインタフェースの削除
    UltraZedからは能動素子無しにUltraZedボード⇒Ultra96toPMODボード⇒PMODインタフェースボードと経由して信号を通していました。今回評価したところ、反射が起きて正常に動作しませんでした。Ultra96toPMODボード内でバッファを通す必要があったようです。設計変更も考えましたが、あまり需要が無さそうであるため、このインタフェースは削除することにしました。これに伴いZenarダイオードによる電源のOR回路も省略でき、電源まわりがすっきりしました。

  • 4層から2層に変更
    4層基板を2層としました。主な理由は、以前はそれほど高額でない料金で4層板が設計できたものが、EAGLEがAutodeskに買収されたため、高額なサブスクリプションでなければ4層板が設計できなくなったことです。無償で設計できるのが2層までとなったため、設計変更しました。

図%%.1
図434.1 Ultra96toPMODV8ボード表面図

データの場所は、https://github.com/mocapapa/Ultra96toPMODV8です。

今回もPCBA(SMD実装込み)を依頼しましたが、SeedFusionだと1万5千円以上だったので、BokTechに依頼しました。費用内訳は、

  • 基板代 1.0 USD
  • アセンブリ費用(部品代込み) 29.83 USD
  • DHL送料 34.0 USD

の合計64.83 USDでした。


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

デザインのボード間移植

posted by sakurai on June 18, 2021 #424

ArtyボードからUltra96ボードへ

RTLにはボード依存性はありませんが、トップモジュールやIPにはボード依存性があるため、その移植が必要となります。まずトップ配線(ブロック間配線)は、Export Block Designにより、配線情報がTCLにより得られるので、それを入力したいところです。しかし、ボード依存性があるようで、新ボードを設定した上で旧ボードのTCLを読み込むとエラーになってしまいます。そのため、

  • 旧ボードの環境でデザインを構築しておき、新規ボードに変換する

方法により、デザインのボード間移植を実施しました。

新規プロジェクトの生成

最初に旧ボードでプロジェクトを生成します。この段階で必要なものはVerilogソースが全て含まれているsrcディレクトリ、ブロックデザインのTCL、新ボードのXDCのひな形です。

  1. Vivadoの下にプロジェクトフォルダを作成します。その下に、Verilogソースが全て含まれているsrcディレクトリ、ブロックデザインのtcl及び、xdcを配置します。
  2. Vivadoを起動し、Create Project⇒Next⇒RTLプロジェクトを選択し、Verilogソースフォルダを選択します。
  3. 次にconstraintファイルとしてxdcを設定します。
  4. Boardsとして旧ボードを選択します。
  5. FinishによりProjectが生成されます。
  6. IP Integrator⇒Create Block Designを実行します。
  7. BLOCK DESIGN⇒Sources⇒Design sourcesのトップデザインであるdesin_1に対してラッパを生成します。
  8. design_1を選択して右クリックでCreate HDL wrapperを実行するとダイアログが現れます。
  9. Let Vivado ...を選択してOKをクリックします。
  10. オレンジの階層だったものが、design_1_wapperというグリーンの階層が生成されます。
  11. それを右クリックし、Set as topにより、トップ階層とします。
  12. 最下段のTCL Console内で、source C:/Users/<ユーザ名>/Vivado/<プロジェクト名>/design_1.tclを実行します。
  13. ブロックが配置され、ブロック間に配線されます。Diagramを右クリックしてExpand Allし、Regenerate Layoutをクリックします。
  14. タイトルコメントのText sizeを64、Box fill colorを204,255,255とします。

新ボードへ移行

  1. ボードが旧ボードになっているので、PROJECT MANAGER⇒Settingsでダイアログを立ち上げ、Project Settings⇒General⇒Project device:によりボードを新ボードに変更します。
  2. BLOCK DESIGNに、IPのアップグレードを促す指示が出るため、個数をクリックします。Show IP Statusをクリックします。
  3. 最下段のUpgrade SelectedをクリックしIPのアップグレードを実施します。
  4. IPによっては結線が外れていることがあるため、良く見直して、外れていれば接続しなおします。

注意点

coeファイルは相対ディレクトリで記録されますが、tclスクリプトからうまく参照できないようなので、全て絶対ディレクトリ(例:e:\file.coe)として参照できるようにしました。


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

ゲームFSMとサウンドFSMの連携

posted by sakurai on June 5, 2020 #271

Ultra96においてBSVで開発

元々Verilog版では、コマンドバッファに書き込むだけで特に何もしなくても動作していました。今回BSVで再設計する際に、サウンドを4chとし、取りこぼしを避けるために考えたのがサウンドキュー(FIFO)でした。

図%%.1
図271.1 サウンドキュー

これはVivadoのFIFOジェネレータで作成したため、最小段数でもかなり深く1024段程度となっています。 実験したところ、確かに取りこぼしは無いのですが、一方、サウンドがゲームとズレて行き、まるでサウンドレコーダのような動作になってしまいました。そのため、FIFOを1段に修正しました。FIFOジェネレータでは1段のFIFOは作成できないのでVerilogで記述しました。1段のためFIFOと呼ぶのはおかしいのでコマンドバッファと呼ぶことにします。

コマンドバッファには、ゲームFSMからコマンドが来たことを示すフラグemptyを設け、書き込むと!emptyとなるようにします。サウンドFSMからは!emptyの時に新たにコマンドが来たと判断し、コマンドを読んだ後にemptyに変更します。

図%%.2
図271.2 1段バッファに変更

Artyボード移植後

Ultra96ではこれで動作していたのですが、Artyボードに移植後に自機増加音が無視されることに気づきました。サウンドFSMが取りこぼしているのだと推測し、再考すると、ゲームFSMが不必要に速いことに気づきました。DSOを接続して調べたところ、96.4%がウェイトだと判明したので、これを1MHzに落としたところ、動作するようでした。

ところが実験すると、依然として自機増加音(コマンドNo.9)が無視されるようです。そこで、ILAを接続して、

  • サウンドコマンド
  • サウンドFSMステート
  • コマンドバッファemtpy
  • サウンドFSM内部フラグ(fNO9)

を観測しました。最後の内部フラグfNO9は自機増加音がプリエンプトされないように割込みを禁止するためのフラグで、コマンドNo.9を受け付けた際にTrueになる信号です。

図%%.3
図271.3 ILA波形(NG)

図271.3はゲームFSMクロックを2MHzとして取得したものですが、フラグfNO9がTrueにならず、コマンドNo.9を無視しています。その原因は、サウンドFSMが受け取る前に次のコマンドNo.4を上書きしているためです。

従って、コマンドの書き込みの際にemptyである場合のみ書き込み、!emptyの場合は捨てる処理を行います(図271.4のマゼンタ矢印の処理を追加)。

図%%.4
図271.4 両側でemptyを確認するように修正

このように修正したところ、No.9の次のコマンドが!empty(=buffer full)のため捨てられることにより、図271.5のように受け付けられるようになりました。
図%%.5
図271.5 ILA波形(OK)

FIFOではないので、原理上取りこぼしは防げないものの、実用上これで動作するようです。

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

6809 IPの修正(2)

posted by sakurai on October 3, 2019 #162

6809 IPは、Verilogステートマシン設計されているため、Vivadoのロジックシミュレータでステート毎に値をチェックして行きました。飛び先である\$FF12を用意されているものの、PCに書き込まれていないことが判りました。とは言え、JMP命令は正しくデコードされ、内部信号のop_JMP(JMP命令であることを示すデコード信号)は正しく出力されています。

図%%.1
図162.1 修正前の6809CPUの動作

ステート遷移を修正し、レジスタ書き込みで終わっている箇所をジャンプステートに修正し、さらに、PCへの書き込みアサートを追加しました。

ステートの遷移は、修正前が、0f,16, 17, 18, 19, 11, 12, (09=次の命令フェッチ)のようになっているのに対して、修正後は0f, 16, 17, 18, 19, 1b, (09=次の命令フェッチ)のように遷移し、かつ、オレンジ色で示したk_write_pc信号がアサートされ、new_pcである\$FF12\$FF12がPCにセットされています。結果として正しく\$FF12にジャンプしています。

図%%.2
図162.2 修正後の6809CPUの動作

修正前は誤ってステートが、\$11(SEQ_GRAL_ALU), \$12(SEQ_GRAL_WBACK)と、レジスタ書き込みのステート遷移となっているのに対して、修正後は\$1b(SEQ_JMP_LOAD_PC)と、JMP命令のステートに遷移しています。

例えばメインフレームのような大型機をどのようにテストしているかと言えば、もちろん単体命令をひとつづつテストすることも行いますが、キャッシュ、仮想記憶、ページングの記憶階層があります。そのためのタイミングによるバグの可能性があるので、ランダム試験を実施します。命令を乱数で発生し、ただし不正命令とはならないように制約をかけ、ソフトシミュレータで正解値を取得します。これを論理シミュレータにかけ、結果値であるレジスタの値やメモリの値が正しいかをチェックします。メモリの値はひとつずつチェックすることなく、領域のチェックサムを取ることで確認します。

さらにこれを発展させ、実機にランダムプログラム生成プログラムを載せて、実行時に正解値を生成しチェックします。一見バグ値どうしを比較してOKとなりそうですが、いろいろと条件を変え、命令をページクロスさせて前半と後半でキャッシュやページのヒットミスを変えることで、演算値が変わることがあり得ます。これはプロセッサがパイプライン動作していることから、バグによってはタイミングによって結果が変わることがありうるためです。

ということで、メインフレーム並みの信頼性を保証するなら、上記のようなテストを実施しなければなりません。


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

6809 IPの修正

posted by sakurai on September 27, 2019 #161

FM=7のハードウェアエミュレーションをFPGAで実行するプロジェクトを遂行していましたが、FM-7のROMイメージもZ80カードI/Fを用いることにより、すんなり抜き出すことができました。

それをVivadoに持ち込むにあたって、COEファイルという形式に変換し、OpenCoresからダウンロードした6809を動かしたのですが、動作しないようです。実機の動作と比較するために、実機にはロジックアナライザを接続しました。

前記事のArduino-Z80I/FカードにはFM-7の内部バスが現れているので、実はArduinoは動かさなくても、ロジックアナライザを接続すれば、メインCPUである6809の動作が把握できます。ロジックアナライザも昔は数百万円したかと思いますが、私の購入したものは17,000円くらいでした。これで32CH 200K 400MSa/sですから、アドレス、データ、主要制御信号を観測するのに十分です。

●Arduinoマイコンが870円(送料別) https://www.banggood.com/RobotDyn-Mega-2560-PRO-Embed-CH340G-ATmega2560-16AU-Development-Module-Board-With-Pin-Headers-For-Arduino-p-1397734.html

●ボード作成が5枚で4.9 USD https://www.fusionpcb.jp/

●コネクタは少々高くて743円(送料別) https://jp.rs-online.com/web/p/pcb-headers/6020498/

●ロジックアナライザは消耗品ではないので高いですが、それでも17,299円 https://www.banggood.com/Hantek-4032L-Logic-Analyzer-32Channels-USB-Oscilloscope-Handheld-2G-Memory-Depth-Osciloscopio-Portat-p-1376105.html

のように比較的気軽に試すことができます。

さて、このような環境でFPGAのシミュレーションを実行したら、おかしな点を見つけました。具体的にはJMP命令が動作しません。著者に連絡を取り、報告したところ、「It doesn't surprise me that a couple (or more) things do not work.」とのことで、自分でなんとかするしかなさそうです。FM-7システムの中で6809をデバッグするのは大変なので、新たに図のような単体テスト環境を作成しました。

図%%.1
図161.1 6809 IP単体試験回路図

6809 CPUに、リセット、クロック、ROMを接続しただけです。RAMはありません。このROMに以下のようなテストプログラムを置き、実行させたところ、

FF00         start  org   \$ff00
           
FF00 8EFF12         ldx   #lab1
           ;    jmp   0,x
FF03 6E00          fcb   \$6e,\$00
           
FF05 8EFF15     lab2  ldx   #lab3
FF08 6E01          jmp   1,x
               
FF0A 8EFF12     lab4  ldx   #lab1
FF0D 6E84          jmp   ,x
FF0F 7EFF0F         jmp *
               
FF12 7EFF05     lab1  jmp   lab2
FF15 12       lab3  nop
FF16 7EFF0A         jmp   lab4
           
FFFE             org   \$fffe
FFFE FF00          fdb   start
           ;
0000             end

最初の\$FF03番地のJMPを、JMPせずに実行してしまいます。JMP命令でもインデックスアドレシングのみ動作しないようです。ちなみに、JMP ,XとJMP 0,Xは動作は同じですが、オペコードは異なります(\$6E,\$00と\$6E,\$84)。が、動作が同じであるため、JMP ,Xと書いてもJMP 0,Xのオペコードがアセンブラから出力されるため、やむなく上記のようにFCBで記述しました。


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

6809の割込み動作(8)

posted by sakurai on August 23, 2019 #155

IRQ/FIRQが正常動作したので、メインCPUとサブCPUの協調動作を実行してみます。

  1. メインCPU
  • サブCPUのreadyを待つ
  • サブCPUをhaltする
  • 共有メモリにデータを書き込む
  • 共有メモリの先頭のMSB=0で指示とする
  • サブCPUのhaltを解除する
  1. サブCPU
  • リセット後サブCPUの状態はハード的にbusy
  • サブCPUの状態をreadyにする
  • 共有メモリの先頭のMSB==0となるのを待つ
  • サブCPUの状態をbusyにする
  • 共有メモリの内容をデコードする

図%%.1
図155.1 協調動作フローチャート

このフローに基づき、協調動作のシミュレーションを行ったところ、正しく動作しました。


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

6809の割込み動作(7)

posted by sakurai on August 22, 2019 #154

タイムチャートを見直すと、例外処理中でEフラグをクリアする処理は入っていますが、一方のセット信号が初期状態からずっと不定です。このため、Eフラグが不定となっているようです。従って、セット信号を初期状態でネゲートします。

図%%.1
図154.1 割込みタイムチャート

k_set_eの初期化をしたところ、正しく動作しました。このIPは総じて割込みの実装が中途半端にしかされておらず、割込みは実質テストしていないようです。プロセッサにおいて割込みが動作しないのは致命的であり、使い物になりません。


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

6809の割込み動作(6)

posted by sakurai on August 21, 2019 #153

次にFIRQを実装します。同様にFフラグセット、クリア論理を入れましたが、割込みハンドラまでは正しく動作するものの、RTI命令の実行時にスタックを過剰に回復しています。積んだ以上に回復するという、いわゆるスタックアンダーフローを起こしてしまいます。

図%%.1
図153.1 割込みタイムチャート

まず、FIRQの動作を見てみると図153.2のようになります。Eフラグをクリアしてからpushすると書かれていますが、クリアされずXとなっています。

図%%.2
図153.2 FIRQの動作

次に、RTIの動作を見てみると図153.2のようになります。Eフラグは0であるべきなので、スタックからはCCR及びPCのみが回復されるはずです。が、タイムチャートではさらに他のレジスタも回復しているようです。

図%%.3
図153.3 RTIの動作

この誤動作の原因は、CCR[7]のEフラグが不定となっていることです。従って、図153.2にあるとおり、例外処理中でEフラグをクリアする処理を入れれば動作するはずです。


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


ページ: