3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-23 00:55:32 +00:00

sv: support assignments within expressions

- Add support for assignments within expressions, e.g., `x[y++] = z;` or
  `x = (y *= 2) - 1;`. The logic is handled entirely within the parser
  by injecting statements into the current procedural block.
- Add support for pre-increment/decrement statements, which are
  behaviorally equivalent to post-increment/decrement statements.
- Fix non-standard attribute position used for post-increment/decrement
  statements.
This commit is contained in:
Zachary Snow 2023-09-05 22:19:28 -04:00
parent 83b1a57eed
commit 4edb1a1921
15 changed files with 231 additions and 24 deletions

View file

@ -0,0 +1,60 @@
module top;
integer x, y, z;
task check;
input integer a, b, c;
assert (x == a);
assert (y == b);
assert (z == c);
endtask
always_comb begin
x = 0; y = 0; z = 0;
check(0, 0, 0);
// post-increment/decrement statements
x++;
check(1, 0, 0);
y (* foo *) ++;
check(1, 1, 0);
z--;
check(1, 1, -1);
z (* foo *) --;
check(1, 1, -2);
// pre-increment/decrement statements are equivalent
++z;
check(1, 1, -1);
++ (* foo *) z;
check(1, 1, 0);
--x;
check(0, 1, 0);
-- (* foo *) y;
check(0, 0, 0);
// procedural pre-increment/decrement expressions
z = ++x;
check(1, 0, 1);
z = ++ (* foo *) x;
check(2, 0, 2);
y = --x;
check(1, 1, 2);
y = -- (* foo *) x;
// procedural post-increment/decrement expressions
// TODO: support attributes on post-increment/decrement
check(0, 0, 2);
y = x++;
check(1, 0, 2);
y = x--;
check(0, 1, 2);
// procedural assignment expressions
x = (y = (z = 99) + 1) + 1;
check(101, 100, 99);
x = (y *= 2);
check(200, 200, 99);
x = (z >>= 2) * 4;
check(96, 200, 24);
y = (z >>= 1'sb1) * 2; // shift is implicitly cast to unsigned
check(96, 24, 12);
end
endmodule

View file

@ -0,0 +1,3 @@
read_verilog -sv asgn_expr.sv
proc
sat -verify -prove-asserts -show-all

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only permitted within procedures." 1
read_verilog -sv <<EOF
module top;
integer x, y;
assign x = y++;
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only permitted within procedures." 1
read_verilog -sv <<EOF
module top;
integer x;
wire [++x:0] y;
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only permitted within procedures." 1
read_verilog -sv <<EOF
module top;
integer x;
integer y = --x;
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only permitted within procedures." 1
read_verilog -sv <<EOF
module top;
integer x, y;
assign x = (y = 1);
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only permitted within procedures." 1
read_verilog -sv <<EOF
module top;
integer x, y;
assign x = (y += 2);
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only supported in SystemVerilog mode." 1
read_verilog <<EOF
module top;
integer x, y;
initial y = ++x;
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only supported in SystemVerilog mode." 1
read_verilog <<EOF
module top;
integer x, y;
initial y = x++;
endmodule
EOF

View file

@ -0,0 +1,7 @@
logger -expect error "Assignments within expressions are only supported in SystemVerilog mode." 1
read_verilog <<EOF
module top;
integer x, y;
initial y = (x = 1);
endmodule
EOF

View file

@ -0,0 +1,15 @@
read_verilog -sv <<EOF
module top;
integer x, y;
initial y = (x += 1);
endmodule
EOF
design -reset
logger -expect error "syntax error, unexpected TOK_ID" 1
read_verilog <<EOF
module top;
integer x, y;
initial y = (x += 1);
endmodule
EOF

View file

@ -15,7 +15,7 @@ EOT
select -assert-none a:* a:src %d
logger -expect error "syntax error, unexpected ATTR_BEGIN" 1
logger -expect error "syntax error, unexpected ';', expecting ATTR_BEGIN or TOK_INCREMENT or TOK_DECREMENT" 1
design -reset
read_verilog <<EOT
module top;