update test and golden for split_var
This commit is contained in:
parent
20b59f381d
commit
a67c47e8a9
|
|
@ -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<<i):width*(i+1)-1], tmp[width*i:width*i+((width-1) - (2**i))]};
|
||||
end else begin
|
||||
tmp[width*(i+1):width*(i+1+1)-1] = tmp[width*i:width*(i+1)-1];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
assign tmp[width*0:width*(0+1)-1] = in;
|
||||
assign out = tmp[width*depth:width*(depth+1)-1];
|
||||
endmodule
|
||||
|
||||
|
||||
module t(/*AUTOARG*/ clk);
|
||||
input clk;
|
||||
localparam depth = 3;
|
||||
localparam width = 2**depth;
|
||||
logic [width-1:0] in, out0;
|
||||
logic [depth-1:0] shift = 0;
|
||||
input clk;
|
||||
localparam depth = 3;
|
||||
localparam width = 2**depth;
|
||||
localparam numsub = 7;
|
||||
logic [width-1:0] in;
|
||||
logic [width-1:0] out[0:numsub-1];
|
||||
logic [depth-1:0] shift = 0;
|
||||
|
||||
`ifndef VERILATOR
|
||||
// The following variables can not be splitted. will see warnings.
|
||||
logic should_show_warning0; /*verilator split_var*/
|
||||
logic [1:0][7:0]should_show_warning1; /*verilator split_var*/
|
||||
logic [7:0]should_show_warning2[0:1][0:3]; /*verilator split_var*/
|
||||
`endif
|
||||
// barrel shifter
|
||||
barshift_1d_unpacked #(.depth(depth)) shifter0(.in(in), .out(out[0]), .shift(shift));
|
||||
barshift_1d_unpacked_struct0 #(.depth(depth)) shifter1(.in(in), .out(out[1]), .shift(shift));
|
||||
barshift_1d_unpacked_struct1 #(.depth(depth)) shifter2(.in(in), .out(out[2]), .shift(shift));
|
||||
barshift_2d_packed_array #(.depth(depth)) shifter3(.in(in), .out(out[3]), .shift(shift));
|
||||
barshift_2d_packed_array_le #(.depth(depth)) shifter4(.in(in), .out(out[4]), .shift(shift));
|
||||
barshift_1d_packed_struct shifter5(.in(in), .out(out[5]), .shift(shift));
|
||||
barshift_bitslice #(.depth(depth)) shifter6(.in(in), .out(out[6]), .shift(shift));
|
||||
|
||||
// barrel shifter
|
||||
barshift #(.depth(depth)) shifter0(.in(in), .out(out0), .shift(shift));
|
||||
|
||||
assign in = 8'b10001110;
|
||||
logic [7:0] [7:0] exp = {
|
||||
8'b10001110, 8'b01000111, 8'b10100011, 8'b11010001,
|
||||
8'b11101000, 8'b01110100, 8'b00111010, 8'b00011101};
|
||||
always @(posedge clk) begin
|
||||
$display("in:%b shift:%d out:%b exp:%b", in, shift, out0, exp[7-shift]);
|
||||
if (out0 != exp[7-shift]) $stop;
|
||||
if (shift == 7) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
assign in = 8'b10001110;
|
||||
/*verilator lint_off LITENDIAN*/
|
||||
logic [7:0] [7:0] exp = {
|
||||
8'b10001110, 8'b01000111, 8'b10100011, 8'b11010001,
|
||||
8'b11101000, 8'b01110100, 8'b00111010, 8'b00011101};
|
||||
/*verilator lint_on LITENDIAN*/
|
||||
always @(posedge clk) begin
|
||||
automatic bit failed = 0;
|
||||
$display("in:%b shift:%d exp:%b", in, shift, exp[7-shift]);
|
||||
for (int i = 0; i < numsub; ++i) begin
|
||||
if (out[i] != exp[7-shift]) begin
|
||||
$display("Missmatch out[%d]:%b", i, out[i]);
|
||||
failed = 1;
|
||||
end
|
||||
end
|
||||
if (failed) $stop;
|
||||
if (shift == 7) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
shift <= shift + 1;
|
||||
end
|
||||
shift <= shift + 1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,22 +1,34 @@
|
|||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:4: Stray pragma of split_var is detected.
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:2: Stray pragma of split_var is detected.
|
||||
: ... In instance t
|
||||
/*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
/*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
... Use "/* verilator lint_off SPLITVAR */" and lint_on around source to disable this message.
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:7: Pragma split_var is specified on 'should_show_warning0' which type is not supported yet. Only unpacked 1D array is supported by this version.
|
||||
: ... In instance t
|
||||
logic should_show_warning0; /*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:8: Pragma split_var is specified on 'should_show_warning1' which type is not supported yet. Only unpacked 1D array is supported by this version.
|
||||
: ... In instance t
|
||||
logic [1:0][7:0]should_show_warning1; /*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:9: Pragma split_var is specified on 'should_show_warning2' which type is not supported yet. Only unpacked 1D array is supported by this version.
|
||||
: ... In instance t
|
||||
wire [7:0]should_show_warning2[0:1][0:3]; /*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:30: Variable 'cannot_split' will not be split because index cannot be determined statically.
|
||||
: ... In instance t.i_sub0
|
||||
rd_data = cannot_split[addr];
|
||||
^~~~
|
||||
rd_data = cannot_split[addr];
|
||||
^~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:39: Variable 'cannot_split0' will not be split because the entire unpacked array is referred. Such access is not supported yet.
|
||||
: ... In instance t.i_sub1
|
||||
cannot_split1 = cannot_split0;
|
||||
^~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:39: Variable 'cannot_split1' will not be split because the entire unpacked array is referred. Such access is not supported yet.
|
||||
: ... In instance t.i_sub1
|
||||
cannot_split1 = cannot_split0;
|
||||
^~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:5: Pragma split_var is specified on a variable whose type is not supported. Unpacked dimension must be 1D or none and packed portion must be an aggregate type of bit or logic.
|
||||
: ... In instance t
|
||||
real should_show_warning0; /*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:6: Pragma split_var is specified on a variable whose type is not supported. Unpacked dimension must be 1D or none and packed portion must be an aggregate type of bit or logic.
|
||||
: ... In instance t
|
||||
string should_show_warning1[0:2]; /*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:7: Pragma split_var is specified on a variable whose type is not supported. Unpacked dimension must be 1D or none and packed portion must be an aggregate type of bit or logic.
|
||||
: ... In instance t
|
||||
wire [7:0]should_show_warning2[0:1][0:3]; /*verilator split_var*/
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:50: Variable 'cannot_split' will not be split because bit range cannot be determined statically.
|
||||
: ... In instance t.i_sub2
|
||||
rd_data = cannot_split[addr];
|
||||
^
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -1,32 +1,52 @@
|
|||
|
||||
|
||||
module t();
|
||||
/*stray pragma */ /*verilator split_var*/
|
||||
/*stray pragma */ /*verilator split_var*/
|
||||
|
||||
// The following variables can not be splitted. will see warnings.
|
||||
logic should_show_warning0; /*verilator split_var*/
|
||||
logic [1:0][7:0]should_show_warning1; /*verilator split_var*/
|
||||
wire [7:0]should_show_warning2[0:1][0:3]; /*verilator split_var*/
|
||||
// The following variables can not be splitted. will see warnings.
|
||||
real should_show_warning0; /*verilator split_var*/
|
||||
string should_show_warning1[0:2]; /*verilator split_var*/
|
||||
wire [7:0]should_show_warning2[0:1][0:3]; /*verilator split_var*/
|
||||
|
||||
logic [3:0] addr;
|
||||
logic [7:0] rd_data;
|
||||
logic [3:0] addr;
|
||||
logic [7:0] rd_data0, rd_data1, rd_data2;
|
||||
|
||||
sub0 i_sub0(.addr(addr), .rd_data(rd_data));
|
||||
sub0 i_sub0(.addr(addr), .rd_data(rd_data0));
|
||||
sub1 i_sub1( .rd_data(rd_data1));
|
||||
sub2 i_sub2(.addr(addr), .rd_data(rd_data2));
|
||||
|
||||
|
||||
initial begin
|
||||
addr = 0;
|
||||
addr = 1;
|
||||
$finish;
|
||||
end
|
||||
initial begin
|
||||
addr = 0;
|
||||
addr = 1;
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module sub0(input [3:0]addr, output logic [7:0] rd_data);
|
||||
|
||||
logic [7:0] cannot_split[0:15]; /*verilator split_var*/
|
||||
always_comb
|
||||
rd_data = cannot_split[addr];
|
||||
logic [7:0] cannot_split[0:15]; /*verilator split_var*/
|
||||
always_comb
|
||||
rd_data = cannot_split[addr];
|
||||
|
||||
endmodule
|
||||
|
||||
module sub1(output logic [7:0] rd_data);
|
||||
|
||||
logic [7:0] cannot_split0[0:15]; /*verilator split_var*/
|
||||
logic [7:0] cannot_split1[0:15]; /*verilator split_var*/
|
||||
always_comb begin
|
||||
cannot_split1 = cannot_split0;
|
||||
rd_data = cannot_split1[0];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module sub2(input [3:0]addr, output logic [7:0] rd_data);
|
||||
|
||||
logic [15:0] [7:0] cannot_split; /*verilator split_var*/
|
||||
always_comb
|
||||
rd_data = cannot_split[addr];
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue