3.5.1.17.1 Struct Packing
(Ask a Question)Packing a struct
creates a single scalar with a wide word width. All the struct
members are placed in the scalar with their order in the struct
definition such that the first element is the least significant part of the vector and the last element is the most significant part of the vector. Packing allows all the struct
elements to be read and written simultaneously. There are two packing options in SmartHLS™: bit-packing and byte-packing. A pragma is specified for the argument / variable to be packed with the packing option. Note that packing an array of struct
results in an array with each element as a wide-vector representing the packed struct
.
struct
to another type only if the packed type is the same as the cast type. For example, the following code shows a supproted cast for struct s
because packing the two uint8_t
members is the same as uint16_t
:struct S {
uint8_t a;
uint8_t b
};
#pragma HLS memory impl variable(s) pack(bit)
S s;
uint16_t &cast = (uint16_t &)s;
- Bit-Packing
- Bit-packing uses the bit-width of each of element of the
struct
. In our example,clients
argument can be bit-packed as following:int find(Client clients[N], ap_uint<6> id) { #pragma HLS function noinline //...
} UpdateResult update(Client clients[N], ap_uint<6> id, Account acc) { #pragma HLS function top #pragma HLS memory impl argument(clients) pack(bit) //...
}
In the HLS summary report, the interface forclients
has a data width of 134, which is the sum of theid
(6-bits),acc.checking
(64-bits), andacc.savings
(64-bits). The following layout of packedstruct
follows the order of the fields such that the first field is the least significant part of the layout.|133 .......... 70|69 .......... 6|5 .. 0| |-----------------|---------------|------| | acc.savings | acc.checking | id |
| RTL Interface Generated by SmartHLS | +----------+-----------------+---------------------------------+------------------+------------------+ | C++ Name | Interface Type | Signal Name | Signal Bit-width | Signal Direction | +----------+-----------------+---------------------------------+------------------+------------------+ | | Clock & Reset | clk (positive edge) | 1 | input |
| | | clients_address_b | 2 | output | | | | clients_clken | 1 | output | | | | clients_read_data_a | 134 | input | | | | clients_read_data_b | 134 | input | | | | clients_read_en_a | 1 | output | | | | clients_read_en_b | 1 | output | | | | clients_write_data_a | 134 | output | | | | clients_write_data_b | 134 | output | | | | clients_write_en_a | 1 | output | | | | clients_write_en_b | 1 | output | +----------+-----------------+---------------------------------+------------------+------------------+ | acc | Scalar Memory | acc_read_data | 128 | input |
- Byte-Packing
- Byte-packing is similar to bit-packing except that each element of the
struct
is aligned to 8-bits. In our example,clients
can be byte-packed as following:int find(Client clients[N], ap_uint<6> id) { #pragma HLS function noinline //...
} UpdateResult update(Client clients[N], ap_uint<6> id, Account acc) { #pragma HLS function top #pragma HLS memory impl argument(clients) pack(byte) //...
}
In the HLS summary report, the interface for
clients
has a data width of 136, which is the sum of theid
(8-bits),acc.checking
(64-bits), andacc.savings
(64-bits). The following layout of packedstruct
follows the order of the fields such that the first field is the least significant part of the layout.|135 .......... 72|71 .......... 8|7 .. 0| |-----------------|---------------|------| | acc.savings | acc.checking | id |
| RTL Interface Generated by SmartHLS | +----------+-----------------+---------------------------------+------------------+------------------+ | C++ Name | Interface Type | Signal Name | Signal Bit-width | Signal Direction | +----------+-----------------+---------------------------------+------------------+------------------+ | | Clock & Reset | clk (positive edge) | 1 | input |
For byte-packing, the interface can either use byte-enable to write individual fields or it can be a wide scalar as shown before. To use byte-enable signals,| | | clients_address_b | 2 | output | | | | clients_clken | 1 | output | | | | clients_read_data_a | 136 | input | | | | clients_read_data_b | 136 | input | | | | clients_read_en_a | 1 | output | | | | clients_read_en_b | 1 | output | | | | clients_write_data_a | 136 | output | | | | clients_write_data_b | 136 | output | | | | clients_write_en_a | 1 | output | | | | clients_write_en_b | 1 | output | +----------+-----------------+---------------------------------+------------------+------------------+ | acc | Scalar Memory | acc_read_data | 128 | input |
byte_enable
parameter should be set totrue
in the packing pragma:int find(Client clients[N], ap_uint<6> id) { #pragma HLS function noinline //...
} UpdateResult update(Client clients[N], ap_uint<6> id, Account acc) { #pragma HLS function top #pragma HLS memory impl argument(clients) pack(byte) byte_enable(true) //...
}
The HLS summary report will showclients_byte_en_a
andclients_byte_en_b
signals that are added to the interface.Important:byte_enable
parameter is default tofalse
and can only be specified withpack(byte)
, i.e. using it withpack(bit)
will error during compilation.| RTL Interface Generated by SmartHLS | +----------+-----------------+---------------------------------+------------------+------------------+ | C++ Name | Interface Type | Signal Name | Signal Bit-width | Signal Direction | +----------+-----------------+---------------------------------+------------------+------------------+ | | Clock & Reset | clk (positive edge) | 1 | input |
| | | clients_address_b | 2 | output | | | | clients_byte_en_a | 17 | output | | | | clients_byte_en_b | 17 | output | | | | clients_clken | 1 | output | | | | clients_read_data_a | 136 | input | | | | clients_read_data_b | 136 | input | | | | clients_read_en_a | 1 | output | | | | clients_read_en_b | 1 | output | | | | clients_write_data_a | 136 | output | | | | clients_write_data_b | 136 | output | | | | clients_write_en_a | 1 | output | | | | clients_write_en_b | 1 | output | +----------+-----------------+---------------------------------+------------------+------------------+ | acc | Scalar Memory | acc_read_data | 128 | input |