ZYBOでシンセサイザー作成(1)LチカとHelloWorld

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」をクリックして、プロジェクトを新規に作成します。

プロジェクトの作成画面1

「Create a New Vivado Project」はプロジェクトを作成するためにやることが書いてあるだけなので、そのまま「Next」をクリックします。

プロジェクトの作成画面2

「Project Name」では、プロジェクトの名前とプロジェクトの格納フォルダを指定します。私の場合は、

  • プロジェクト名:zybo_synthesizer
  • プロジェクトの格納フォルダ:D:/v20

として、「Create project subdirectory」にチェックしました。「Create project subdirectiory」にチェックONすることで、プロジェクトの格納フォルダの下にプロジェクト名のフォルダが作成され、その下にプロジェクトファイルが作成されます。

プロジェクトの作成画面3

「Project type」では、作成するプロジェクトのタイプを指定します。ここでは「RTL Project」を選択します。「Do not specify sources at this time」にもチェックONしておきます。チェックONしておくと、verilogファイルなどのソースファイルを追加する画面を省略します。あとで追加することもできるので基本的にチェックONしておきます。

プロジェクトの作成画面4

「Default Part」では、使用するFPGAバイスを選択します。ボードファイルのインストールをしていれば、「Boards」を選択することで、「Display Name」の中に「Zybo Z7-20」があると思います。「Zybo Z7-20」を選択して、「Next」をクリックします。

プロジェクトの作成画面5

「New Project Summary」では、プロジェクトの設定内容を確認して、問題なければ「Finish」をクリックします。

プロジェクトの作成画面6

回路の作成

Verilogファイルは書かないで、VivadoのIPインテグレータだけを使って、回路の作成をします。

IP インテグレータによる回路作成

IP インテグレータの起動

Flow Navigator から 「IP INTEGRATOR」の「Create Block Design」 をクリックします。 小さいウィンドウが出て、「Design Name」 や 「Directory」を変えることができますが、デフォルトのままでいいです。これで「Diagram」のタブができます。「Diagram」で GUI 的に回路作成ができます。

インテグレータによる回路作成1

IP の配置

Diagramで「ADD IP」をクリックすると、IP(機能ごとにまとまった回路)のリストが表示されますので、「ZYNQ7_Processing_System」をダブルクリックして配置します。また、同じようにして「AXI GPIO」も配置します。

インテグレータによる回路作成2

IP の接続

IPを配置したら、「Run Block Automation」をクリックします。Zynq の設定が表示されますので、「Apply Board Preset」にチェックがあることを確認して、「OK」をクリックします。「Apply Board Preset」にチェックONすることで、ボード上にあるDDRメモリなどにしたがって Zynq の設定をしてくれます。

インテグレータによる回路作成3

「AXI GPIO」をダブルクリックして、「AXI GPIO」の設定をします。「IP Configuration」タブで「All Outputs」にチェックをして、「GPIO Width」を 4 と設定します。「OK」をクリックして設定を終了します。

インテグレータによる回路作成4

「Run Connection Automation」をクリックして、Zynq と「AXI GPIO」を自動接続をします。接続の設定では、「GPIO」はチェックOFFし、「S-AXI」にはチェックONして、「OK」をクリックします。

インテグレータによる回路作成5
インテグレータによる回路作成6

「Run Connection Automation」を実行すると、「Processor System Reset」(リセット信号を生成する回路)と「AXI Interconnect」(AXI のハブ的な回路)が自動生成されて、IP間が接続されます。

インテグレータによる回路作成7

つづいて、「AXI GPIO」の「GPIO」端子の「+」部分をクリックすると、端子が展開されて「gpio_io_o[3:0]」が表示されます。これを右クリックして、メニューから「Make External」を実行することで、「AXI GPIO」の出力とFPGAの出力ポートを接続します。

インテグレータによる回路作成8

これで回路ができました。

