AXI4-DMAを試行している。Vivado-HLSでカスタムIPを作成し、Vivado-HLSのコアをAXI4-Streamで接続し、SDKから制御できるようになりたい。
前回、VivadoにカスタムIPをインプリメントし、デザインを生成した。次にSDKを使って制御してみる。
VivadoのカスタムIPから割り込みを受信する方法
まず、Zynq上に作成したデザインをもう一度振り返ってみる。
今回、xlconcatという、信号をconcatするブロックを使っている。これでmatrix_hls_accelブロックの割り込み通知信号をProcessingSystemに接続しており、この配線を通じて割り込みを通知する。
AXI4-DMAでの通信方法の基本
AXI4-DMAを通じてデータを転送する基本は、XAxiDma_SimpleTransfer
だ。
XAxiDma_SimpleTransfer(&AxiDma, (unsigned int) matrix_c, DIM*DIM*sizeof(float), XAXIDMA_DEVICE_TO_DMA);
XAXIDMA_DEVICE_TO_DMA
もしくはXAXIDMA_DMA_TO_DEVICE
を選択する。DEVICE_TO_DMA
ならばPLからPSへの転送、DMA_TO_DEVICE
ならばPSからPLへの転送のようだ。
データの転送の方法だが、まずはソースデータとなるmatrix_a[DIM][DIM], matrix_b[DIM][DIM]
を転送し、演算を実行、演算が終了するとmatrix_c[DIM][DIM]
へ回収する。
int status; status = XAxiDma_SimpleTransfer(&AxiDma, (unsigned int) A, dma_size, XAXIDMA_DMA_TO_DEVICE); status = XAxiDma_SimpleTransfer(&AxiDma, (unsigned int) B, dma_size, XAXIDMA_DMA_TO_DEVICE); // 演算を実行 status = XAxiDma_SimpleTransfer(&AxiDma, (unsigned int) res_hw, dma_size, XAXIDMA_DEVICE_TO_DMA);
とすれば良いだろう。また、演算の終了は割り込みで通知すれば良いかな?
// Initialize the exception handler Xil_ExceptionInit(); // Register the exception handler //print("Register the exception handler\n\r"); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic); //Enable the exception handler Xil_ExceptionEnable(); // Connect the Adder ISR to the exception table xil_printf ("Connect the Adder ISR to the Exception handler table\n\r"); result = XScuGic_Connect(&ScuGic,XPAR_FABRIC_HLS_ACCEL_1_INTERRUPT_INTR,(Xil_InterruptHandler)XMmultIsr,&MatrixAccel); if(result != XST_SUCCESS){ return result; } // xil_printf ("Enable the Adder ISR\n\r"); XScuGic_Enable(&ScuGic,XPAR_FABRIC_HLS_ACCEL_1_INTERRUPT_INTR);
XPAR_FABRIC_HLS_ACCEL_1_INTERRUPT_INTR
は 割り込みポートの61番と定義した。
#define XPAR_FABRIC_HLS_ACCEL_1_INTERRUPT_INTR (61)
これはPSの割り込みポートとして定義されているポートだ。
61番のポートに割り込みが発生すると、XMmultIsr()
が呼ばれるようにする。
void XMmultIsr(void *InstancePtr){ XHls_matrix_accel *pExample = (XHls_matrix_accel *)InstancePtr; xil_printf("Received\n"); //Disable the global interrupt XHls_matrix_accel_InterruptGlobalDisable(pExample); //Disable the local interrupt XHls_matrix_accel_InterruptDisable(pExample,0xffffffff); ...
まだソースコードが完成していないので、ソースコードの公開は出来ないが、とりあえず割り込み通知を受信は確認できた。下記のコンソールで、"Received"の文字が受信できていることが分かる。
ただし、回収したデータおかしい。うまく計算できていないようだ。これはもうちょっとデバッグが必要だな。