LoginSignup
50
31

More than 5 years have passed since last update.

ZYBO (Zynq) 初心者ガイド (2) Hello Worldプロジェクト

Last updated at Posted at 2018-01-06

この記事の内容を4分で見る( https://www.youtube.com/watch?v=VJCL2Z81DLQ )

環境

  • 開発用PC: Windows 10 64-bit
    • Vivado 2017.4 WebPACKライセンス
    • Xilinx SDK 2017.4
  • ターゲットボード: ZYBO (Z7-20)

Windows環境は1回目を参照。

Hello Worldプロジェクト

PS部のUARTとCPU上のソフトウェアでHello Worldを出力します。メインはPS部ですが、まずはVivadoでハードウェアを作ります。その後、SDKでHello Worldソフトを書きます。

プロジェクトの作成 (Vivado)

まず、Vivadoでハードウェアを作ります。Vivado 2017.4を起動します。そして、File -> New Project。プロジェクトの保存先とプロジェクト名を設定します。ここではプロジェクト名は"project_1"にします。プロジェクトタイプは "RTL Project"にします。"Add Sources"と"Add Constraints"では何もせずNext。"Default Part"の所で、まず"Boards"を選びます。そして、Vendorにdigilentinc.comを選びます。Display NameにZybo Z7-20を選びます。これらは、前回の環境設定の所でボードファイルを追加したため選択可能となっています。Nextをクリック、Finishをクリックしてプロジェクト作成完了です。使用しているボードが違う場合には、適宜置き換えてください。

01.jpg
02.jpg
03.jpg

無事プロジェクトが作成されると、以下のような画面になります。

04.jpg

PSだけのハードウェアを作る (Vivado)

PSだけのブロックデザインを作る

上のVivado画面を見ると、Top module nameがNot definedとなっています。つまり、今は空っぽの状態です。これに、PS部だけのモジュールを作り搭載します。PS部とはCPU(ARM Cortex-9 x 2) と、UART等のペリフェラルIFを持つユニットです。
左側のFlow Navigator -> IP INTEGRATOR -> Create Block Designで、新しいブロックデザインを作ります。名前はデフォルトのままdesign_1とします。

05.jpg

Diagramビューの"Press the + button to add IP"をクリックして、"ZYNQ7 Processing System"を選択します。すると、PS部が配置されます。そして、画面上の"Run Block Automation"をクリックします。設定Window画面が出ますが、「Apply Board Preset」にチェックがついていることを確認してOKしてください。これによって、プロジェクト作成時に指定したボード(ZYBO)に適したPSが作られて、配置されます。

06.jpg
07.jpg

PS部のプロパティ変更もできます。"Block Properties"の所から変更が出来ます。又は、DiagramビューでPSをダブルクリックすることでも、PSをカスタマイズできます。今回は、何も変更しません。このPSは既にZYBOボードに適した設定になっているためです。例えば、ターミナル出力に使うUART1用のIOは複数の候補から選択することが出来ますが、実際にボード上で接続されているのは、MIO48とMIO49です。今作ったPSもUART1はMIO48とMIO49を使うように設定されています。

設定は変更しませんが、どのようなことが出来るか見てみます。
PS部のオーバービューを見たり
08.jpg

各種コンフィギュレーションをしたり (例えば、UARTのボーレート変更)
09.jpg

ペリフェラル用のIOとして、どのピンを使うかの設定をしたり (MIO(Multiplexed IO)というピンから選ぶ。マイコンによくある、どの機能にするかを選ぶMUXみたいな感じ)
10.jpg

作成したブロックデザインをチェックする

PSを配置しただけですが、とにかくブロックデザインを作ってみました。これが問題ないかどうかをチェックします。Diagramビュー上で右クリック -> Validate Designを選ぶことで、チェックできます。すると、こんなシンプルなデザインなのに、なんとエラーが出ていました。M_AXI_GP0_ACLKにクロックが正しく供給されていないのが原因のようです。

10_1.jpg

ブロックデザインを修正する

AXIはIP間を接続するときに使うバスです。PSがマスターとなって、他のスレーブIP(例えば、AXI GPIO)と接続するときに使います。M_AXI_GP0_ACLKはその基になるクロックです。そのため、今回は使わないので、AXI_GP0のマスター機能そのものをOFFにすることでも修正可能です。しかし、どうせそのうち使うので、今回はちゃんとクロックを供給設定してあげることで修正します。ちょうど、PSからFCLK_CLK0というポートが出ています。この設定を見ると、50MHzの出力のようです。周波数などは変更可能ですが、今回はデフォルトのまま使います。

10_2.jpg

このFCLK_CLK0とM_AXI_GP0_ACLKを接続してあげます。Diagramビュー上でPSのピンの近くにマウスカーソルを持っていくと鉛筆アイコンになるので、そのままドラッグして接続するだけです。

10_3.jpg

この状態で再度Validate Designすると、エラーが消えています。

ハードウェアを完成させる

以上で、PS部だけを持つブロックデザインが完成。Hello Worldのためには、CPUとUARTだけあればいいので、今回はこれで十分です。このブロックデザインを、最上位デザインとして使います。まず、出力ファイルを生成してソースファイルを作成します。次に、HDLラッパーを作成して全体のデザインフローで使えるようにします。

具体的には、"BLOCK DESIGN" -> "Sources"タブ上で、今回のデザイン("design_1")で右クリック

  1. Generate Output Products -> Generate
  2. Create HDL Wrapper -> OK

11.jpg

1のGenerate Output Productsによって、verilogソースコードが生成されます。2のCreate HDL Wrapperによって最上位HDLファイルが生成されます。これに依って、最上位がdesign_1_wrapper.vとなり、その下にdesign_1.vが来ます。以下のように、Sourcesタブ内で上下関係やソースの中身を確認することが出来ます。

12.jpg

また、ProjectSummaryを見ると、自動的にTop module nameが、今生成したdesign_1_wrapperになっていることが分かります。

13.jpg

ハードウェアをエクスポートする

ハードウェアが完成したので、これをエクスポートします。ビットストリーム(*.bit)というファイルが出力結果になります。左側のFlow Navigator -> PROGRAM AND DEBUG -> Generate Bitstreamをクリックします。これによって、論理合成&配置配線が行われてビットストリームファイルが生成されます。生成には少し時間がかかります。完了後、ポップアップウィンドウが出ます。生成結果のレポート等を見たければ、ここで選んでください。特に不要ならCancel。成果物はproject_1\project_1.runs\impl_1\design_1_wrapper.bitに保存されます。

14.jpg

生成したビットストリームを、ソフトウェア(Xilinx SDK)で使いやすいようにエクスポートします。メニューバー -> File -> Export -> Export Hardware。Include bitstreamにチェックをつけて、OK

15.jpg

その結果、project_1\project_1.sdkというフォルダと、その下にdesign_1_wrapper.hdfファイルが生成されます。これがハードウェア側の成果物であり、次にやるソフトウェア実装へのインプットになります。project_1\project_1.sdkフォルダがそのままXilinx SDK (EclipseベースのIDE)のワークスペースになります。design_1_wrapper.hdfにはメモリマップ情報などとビットストリームファイルが含まれています。

ソフトウェアを実装する (Xilinx SDK)

Xilinx SDKの起動

Vivado上のメニューバー -> File -> Launch SDK -> OKで、今までVivadoで作成したハードウェア用のソフトウェア開発環境が立ち上がります。具体的には、自動的にXilinx SDKが立ち上がり、hw_platformフォルダが作られる。hw_platformフォルダにビットストリームファイルのコピー、PSに必要なクロック設定等を行うCソースコード生成が行われます。hw_platformフォルダが、対象となるハードウェア(先ほど作成したハードウェア)の情報をまとめたフォルダになります。

プロジェクト作成

SDK上のメニューバー -> New -> Application Project で、新しいソフトウェアプロジェクトを作ります。ここから先は、通常のマイコン用ソフト開発と同じです。以下の設定でプロジェクトを作ります。

  • プロジェクト名: HelloWorld
  • OS: なし
  • ハードウェア: 先ほどVivadoで作ったハードウェア (design_1_wrapper_hw_platform_0)
  • 動作CPU: CPU0
  • 言語: C言語

16.jpg

HelloWorldというフォルダと、HelloWorld_bspというフォルダが作られます。HelloWorldがこれからメインで実装していくところになります。HelloWorld_bspが、今回使用するハードウェア(ボード)用のライブラリ群になります。UARTを使用したprint関数等が含まれています。

17.jpg

ソースコード

Hello WorldをUARTから出力するコードを書きます。が、実は、自動生成されたソースコード上で既に以下のように実装されています。なので、そのままでOKです。

helloworld.c
int main()
{
    init_platform();

    print("Hello World\n\r");

    cleanup_platform();
    return 0;
}

実行する

ボードの準備

ZYBOのボード上でJP5のジャンパ接続を変えてJTAGの所をショートさせます(デフォルトはQSPI)。これによって、今回作成したハードウェアをJTAG(USB)経由で書き込めます。ボード上のマイクロUSB端子(J12)にUSBケーブルを刺して、PCと接続します。電源ONします。

PC側で、適当なターミナルソフト(例えばTera Term)を起動して、USB Serial Portに接続します。ボーレートは115200にします。

18.jpg

ハードウェア情報を書き込む

まず最初に、ハードウェア情報(ビットストリームファイル)を書き込みます。メニューバー -> Xilinx -> Program FPGAで、以下のウィンドウが表示されるので、Program。これによって、ZYBOは先ほどVivadoで作成したとおりのハードウェア構成になりました。これは、電源をOFFにするまで保たれます。電源をOFF/ONしたりリセットしたら、再度書き込みが必要になります。

19.jpg

プログラムを実行する

ここまで来たら、通常のマイコンと同じです。Project Explorer上でHelloWorldプロジェクトを選択しておきます。

  • 実行: メニューバー -> Run As -> Launch on Hardware (System Debugger)、または再生ボタン
  • デバッグ: メニューバー -> Debug As -> Launch on Hardware (System Debugger)、または虫ボタン

実行すると、ターミナル上にHello Worldと表示されれば成功です。

ハードウェアの変更を反映する

Xilinx SDK上で既にプロジェクトを作成して、ソフト開発を進めている最中に、ハードウェア側(hdfファイル)を変更したとします。その変更をSDKにも反映する必要があります。試しに、UARTのボーレートを115200から9600に変えてみます。

ハードウェアを変更してみる

再びVivadoに戻って、design_1のブロックデザインを開きます。DiagramビューでPSをダブルクリックして、プロパティ画面を開きます。以下のように、UART1のボーレートを9600に変更してみます。

30.jpg

その後、Generate Output Products、Create HDL Wrapper、Generate Bitstream、Export Hardware(include bitstream)します。

SDKに戻る

すると、SDK側の画面に以下のようなウィンドウが表示されて、自動で更新してくれます。

31.jpg

おまけ: 自分でSDKプロジェクトを作る (Xilinx SDK)

ハードウェア屋さんの成果物

趣味でやる場合には自分でハードもソフトもやると思います。その場合には、Vivadoから自分で直接SDKを起動できます。しかし、業務だったりチーム開発の場合にはどうでしょうか。Vivado全体のプロジェクトファイルをソフト/ハード同じところでソース管理していたり、同じパソコンで交互に開発している場合には、問題ないと思いますが、現実的ではないと思います。(もしかしたら、ソース管理共通化はできるかもしれないが、実際の開発現場だとどうしてるんだろう??) 個人的には、ハードウェア屋さんの成果物であるhdfファイルを界面にやり取りするのがいいのかなと思います。

この場合、ソフト屋さんは自分でSDKのプロジェクトを作る必要があります。以後、design_1_wrapper.hdfをインプットとして話を進めます。このファイルはハード屋さんがVivadoで作った成果物です。

hw_platformを作る

Xilinx SDKをスタートメニューから単独で起動する。ワークスペースを適当に設定する。SDK上のメニューバー -> File -> New -> Board Support Packageで、以下のようにhdfファイルを指定する。プロジェクト名は自動的に決まるのでそのまま。これによって、hw_platformフォルダが作られます。これは、先ほどVivadoからLaunch SDKした場合の自動生成と同じになります。

20.jpg

引き続き、BSPの設定をするウィンドウが現れます。BSPはここで作ってもいいのですが、先ほどやったように、Application Projectを作るときにも自動生成できるので、ここではCancelしておきます。ここまで来たら、先ほどのVivadoからLaunch SDKした場合と同じです。好きなようにApplication Projectを作成して実装してください。

ハードウェアの変更を反映する

先ほどと同様に、SDK側でソフト開発中に、ハードウェア(hdf)が更新されたら、その反映をする必要があります。新しいhdfをdesign_1_wrapper_new.hdfとします。

Xilinx SDK内で、Project Explorer上で既に作成済みのhw_platformプロジェクトを右クリックして、"Change Hardware Platform Specification"を選びます。design_1_wrapper_new.hdfを選択します。すると、hw_platformとbspプロジェクトも更新されます。

32.jpg

おまけ2

Xilinx SDKを起動したらまず、Project -> Build Automaticallyのチェックを外しておくと良いと思います。

おまけ3

今回、Vivado上でハードウェアを作成しました。しかし、配置したのはPSだけで、PLに相当する部品は何も配置していません。そのため、実はビットストリームは書き込まないでも動きます。ただしその場合、実行/Debug開始するときに、FPGA書き込みが完了してない(DONE pin is not high)と注意されます。無視してOKです。ちなみに、PSに関する設定はビットストリームファイルではなく、hdfに保存されているようです。

参考資料

https://www.xilinx.com/support/documentation/sw_manuals_j/xilinx2013_4/ug898-vivado-embedded-design.pdf
https://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2015_2/ug1165-zynq-embedded-design-tutorial.pdf

50
31
20

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
31