ZynqでVivado HLSで作ったIPからスイッチ入力させる
前回 ZynqでVerilogで作ったIPからLEDを光らせる - 今日やったこと でVerilogから言わばAXI-GPIOが実装できたので今度はVivado HLSからAXI-GPIOを作成してみる。
memcpyは以前実装したが、Directiveが両方S_AXIだったことなど理解に足りない部分があったので改めてという目論見である。
Vivado HLSでボタン入力を実装
sourceにtest_function.cを作成。ボタン入力を実装。
typedef unsigned long long u64; typedef unsigned char u8; void test_function(u64* src, u8* data_in){ *src = *data_in; }
Directive設定
test_functionをINTERFACE, s_axiliteに、srcをINTERFACE, s_axiliteに、data_inをINTERFACEに設定。
高位合成後、IPパッケージ化する。
Vivado HLSで読み込み
DiagramのProjectSettingからHLSで作成したプロジェクトを参照に追加
(myipは前回Verilogで作成したIP)
配線を作成
Synthesize後にピン配置を直す->BitStream作成->Export Hardware->Launch SDK
ソフトウェア処理
[デザイン名]_hardware_pratform_0のdriversに自作IPのドライバが用意されていて使い方もコメント記述されているようだ。
ここのドライバの関数を叩けばレジスタ直叩きを避けられるような記述のようなのでまた試す。(ビルドがうまく行かなかったので今回は省いた
xtest_function_hw.h
// AXILiteS // 0x00 : Control signals // bit 0 - ap_start (Read/Write/SC) // bit 1 - ap_done (Read/COR) // bit 2 - ap_idle (Read) // bit 3 - ap_ready (Read) // bit 7 - auto_restart (Read/Write) // others - reserved // 0x04 : Global Interrupt Enable Register // bit 0 - Global Interrupt Enable (Read/Write) // others - reserved // 0x08 : IP Interrupt Enable Register (Read/Write) // bit 0 - Channel 0 (ap_done) // others - reserved // 0x0c : IP Interrupt Status Register (Read/TOW) // bit 0 - Channel 0 (ap_done) // others - reserved // 0x10 : Data signal of src // bit 31~0 - src[31:0] (Read) // 0x14 : Data signal of src // bit 31~0 - src[63:32] (Read) // 0x18 : Control signal of src // bit 0 - src_ap_vld (Read/COR) // others - reserved // (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake) #define XTEST_FUNCTION_AXILITES_ADDR_AP_CTRL 0x00 #define XTEST_FUNCTION_AXILITES_ADDR_GIE 0x04 #define XTEST_FUNCTION_AXILITES_ADDR_IER 0x08 #define XTEST_FUNCTION_AXILITES_ADDR_ISR 0x0c #define XTEST_FUNCTION_AXILITES_ADDR_SRC_DATA 0x10 #define XTEST_FUNCTION_AXILITES_BITS_SRC_DATA 64 #define XTEST_FUNCTION_AXILITES_ADDR_SRC_CTRL 0x18
実行された後にsrcを読み出せばスイッチ入力が取れるはずなので、前回のコードを改変
unsigned int* sw_baseaddr = XPAR_TEST_FUNCTION_0_S_AXI_AXILITES_BASEADDR; int main() { while(1){ //Start HLS Function sw_baseaddr[0] |= 0x1; while(!(sw_baseaddr[0] & 0x4)); uint32_t sw_data = sw_baseaddr[4];//src[31:0] uint8_t pushsw_data = (sw_data & 0xf); uint8_t slidesw_data = ((sw_data >> 4) & 0xf); uint8_t led_data = pushsw_data ^ slidesw_data; Xil_Out8(XPAR_MYIP_0_0, led_data); xil_printf("push:%x, slide:%x, led:%x\r\n", pushsw_data, slidesw_data, led_data); } return 0; }
無事に今までと同じ動作が確認できた。もっとHLSで複雑な動作も試していく。