Vitis/Vivado 2020.1でMicroBlazeを使う

Pocket

Vitis/Vivado 2019.2ではVivado SDKがなくなり、ソフトウェア開発はVitisに統合されました。MicroBlazeを使う場合もVivadoでハードウェアモジュールを組み立ててVitisでソフトウェアの開発をします。

この記事は、Vivado 2020.1でArtyを対象にMicroBlazeを使った開発をする手順のメモです。

Vivadoでハードウェアモジュールを作る

Vivadoでのおおまかな開発の流れは次のとおりです。

  • IP IntegratorでMicroBlazeデザインを用意
  • generate bitstreamでbitファイルを作成
  • 「export Hardware」→「Fixed」→include bitstreamで、.xsaファイルを作る

IP IntegratorでMicroBlazeデザインを用意する

プロジェクトを作成して、Create Block DesignをクリックしてIP Integratorを起動します。とりあえず主役(?)のMicroBlazeを置きます。

Run Block AutomationをクリックしてMicroBlazeの設定をします。ここでは、Local Memoryを32KBに設定。

Run Block Automationが終わるとクロック(clk_wiz_1)やリセット(rst_clk_wiz_1_100M)などのモジュールが追加されます。ついでに、UART(axi_uartlite_0)とGPIO(axi_gpio_0)のインスタンスも追加しました。UARTのボーレートを変更したけれればaxi_uartlite_0をダブルクリックしてダイアログを開いて設定.デフォルトは9600ボーだった.

clk_wiz_1を設定。入力クロックをSingle ended clock capable pinにリセットの極性をActive Lowにセット。

設定したら Run Connection Automationでクロックの入力信号を外に引き出す

リセットモジュールのext_reset_inも外に出力。

GPIOはLED出力とスイッチ入力に割り当てる

設定したら Run Connection Automationで、全部接続。

最終的には、こんな感じに。

メモリマップはこんな感じ

bitファイルを生成

IPIで作ったブロックのラッパーモジュールを作って合成。ラッパーモジュールはいつものようにCreate HDL Wrapperで生成。

ハードウェアのエクスポート

Vitisでのソフトウェア開発用にハードウェア情報をパックします。まずは、File → Export → Export Hardware…でウィザードを開きます。

ウィザードで、Fixedを選択してNext

Include bitstreamを選択してNext

エクスポート先は適当に決めます。ここではプロジェクト直下が指定されています。エクスポートされるファイルの拡張子は .xsa です。Next→Finishでエクスポート完了。

Vitisでソフトウェア開発

おおまかな流れは次の通り。

  • Vivado プロジェクトの下に作業ディレクトリを作成
  • プロジェクトの作成とXSAの読み込み
  • とりあえずのHello World

作業ディレクトリの作成

作業ディレクトリはVitis起動時に用意します。ここでは、Vivadoプロジェクトの下にvitisという名前のディレクトリを作成してみました。

Eclipseのウェルカムウィンドウが表示されます。

Create Application Projectをクリックして、プロジェクト作成ウィザードを開きます。

プロジェクトの作成とXSAの読み込み

ウィザードを使ってソフトウェア開発用のプロジェクトを作成します。

Create a new platform from hardware (XSA) タブを選択して、Vivadoで作ったxsaファイルを指定します。

アプリケーションプロジェクト名は hello_world とつけてみました。

XSA(ハードウェア)とアプリケーションソフトウェアの間に位置するドメインの設定です。今回はMicroBlazeが一つですしOSものせないので、そのまま次にすすめます。

アプリケーションの雛形を選ぶことができるので、Hello Worldを選択して Finish をクリックします。

Hello World

プロジェクト作成ウィザードを閉じると作成したアプリケーション開発用のウィンドウが開きます。ツールバーの、ハンマーアイコンでプロジェクトをビルドします。

ソフトウェアのビルドが終わったら実行前に、FPGAをコンフィギュレーションします。メニューのXilinx→Program FPGAをクリックします。

FPGAのコンフィギュレーションダイアログです。xsaにビットストリームを含んでいれば、そのビットストリームが選ばれています。もちろん、別途ビットストリームファイルを選択しても構いません。

FPGAをコンフィギュレーションしたらソフトウェアの実行です。 hello_worldの下のBinariesの下にあるhello_world.elfを選択して、ツールバーの虫アイコン右の矢印をクリック、Launch on Hardware (Single Application Debug)をクリックします。

デフォルトでinit_platform()のところにブレークポイントがセットされていて一旦停止するので、ツールバーの再生ボタン(Resume)をクリックして、プログラムを実行します。

UARTが接続されたターミナル /dev/ttyUSB1 とかを開いておくと、無事にHello Worldが表示されることが確認できます。

GPIO経由でLEDを点灯させることもできます。たとえば、ソースコードはこんな感じ。

int main()
{
    init_platform();

    print("Hello World\n\r");
    print("Successfully ran Hello World application");

    volatile unsigned int * led = (volatile unsigned int*)0x40000000;
    int i = 0;
    for(int i = 0; i < 256; i++){
    	*led = i;
    	xil_printf("%d\n\r", i);
    	usleep(500000);
    }

    cleanup_platform();
    return 0;
}

実行すると、500m秒ごとにカウント値が表示されてLEDも点滅します。