Source: http://marsee101.blog19.fc2.com/blog-entry-3344.html
Vivado HLS 勉強会3 (AXI4 Lite Slave)をSlideShare に公開しました。
内容は、
Vivado HLS 2015.4 を使用して、今までやってきた掛け算回路をAXI4 Lite Slaveインターフェースで実装します。
Vivado HLSでIP化を行って、Vivado 2015.4のIPIを使用してZYBOに実装します。
Vivado HLSで自動的に作製されたドライバを使用して、アプリケーションを作製し、掛け算回路を制御します。
ZYBO実機で掛け算回路を動作させます。シリアル・ターミナルで掛け算を行います。
という感じです。
AXI4 バス・インターフェースの知識が必要となります。波形を見なければ問題ないんですが。。。
AXI4 バス・インターフェースの生成はディレクティブ1発でOKです。何も難しいところはありません。しかもベアメタルとLinuxのドライバを自動的に生成してくれます。自動生成されたドライバを使用してベアメタル(OS無し)で掛け算回路をシリアル・インターフェース経由で動作させます。Linux 用のドライバは、UIOを使用するのが前提になっています。Linux用のドライバは手順が複雑なので、今回は使用しません。
それでは、Vivado HLS 勉強会3 (AXI4 Lite Slave)で使用するコードを貼っておきます。
まずは、ZYBO_zynq_def.xml が必要なんですが、Digilent 社のサイトには無くなってしまいました。ですが、fpga-zynq/zybo/src/xml/ZYBO_zynq_def.xml にありました。ここのコードをコピー&ペーストして、ZYBO_zynq_def.xml として保存すれば使えると思います。
最初に、multi_apuint.cpp を貼っておきます。
// multi_apuint.cpp
#include <stdio.h>
#include <string.h>
#include <ap_int.h>void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out){
#pragma HLS PIPELINE
#pragma HLS INTERFACE ap_hs register port=multi_in1
#pragma HLS INTERFACE ap_hs register port=multi_in0
#pragma HLS INTERFACE ap_vld register port=multi_out
#pragma HLS INTERFACE ap_ctrl_hs port=return
*multi_out = multi_in0 * multi_in1;
}
次に、multi_apuint_tb.cpp を貼っておきます。
#include <string.h>
#include <ap_int.h>void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out);int main(){
using namespace std;ap_uint<8> multi_in0;
ap_uint<8> multi_in1;
ap_uint<16> multi_out;for (multi_in0=0, multi_in1=1; multi_in0<10; multi_in0++, multi_in1++){
multi_apuint(multi_in0, multi_in1, &multi_out);
cout << "multi_out = " << multi_out << endl;
if (multi_out != (multi_in0 * multi_in1))
return(1);
}return(0);
}
最後に、multi_test.c を貼っておきます。
Vivado HLS 勉強会3 (AXI4 Lite Slave)をSlideShare に公開しました。内容は、Vivado HLS 2015.4 を使用して、今までやってきた掛け算回路をAXI4 Lite Slaveインターフェースで実装します。 Vivado HLSでIP化を行って、Vivado 2015.4のIPIを使用してZYBOに実装します。 Vivado HLSで自動的に作製されたドライバを使用して、アプリケーションを作製し、掛け算回路を制御します。ZYBO実機で掛け算回路を動作させます。シリアル・タ// multi_test.c
// 2015/07/24 : by marsee
// multi_in0 の入力の時に999を入力すると終了する
//#include <stdio.h>
#include "xmulti_apuint.h"
#include "xparameters.h"
#include "xil_types.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xscugic.h"int main(){
XMulti_apuint XMluti_ap;
XMulti_apuint_Config *XMulti_apPtr;
int val;// Look Up the device configuration
XMulti_apPtr = XMulti_apuint_LookupConfig(0);
if (!XMulti_apPtr){
fprintf(stderr, "XMulti_apuint configuration failed.\n");
return(-1);
}// Initialize the Device
int Xlap_status = XMulti_apuint_CfgInitialize(&XMluti_ap, XMulti_apPtr);
if (Xlap_status != XST_SUCCESS){
fprintf(stderr, "Could not Initialize XMulti_apuint\n");
return(-1);
}while(1){
printf("\n\rmulti_in0 = ");
scanf("%d", &val);
if(val == 999)
break;
XMulti_apuint_Set_multi_in0_V(&XMluti_ap, val);printf("\n\rmulti_in1 = ");
scanf("%d", &val);
XMulti_apuint_Set_multi_in1_V(&XMluti_ap, val);while(!XMulti_apuint_IsIdle(&XMluti_ap)) ;
XMulti_apuint_Start(&XMluti_ap);
while(!XMulti_apuint_IsDone(&XMluti_ap)) ;
printf("\n\rmulti_out = %d\n\r", (int)XMulti_apuint_Get_multi_out_V(&XMluti_ap));
}return(0);
}