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: 
Highlighted
Voyager
Voyager
9,826 Views
Registered: ‎10-07-2011

VivadoHLS and AXI4-Stream

Jump to solution

Hello all,

 

I'm doing my very first steps with HLS and am a little bit confused. I already have a working project on the ZC702 board that just demonstrates the data transfer capabilities of the ZYNQ from external memory to the FPGA fabric using DMA.

 

My test system is using DMA to retrieve (MM2S) data from DDR, send it to the AXI4-Stream input port of some data processing engine, and use a second DMA engine to store the result back into DDR (S2MM).

 

The original data processing engine was written in VHDL. Now, I would like to write it in C and use HLS. I'm getting something out of HLS, but the interfaces are not the expected AXI4-Stream signal set. Here's what I get:

 

entity DataProcessingEngine is

  port (

    ap_start : IN STD_LOGIC;

    ap_done : OUT STD_LOGIC;

    ap_idle : OUT STD_LOGIC;

    ap_ready : OUT STD_LOGIC; 

    x_data : IN STD_LOGIC_VECTOR (15 downto 0);

    ap_return : OUT STD_LOGIC_VECTOR (15 downto 0)

  );

end;

 

So, no clock signal, no reset and no AXI4-Stream ports... What I would like to see is:

 

entity DataProcessingEngine is

  port (

    clock : IN STD_LOGIC;

    reset: IN STD_LOGIC;

 

    x_tdata : IN STD_LOGIC_VECTOR (15 downto 0);

    x_tkeep : IN STD_LOGIC_VECTOR (1 downto 0);

    x_tlast : IN STD_LOGIC;

    x_tvalid : IN STD_LOGIC;

    x_tready : OUT STD_LOGIC;

 

    ap_return_tdata : OUT STD_LOGIC_VECTOR (15 downto 0);

    ap_return_tkeep : OUT STD_LOGIC_VECTOR (1 downto 0);

    ap_return_tlast : OUT STD_LOGIC;

    ap_return_tvalid : OUT STD_LOGIC;

    ap_return_tready : IN STD_LOGIC;

  );

end;

 

 

Is this possible? If so, how? Any reference to existing documentation?

 

Many thanks!

 

Claude

 

 

1 Solution

Accepted Solutions
Voyager
Voyager
14,969 Views
Registered: ‎10-07-2011

Re: VivadoHLS and AXI4-Stream

Jump to solution

Hello all,

 

Just to wrap-up on all the above... I succeeded doing something with HLS. See UG871, "Interface Synthesis, Lab 4". The C code is as below:

 

void      DataProcessingEngine(short x[1], short r[1])

{

#pragma HLS interface ap_ctrl_none port=return     // This prevents the unwanted block control signals to appear

 

#pragma HLS interface ap_fifo port=x               // Input stream; ap_fifo is the only interface supporting                                                    // the AXI4-Stream protocol per UG902, figure 1-37.

#pragma HLS RESOURCE variable=x core=AXIS          // Force the AXI4-Stream signal set

 

#pragma HLS interface ap_fifo port=r               // Output stream

#pragma HLS RESOURCE variable=r core=AXIS

 

    r[0] = ~x[0];

    return;

}

 

Note that the AXI4-Stream signal set will only show-up in the RTL when the created IP is EXPORTed (ie EXPORT RTL command). Until then, the interface will show-up as a standard FIFO interface, which may lead you think you are going down the wrong path...

 

entity DataProcessingEngine is

  port (

    ap_clk : IN STD_LOGIC;

    ap_rst : IN STD_LOGIC;

    x_dout : IN STD_LOGIC_VECTOR (15 downto 0);

    x_empty_n : IN STD_LOGIC;

    x_read : OUT STD_LOGIC;

    r_din : OUT STD_LOGIC_VECTOR (15 downto 0);

    r_full_n : IN STD_LOGIC;

    r_write : OUT STD_LOGIC

  );

end;

 

Finally, the above still misses the other AXIS signals (ie TSTRB, TKEEP, TLAST, ...). If you need them, you have to modify the source code as below. Note that you are forced to have at least 1 TUSER bit, 1 TID bit and 1 TDEST bit. But I guess the associated logic will be flushed downstream if these are of no use.

 

