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 agb3
Visitor
4,230 Views
Registered: ‎07-01-2016

"Best" way to create 72-bit bus interface

Jump to solution

I would like to create an IP block in HLS which supplies a 72-bit-wide bus  to control another IP block. I need the ability to write to arbitrary bits on this bus. (For instance, set bit/wire 30 or set bits/wires 0-22 to an appropriately-masked integer.) Unfortunately, I'm new to HLS and am not sure how to do this in a clean/canonical manner.

 

72bit.png

(Picture of the 72-bit bus in question)

 

My initial approach was to declare a packed struct with bit-fields, and then write to members of the struct as necessary, like so:

struct ctrl_tdata {
	uint32_t btt    : 23;
	bool     type   : 1;
	uint8_t  dsa    : 6;
	bool     eof    : 1;
	bool     drr    : 1;
	uint32_t saddr  : 32;
	uint8_t  tag    : 4;
	uint8_t RESERVED: 4;
	uint8_t  xuser  : 4;
	uint8_t  xcache : 4;
} __attribute__((packed));

Pointers to that struct are arguments to my top level function (I need two of these control busses):

void ddr_diver(volatile char *axi_w,  volatile char *axi_r,
               ctrl_tdata *s2mm_ctrl, ctrl_tdata *mm2s_ctrl,
               bool *w_ready,         bool *r_ready) {

	...
	
	#pragma HLS INTERFACE ap_none port=s2mm_ctrl
	#pragma HLS INTERFACE ap_none port=mm2s_ctrl

	...
}

Unfortunately, when attempting to modify members of the struct, and thereby specific "wires" on the bus, I get some peculiar errors. For example, this function, which I think ought to set the "address" bits of the bus (32-64)

51:  void set_address(ctrl_tdata *ctrl, uint32_t addr) {
52:  	  ctrl->saddr = addr;
53:  }

results in the error:

ddr_diver/src/diver.cpp:51: Argument 'ctrl' of function 'ddr_diver' (ddr_diver/src/diver.cpp:67) has an unsynthesizable type (possible cause(s): structure variable cannot be decomposed due to (1) unsupported type conversion; (2) memory copy operation; (3) function pointer used in struct; (4) unsupported pointer comparison).

Similarly, I get an error when attempting to set ctrl->btt with a bit-masked int, I suspect because it is only 23 bits:

ddr_diver/src/diver.cpp:47: unsupported pointer reinterpretation from type '%struct.ctrl_tdata.0.1.2 = type <{ [3 x i8], i8, i32, i8, i8...' to type 'i32*' on variable 'ctrl'.

 

I suspect that my approach is not "kosher" by HLS standards. I would be delighted if anybody knew how to do this such that:

- The IP actually synthesizes

- There is  a "pretty" interface which supplies nothing but that 72-bit bus (see above picture).

- Bit operations can be elegantly performed on that interface.

 

(I can think of a few ugly alternatives -- for instance, bit shifting to place values in 3 uint32_t's, then concatenating w/ some Verilog code to supply the 72-bit bus signal -- but that seems brutish, tedious, and frankly, wrong!)

 

 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
Highlighted
Visitor agb3
Visitor
7,807 Views
Registered: ‎07-01-2016

Re: "Best" way to create 72-bit bus interface

Jump to solution

I've found a reasonably good way to do it. It turns out that HLS will accept bitfields, but there's not much of a good reason to use them. Instead, I declared each struct member as a ap_uint<number of bits>. So that HLS wouldn't split up the struct into several ports by default, I specified a  #pragma HLS DATA_PACK variable=... for each struct argument of my top-level function.

 

I realized that I had also made another minor error -- the total bit-count of the struct was 80, because the xUSER and xCACHE fields are typically not present in the DataMover IP I'm interfacing with.

 

This seems like a more elegant solution. Hopefully, it's the "correct" way to go about this.

View solution in original post

0 Kudos
1 Reply
Highlighted
Visitor agb3
Visitor
7,808 Views
Registered: ‎07-01-2016

Re: "Best" way to create 72-bit bus interface

Jump to solution

I've found a reasonably good way to do it. It turns out that HLS will accept bitfields, but there's not much of a good reason to use them. Instead, I declared each struct member as a ap_uint<number of bits>. So that HLS wouldn't split up the struct into several ports by default, I specified a  #pragma HLS DATA_PACK variable=... for each struct argument of my top-level function.

 

I realized that I had also made another minor error -- the total bit-count of the struct was 80, because the xUSER and xCACHE fields are typically not present in the DataMover IP I'm interfacing with.

 

This seems like a more elegant solution. Hopefully, it's the "correct" way to go about this.

View solution in original post

0 Kudos