AXI GPIOはXilinxが用意したIPですが今回は自作のAXIバスを利用したIPを作成して、それを使ってLチカします。
まずは前回までを参考に新規でVivadoプロジェクトを作成してください。
IPの雛形RTLを作成する
Vivado上部メニューのToolsのCreate and Package New IPをクリックします。
ここではIPを作成できますよ的な案内なのでNextをクリックして次の画面に進みます。
Create AXI4 PeripheralのCreate a new AXI4 peripheralを選択して、Nextをクリックします。
NameにIPの名前を入力します。Display nameはNameに合わせて自動で入力されます。保存場所IP locationは変えてもいいですがデフォルトのままでNextをクリックします。
この画面(Add Interfaces)ではどのAXIバスを使うかやデータ幅やレジスタの数などの設定ができます。デフォルトのままNextをクリックします。
次に何を行うか聞かれているので、Edit IPを選択してFinishをクリックします。
すると新しくIP作成用のVivadoウィンドウが開きます。
Source内に自動でIP用の雛形が作成されています。Lchika_IP_v1_0とその中でインスタンスされているLchika_IP_v1_0_S00_AXIが雛形なのでそれらを編集してIPを作っていくことになります。ソース内にユーザーが追記できる場所にはコメントが書かれています(例:// Users to add ports hereなど)。また雛形の説明も適宜コメントで書かれています(英語ですが)。
Lchika_IP_v1_0_S00_AXIを編集する
CPU(Xilinx SDKで作成するC or C++プログラム)からはAXIバスを通してLchika_IP_v1_0_S00_AXI内のレジスタ(slv_reg0、slv_reg1、slv_reg2、slv_reg3 はじめのほうの設定Add Interfacesでレジスタ数をデフォルトのまま=4にしたので4つのレジスタがあります)にアクセスしてIPに指示を与えることになります。
slv_reg0をスイッチレジスタ、slv_reg1をLED選択レジスタ、slv_reg2を周期設定レジスタとしてLチカIPを作成してみます。(slv_reg3は使いません)
slv_reg0の0ビット目が1ならLチカ動作開始0ならLチカ動作停止します。slv_reg1の1が立っているビットがLチカ動作の対象LEDになります(ZYBOの4つのLEDを使うので0~3ビット目まで有効)。slv_reg0で動作開始後slv_reg2の値の数だけクロックが来たらLEDの明暗を反転させます。
まずはLEDを光らせるための出力ポートを記述しておきます。
// Users to add ports hereというコメントの下に「output wire [3:0] led,」と記述します。
次に// Add user logic hereというコメントの下に以下を記述します。
reg [31:0] counter;
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 || counter >= slv_reg2 || slv_reg0 == 0 )
counter <= 0;
else
counter <= counter + 1;
end
reg light;
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 || slv_reg0 == 0 )
light <= 0;
else if( counter >= slv_reg2 )
light <= ~light;
else
light <= light;
end
assign led= slv_reg1[3:0] & {light,
light, light, light} ;
Lchika_IP_v1_0を編集する
次にLchika_IP_v1_0を編集します。
// Users to add ports hereというコメントの下に「output wire [3:0] led,」と記述します。
次に、Lchika_IP_v1_0_S00_AXIのインスタンス部にled(出力ポート)の接続の記述をします。
) Lchika_IP_v1_0_S00_AXI_inst ( という雛形の記述の下に「.led(led),」と記述してください。
これでLchika_IP_v1_0の編集は終わりです。
IPをパッケージ化する
Package IPタブのCustomization ParametersにMerge changes from
Customization Parameters Wizardと出ているのでこれをクリックします。
同様にFile Groups のMega changes from File Groups Wizardをクリックします。
さらに同様にReview and PackageのIP has been modifiedをクリックします。
警告が消えたらRe-Package IPをクリックします。
YesをクリックするとIP作成のVivadoプロジェクトが閉じます。
これでIPのパッケージ化は完了です。
IPを回路に実装する
以下の作業は普通のIPを使うときとほとんど同じです。
一番初めに作ったプロジェクト(まだ閉じられていないほうのプロジェクト)でCreate
Block Designをクリックしてブロックデザインを作成します。
まずはAdd IPでZYNQ7 Processing Systemを追加してRun Block
Automationをクリックし、Apply Board Presetにチェックがあるのを確認してOKをクリックします。
もう一度Add IPを開きます。よく確認してみると先ほど作成したIPがあるはずです。先ほど作成したIPをクリックしてDiagramに追加します。
追加したら、Run Block Automationをクリックし、デフォルトのままOKをクリックします。
作成したIPから出ている出力端子(led[3:0])を右クリックしてMake Externalをクリックし外部出力端子を作成します。
以下のような回路になったと思います。(Run Block Automation時に自動でProcessor System ResetやAXI Interconnectも追加されます。)
Ctrl+Sでデザインを保存し、右クリックからValidate Designをクリックしてブロックデザインに問題がないかチェックします。
Sourcesのdesign_1上で右クリックしCreate HDL Wrapperでラッパーファイルを作成します。Let Vivado manage wrapper and auto-updateを選択してOKをクリックします。
Open Elaborated Designをクリックしてピン制約を追加します。(Open Elaborated Designが完了するまで数分かかります)I/O
Portsが開けるようになったら、led_0のI/O StdはLVCMOS33に、Package Pinは、[0]がM14、[1]がM15、[2]がG14、[3]がD18に設定し適当な名前で保存します。
Generate Bitstreamを実行してBitstreamファイルの生成を行います。
生成が完了したら、Vivado上部メニューのFileのExportのExport Hardwareをクリックします。
必ずInclude bitstreamにチェックを入れてからOKをクリックします。
その後、Launch SDKをクリックしてSDKを起動させます。
Xilinx SDKで制御ソフト作成・動作確認する
SDKメニューのFile→New→Application Projectをクリックし、アプリケーションプロジェクトを作成します。
Project nameにプロジェクト名を入力して、Nextに進み、Empty Applicationを選択しFinishをクリックします。
Project Explorerのアプリケーションプロジェクトフォルダのsrcを右クリック→New→Source Fileをクリックします。
適当に名前(拡張子.cまで付ける)を付けてFinishをクリックしてソースファイルを追加します。(ここではmain.cにしました)
追加したソースにmain関数を記述します。
以下にmain.cの記述を示します。
#include "xparameters.h"
#include <unistd.h>
#define IP_SW *((volatile unsigned
int*)XPAR_LCHIKA_IP_0_S00_AXI_BASEADDR)
#define IP_FREQ *((volatile unsigned
int*)(XPAR_LCHIKA_IP_0_S00_AXI_BASEADDR+0x08))
#define IP_SEL *((volatile unsigned
int*)(XPAR_LCHIKA_IP_0_S00_AXI_BASEADDR+0x04))
int main(){
unsigned
int i,j;
while(1){
for(i=0;i<4;i++){
for(j=0;j<5;j++){
IP_SEL
= 0x01 << i;
IP_FREQ
= 0x989680*j;
IP_SW
= 0x01;
usleep(1000000);
}
}
}
return
0;
}
IP_FREQ = 0x989680*j;では点滅間隔を0x989680*jクロックカウントつまり10000000*jに設定しています。IPのクロックは100MHzなので0.1×j秒間隔になります。
IP_FREQ = 0x989680*j;では点滅間隔を0x989680*jクロックカウントつまり10000000*jに設定しています。IPのクロックは100MHzなので0.1×j秒間隔になります。
main関数が完成したらSDKメニューのProject→Cleanをクリックし、Clean all projectsを選択しOKをクリックします。
ビルドが終了したらmain関数にエラーがないかチェックします。(あれば修正します)。たまにmain関数以外でエラーが出ることがありますが、ビルド後Consoleに18:02:03 Build Finished (took 1s.116ms)のような記述が書かれていればビルドは通っています。
よくincludeでエラーやワーニングが出ますがビルドが通っていれば無視してOKな場合が多いです。
ZYBOのJP5がJTAGになっている事を確認してPCと接続し電源(sw4)を入れます。SDKのProgram FPGAのアイコンをクリックします。
ProgramをクリックするとZYBOにbitstreamファイルが書き込まれます。ZYBO上のDONEの緑色LEDが光っていれば正常に書き込まれているはずです。
Project Explorerのアプリケージョンフォルダ(ここではIP_Lchika)を右クリックして、Debug As→Debug Configrationsをクリックします。
Xilinx C/C++ application(System Debugger)をダブルクリックするとSystem Debugger using Debug_IP_Lchika.elf on Localが作成されるのでそれを選択しDebugをクリックします。(再度DebugするときはSystem Debugger using Debug_IP_Lchika.elf on LocalをクリックしてDebugをクリックすれば大丈夫です。)
デバッグ用画面に切り替えるかどうか聞かれるのでYesをクリックします。ちなみに画面はSDKの一番右上の虫マークとCマークをクリックすると切り替えられます。
Resumeボタン(再生マーク)をクリックするとプログラムが動きだし、ZYBOのLEDがチカチカするはずです。
Cプログラムの修正する場合はDisconnectボタンをクリックしてから修正し、修正後は同様の手順でビルド・bitstreamファイル書き込み(ZYBOの電源は落とさなくてもいい)・デバッグを行ってください。
これで作ったIPの動作確認ができました。
自作IPの他プロジェクトでの呼び出し方法
せっかくIPを作ったのでいろんなプロジェクトで流用したいですよね。
呼び出したいプロジェクトのVivadoのSettingsをクリックし、IP→Repositoryをクリックします。+マークをクリックして自作したIPのフォルダ(component.xmlなどが入っているフォルダ 今回の場合Lchika_IP_1.0というフォルダ)を指定してSelectをクリックし、OKをクリックしてSettingsを閉じます。
登録はこれだけです。
ためしにブロックデザインでAdd IPをしてみると、ちゃんと出てきました。
0 件のコメント:
コメントを投稿