2024年の今、「FPGAボードで学ぶVerilog HDL」で遊ぶ (Xilinx Spartan-3E) (3) MicroBlaze MCS [電子工作・プログラミング]

前回で、本の内容に加えシリアル通信ができるようになり、初等的な内容をテストするには、だいぶお腹一杯という感じになってきました。
IPコアのリストを眺めていると、ISE 14.7では、ISE 8.2に比べ、Debug(ILA, VIO, ICON, ATC2)とEmbedded Processing(MicroBlaze MCS)が新たに選べるようになっていました。調べると、Xilinx社提供のソフトプロセッサMicroBlazeは、XilinxのFPGAであれば、無償で利用できるそうです。そこで、本書付属のFPGAボードで、MicroBlazeのテスト動作による学習をしてみたいと思います。

いくつか試したところ、本書同梱のボードに使用されているSpartan-3EのXC3S100Eはリソースが少ないので、フル機能のMicroBlazeはぎりぎり実装できますが、それで精一杯で、ほぼ何もできない感じでした。機能固定版のMicroBlaze MCSであれば、4割程度のリソースを残しつつ実装できたので、こちらの実装手順について、以下にメモします。

最初に、参考資料として、AMD社公式のプロダクトガイドを挙げておきます。
PG048 LogiCORE IP MicroBlaze Micro Controller System v1.4
PG052 LogiCORE IP I/O Module v1.03a
ポイントは、最新版ではなく、ISE 14.7版を参照することです。幸い、本日時点では問題なく参照できます。特にPG048のP34以降は、ISE 14.7のProject Navigatorでの操作をそのまま記載しています。以下のメモでも、基本的にこちらの手順に従います。
ちなみに、MicroBlaze MCS v3(Vivado用)のPG116であれば、日本語の資料もあります。

他には、下記2つのページをかなり参考にさせて頂きました。
ISE14.6でMicroBlazeを使う
MicroBlazeを使う

以下、手順のメモ

PlanAheadではなく、ISE 14.7のProject Navigatorで行いました。ISE起動後、新規プロジェクトの作成の後、Hierarchyウィンドウで右クリックし、New sourse...を選び、IPを選びます。選択画面から、Embedded Processing→Processor→MicroBlaze MCSを選びます。選択し生成すると、詳細設定のダイアログが開きます。
Instance Hierarchial Design Nameは適当に付けます。但し、後で作成するトップモジュールでは、間違いなくその名前でインスタンス化します。Input Clock Frequencyは、FPGAボードのクロックに合わせて33.333 MHzと入力します。Memory Sizeはケチって4KBとします。デフォルトではすべてのオプションのチェックボックスが外れているはずです。今回は、最小限の確認ということで、UARTのReceiver/Transmitterと、GPO1を1ビットだけONにしました。特に、MCSタブのEnable Debug SupportはOFFにしました。使えたらソフトウェアのデバッグに良いのですが、リソース不足のためか配置に成功しませんでした。ここまで設定したら、Generateでダイアログを閉じます。

Creatingと表示され、アイコンがぐるぐる回るので、しばし待つと、IPの生成が完了します。DesignビューのHierarchyでいま生成したIPを選択すると、ProcessesのCORE Generatorの中に、View HDL Instatntiation Templateがあります。ダブルクリックして表示すると、一番下のところにINSTANTIATION Templateがあるので、それをトップモジュールにペーストし、your_instance_nameを上で設定した名前に合わせます。他、適宜配線を行います。CLKはいつも通りボードのP63に、UART_RxはボードのP79に、UART_TxはボードのP83に、GPO1はLED1のP17に接続します。また、明確な記載が見つからなかったのですが、CPUのリセットはActive Highのようで、ボードのSW(P24)をそのままつなぐと、ちょうどボタン押下=リセットとなります。

トップモジュールと制約ファイルの記述ができたら、Synthesizeを実行します。成功したら、IPの詳細設定ダイアログのPlanAhead & Project Navigator Informationの記載に従い、microblaze_mcs_setup.tclスクリプトを実行します。View→Panels→Tcl ConsoleでTclコンソールを表示し、source ipcore_dir/microblaze_mcs_setup.tcl を入力し、Enterを押します。その後、ビットストリーム生成まで行います。

次いで、XSDKを起動しますが、仮想マシンでのエラー対策で、下記コマンドラインで起動します。
xsdk -vmargs -Dorg.eclipse.swt.internal.gtk.cairoGraphics="false"

