cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
eisuke.mochizuki
Observer
Observer
1,468 Views
Registered: ‎06-25-2019

Vivado HLS "data_pack" vs Vitis HLS "aggregate" pragma

Jump to solution

Hi, I face problem when translate my HLS code Vivado HLS 2020.1 to Vitis HLS 2020.2.
Specifically, I use the following struct in order to connect to "M_AXIS_S2MM_STS" port of "AXI DataMover" IP.

 

struct StatusWord {
ap_uint<4> tag;
ap_uint<1> interr;
ap_uint<1> decerr;
ap_uint<1> slverr;
ap_uint<1> okay;
};

 


# Vivado HLS 2020.1 with "#pragma HLS data_pack"
When synthesis in Vivado HLS 2020.1 with "#pragma HLS data_pack", bitwidth of TDATA is 8 bits. It is OK.

 

|mm2s_sts_in_V_TDATA | in | 8| axis | mm2s_sts_in_V | pointer |
|mm2s_sts_in_V_TVALID | in | 1| axis | mm2s_sts_in_V | pointer |
|mm2s_sts_in_V_TREADY | out | 1| axis | mm2s_sts_in_V | pointer |

 

 

# Vitis HLS 2020.2  with "#pragma HLS aggregate"
In Vitis HLS 2020.2, "#pragma HLS data_pack" does not support, I use "#pragma HLS aggregate" intead. However, bitwidth of TDATA is 40 bits. It is not OK.

 

|mm2s_sts_in_V_TDATA | in| 40| axis| mm2s_sts_in_V| pointer|
|mm2s_sts_in_V_TVALID | in| 1| axis| mm2s_sts_in_V| pointer|
|mm2s_sts_in_V_TREADY | out| 1| axis| mm2s_sts_in_V| pointer|

 

 

I think this problem is occured by Vitis HLS specification. Vitis HLS align each elemets to 8bit.

image-20210603122059662.png

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug1399-vitis-hls.pdf#page=154

 

Do you have any idea to avoid this problem?

Regards

0 Kudos
1 Solution

Accepted Solutions
frederic
Xilinx Employee
Xilinx Employee
1,117 Views
Registered: ‎04-14-2013

I recommend you wait for 2021.1 (coming out this month) but here is a workaround using the packed attribute for structs and bit fields.

#include <ap_int.h>
#include <hls_stream.h>

struct __attribute__((packed)) StatusWord {
  char tag : 4;
  bool interr : 1;
  bool decerr : 1;
  bool slverr : 1;
  bool okay : 1;
};

void MyModule(
  hls::stream<StatusWord>& mm2s_sts_in,
  hls::stream<StatusWord>& mm2s_sts_out)
{
#pragma HLS INTERFACE axis register_mode=both register port=mm2s_sts_out
#pragma HLS INTERFACE axis register_mode=both register port=mm2s_sts_in

  mm2s_sts_out.write(mm2s_sts_in.read());
}

 Then the interface is reported by 2020.2 to be like this (which is I believe what you wanted with AXI Stream and most compact representation for the data):

================================================================
== Interface
================================================================
* Summary: 
+-----------------------+-----+-----+------------+----------------+--------------+
|       RTL Ports       | Dir | Bits|  Protocol  |  Source Object |    C Type    |
+-----------------------+-----+-----+------------+----------------+--------------+
|ap_clk                 |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_rst_n               |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_start               |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_done                |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_idle                |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_ready               |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|mm2s_sts_in_V_TDATA    |   in|    8|        axis|   mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_TVALID   |   in|    1|        axis|   mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_TREADY   |  out|    1|        axis|   mm2s_sts_in_V|       pointer|
|mm2s_sts_out_V_TDATA   |  out|    8|        axis|  mm2s_sts_out_V|       pointer|
|mm2s_sts_out_V_TVALID  |  out|    1|        axis|  mm2s_sts_out_V|       pointer|
|mm2s_sts_out_V_TREADY  |   in|    1|        axis|  mm2s_sts_out_V|       pointer|
+-----------------------+-----+-----+------------+----------------+--------------+

 

View solution in original post

14 Replies
frederic
Xilinx Employee
Xilinx Employee
1,396 Views
Registered: ‎04-14-2013

Add the keyword "bit" when applying the AGGREGATE pragma:

#pragma HLS AGGREGATE variable=<name_of_struct_variable> bit
0 Kudos
eisuke.mochizuki
Observer
Observer
1,356 Views
Registered: ‎06-25-2019

Hi, frederic. Thank you for your reply.
I try with "bit" pragma, but it is not well.