#include  <ap_axi_sdata.h>

 

void      DataProcessingEngine(ap_axis<16,1,1,1> *x, ap_axis<16,1,1,1> *r)

{

#pragma HLS interface ap_ctrl_none port=return

 

#pragma HLS interface ap_fifo port=x

#pragma HLS resource core=AXIS variable=x metadata="-bus_bundle S_AXIS" \

       port_map={{x_data_V TDATA} {x_strb_V TSTRB} {x_keep_V TKEEP} {x_user_V TUSER} \

                {x_last_V TLAST} {x_id_V TID} {x_dest_V TDEST}}

 

#pragma HLS interface ap_fifo port=r

#pragma HLS resource core=AXI4Stream variable=r metadata="-bus_bundle M_AXIS" \

       port_map={{r_data_V TDATA} {r_strb_V TSTRB} {r_keep_V TKEEP} {r_user_V TUSER} \

               {r_last_V TLAST} {r_id_V TID} {r_dest_V TDEST}}

 

     r->data = ~x->data;

     r->keep = x->keep;

     r->strb = x->strb;

     r->user = x->user;

     r->last = x->last;

     r->id = x->id;

     r->dest = x->dest;

 

     return;

}

 

The above code will synthesize as a combinatorial thing. There will be no register along the AXIS path.

 

Cheers,

 

Claude

 

5 Replies
Xilinx Employee
Xilinx Employee
9,817 Views
Registered: ‎08-17-2011

Re: VivadoHLS and AXI4-Stream

Jump to solution

Hello Claude and welcome to Vivado HLS!!

 

 

It looks like you're on the right progression path with already challenging learning tasks.

 

I think that you are missing some directives for the IO interface adaptors (and some other help) -> UG902 would be the first stop.

 

 

Further coding examples that could be useful to you are located into your VHLS installation, examples/design and coding directories. 

With your description, I think this one would help is examples/design/axi_stream_side_channel_data

you can open them from the GUI as well: help > welcome >  browse examples > design example etc..

 

*WARNING*: the code example in 2013.2 will issue a warning, so I'm attaching to this message the version that will be released in 2013.3 - if you check the code, it's the same, but directives change.

You can use it as a replacement.

 

A further comment: there are at least 2 version of RTL generated, at different levels of abstraction.

1- there is the generated RTL from your C - if the top level for c-synthesis is called example, then the RTL is in PROJECT/SOLUTION/syn/verilog or vhdl and is named example.v/.vhd it matches the C ports

2- when you export your IP, an additional wrapper is put around it, for example a bus adaptor will map your C inputs into AXI-lite memory mapped registers. This set of RTL files goes into PROJECT/SOLUTION/impl/ and the top wrapper at this stage is called example_top.v/.vhd

 

In conclusion, the signals that you are expecting to see will be in the exported IP resulting from “export_design”, not the ones from the top level IP: they may be similar or very different depending on your directives.

 

I hope this answer helps you more than it may confuse you!

Let us know how you are getting on with your learning.

 

- Hervé

SIGNATURE:
* New Dedicated Vivado HLS forums* http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls
* Readme/Guidance* http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

* Please mark the Answer as "Accept as solution" if information provided is helpful.
* Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Teacher muzaffer
Teacher
9,816 Views
Registered: ‎03-31-2012

Re: VivadoHLS and AXI4-Stream

Jump to solution

You need to annotate the source with some pragmas for an AXI stream interface to be generated. Read this document http://www.xilinx.com/support/documentation/sw_manuals/xilinx2013_2/ug902-vivado-high-level-synthesis.pdf (specially starting from page 99).

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Xilinx Employee
Xilinx Employee
9,810 Views
Registered: ‎08-17-2011

Re: VivadoHLS and AXI4-Stream

Jump to solution

Thanks Muzaffer,
your link points to 2012.2 but the upcoming release is 2013.3.. can you edit please? I usually just say to check UG902 and leave it to the users to figure out the rest :)
BTW this thread should be in the HLS dedicated thread:
http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls
If a moderator reads this, please move it, thanks!

- Hervé

