cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
aakarshitha
Visitor
Visitor
613 Views
Registered: ‎02-28-2019

Hls block

Hello @vkanchan 

Vivado hls block in sysgen takes only scalar input at the Port.

Out input needs to be either a 1d or a 2d array.

Should our codes in hls then take all inputs as scalar?

Like for eg void func(int a, int *s)

Then how else to modify to take an array as an input?

0 Kudos
3 Replies
u4223374
Advisor
Advisor
597 Views
Registered: ‎04-26-2015

What do you mean by "array"? What is the physical representation of this in hardware?

 

If you want to just have a parallel array input, you can do that by defining an array argument to the top-level function and fully partitioning it. However, this rapidly becomes unmanageable - a 1000-element array of 32-bit values is going to have somewhat more than 32,000 input wires going into it, which is almost certainly un-routable.

 

If you're expecting that the array will be in RAM, then define an array argument to the top-level function and use the INTERFACE pragma to set the type to "bram" (or ap_memory).

 

If you're expecting the array to appear as a stream, one element at a time, then the "axis" interface type is relevant.

 

Finally, if you're planning to access an array stored in off-chip memory (eg. via a Zynq PS) then you can use the "m_axi" interface to generate a full AXI4 Master.

0 Kudos
aakarshitha
Visitor
Visitor
574 Views
Registered: ‎02-28-2019

Hello @u4223374 ,

Yes sure.Let me clarify few things:

1. We have coded and got the blocks in the library of model composer, created a design that runs perfectly in model composer. Then we made a subsystem for each of the blocks and exported to sysgen. Now that is where we are stuck. (PFA the screenshots)

2. Can you tell us how to store an image into an off-chip memory and also how to use the AXI Master interface block? 

Thank you,

-Aakarshitha

 

complete_ss1.JPG
complete_ss_blockproc_2.JPG
0 Kudos
u4223374
Advisor
Advisor
551 Views
Registered: ‎04-26-2015

@aakarshitha 

 

(1) Right. I've never used Model Composer, but I can see basically what's happening here.

 

(2) In HLS, you just define a block like this:

 

void top_function(int data[307200]) {
#pragma HLS INTERFACE m_axi port=data offset=slave

...
}

That will create an AXI Master port on the block, with the offset controlled by a register accessible on the AXI Lite interface (or you can use offset=none or offset=direct if you don't want AXI Lite). Normally you would plug that AXI Master into a memory controller of some sort. On the Zynq chips, you can use the PS HP AXI Slave ports, which give direct access to the PS DDR RAM. On everything else, if you instantiate the MIG core (memory controller) then you can plug the AXI Master into that.

With that connected, reading "data" in HLS will read from off-chip RAM, and writing to it will write to off-chip RAM. HLS may do a bit of buffering (eg. if you read from the same location ten times in a row, it might only read once and just store the value internally). If you need to disable that (unlikely) then you can declare "data" as a volatile int. For best performance you should also try to use the AXI Burst functionality; essentially this just means doing long-ish sequential reads/writes of one element per clock cycle. For image processing, reading a whole line at once is often sensible, although even just reading 4 - 16 pixels gets you almost all of the benefit.

0 Kudos