|mm2s_sts_in_V_TDATA | in| 40| axis| mm2s_sts_in_V| pointer|
|mm2s_sts_in_V_TVALID | in| 1| axis| mm2s_sts_in_V| pointer|
|mm2s_sts_in_V_TREADY | out| 1| axis| mm2s_sts_in_V| pointer|

 

And in synthesis log, there is "Ignore aggregate" warning.

WARNING: [HLS 214-255] Ignore aggregate pragma/directive on AXI-Stream interface 'mm2s_sts_in'

 

If you know, could you tell me why aggregate pragma is ignored?

Regards.

0 Kudos
hemangd
Moderator
Moderator
1,346 Views
Registered: ‎03-16-2017

@eisuke.mochizuki aggregate pragma does not support with axis interface with 2020.2 Vitis HLS.

Can you please try with DISAGGREGATE PRAGMA on each element of the struct? (disaggregation of data ports)

From UG 1399:

newww.JPG

Regards,
hemangd

Don't forget to give kudos and mark it as accepted solution if your issue gets resolved.
0 Kudos
eisuke.mochizuki
Observer
Observer
1,316 Views
Registered: ‎06-25-2019

Hi, hemangd. Thank you for your reply.
I try with "DISAGGREGATE" pragma.

#pragma HLS DISAGGREGATE variable=mm2s_sts_in
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.tag
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.interr
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.decerr
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.slverr
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.okay

 

Synthesis is succesefull, however bitwidth is still 40 bits and protocol is not axis but ap_fifo.

|mm2s_sts_in_V_dout     |   in|   40|     ap_fifo|      mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_empty_n  |   in|    1|     ap_fifo|      mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_read     |  out|    1|     ap_fifo|      mm2s_sts_in_V|       pointer|


Regards.

0 Kudos
hemangd
Moderator
Moderator
1,300 Views
Registered: ‎03-16-2017

@eisuke.mochizuki Kindly paste your full cpp file.

Regards,
hemangd

Don't forget to give kudos and mark it as accepted solution if your issue gets resolved.
0 Kudos
wave_rider
Visitor
Visitor
1,252 Views
Registered: ‎03-10-2021

Hi,

"data_pack" pragma can be applied to interface in vivado_hls but when "aggregate" is applied to interface in vitis_hls, it will only byte aligned instead of packed on bit level. I had raised my concern about this in this forum and NO XILINX team seems to be care.

the only work around is to do the manual packing by yourself by making everything back to ap_uint.

good luck.

eisuke.mochizuki
Observer
Observer
1,201 Views
Registered: ‎06-25-2019

@hemangd This is my latest cpp file.

#include <ap_int.h>
#include <hls_stream.h>

struct StatusWord {
  ap_uint<4> tag;
  ap_uint<1> interr;
  ap_uint<1> decerr;
  ap_uint<1> slverr;
  ap_uint<1> okay;
};

void MyModule(
  hls::stream<StatusWord>& mm2s_sts_in,
  hls::stream<StatusWord>& mm2s_sts_out)
{
#pragma HLS DISAGGREGATE variable=mm2s_sts_in
#pragma HLS DISAGGREGATE variable=mm2s_sts_out

#pragma HLS INTERFACE axis port=mm2s_sts_in.V.tag
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.interr
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.decerr
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.slverr
#pragma HLS INTERFACE axis port=mm2s_sts_in.V.okay
#pragma HLS INTERFACE axis port=mm2s_sts_out.V.tag
#pragma HLS INTERFACE axis port=mm2s_sts_out.V.interr
#pragma HLS INTERFACE axis port=mm2s_sts_out.V.decerr
#pragma HLS INTERFACE axis port=mm2s_sts_out.V.slverr
#pragma HLS INTERFACE axis port=mm2s_sts_out.V.okay

  mm2s_sts_out.write(mm2s_sts_in.read());
}

And synthesis result is here.

================================================================
== Interface
================================================================
* Summary:
+-----------------------+-----+-----+------------+----------------+--------------+
|       RTL Ports       | Dir | Bits|  Protocol  |  Source Object |    C Type    |
+-----------------------+-----+-----+------------+----------------+--------------+
|ap_clk                 |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_rst                 |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_start               |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_done                |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_idle                |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_ready               |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|mm2s_sts_in_V_dout     |   in|   40|     ap_fifo|   mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_empty_n  |   in|    1|     ap_fifo|   mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_read     |  out|    1|     ap_fifo|   mm2s_sts_in_V|       pointer|
|mm2s_sts_out_V_din     |  out|   40|     ap_fifo|  mm2s_sts_out_V|       pointer|
|mm2s_sts_out_V_full_n  |   in|    1|     ap_fifo|  mm2s_sts_out_V|       pointer|
|mm2s_sts_out_V_write   |  out|    1|     ap_fifo|  mm2s_sts_out_V|       pointer|
+-----------------------+-----+-----+------------+----------------+--------------+

