mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-23 00:55:32 +00:00
Merge pull request #2529 from zachjs/unnamed-genblk
verilog: significant block scoping improvements
This commit is contained in:
commit
baf1875307
33 changed files with 783 additions and 262 deletions
33
tests/simple/func_block.v
Normal file
33
tests/simple/func_block.v
Normal file
|
@ -0,0 +1,33 @@
|
|||
`default_nettype none
|
||||
|
||||
module top(inp, out1, out2, out3);
|
||||
input wire [31:0] inp;
|
||||
|
||||
function automatic [31:0] func1;
|
||||
input [31:0] inp;
|
||||
reg [31:0] idx;
|
||||
for (idx = 0; idx < 32; idx = idx + 1) begin : blk
|
||||
func1[idx] = (idx & 1'b1) ^ inp[idx];
|
||||
end
|
||||
endfunction
|
||||
|
||||
function automatic [31:0] func2;
|
||||
input [31:0] inp;
|
||||
reg [31:0] idx;
|
||||
for (idx = 0; idx < 32; idx = idx + 1) begin : blk
|
||||
func2[idx] = (idx & 1'b1) ^ inp[idx];
|
||||
end
|
||||
endfunction
|
||||
|
||||
function automatic [31:0] func3;
|
||||
localparam A = 32 - 1;
|
||||
parameter B = 1 - 0;
|
||||
input [31:0] inp;
|
||||
func3[A:B] = inp[A:B];
|
||||
endfunction
|
||||
|
||||
output wire [31:0] out1, out2, out3;
|
||||
assign out1 = func1(inp);
|
||||
assign out2 = func2(inp);
|
||||
assign out3 = func3(inp);
|
||||
endmodule
|
25
tests/simple/func_recurse.v
Normal file
25
tests/simple/func_recurse.v
Normal file
|
@ -0,0 +1,25 @@
|
|||
module top(
|
||||
input wire [3:0] inp,
|
||||
output wire [3:0] out1, out2
|
||||
);
|
||||
function automatic [3:0] pow_a;
|
||||
input [3:0] base, exp;
|
||||
begin
|
||||
pow_a = 1;
|
||||
if (exp > 0)
|
||||
pow_a = base * pow_a(base, exp - 1);
|
||||
end
|
||||
endfunction
|
||||
|
||||
function automatic [3:0] pow_b;
|
||||
input [3:0] base, exp;
|
||||
begin
|
||||
pow_b = 1;
|
||||
if (exp > 0)
|
||||
pow_b = base * pow_b(base, exp - 1);
|
||||
end
|
||||
endfunction
|
||||
|
||||
assign out1 = pow_a(inp, 3);
|
||||
assign out2 = pow_b(2, 2);
|
||||
endmodule
|
41
tests/simple/func_width_scope.v
Normal file
41
tests/simple/func_width_scope.v
Normal file
|
@ -0,0 +1,41 @@
|
|||
module top(inp, out1, out2);
|
||||
input wire signed inp;
|
||||
|
||||
localparam WIDTH_A = 5;
|
||||
function automatic [WIDTH_A-1:0] func1;
|
||||
input reg [WIDTH_A-1:0] inp;
|
||||
func1 = ~inp;
|
||||
endfunction
|
||||
wire [func1(0)-1:0] xc;
|
||||
assign xc = 1'sb1;
|
||||
wire [WIDTH_A-1:0] xn;
|
||||
assign xn = func1(inp);
|
||||
|
||||
generate
|
||||
if (1) begin : blk
|
||||
localparam WIDTH_A = 6;
|
||||
function automatic [WIDTH_A-1:0] func2;
|
||||
input reg [WIDTH_A-1:0] inp;
|
||||
func2 = ~inp;
|
||||
endfunction
|
||||
wire [func2(0)-1:0] yc;
|
||||
assign yc = 1'sb1;
|
||||
wire [WIDTH_A-1:0] yn;
|
||||
assign yn = func2(inp);
|
||||
|
||||
localparam WIDTH_B = 7;
|
||||
function automatic [WIDTH_B-1:0] func3;
|
||||
input reg [WIDTH_B-1:0] inp;
|
||||
func3 = ~inp;
|
||||
endfunction
|
||||
wire [func3(0)-1:0] zc;
|
||||
assign zc = 1'sb1;
|
||||
wire [WIDTH_B-1:0] zn;
|
||||
assign zn = func3(inp);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
output wire [1023:0] out1, out2;
|
||||
assign out1 = {xc, 1'b0, blk.yc, 1'b0, blk.zc};
|
||||
assign out2 = {xn, 1'b0, blk.yn, 1'b0, blk.zn};
|
||||
endmodule
|
27
tests/simple/genblk_collide.v
Normal file
27
tests/simple/genblk_collide.v
Normal file
|
@ -0,0 +1,27 @@
|
|||
`default_nettype none
|
||||
|
||||
module top1;
|
||||
generate
|
||||
if (1) begin : foo
|
||||
if (1) begin : bar
|
||||
wire x;
|
||||
end
|
||||
assign bar.x = 1;
|
||||
wire y;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module top2;
|
||||
genvar i;
|
||||
generate
|
||||
if (1) begin : foo
|
||||
wire x;
|
||||
for (i = 0; i < 1; i = i + 1) begin : foo
|
||||
if (1) begin : foo
|
||||
assign x = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
21
tests/simple/genblk_dive.v
Normal file
21
tests/simple/genblk_dive.v
Normal file
|
@ -0,0 +1,21 @@
|
|||
`default_nettype none
|
||||
module top(output wire x);
|
||||
generate
|
||||
if (1) begin : Z
|
||||
if (1) begin : A
|
||||
wire x;
|
||||
if (1) begin : B
|
||||
wire x;
|
||||
if (1) begin : C
|
||||
wire x;
|
||||
assign B.x = 0;
|
||||
wire z = A.B.C.x;
|
||||
end
|
||||
assign A.x = A.B.C.x;
|
||||
end
|
||||
assign B.C.x = B.x;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
assign x = Z.A.x;
|
||||
endmodule
|
18
tests/simple/genblk_order.v
Normal file
18
tests/simple/genblk_order.v
Normal file
|
@ -0,0 +1,18 @@
|
|||
`default_nettype none
|
||||
module top(
|
||||
output wire out1,
|
||||
output wire out2
|
||||
);
|
||||
generate
|
||||
if (1) begin : outer
|
||||
if (1) begin : foo
|
||||
wire x = 0;
|
||||
if (1) begin : foo
|
||||
wire x = 1;
|
||||
assign out1 = foo.x;
|
||||
end
|
||||
assign out2 = foo.x;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
|
@ -260,3 +260,66 @@ module gen_test8;
|
|||
`ASSERT(gen_test8.A.C.x == 1)
|
||||
`ASSERT(gen_test8.A.B.x == 0)
|
||||
endmodule
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
module gen_test9;
|
||||
|
||||
// `define VERIFY
|
||||
`ifdef VERIFY
|
||||
`define ASSERT(expr) assert property (expr);
|
||||
`else
|
||||
`define ASSERT(expr)
|
||||
`endif
|
||||
|
||||
wire [1:0] w = 2'b11;
|
||||
generate
|
||||
begin : A
|
||||
wire [1:0] x;
|
||||
begin : B
|
||||
wire [1:0] y = 2'b00;
|
||||
`ASSERT(w == 3)
|
||||
`ASSERT(x == 2)
|
||||
`ASSERT(y == 0)
|
||||
`ASSERT(A.x == 2)
|
||||
`ASSERT(A.C.z == 1)
|
||||
`ASSERT(A.B.y == 0)
|
||||
`ASSERT(gen_test9.w == 3)
|
||||
`ASSERT(gen_test9.A.x == 2)
|
||||
`ASSERT(gen_test9.A.C.z == 1)
|
||||
`ASSERT(gen_test9.A.B.y == 0)
|
||||
end
|
||||
begin : C
|
||||
wire [1:0] z = 2'b01;
|
||||
`ASSERT(w == 3)
|
||||
`ASSERT(x == 2)
|
||||
`ASSERT(z == 1)
|
||||
`ASSERT(A.x == 2)
|
||||
`ASSERT(A.C.z == 1)
|
||||
`ASSERT(A.B.y == 0)
|
||||
`ASSERT(gen_test9.w == 3)
|
||||
`ASSERT(gen_test9.A.x == 2)
|
||||
`ASSERT(gen_test9.A.C.z == 1)
|
||||
`ASSERT(gen_test9.A.B.y == 0)
|
||||
end
|
||||
assign x = B.y ^ 2'b11 ^ C.z;
|
||||
`ASSERT(x == 2)
|
||||
`ASSERT(A.x == 2)
|
||||
`ASSERT(A.C.z == 1)
|
||||
`ASSERT(A.B.y == 0)
|
||||
`ASSERT(gen_test9.w == 3)
|
||||
`ASSERT(gen_test9.A.x == 2)
|
||||
`ASSERT(gen_test9.A.C.z == 1)
|
||||
`ASSERT(gen_test9.A.B.y == 0)
|
||||
end
|
||||
endgenerate
|
||||
|
||||
`ASSERT(w == 3)
|
||||
`ASSERT(A.x == 2)
|
||||
`ASSERT(A.C.z == 1)
|
||||
`ASSERT(A.B.y == 0)
|
||||
`ASSERT(gen_test9.w == 3)
|
||||
`ASSERT(gen_test9.A.x == 2)
|
||||
`ASSERT(gen_test9.A.C.z == 1)
|
||||
`ASSERT(gen_test9.A.B.y == 0)
|
||||
endmodule
|
||||
|
|
11
tests/simple/local_loop_var.sv
Normal file
11
tests/simple/local_loop_var.sv
Normal file
|
@ -0,0 +1,11 @@
|
|||
module top(out);
|
||||
output integer out;
|
||||
initial begin
|
||||
integer i;
|
||||
for (i = 0; i < 5; i = i + 1)
|
||||
if (i == 0)
|
||||
out = 1;
|
||||
else
|
||||
out += 2 ** i;
|
||||
end
|
||||
endmodule
|
15
tests/simple/loop_var_shadow.v
Normal file
15
tests/simple/loop_var_shadow.v
Normal file
|
@ -0,0 +1,15 @@
|
|||
module top(out);
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 2; i = i + 1) begin : loop
|
||||
localparam j = i + 1;
|
||||
if (1) begin : blk
|
||||
localparam i = j + 1;
|
||||
wire [i:0] x;
|
||||
assign x = 1'sb1;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
output wire [63:0] out;
|
||||
assign out = {loop[0].blk.x, loop[1].blk.x};
|
||||
endmodule
|
27
tests/simple/named_genblk.v
Normal file
27
tests/simple/named_genblk.v
Normal file
|
@ -0,0 +1,27 @@
|
|||
`default_nettype none
|
||||
module top;
|
||||
generate
|
||||
if (1) begin
|
||||
wire t;
|
||||
begin : foo
|
||||
wire x;
|
||||
end
|
||||
wire u;
|
||||
end
|
||||
begin : bar
|
||||
wire x;
|
||||
wire y;
|
||||
begin : baz
|
||||
wire x;
|
||||
wire z;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
assign genblk1.t = 1;
|
||||
assign genblk1.foo.x = 1;
|
||||
assign genblk1.u = 1;
|
||||
assign bar.x = 1;
|
||||
assign bar.y = 1;
|
||||
assign bar.baz.x = 1;
|
||||
assign bar.baz.z = 1;
|
||||
endmodule
|
14
tests/simple/nested_genblk_resolve.v
Normal file
14
tests/simple/nested_genblk_resolve.v
Normal file
|
@ -0,0 +1,14 @@
|
|||
`default_nettype none
|
||||
module top;
|
||||
generate
|
||||
if (1) begin
|
||||
wire x;
|
||||
genvar i;
|
||||
for (i = 0; i < 1; i = i + 1) begin
|
||||
if (1) begin
|
||||
assign x = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
17
tests/simple/unnamed_block_decl.sv
Normal file
17
tests/simple/unnamed_block_decl.sv
Normal file
|
@ -0,0 +1,17 @@
|
|||
module top(z);
|
||||
output integer z;
|
||||
initial begin
|
||||
integer x;
|
||||
x = 1;
|
||||
begin
|
||||
integer y;
|
||||
y = x + 1;
|
||||
begin
|
||||
integer z;
|
||||
z = y + 1;
|
||||
y = z + 1;
|
||||
end
|
||||
z = y + 1;
|
||||
end
|
||||
end
|
||||
endmodule
|
|
@ -1,13 +1,17 @@
|
|||
module test(x, y, z);
|
||||
`default_nettype none
|
||||
module test;
|
||||
localparam OFF = 0;
|
||||
generate
|
||||
if (OFF) ;
|
||||
else input x;
|
||||
if (!OFF) input y;
|
||||
else wire x;
|
||||
if (!OFF) wire y;
|
||||
else ;
|
||||
if (OFF) ;
|
||||
else ;
|
||||
if (OFF) ;
|
||||
input z;
|
||||
wire z;
|
||||
endgenerate
|
||||
assign genblk1.x = 0;
|
||||
assign genblk2.y = 0;
|
||||
assign z = 0;
|
||||
endmodule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
read_verilog gen_if_null.v
|
||||
select -assert-count 1 test/x
|
||||
select -assert-count 1 test/y
|
||||
select -assert-count 1 test/genblk1.x
|
||||
select -assert-count 1 test/genblk2.y
|
||||
select -assert-count 1 test/z
|
||||
|
|
12
tests/verilog/bug2493.ys
Normal file
12
tests/verilog/bug2493.ys
Normal file
|
@ -0,0 +1,12 @@
|
|||
logger -expect error "Failed to detect width for identifier \\genblk1\.y!" 1
|
||||
read_verilog <<EOT
|
||||
module top1;
|
||||
wire x;
|
||||
generate
|
||||
if (1) begin
|
||||
mod y();
|
||||
assign x = y;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
EOT
|
21
tests/verilog/bug656.v
Normal file
21
tests/verilog/bug656.v
Normal file
|
@ -0,0 +1,21 @@
|
|||
module top #(
|
||||
parameter WIDTH = 6
|
||||
) (
|
||||
input [WIDTH-1:0] a_i,
|
||||
input [WIDTH-1:0] b_i,
|
||||
output [WIDTH-1:0] z_o
|
||||
);
|
||||
genvar g;
|
||||
generate
|
||||
for (g = 0; g < WIDTH; g = g + 1) begin
|
||||
if (g > 2) begin
|
||||
wire tmp;
|
||||
assign tmp = a_i[g] || b_i[g];
|
||||
assign z_o[g] = tmp;
|
||||
end
|
||||
else begin
|
||||
assign z_o[g] = a_i[g] && b_i[g];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
13
tests/verilog/bug656.ys
Normal file
13
tests/verilog/bug656.ys
Normal file
|
@ -0,0 +1,13 @@
|
|||
read_verilog bug656.v
|
||||
|
||||
select -assert-count 1 top/a_i
|
||||
select -assert-count 1 top/b_i
|
||||
select -assert-count 1 top/z_o
|
||||
|
||||
select -assert-none top/genblk1[0].genblk1.tmp
|
||||
select -assert-none top/genblk1[1].genblk1.tmp
|
||||
select -assert-none top/genblk1[2].genblk1.tmp
|
||||
|
||||
select -assert-count 1 top/genblk1[3].genblk1.tmp
|
||||
select -assert-count 1 top/genblk1[4].genblk1.tmp
|
||||
select -assert-count 1 top/genblk1[5].genblk1.tmp
|
26
tests/verilog/genblk_case.v
Normal file
26
tests/verilog/genblk_case.v
Normal file
|
@ -0,0 +1,26 @@
|
|||
module top;
|
||||
parameter YES = 1;
|
||||
generate
|
||||
if (YES) wire y;
|
||||
else wire n;
|
||||
|
||||
if (!YES) wire n;
|
||||
else wire y;
|
||||
|
||||
case (YES)
|
||||
1: wire y;
|
||||
0: wire n;
|
||||
endcase
|
||||
|
||||
case (!YES)
|
||||
0: wire y;
|
||||
1: wire n;
|
||||
endcase
|
||||
|
||||
if (YES) wire y;
|
||||
else wire n;
|
||||
|
||||
if (!YES) wire n;
|
||||
else wire y;
|
||||
endgenerate
|
||||
endmodule
|
15
tests/verilog/genblk_case.ys
Normal file
15
tests/verilog/genblk_case.ys
Normal file
|
@ -0,0 +1,15 @@
|
|||
read_verilog genblk_case.v
|
||||
|
||||
select -assert-count 0 top/genblk1.n
|
||||
select -assert-count 0 top/genblk2.n
|
||||
select -assert-count 0 top/genblk3.n
|
||||
select -assert-count 0 top/genblk4.n
|
||||
select -assert-count 0 top/genblk5.n
|
||||
select -assert-count 0 top/genblk6.n
|
||||
|
||||
select -assert-count 1 top/genblk1.y
|
||||
select -assert-count 1 top/genblk2.y
|
||||
select -assert-count 1 top/genblk3.y
|
||||
select -assert-count 1 top/genblk4.y
|
||||
select -assert-count 1 top/genblk5.y
|
||||
select -assert-count 1 top/genblk6.y
|
11
tests/verilog/hidden_decl.ys
Normal file
11
tests/verilog/hidden_decl.ys
Normal file
|
@ -0,0 +1,11 @@
|
|||
logger -expect error "Identifier `\\y' is implicitly declared and `default_nettype is set to none" 1
|
||||
read_verilog <<EOT
|
||||
`default_nettype none
|
||||
module top1;
|
||||
wire x;
|
||||
generate
|
||||
if (1) wire y;
|
||||
endgenerate
|
||||
assign x = y;
|
||||
endmodule
|
||||
EOT
|
28
tests/verilog/unnamed_block.ys
Normal file
28
tests/verilog/unnamed_block.ys
Normal file
|
@ -0,0 +1,28 @@
|
|||
read_verilog <<EOT
|
||||
module top;
|
||||
initial begin : blk
|
||||
integer x;
|
||||
end
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
delete
|
||||
|
||||
read_verilog -sv <<EOT
|
||||
module top;
|
||||
initial begin
|
||||
integer x;
|
||||
end
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
delete
|
||||
|
||||
logger -expect error "Local declaration in unnamed block is only supported in SystemVerilog mode!" 1
|
||||
read_verilog <<EOT
|
||||
module top;
|
||||
initial begin
|
||||
integer x;
|
||||
end
|
||||
endmodule
|
||||
EOT
|
39
tests/verilog/unnamed_genblk.sv
Normal file
39
tests/verilog/unnamed_genblk.sv
Normal file
|
@ -0,0 +1,39 @@
|
|||
// This test is taken directly from Section 27.6 of IEEE 1800-2017
|
||||
|
||||
module top;
|
||||
parameter genblk2 = 0;
|
||||
genvar i;
|
||||
|
||||
// The following generate block is implicitly named genblk1
|
||||
|
||||
if (genblk2) logic a; // top.genblk1.a
|
||||
else logic b; // top.genblk1.b
|
||||
|
||||
// The following generate block is implicitly named genblk02
|
||||
// as genblk2 is already a declared identifier
|
||||
|
||||
if (genblk2) logic a; // top.genblk02.a
|
||||
else logic b; // top.genblk02.b
|
||||
|
||||
// The following generate block would have been named genblk3
|
||||
// but is explicitly named g1
|
||||
|
||||
for (i = 0; i < 1; i = i + 1) begin : g1 // block name
|
||||
// The following generate block is implicitly named genblk1
|
||||
// as the first nested scope inside g1
|
||||
if (1) logic a; // top.g1[0].genblk1.a
|
||||
end
|
||||
|
||||
// The following generate block is implicitly named genblk4 since
|
||||
// it belongs to the fourth generate construct in scope "top".
|
||||
// The previous generate block would have been
|
||||
// named genblk3 if it had not been explicitly named g1
|
||||
|
||||
for (i = 0; i < 1; i = i + 1)
|
||||
// The following generate block is implicitly named genblk1
|
||||
// as the first nested generate block in genblk4
|
||||
if (1) logic a; // top.genblk4[0].genblk1.a
|
||||
|
||||
// The following generate block is implicitly named genblk5
|
||||
if (1) logic a; // top.genblk5.a
|
||||
endmodule
|
8
tests/verilog/unnamed_genblk.ys
Normal file
8
tests/verilog/unnamed_genblk.ys
Normal file
|
@ -0,0 +1,8 @@
|
|||
read_verilog -sv unnamed_genblk.sv
|
||||
select -assert-count 0 top/genblk1.a
|
||||
select -assert-count 1 top/genblk02.b
|
||||
select -assert-count 0 top/genblk1.a
|
||||
select -assert-count 1 top/genblk02.b
|
||||
select -assert-count 1 top/g1[0].genblk1.a
|
||||
select -assert-count 1 top/genblk4[0].genblk1.a
|
||||
select -assert-count 1 top/genblk5.a
|
Loading…
Add table
Add a link
Reference in a new issue