先ほどProject Navigatorで表示されていた、IPの詳細設定ダイアログのMCSタブ中のSoftware Develeopment Informationの記載通りに進めます。適当な場所にworkspaceを作成し、Hardware Platform Specificationで、ハードウェアの設定のxmlファイルをインポートします。デフォルトの設定であれば、ISEのプロジェクトフォルダの直下のipcore_dirの中に、..._sdk.xmlがあるはずです。
xmlファイルを指定すると、BMMファイルは自動的に設定されますが、Implement中に生成された..._bd.bmmに選び直します。ついでに、先ほど生成したbitstreamも指定しておきます。Finishでダイアログを閉じます。
Welcome...のタブを閉じると、system.xmlの内容が表示されます。Software Develeopment Informationの記載にあった、Board Support Packageの作成は、省略しても、Application Project作成時に同時に作成されます。Application Project作成のダイアログでは、Project nameを適当につけます。Target Hardwareが、先ほど作成したPlatformとProcessorになっていることが確認できます。OS Platformはstandaloneに、LanguageはCとして進め、Hello Worldプロジェクトを選択してみます。

ソフトウェアのプロジェクトが作成されると、最初に自動でコンパイルが実行され、失敗します。最初のエラーメッセージを見ると、
section `.stack' will not fit in region `ilmb_cntlr_dlmb_cntlr'
と記載があります。スタックが大きいのかなと思い、減らしてみます。srcディレクトリの中にあるリンカスクリプトlscript.ldをダブルクリックで開き、Stack SizeとHeap Sizeがそれぞれ0x400(1024 bytes)となっているところを0x200に減らします。lscript.ldの変更を保存すると、再度コンパイルが行われ、今度は成功します。Console中のmb-Sizeの出力を見ると、dec 3598 bytesとなっていて、4KBに収まっていることが分かります。逆に、先ほどはbssがさらに1024 bytes大きかったはずなので、確かに4KBに収まっていなかったことが分かります。

デフォルトで記述されているプログラムは、標準出力にHello Worldと出力するプログラムです。標準入出力は、SDK側でUARTの送受信に結びつけられています。stdio.hがインクルードされているので、C言語の標準ライブラリのルーチンが使えると思われますが、あっという間にプログラムのサイズが4KBを超えてしまうので、ここは直接レジスタの値を操作して、簡単なシリアルの読み書きを行ってみます。

I/O Moduleのドキュメントから、アドレス0x80000008の1ビット目がシリアル受信完了、アドレス0x80000000の下8ビットがシリアル受信したデータ(UART_RX)、アドレス0x80000004の下8ビットがシリアル送信するデータ(UART_TX)と分かります。UART_RXは、読み込むだけでシリアル受信完了フラグが解除されるようです。そこで、シリアル受信完了をポーリングし、受信できていたらUART_RXをそのままUART_TXにエコーバックするプログラムを作成してみます。合間に、適当にGPO1(0x80000010)の1ビット目をON/OFFします。あと、レジスタは一応32ビット幅なので、上記のレジスタはvolatile int*として扱って、読み書きをします。作成したプログラムのコードを下記に示します。


保存するとmb-gccが走り、ELFファイルが生成されます。これでソフトウェアの用意ができました。

FPGAボードへの書き込み時は、Xilinx Tools→Configure JTAG SettingsでXilinx Parallel III Cableを明示的に選びます。PortにLPT1とありますが、そのまま変更無しでOKでした。(自動で/dev/parport0に置き換えられる?) JTAG Device Chainは自動認識のままでOKです。その後、Xilinx Tool→Program FPGAを選択するとダイアログが開き、書き込むファイルを選択します。bitstreamとbmmファイルは、先ほど選択したファイルがsystem...とリネームされて入っているので、そのままにします。
Software Configurationは、生成したelfファイルを選択します。デバッガが使えないので、bootloopを書き込み→後でソフトウェアをデバッグ実行、という手順は使えません。
Programボタンを押すと、elfcheckやdata2memが走り、downlaod.bitを作成した後、コンフィグレーションが実行されます。BMMファイルの選択が間違っていると、ここでエラーが発生します。無事にできていれば、プログレスバーが最大になったところで、回路とソフトウェアが動作するはずです。

各種設定を適切に合わせたターミナルソフトを開いておくと、回路が動作開始したときにHello Worldと文字が表示され、以降、ターミナルに何か入力すると、それがエコーバックされるはずです。同時に、人間が感知できる速さでLED1が点滅し、リセットボタンに割り当てたSW4を押すと、押している間は動作が停止し、離した瞬間に再度Hello Worldが表示されるはずです。

これで、「FPGAボードで学ぶVerilog HDL」の付属FPGAボードで、ソフトプロセッサMicroBlaze MCSの動作が確認できました。ただ、色々やろうとすると、やはりリソースが足りない気はします。そろそろこのボードは卒業して、新しいFPGAボードで遊ぶのが良いのかもしれません。

5月5日15時12分
fartrip
コメント(0) 

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。