SIGNATURE:
* New Dedicated Vivado HLS forums* http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls
* Readme/Guidance* http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

* Please mark the Answer as "Accept as solution" if information provided is helpful.
* Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Voyager
Voyager
9,791 Views
Registered: ‎10-07-2011

Re: VivadoHLS and AXI4-Stream

Jump to solution

Hello Hervé,

 

Looking at the file you attached, I noticed that it is C++. Is there a way to code AXI4-Stream stuff in plain C or is C++ mandatory?

 

Also, the example function is defined as below:

 

    void example(ap_axis<32,2,5,6> A[50], ap_axis<32,2,5,6> B[50]){

 

If I understand well, the "50" is the depth of the incoming and outgoing FIFOs. Right?

 

If so, how can we set-up a pure stream interface (ie without FIFOs)?

 

Thanks again!

 

Claude

0 Kudos
Voyager
Voyager
14,970 Views
Registered: ‎10-07-2011

Re: VivadoHLS and AXI4-Stream

Jump to solution

Hello all,

 

Just to wrap-up on all the above... I succeeded doing something with HLS. See UG871, "Interface Synthesis, Lab 4". The C code is as below:

 

void      DataProcessingEngine(short x[1], short r[1])

{

#pragma HLS interface ap_ctrl_none port=return     // This prevents the unwanted block control signals to appear

 

#pragma HLS interface ap_fifo port=x               // Input stream; ap_fifo is the only interface supporting                                                    // the AXI4-Stream protocol per UG902, figure 1-37.

#pragma HLS RESOURCE variable=x core=AXIS          // Force the AXI4-Stream signal set

 

#pragma HLS interface ap_fifo port=r               // Output stream

#pragma HLS RESOURCE variable=r core=AXIS

 

    r[0] = ~x[0];

    return;

}

 

Note that the AXI4-Stream signal set will only show-up in the RTL when the created IP is EXPORTed (ie EXPORT RTL command). Until then, the interface will show-up as a standard FIFO interface, which may lead you think you are going down the wrong path...

 

entity DataProcessingEngine is

  port (

    ap_clk : IN STD_LOGIC;

    ap_rst : IN STD_LOGIC;

    x_dout : IN STD_LOGIC_VECTOR (15 downto 0);

    x_empty_n : IN STD_LOGIC;

    x_read : OUT STD_LOGIC;

    r_din : OUT STD_LOGIC_VECTOR (15 downto 0);

    r_full_n : IN STD_LOGIC;

    r_write : OUT STD_LOGIC

  );

end;

 

Finally, the above still misses the other AXIS signals (ie TSTRB, TKEEP, TLAST, ...). If you need them, you have to modify the source code as below. Note that you are forced to have at least 1 TUSER bit, 1 TID bit and 1 TDEST bit. But I guess the associated logic will be flushed downstream if these are of no use.

 

#include  <ap_axi_sdata.h>

 

void      DataProcessingEngine(ap_axis<16,1,1,1> *x, ap_axis<16,1,1,1> *r)

{

#pragma HLS interface ap_ctrl_none port=return

 

#pragma HLS interface ap_fifo port=x

#pragma HLS resource core=AXIS variable=x metadata="-bus_bundle S_AXIS" \

       port_map={{x_data_V TDATA} {x_strb_V TSTRB} {x_keep_V TKEEP} {x_user_V TUSER} \

                {x_last_V TLAST} {x_id_V TID} {x_dest_V TDEST}}

 

#pragma HLS interface ap_fifo port=r

#pragma HLS resource core=AXI4Stream variable=r metadata="-bus_bundle M_AXIS" \

       port_map={{r_data_V TDATA} {r_strb_V TSTRB} {r_keep_V TKEEP} {r_user_V TUSER} \

               {r_last_V TLAST} {r_id_V TID} {r_dest_V TDEST}}

 

     r->data = ~x->data;

     r->keep = x->keep;

     r->strb = x->strb;

     r->user = x->user;

     r->last = x->last;

     r->id = x->id;

     r->dest = x->dest;

 

     return;

}

 

The above code will synthesize as a combinatorial thing. There will be no register along the AXIS path.

 

Cheers,

 

Claude