UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor tester@ki
Visitor
187 Views
Registered: ‎01-03-2019

Communication with Custom IP over DDR doesn't work

Hello,

I have tried to made a simple example like https://forums.xilinx.com/t5/Embedded-Processor-System-Design/Write-to-DDR-from-PS-read-form-PL-with-custom-IP/m-p/817985.

Code for the Custom IP is:

 

void addTwoVariables (int* x,int *y, int *result)
{
#pragma HLS INTERFACE m_axi depth=1 port=result offset=slave bundle=Output1
#pragma HLS INTERFACE m_axi depth=1 port=y offset=slave bundle=Input2
#pragma HLS INTERFACE m_axi depth=1 port=x offset=slave bundle=Input1
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS

		*result = *x + *y;
}

 

To generate the IP-Core, I have used Vivado_HLS.

The connection to the Zync UltraSCALE+ 102 is made with an S_AXI_HPC0_FPD port, like in the link. On the Zync Platform the CCI for HPC0 is enabled.

 

architecture.png

 

After that, I made a simple C-Code to communicate with the IP.

void Init(int * xPtrAddr, int * yPtrAddr, int* resultAddr)
{
    XAddtwovariables_Initialize(&xadd,XPAR_ADDTWOVARIABLES_0_DEVICE_ID);

    XAddtwovariables_InterruptGlobalDisable(&xadd);
    XAddtwovariables_InterruptDisable(&xadd, 1);

    XAddtwovariables_Set_x(&xadd, (u32) xPtrAddr);
    XAddtwovariables_Set_y(&xadd, (u32) yPtrAddr);
    XAddtwovariables_Set_result(&xadd, (u32) resultAddr);

    Xil_DCacheFlush();
    print_accel_status();

}


int x [1]__attribute__ ((aligned (64))) = {10};
int y [1] __attribute__ ((aligned (64))) = {10};
int resultarry [1] __attribute__ ((aligned (64)));

int main()
{
    init_platform();

    print("Hello World\n\r");

    Init(x,y,resultarry);


    int *xwert = XAddtwovariables_Get_x(&xadd);
    int *ywert = XAddtwovariables_Get_y(&xadd);

    printf("X: %d\n", *xwert);
    printf("Y: %d\n", *ywert);

	//Xaddtwovariables__EnableAutoRestart();

	XAddtwovariables_Start(&xadd);
	while(!XAddtwovariables_IsDone(&xadd)){}
	Xil_DcacheInvalidate();

	//Xaddtwovariables__DisableAutoRestart();
  
    printf("Result: %d\n", resultarry[0]);

    cleanup_platform();
    return 0;
}

Now my issue is, that I don’t get results. I added the lines as described in the link above, that the Cache is Flushed after write and invalidated before the read. But nothing happens. But when I add the function Xaddtwovariables_EnableAutoRestart before I start the IP with the function Xaddtwovariables_Start and function Xaddtwovariables_DisableAutoRestart after the cache is invalidated and then read the result, I receive correct results in my C-Code. But it seems like a workaround.

Additionally I looked at the waveforms in both examples, the correct values are written to the bus. But only in the example with AutoRestart, the results are available in the C-Code.

Does anyone have an idea about what might be going wrong ?

Best Regards

0 Kudos
1 Reply
Visitor daubin1
Visitor
94 Views
Registered: ‎04-11-2018

Re: Communication with Custom IP over DDR doesn't work

Placing the IP in EnableAutoRestart mode allows the IP to work in a non-blocking fashion.

This way you can collect data while not talking to it via C.

From the bottom of page 175 in the High-Level Synthesis pdf (UG902)

The second recommended flow is for continuous execution of the block. In this mode, the
input ports included in the AXI4 Slave Lite interface should only be ports which perform
configuration. The block will typically run must faster than a CPU. If the block must wait for
inputs, the block will spend most of its time waiting:
• Use the interrupt function to determine how you wish the interrupt to operate.
• Load the register values for the block input ports. In the above example this is
performed using API functions XExample_Set_a, XExample_Set_a and
XExample_Set_c_i.
• Set the auto-start function using API XExample_EnableAutoRestart

Allow the function to execute. The individual port I/O protocols will synchronize the
data being processed through the block.
• Address any interrupts which are generated. The output registers could be accessed
during this operation but the data may change often.
• Use the API function XExample_DisableAutoRestart to prevent any more
executions.
• Read the output registers. In the above example this is performed using API functions
XExample_Get_c_o and XExample_Set_c_o_vld.

0 Kudos