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で作成したプロジェクトを参照に追加

f:id:tohkaf:20151229234630p:plain

(myipは前回Verilogで作成したIP)

配線を作成

f:id:tohkaf:20151229234749p:plain

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で複雑な動作も試していく。