diff --git a/test_regress/t/t_split_var_0.v b/test_regress/t/t_split_var_0.v index 4c4804dbf..070ee7569 100644 --- a/test_regress/t/t_split_var_0.v +++ b/test_regress/t/t_split_var_0.v @@ -1,52 +1,201 @@ -module barshift #(parameter depth = 2, localparam width = 2**depth) ( + +// If split_var pragma is removed, UNOPTFLAT appears. + +module barshift_1d_unpacked #(parameter depth = 2, localparam width = 2**depth) ( input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); -// If the following split_array var is removed, ALWCOMBORDER and UNOPTFLAT appear. -logic [width-1:0] tmp[depth-2:-2]; /*verilator split_var*/ -generate - for(genvar i = 0; i < depth; ++i) begin - always_comb - if (shift[i]) begin - tmp[i+1-2] = {tmp[i-2][(1 << i)-1:0], tmp[i-2][width-1:(2**i)]}; - end else begin - tmp[i + 1 - 2] = tmp[i-2]; + localparam offset = -3; + logic [width-1:0] tmp[depth+offset:offset]; /*verilator split_var*/ + generate + for(genvar i = 0; i < depth; ++i) begin + always_comb + if (shift[i]) begin + tmp[i+1+offset] = {tmp[i+offset][(1 << i)-1:0], tmp[i+offset][width-1:(2**i)]}; + end else begin + tmp[i+1+offset] = tmp[i+offset]; + end end - end -endgenerate -assign tmp[0-2] = in; -assign out = tmp[depth-2]; + endgenerate + assign tmp[0+offset] = in; + assign out = tmp[depth+offset]; +endmodule + + +module barshift_1d_unpacked_struct0 #(parameter depth = 2, localparam width = 2**depth) ( + input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); + + localparam offset = 1; + typedef struct packed { logic [width-1:0] data; } data_type; + data_type tmp[depth+offset:offset]; /*verilator split_var*/ + generate + for(genvar i = 0; i < depth; ++i) begin + always_comb + if (shift[i]) begin + tmp[i+1+offset] = {tmp[i+offset][(1 << i)-1:0], tmp[i+offset][width-1:(2**i)]}; + end else begin + tmp[i+1+offset] = tmp[i+offset]; + end + end + endgenerate + assign tmp[0+offset] = in; + assign out = tmp[depth+offset]; +endmodule + + +module barshift_1d_unpacked_struct1 #(parameter depth = 2, localparam width = 2**depth) ( + input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); + + localparam offset = 2; + typedef struct packed { int data; } data_type; + data_type tmp[depth+offset:offset]; /*verilator split_var*/ + + localparam [32-width-1:0] pad = 0; + generate + for(genvar i = 0; i < depth; ++i) begin + always_comb + if (shift[i]) begin + tmp[i+1+offset] = {pad, tmp[i+offset][(1 << i)-1:0], tmp[i+offset][width-1:(2**i)]}; + end else begin + tmp[i+1+offset] = tmp[i+offset]; + end + end + endgenerate + assign tmp[0+offset] = {pad, in}; + assign out = tmp[depth+offset][width-1:0]; +endmodule + + +module barshift_2d_packed_array #(parameter depth = 2, localparam width = 2**depth) ( + input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); + + localparam offset = -2; + /*verilator lint_off LITENDIAN*/ + reg [offset:depth+offset][width-1:0] tmp; /*verilator split_var*/ + /*verilator lint_on LITENDIAN*/ + + generate + for(genvar i = 0; i < depth; ++i) begin + always_comb + /*verilator lint_off ALWCOMBORDER*/ + if (shift[i]) begin + tmp[i+1+offset] = {tmp[i+offset][(1 << i)-1:0], tmp[i+offset][width-1:(2**i)]}; + end else begin + tmp[i+1+offset][1:0] = tmp[i+offset][1:0]; + tmp[i+1+offset][width-1:2] = tmp[i+offset][width-1:2]; + end + /*verilator lint_on ALWCOMBORDER*/ + end + endgenerate + assign tmp[0+offset] = in; + assign out = tmp[depth+offset]; +endmodule + + +module barshift_2d_packed_array_le #(parameter depth = 2, localparam width = 2**depth) ( + input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); + + localparam offset = -2; + /*verilator lint_off LITENDIAN*/ + reg [offset:depth+offset][offset:width-1+offset] tmp; /*verilator split_var*/ + /*verilator lint_on LITENDIAN*/ + + generate + for(genvar i = 0; i < depth; ++i) begin + always_comb + /*verilator lint_off ALWCOMBORDER*/ + if (shift[i]) begin + tmp[i+1+offset] = {tmp[i+offset][width-(2**i)+offset:width-1+offset], tmp[i+offset][offset:width-(2**i)-1+offset]}; + end else begin // actulally just tmp[i+1+offset] = tmp[i+offset] + tmp[i+1+offset][0+offset:2+offset] = tmp[i+offset][0+offset:2+offset]; + tmp[i+1+offset][3+offset] = tmp[i+offset][3+offset]; + {tmp[i+1+offset][4+offset],tmp[i+1+offset][5+offset]} = {tmp[i+offset][4+offset], tmp[i+offset][5+offset]}; + {tmp[i+1+offset][7+offset],tmp[i+1+offset][6+offset]} = {tmp[i+offset][7+offset], tmp[i+offset][6+offset]}; + end + /*verilator lint_on ALWCOMBORDER*/ + end + endgenerate + assign tmp[0+offset] = in; + assign out = tmp[depth+offset]; +endmodule + + +module barshift_1d_packed_struct #(localparam depth = 3, localparam width = 2**depth) ( + input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); + + typedef struct packed { + logic [width-1:0] v0, v1, v2, v3; + } data_type; + wire data_type tmp; /*verilator split_var*/ + + assign tmp.v0 = in; + assign tmp.v1 = shift[0] == 1'b1 ? {tmp.v0[(1 << 0)-1:0], tmp.v0[width-1:2**0]} : tmp.v0; + assign tmp.v2 = shift[1] == 1'b1 ? {tmp.v1[(1 << 1)-1:0], tmp.v1[width-1:2**1]} : tmp.v1; + assign tmp.v3 = shift[2] == 1'b1 ? {tmp.v2[(1 << 2)-1:0], tmp.v2[width-1:2**2]} : tmp.v2; + assign out = tmp.v3; +endmodule + + +module barshift_bitslice #(parameter depth = 2, localparam width = 2**depth) ( + input [width-1:0] in, input [depth-1:0] shift, output [width-1:0]out); + + /*verilator lint_off LITENDIAN*/ + wire [0:width*(depth+1) - 1] tmp; /*verilator split_var*/ + /*verilator lint_on LITENDIAN*/ + + generate + for(genvar i = 0; i < depth; ++i) begin + always_comb + if (shift[i]) begin + tmp[width*(i+1):width*(i+1+1)-1] = {tmp[width*(i+1)-(1<