Regards, 

0 Kudos
eisuke.mochizuki
Observer
Observer
1,200 Views
Registered: ‎06-25-2019

@wave_rider Thank you for your important information.

> the only work around is to do the manual packing by yourself by making everything back to ap_uint.

Yes, I think that may be best way...

Regards,

0 Kudos
ramananr
Xilinx Employee
Xilinx Employee
1,192 Views
Registered: ‎08-22-2019

Hi, 

The 2021.1 release of Vitis HLS now adds support for a "-compact bit" option to the aggregate pragma. This makes the aggregate pragma (and padding removal) the same as the old DATA_PACK pragma. 

0 Kudos
ramananr
Xilinx Employee
Xilinx Employee
1,189 Views
Registered: ‎08-22-2019

Hi,

Couple of clarifications:

a. Only structs can be disaggregated using the DISAGGREGATE pragma. A stream however cannot be disaggregated.

b. Vitis HLS 2021.1 brings support for a "-compact=bit" option to the AGGREGATE pragma which will behave exactly the same as the old DATA_PACK pragma. 

#pragma HLS aggregate variable=<variable> compact=bit

Vitis HLS 2021.1 will be available later this month. 

frederic
Xilinx Employee
Xilinx Employee
1,118 Views
Registered: ‎04-14-2013

I recommend you wait for 2021.1 (coming out this month) but here is a workaround using the packed attribute for structs and bit fields.

#include <ap_int.h>
#include <hls_stream.h>

struct __attribute__((packed)) StatusWord {
  char tag : 4;
  bool interr : 1;
  bool decerr : 1;
  bool slverr : 1;
  bool okay : 1;
};

void MyModule(
  hls::stream<StatusWord>& mm2s_sts_in,
  hls::stream<StatusWord>& mm2s_sts_out)
{
#pragma HLS INTERFACE axis register_mode=both register port=mm2s_sts_out
#pragma HLS INTERFACE axis register_mode=both register port=mm2s_sts_in

  mm2s_sts_out.write(mm2s_sts_in.read());
}

 Then the interface is reported by 2020.2 to be like this (which is I believe what you wanted with AXI Stream and most compact representation for the data):

================================================================
== Interface
================================================================
* Summary: 
+-----------------------+-----+-----+------------+----------------+--------------+
|       RTL Ports       | Dir | Bits|  Protocol  |  Source Object |    C Type    |
+-----------------------+-----+-----+------------+----------------+--------------+
|ap_clk                 |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_rst_n               |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_start               |   in|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_done                |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_idle                |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|ap_ready               |  out|    1|  ap_ctrl_hs|        MyModule|  return value|
|mm2s_sts_in_V_TDATA    |   in|    8|        axis|   mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_TVALID   |   in|    1|        axis|   mm2s_sts_in_V|       pointer|
|mm2s_sts_in_V_TREADY   |  out|    1|        axis|   mm2s_sts_in_V|       pointer|
|mm2s_sts_out_V_TDATA   |  out|    8|        axis|  mm2s_sts_out_V|       pointer|
|mm2s_sts_out_V_TVALID  |  out|    1|        axis|  mm2s_sts_out_V|       pointer|
|mm2s_sts_out_V_TREADY  |   in|    1|        axis|  mm2s_sts_out_V|       pointer|
+-----------------------+-----+-----+------------+----------------+--------------+

 

View solution in original post

eisuke.mochizuki
Observer
Observer
1,085 Views
Registered: ‎06-25-2019

@ramananr Thank you for your important information.

> Vitis HLS 2021.1 will be available later this month

I got it. I will try with "-compact=bit" option.

Regards,

0 Kudos
eisuke.mochizuki
Observer
Observer
1,084 Views
Registered: ‎06-25-2019

@frederic Thank you for your great support.

In my enviroment, this code works good!

> which is I believe what you wanted with AXI Stream and most compact representation for the data

Yes, this is the target interface.

In Vitis HLS 2020.2, I will use this format. Thank you.

Regards,

0 Kudos
wave_rider
Visitor
Visitor
694 Views
Registered: ‎03-10-2021

Thank you for finally listen to our voices

0 Kudos