Axis interfaceをSDK上で使用する

June 02, 2020

Vivado HLSのinterfaceには様々な物が有るが,その中の引数をaxis interfaceで合成したIPを作成後,それをSDK上で使用する方法が検索しても中々出てこなかったのでメモしておく.

サンプルとして次の様なIPを用意した.

int axis_test(int inp[4], int outp[4]) {
#pragma HLS INTERFACE axis register both port=inp
#pragma HLS INTERFACE s_axilite port=outp
#pragma HLS INTERFACE s_axilite port=return
	for(int i=0; i<4; i++) outp[i] = inp[i]*2;
	return 0;
}

inp[4]の全ての要素を2倍してoutp[4]に格納するだけの単純なIP.ここで,outpと返り値のINTERFACEはs_axiliteとし,inpはaxisとして合成した.合成したらVivadoを開き,PSと接続する.

SDK側のコードは以下.

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xaxis_test.h"
#include "xllfifo.h"

int main() {
    init_platform();
    XAxis_test inst;
    XAxis_test_Initialize(&inst, XPAR_AXIS_TEST_0_DEVICE_ID);

    int data[4] = {0, 1, 2, 3};
    int out[4];

    XLlFifo fifoinst;

    XAxis_test_Start(&inst);
    XLlFifo_Initialize(&fifoinst, XPAR_AXI_FIFO_MM_S_BASEADDR);

    XLlFifo_Write(&fifoinst, data, 4*4);
    XLlFifo_TxSetLen(&fifoinst, 4*4);

    while(XAxis_test_IsDone(&inst) == 0);
    XAxis_test_Read_outp_Words(&inst, 0, out, 4);

    for(int i=0; i<4; i++) printf("%d", out[i]);
    printf("\n");

    cleanup_platform();
    return 0;
}

ポイントはXLlFifo_WriteXLlFifo_TxSetLenの順序.xllfifo.hには次の様な記述が有る.

XLlFifoTxSetLen begins a hardware transfer of _Bytes bytes out of the transmit channel of the FIFO specified by InstancePtr.

XLlFifoWrite writes _Bytes bytes of the block of memory, referenced by BufPtr, to the transmit channel of the FIFO referenced by InstancePtr.

Writeでtransmit channelにデータを書き込んで,TxSetLenでデータの転送を開始するらしい.これを逆にするとデータの転送がなされなくなるため,ハードウェア側の処理がいつまでも終了しない.結果, while(XAxis_test_IsDone(&inst) == 0);で無限ループに陥る.