制約ファイル(*.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.」を表示します。

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」をクリックで大丈夫です。

Bitstream_Generation_Completed

Zynq のプログラムを実行

Vitisを使って、Zynqのプログラムを実行していきます。

回路情報のコピーとVitis の起動

Vitisを起動する前にVivadoからVitisに対して回路情報を渡す必要があります。そのため、Vivadoでその作業をしてから、Vitis を起動します。

回路情報のコピー

メニューバーから「File」→「Export」→「Export Hardware...」を実行します。最初の画面では、「Next」をクリックします。

エクスポート画面1

「Output」では「Include bitstream」を選択します。これで、Vitisに回路情報を渡すことができます。

エクスポート画面2

「Files」では以下のように設定しました。

  • 名称:design_1_wrapper(デフォルト設定)
  • 保存先:D:/v20/zybo_synthesizer/zybo_synthesizer.vitis
エクスポート画面3

最後に「Finish」をクリックしてエクスポートします。

エクスポート画面4

Vitisの起動

メニューバーから「Tools」→「Launch Vitis IDE」でVitisを起動します。

Zynqのプログラム実行1

ワークスペースの場所は先ほど作成したzybo_synthesizer.vitisフォルダを指定し、「Launch」をクリックします。

Zynqのプログラム実行2

各種プロジェクトの作成

Vitisでは「プラットフォームプロジェクト」と「アプリケーションプロジェクト」の作成をする必要がありますので、これらのプロジェクトを作成していきます。

プラットフォームプロジェクトの作成

起動画面から「Create Platform Project」をクリックします。

Zynqのプログラム実行3

最初の画面では、プロジェクト名を入力します。プロジェクト名は「zybo_synthesizer_platform」としました。

Zynqのプログラム実行4

つぎは「Create a new platform from hardware (XSA)」タブで、Vivadoで作成したプラットフォームファイル(*.xsa)を指定します。「Finish」でプロジェクトが作成されます。

Zynqのプログラム実行5

アプリケーションプロジェクトの作成

メニューバーから「File」→「New」→「Application Project...」を実行します。

Zynqのプログラム実行6

最初の画面では、そのまま「Next」をクリックします。

Zynqのプログラム実行7

次の画面では、プラットフォームの選択をします。デフォルトでさきほど作成したプラットフォームが設定されていますので、確認してそのまま「Next」をクリックします。

Zynqのプログラム実行8

つづいて、アプリケーションプロジェクト名を入力する画面になります。アプリケーションプロジェクト名は「helloworld」としました。

Zynqのプログラム実行9

ドメインの選択では、そのまま「Next」をクリックします。

Zynqのプログラム実行10

テンプレートを選択する画面では、「Empty Application」を選択して、「Finish」をクリックします。

Zynqのプログラム実行11

プログラムの作成と実行

プログラムをC言語で作成して、シリアルターミナルなどを設定して、プログラムを実行します。

Cファイルの作成

アプリケーションプロジェクト内の「src」フォルダを右クリックして、「New」→「File」をクリックします。ファイル名を入力する画面では、ファイル名を「helloworld.c」として、「Finish」をクリックします。

Zynqのプログラム実行12
Zynqのプログラム実行13

プログラムの記述

プログラムは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に回路情報を渡して、デバッグ時の操作画面に変更されます。

FPGAプログラム中

シリアルターミナルの設定

シリアルターミナルの設定は、「Vitis Serial Terminal」タブの「+」をクリックし、COMポートと通信速度を設定して「OK」をクリックします。基本的には通信速度はデフォルトで、ポートは選択可能なものを選べばいいと思います。

シリアルターミナル
シリアルターミナルの設定

プログラムの実行

プログラムの実行は「Resume」ボタンをクリックすることで行われます。

resumeボタン

実行すると、シリアルターミナルには「Hello World」と表示されます。

シリアルターミナルの様子

また、4つのLEDが以下のように点灯します。

ZYBOがLEDを点灯している様子

おわりに

ZYBOでLチカとHello Worldをしました。まだ、Vitisに慣れないので、慣れていきたいと思います。

お問い合わせフォーム プライバシーポリシー

© 2021 Setoti All rights reserved.