3.5.2.4.1 Advanced Memory Partitioning

Memory partitioning can also be used to partition structs.

struct point {
    char x, y;
};

struct point zero[2][3][4];

#pragma HLS loop unroll factor(1)
for (unsigned i = 0; i < 2; i++)
    #pragma HLS loop unroll factor(1)
    for (unsigned j = 0; j < 3; j++)
        #pragma HLS loop unroll factor(1)
        for (unsigned k = 0; k < 4; k++)
            zero[i][j][k].x = zero[i][j][k].y;

The code above shows a 3-level nested loop, where only the middle loop is fully unrolled. After the middle loop is unrolled, it creates three different memory accesses to non-overlapping regions of the array zero. This means the array can be automatically partitioned across the array dimension 1. Because the x and y fields are accessed separately, each element of struct point can be further partitioned into two partitions. Therefore, SmartHLS will partition the array zero into 6 partitions, one for each non-overlapping access range into the array of structs. This results in the equivalent code below.

struct point {
    char x, y;
};

struct point zero_a0_a0_a0_x[2][4];
struct point zero_a0_a0_a0_y[2][4];
struct point zero_a0_a1_a0_x[2][4];
struct point zero_a0_a1_a0_y[2][4];
struct point zero_a0_a2_a0_x[2][4];
struct point zero_a0_a2_a0_7[2][4];

#pragma HLS loop unroll factor(1)
#pragma HLS loop pipeline
for (unsigned i = 0; i < 2; i++)
    #pragma HLS loop unroll factor(1)
    for (unsigned k = 0; k < 4; k++)
        zero_a0_a0_a0_x[i][k] = zero_a0_a0_a0_y[i][k];
    #pragma HLS loop unroll factor(1)
    for (unsigned k = 0; k < 4; k++)
        zero_a0_a1_a0_x[i][k] = zero_a0_a1_a0_y[i][k];
    #pragma HLS loop unroll factor(1)
    for (unsigned k = 0; k < 4; k++)
        zero_a0_a2_a0_x[i][k] = zero_a0_a2_a0_y[i][k];

For structs or arrays of structs that are specified to be partitioned with user-specified partitioning, the partition dimension must be specified to be 0 or the struct will not be partitioned into its elements. User-specified partitioning only partitions up to the array dimension specified, therefore, if higher dimensions are specified the element type of the array will not be struct type and SmartHLS will not partition the lower dimensions. When dimension 0 is specified for an array, the element type will be struct type and SmartHLS will partition the array completely and then automatically partition the struct elements. When partitioning structs or array elements that are structs, user-specified partitioning will also automatically partition any nested aggregate types.

struct point {
    char x, y;
    int a[10];
};

// "zero" will be partitioned into its elements
// with array "a" also being partitioned into its elements
#pragma HLS memory partition variable(zero) dim(0)
// can also not specify dim(0) as it is 0 by default
struct point zero;

// "one" will be partitioned into 4 structs
// and each struct will be partitioned into its elements
// with array "a" also being partitioned into its elements
#pragma HLS memory partition variable(zero) dim(0)
struct point one[4];

// "two" will be partitioned into 8 structs
// and each struct will be partitioned into its elements
// with array "a" also being partitioned into its elements
#pragma HLS memory partition variable(zero) dim(0)
struct point two[2][4];

// "three" will be partitioned into 2 struct point[4] arrays
// the struct and its elements will not be partitioned
#pragma HLS memory partition variable(zero) dim(1)
struct point three[2][4];

When memory partitioning fails to partition a struct, it will print the following warning.

Warning: The struct, "struct1", on line 168 of struct.c can result in inefficient
memory accesses. We recommend splitting it up into individual elements.

For any aggregate types that holds FIFOs, SmartHLS will automatically apply user-specified partitioning to try to fully partition the memory and make sure the FIFOs become individual variables. In the case that memory partitioning fails to do so, SmartHLS will error out as SmartHLS cannot handle unpartitioned FIFOs.

Info: Found memory with FIFO(s): "array_of_FIFOs" on line 10 of fifos.c. Forcing
partition type to be complete.
Error: The FIFO(s) in memory "array_of_FIFOs" on line 10 of fifos.c was unable to
be split into individual FIFOs by SmartHLS which will result in functional errors.
To better partition the FIFO memory please try moving the FIFOs into a simpler
data structures or manually partitioning the FIFOs into individual variables.