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 shiverspell
Visitor
1,051 Views
Registered: ‎05-03-2018

AXI interface configuration

Hi everyone,


I hope you can help me with my issue. I am very new to FPGA programming so please bare with me.

Currently I am trying to synthesize a design where I have an input array (1536 int) and an output array (512 int). I am trying to create an application where the input array is transferred to the PL by the PS and the output is read back by the PS afterwards.
Therefore I tried to use the AXI interface, in slave mode for the input array with the following directives:
set_directive_resource -core RAM_1P_BRAM -metadata {-bus_bundle CHUNKS} "conway" chunks
set_directive_interface -mode ap_memory -depth 1536 "conway" chunks

and the output array as AXI master with as follows:
set_directive_interface -mode m_axi -depth 512 -bundle NEW_CHUNK "conway" new_chunk


However, this does not synthesize to what I expected. When using a combination of AXI slave and master as shown above, the output array just gets removed. During export I get a bunch of warnings that the output port is not connected and will therefore be removed:
WARNING: [Synth 8-3332] Sequential element (conway_NEW_CHUNK_m_axi_U/bus_read/rs_rreq/data_p2_reg[0]) is unused and will be removed from module conway.

This leads to the following question for me: Did I pick the interfaces correct and if so, how do I need to specify them correctly so I can use the IP properly?

I am pretty confused on what is happening behind the scenes and would be very glad for any hints in the correct direction!


Here are some technical details about the Hardware and Vivado Version I am using:
- Xilinx Zynq UltraScale+ MPSoC ZCU102 Evaluation Kit
- Vivado 2018.2 with the Vivado HL Deisgn Edition license

If you need any additional information I am glad to provide them!

 

 

Thanks!

0 Kudos
10 Replies
Explorer
Explorer
1,032 Views
Registered: ‎03-17-2011

Re: AXI interface configuration

Hello @shiverspell

 

Could you post your HLS code or at least the main declaration?

Thanks.

 

Sebastien

 

--Sebastien
0 Kudos
Visitor shiverspell
Visitor
1,013 Views
Registered: ‎05-03-2018

Re: AXI interface configuration

Hi @sebo 

 

Sure, here is the main file:

 

#include "conway.h"

int determine_neighbors(int* chunks, int cell_idx);
bool determine_state(int alive_cnt, int curr);

/* this is intended to compute only a chunk of a larger board
*  each chunk is 64 * 4 elements large.
*  Copy the current chunk, the previous and the next chunk of
* the board to the FPGA for the computation.
*/
void conway(int chunks[BOARD_X * CHUNK_Y * 3], int new_chunk[BOARD_X * CHUNK_Y])
{
	unsigned int i, j;
	// 0: dead cell
	// 1: alive cell

	int alive_cnt;

	unsigned int chunk_size = 512;

	main_loop:for (i = chunk_size; i < 2 * chunk_size; ++i) {
		// determine how many neighbors of the current cell are alive
		alive_cnt = determine_neighbors(chunks, i);
		// determine the new state and assign it to the return array
		new_chunk[i - chunk_size] = determine_state(alive_cnt, chunks[i]);
	}
}

/* Determine how many neighbors are currently
 * alive.
 *  			n0
 * 		n3	c	n1
 * 			n2
 *
 * Assumption: if n1 or n3 are out of the board
 * border, they are automatically dead (0)
 */
int determine_neighbors(int* chunks, int cell_idx)
{
	int alive_cnt = 0;

	// determine n0
	alive_cnt += *(chunks + cell_idx - BOARD_X);

	// determine n1
	// check whether n1 is out of the right border
	// if not add actual value to alive_cnt
	if((cell_idx % BOARD_X) != (BOARD_X -1))
		alive_cnt += *(chunks + cell_idx + 1);

	// determine n2
	alive_cnt += *(chunks + cell_idx + BOARD_X);

	// determine n3
	// check whether n3 is out of the left border
	// if not add actual value to alive_cnt
	if((cell_idx % BOARD_X) != 0)
		alive_cnt += *(chunks + cell_idx - 1);

	return alive_cnt;
}

/*
*  Determine the new state depending on the number
*  of neighbors alive.
*/
bool determine_state(int alive_cnt, int curr)
{
	int new_state;

	if(curr == 1) // cell is alive
	{
		// if there are 2 or 3 neighbors alive cell stays alive
		if((alive_cnt == 2) || (alive_cnt == 3))
			new_state = 1;
		// if the cell has more or less than 2 or 3 neighbors
		// it dies
		else
			new_state = 0;
	} else { // cell is dead
		// if a dead cell has exactly 3 alive neighbors
		// the cell becomes alive
		if(alive_cnt == 3)
			new_state = 1;
		// if the cell is dead and has not exactly 3 alive
		// neighbors it stays dead
		else
			new_state = 0;
	}

	return new_state;
}

 

 

Here is the header file:

// board size
#define BOARD_X 64
#define CHUNK_Y 8
#define NUM_CHUNKS 8
#define NUM_CYCLES 10

