- ZYBOでシンセサイザー作成(1)LチカとHelloWorld
- ZYBOでシンセサイザー作成(2)オーディオコーデックの使用
- ZYBOでシンセサイザー作成(3)波形テーブル(BRAM)による正弦波の合成
- ZYBOでシンセサイザー作成(4)パラシリ変換 IP の作成
- ZYBOでシンセサイザー作成(5)音を出力する
ZYBOを使ってシンセサイザーを作成したいと思います。久しぶりにVivadoを使うので、まずはLチカとHello Worldからやってみます。主に今回の記事は以下の参考文献をもとに書きました。
環境
- パソコン:Windows10 64 bit
- Vivado 2020.2 をインストール
- Xilinx Vitis 2020.2 をインストール
- ボード:ZYBO Z7-20
Board ファイルのインストール
初期状態ではDigilentのボードであるZYBO-z7-20のボードファイルがないため、ボードファイルをインストールします。DigilentのボードファイルのダウンロードはInstalling Digilent Board Filesの「archive」をクリックすることでダウンロードすることができます。そのzipファイルを解凍して、そのフォルダの中の
「vivado-boards-master\new\board_files\zybo-z7-20」
のフォルダを
「C:\Xilinx\Vivado\<version>\data\boards\board_files」
の下に貼り付けすることでインストールできます。
プロジェクトの作成
まず、「Create New Project」をクリックして、プロジェクトを新規に作成します。
「Create a New Vivado Project」はプロジェクトを作成するためにやることが書いてあるだけなので、そのまま「Next」をクリックします。
「Project Name」では、プロジェクトの名前とプロジェクトの格納フォルダを指定します。私の場合は、
- プロジェクト名:zybo_synthesizer
- プロジェクトの格納フォルダ:D:/v20
として、「Create project subdirectory」にチェックしました。「Create project subdirectiory」にチェックONすることで、プロジェクトの格納フォルダの下にプロジェクト名のフォルダが作成され、その下にプロジェクトファイルが作成されます。
「Project type」では、作成するプロジェクトのタイプを指定します。ここでは「RTL Project」を選択します。「Do not specify sources at this time」にもチェックONしておきます。チェックONしておくと、verilogファイルなどのソースファイルを追加する画面を省略します。あとで追加することもできるので基本的にチェックONしておきます。
「Default Part」では、使用するFPGAデバイスを選択します。ボードファイルのインストールをしていれば、「Boards」を選択することで、「Display Name」の中に「Zybo Z7-20」があると思います。「Zybo Z7-20」を選択して、「Next」をクリックします。
「New Project Summary」では、プロジェクトの設定内容を確認して、問題なければ「Finish」をクリックします。
回路の作成
Verilogファイルは書かないで、VivadoのIPインテグレータだけを使って、回路の作成をします。
IP インテグレータによる回路作成
IP インテグレータの起動
Flow Navigator から 「IP INTEGRATOR」の「Create Block Design」 をクリックします。 小さいウィンドウが出て、「Design Name」 や 「Directory」を変えることができますが、デフォルトのままでいいです。これで「Diagram」のタブができます。「Diagram」で GUI 的に回路作成ができます。
IP の配置
Diagramで「ADD IP」をクリックすると、IP(機能ごとにまとまった回路)のリストが表示されますので、「ZYNQ7_Processing_System」をダブルクリックして配置します。また、同じようにして「AXI GPIO」も配置します。
IP の接続
IPを配置したら、「Run Block Automation」をクリックします。Zynq の設定が表示されますので、「Apply Board Preset」にチェックがあることを確認して、「OK」をクリックします。「Apply Board Preset」にチェックONすることで、ボード上にあるDDRメモリなどにしたがって Zynq の設定をしてくれます。
「AXI GPIO」をダブルクリックして、「AXI GPIO」の設定をします。「IP Configuration」タブで「All Outputs」にチェックをして、「GPIO Width」を 4 と設定します。「OK」をクリックして設定を終了します。
「Run Connection Automation」をクリックして、Zynq と「AXI GPIO」を自動接続をします。接続の設定では、「GPIO」はチェックOFFし、「S-AXI」にはチェックONして、「OK」をクリックします。
「Run Connection Automation」を実行すると、「Processor System Reset」(リセット信号を生成する回路)と「AXI Interconnect」(AXI のハブ的な回路)が自動生成されて、IP間が接続されます。
つづいて、「AXI GPIO」の「GPIO」端子の「+」部分をクリックすると、端子が展開されて「gpio_io_o[3:0]」が表示されます。これを右クリックして、メニューから「Make External」を実行することで、「AXI GPIO」の出力とFPGAの出力ポートを接続します。
これで回路ができました。
制約ファイル(*.xdc)の読み込みと修正
制約ファイル(*.xdc)のダウンロード
FPGA端子の設定をする制約ファイルをダウンロードします。ZYBO Z7用の xdc ファイルは、Digilentページの「Documentaion」→「Master XDC Files」をクリックすると、Digilentの各ボードの制約ファイルがあるGItHubにとぶので、そこからZybo-Z7-Master.xdcをダウンロードします(私は一つのファイルだけダウンロードすることはできなかったので、他のボードの制約ファイルと一緒にダウンロードしました)。
制約ファイル(*.xdc)の読み込み
制約ファイルをプロジェクトに読み込むには、「Project MANAGER」の「Add Sources」をクリックし、「Add or create constraints」を選択します。続いて、さきほどダウンロードしたZybo-Z7-Master.xdcをプロジェクトファイル(*.xpr)と同じ階層にコピーして、それを読み込みます。「Copy constraints files into project」はチェックOFFにしておきます。チェックONにすることで、プロジェクトフォルダのどこかに制約ファイルがコピーされて置かれますが、深い階層に置かれてしまって、制約ファイルの修正や確認がしづらくなるので、私はこのようにしています。「Finish」で制約ファイルが読み込まれます。
制約ファイルの修正
次に、制約ファイルの修正をします。今回はLEDを使いたいので、LED設定箇所の27行目から30行目のコメントを以下のように外します。
##LEDs set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L23P_T3_35 Sch=led[0] set_property -dict { PACKAGE_PIN M15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L23N_T3_35 Sch=led[1] set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_0_35 Sch=led[2] set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L3N_T0_DQS_AD1N_35 Sch=led[3]
ポート名の変更
制約ファイル上でポート名が「led」になっているので、IPインテグレータでもポート名を「led」にします。「gpio_io_o_0」を選択して、「External Port Properties」ペインで「Name」を「led」に変更します。
上位階層とビットストリームの作成
ダイアグラムのチェック
ダイアグラムが完成したら、右クリックのメニューから「Validate Design」を実行して、整合性のチェックをします。回路に問題がなければ、「Validation successful.」を表示します。
もしかしたら、以下のようなクリティカルワーニングが発生するかもしれませんが、Digilentのボードファイルによる問題なので無視しても大丈夫です。
CRITICAL WARNING: [PSU-1] Parameter : PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 has negative value -0.050 . PS DDR interfaces might fail when entering negative DQS skew values. CRITICAL WARNING: [PSU-2] Parameter : PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 has negative value -0.044 . PS DDR interfaces might fail when entering negative DQS skew values. CRITICAL WARNING: [PSU-3] Parameter : PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 has negative value -0.035 . PS DDR interfaces might fail when entering negative DQS skew values. CRITICAL WARNING: [PSU-4] Parameter : PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 has negative value -0.100 . PS DDR interfaces might fail when entering negative DQS skew values.
上位階層の作成
Sourcesペインにおいて、ダイアグラムで作成した階層「design_1」を選択し、右クリックから「Create HDL Wrapper...」を実行します。「Create HDL Wrapper...」によって、ダイアグラムで作った回路を使用するVerilogファイルが作成されます。「Options」では、「Copy generated wrapper to allow user edits 」を選択します。「Let Vivado manage wrapper and auto-update」を選択すると、自動的にラッパーが更新されるそうですが、経験的にポートが追加されないことがあったので、「Copy generated wrapper to allow user edits 」を選択します。
ビットストリームの作成
「PROGRAM AND DEBUG」の「Generate Bitstream」をクリックして、ビットストリームを作成します。論理合成と配置・配線をしていないので、「No Implementation Results Available」のダイアログが出ますが、「Yes」をクリックします。「Launch Runs」では、そのまま「OK」をクリックします。Number of jobsで使用するスレッドの数を指定できますが、デフォルトのままでいいと思います。
正常終了すると、右上のステータスが「write bitstream Complete」となり、次の処理を確認するダイアログが表示されます。「Open Implemented Design」を選択すると、回路規模などを確認することができます。普段、私は「Open Implemented Design」で回路規模を確認することが多いです。回路規模に興味がない人は「Cancel」をクリックで大丈夫です。
Zynq のプログラムを実行
Vitisを使って、Zynqのプログラムを実行していきます。
回路情報のコピーとVitis の起動
Vitisを起動する前にVivadoからVitisに対して回路情報を渡す必要があります。そのため、Vivadoでその作業をしてから、Vitis を起動します。
回路情報のコピー
メニューバーから「File」→「Export」→「Export Hardware...」を実行します。最初の画面では、「Next」をクリックします。
「Output」では「Include bitstream」を選択します。これで、Vitisに回路情報を渡すことができます。
「Files」では以下のように設定しました。
- 名称:design_1_wrapper(デフォルト設定)
- 保存先:D:/v20/zybo_synthesizer/zybo_synthesizer.vitis
最後に「Finish」をクリックしてエクスポートします。
Vitisの起動
メニューバーから「Tools」→「Launch Vitis IDE」でVitisを起動します。
ワークスペースの場所は先ほど作成したzybo_synthesizer.vitisフォルダを指定し、「Launch」をクリックします。
各種プロジェクトの作成
Vitisでは「プラットフォームプロジェクト」と「アプリケーションプロジェクト」の作成をする必要がありますので、これらのプロジェクトを作成していきます。
プラットフォームプロジェクトの作成
起動画面から「Create Platform Project」をクリックします。
最初の画面では、プロジェクト名を入力します。プロジェクト名は「zybo_synthesizer_platform」としました。
つぎは「Create a new platform from hardware (XSA)」タブで、Vivadoで作成したプラットフォームファイル(*.xsa)を指定します。「Finish」でプロジェクトが作成されます。
アプリケーションプロジェクトの作成
メニューバーから「File」→「New」→「Application Project...」を実行します。
最初の画面では、そのまま「Next」をクリックします。
次の画面では、プラットフォームの選択をします。デフォルトでさきほど作成したプラットフォームが設定されていますので、確認してそのまま「Next」をクリックします。
つづいて、アプリケーションプロジェクト名を入力する画面になります。アプリケーションプロジェクト名は「helloworld」としました。
ドメインの選択では、そのまま「Next」をクリックします。
テンプレートを選択する画面では、「Empty Application」を選択して、「Finish」をクリックします。
プログラムの作成と実行
プログラムをC言語で作成して、シリアルターミナルなどを設定して、プログラムを実行します。
Cファイルの作成
アプリケーションプロジェクト内の「src」フォルダを右クリックして、「New」→「File」をクリックします。ファイル名を入力する画面では、ファイル名を「helloworld.c」として、「Finish」をクリックします。
プログラムの記述
プログラムはAPIを用いて記述します。「helloworld.c」に以下のプログラムを記述します。一応、プログラムが記述された「helloworld.c」はGitHubの「1st」フォルダに置いてあります(2021/5/12 追記)。
#include "xparameters.h" // 各IPのパラメータがあるファイル #include "xgpio.h" // AXI GPIO用のAPIがあるファイル #include "xil_printf.h" // xil_printfを使うためのファイル int main(void){ int status; XGpio Gpio; // Hello World をシリアル転送 xil_printf("Hello World. \n"); /* GPIO の初期化 */ // Gpio変数の初期設定 status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID); if(status != XST_SUCCESS) return XST_FAILURE; // 入出力の設定 // 2番目の引数:設定するインターフェース 1:GPIO 2:GPIO2 // 3番目の引数:各ポートの入出力の設定 0:出力 1:入力 XGpio_SetDataDirection(&Gpio, 1, 0x0); // 全て出力に設定 // 信号レベルの設定 // 2番目の引数:設定するインターフェース 1:GPIO 2:GPIO2 // 3番目の引数:各ポートの出力レベルの設定 0:Low 1:High XGpio_DiscreteWrite(&Gpio, 1, 0xF); // 全てHighに設定 }
ビルド
アプリケーションプロジェクトの「helloworld」を選択して、メニューバーから「Project」→「Build Project」を実行して、プロジェクトのビルドを行います。
PCとボードの接続
ZYBOのボード上のジャンパーピンを以下のように設定します。
こうすることで以下のように設定されます。
- 電源供給方法:USBから供給
- 回路情報やプログラムの実行方法:USB経由でPCから実施
この状態でPCとZYBOをMicro-USBで接続すると、赤色のLEDが点灯します。
デバッグの設定
デバッグ設定は、アプリケーションプロジェクト「helloworld」を選択して、虫マークのプルダウンメニューから「Debug As」→「Lunch on Hardware (Single Application Debug)」で実行する。
実行すると、FPGAに回路情報を渡して、デバッグ時の操作画面に変更されます。
シリアルターミナルの設定
シリアルターミナルの設定は、「Vitis Serial Terminal」タブの「+」をクリックし、COMポートと通信速度を設定して「OK」をクリックします。基本的には通信速度はデフォルトで、ポートは選択可能なものを選べばいいと思います。
プログラムの実行
プログラムの実行は「Resume」ボタンをクリックすることで行われます。
実行すると、シリアルターミナルには「Hello World」と表示されます。
また、4つのLEDが以下のように点灯します。
おわりに
ZYBOでLチカとHello Worldをしました。まだ、Vitisに慣れないので、慣れていきたいと思います。