void conway(int chunks[BOARD_X * CHUNK_Y * 3], int new_board[BOARD_X * CHUNK_Y]);

If you need anything else just let me know!

0 Kudos
Explorer
Explorer
996 Views
Registered: ‎03-17-2011

Re: AXI interface configuration

@shiverspell,

 

I guess you have a problem with the function determine_state.

In your code, this function returns a boolean. Now, the bool return feeds the new_chunk output which is not a boolean....

 

Hope this helps.

Sebastien.

--Sebastien
0 Kudos
Visitor shiverspell
Visitor
989 Views
Registered: ‎05-03-2018

Re: AXI interface configuration

Hello @sebo

Oh boy, yes that is totally correct. I changed the data type at some point and forgot to change it there too. What confuses me though is that I thought the C/RTL Cosimulation would have thrown an error at some point on messing up the data type.

 

After changing the data types I tried to synthesize and cosimulate again and now it gets stuck at simulation. However, when removing the interface directives it works just fine. That leads me back to my initial question if the interfaces are chosen and defined correctly there. 

 

Thanks a bunch so far!

0 Kudos
Explorer
Explorer
987 Views
Registered: ‎03-17-2011

Re: AXI interface configuration

@shiverspell,

Good!

 

I'm not an expert in HLS. but, I'd rather se pragma for defining interfaces in the C code itself rather any other mean. At least, everything (cod e& constraints) are defined within the same file. Anyway.

You may want to have a look at this video on youtube.

It could help.

--Sebastien
Visitor shiverspell
Visitor
978 Views
Registered: ‎05-03-2018

Re: AXI interface configuration

@sebo

I am currently using the directive tab of the Vivado HLS GUI for the interface configuration. As far as I understood it from the tutorials I had a look at, you can either use the directives directly within the C code or let them being put into the TCL files, right? I'll try to let Vivado put them directly into the code and see if that makes any difference. 

However, I'll definitely have a look at the video you posted, it looks very promising! 

 

Thanks for your patience and time! :)

0 Kudos
Explorer
Explorer
976 Views
Registered: ‎03-17-2011

Re: AXI interface configuration

Ok. No problem. Let me know if this video helped you.

 

--Sebastien
0 Kudos
Explorer
Explorer
951 Views
Registered: ‎05-23-2011

Re: AXI interface configuration

Hi

 

AXI isn´t very deterministic.

It woul´d be better for the HLS-IP core access the data via BRAM interface.

I think your design can look like this:

 

PS-system---AXI-->Dual-Ported-BRAM (source data)--BRAM-IF--> HLS-IP --BRAM-IF--> DUAL-Ported-BRAM --AXI --> PS-system

 

After copying the data to the first BRAM you start the IP. If the IP is finished you can get an interrupt.

 

Kind regards

 

Thomas

 

 

 

 

 

 

0 Kudos
Visitor shiverspell
Visitor
895 Views
Registered: ‎05-03-2018

Re: AXI interface configuration

Hi @thomasdon, hi @sebo

 

Sorry to let you wait quite a while for an answer, I was trying some things with the suggestions you gave. As both of you suggested using the BRAM interface I tried that. However the results from the PL were just wrong. Therefore I tried to use a much simpler design in order to validate if that had anything to do with my interface configuration. I used an input and an output array with the same size as for the actual implementation and just summed three values (not in a sequential order). 

Yet, I am not sure if I connected everything up correctly. I used a BRAM generator for each of the HLS IP BRAM ports, made it dual channel and connected the two BRAM generators for the input to one AXI BRAM controller and the output to another AXI BRAM controller. This had quite an odd behavior, as I couldn't access more than 1024 elements from the input array. So when I tried to compute something like out = in1 + in2 + in3, where in1 and in2 where within the first 1024 and in3 within the last 512 elements of the array, it only adds up to in1+in2, in3 just got ignored completely. This confuses me completely because apparently the PL is doing things but can somehow not receive anything more than the first 1024 elements. 

This is what I tried so far:

- one AXI BRAM controller (two channels) for both in ports with dual bram generator (true dual port generator, one connected to the HLS IP and one to the controller), address range altered to 8k

- two AXI BRAM controllers (one channel each), one for each in port, with 4k address range

 

I have chosen the directives within Vivado HLS and configured the BRAM generator as well as the AXI BRAM controller according to the tutorial @sebo send and tried to adapt that for the dual ported BRAM as suggested by @thomasdon.

If it helps anything, I can send a screenshot of the Vivado HW design. 

 

Thanks again!

 

0 Kudos
Explorer
Explorer
638 Views
Registered: ‎05-23-2011

Re: AXI interface configuration

Hi

My configuration is nearly the same.
I programmed an ethernet DMA in HLS.
This DMA has one memory area of 4 KB and one of 64 KB. The second one is splitte in two BRAM busses for higher troughput (see picture).

I have nearly random accesses in the areas because I´m checking the frames while receiving and generating the frame content in realtime in some cases.

Kind regards

Thomas

 

 

IGB_BRAM.png
0 Kudos