verilog: fix signedness when removing unreachable cases

This commit is contained in:
Jannis Harder 2022-05-24 14:32:14 +02:00 committed by Zachary Snow
parent c525b5f919
commit cffec1f95f
3 changed files with 39 additions and 0 deletions

View File

@ -5,6 +5,11 @@ List of major changes and improvements between releases
Yosys 0.17 .. Yosys 0.17-dev Yosys 0.17 .. Yosys 0.17-dev
-------------------------- --------------------------
* Verilog
- Fixed an issue where simplifying case statements by removing unreachable
cases could result in the wrong signedness being used for comparison with
the remaining cases
Yosys 0.16 .. Yosys 0.17 Yosys 0.16 .. Yosys 0.17
-------------------------- --------------------------
* New commands and options * New commands and options

View File

@ -1531,6 +1531,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
detectSignWidth(width_hint, sign_hint); detectSignWidth(width_hint, sign_hint);
while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { } while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) { if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) {
children[0]->is_signed = sign_hint;
RTLIL::Const case_expr = children[0]->bitsAsConst(width_hint, sign_hint); RTLIL::Const case_expr = children[0]->bitsAsConst(width_hint, sign_hint);
std::vector<AstNode*> new_children; std::vector<AstNode*> new_children;
new_children.push_back(children[0]); new_children.push_back(children[0]);

View File

@ -0,0 +1,33 @@
logger -expect-no-warnings
read_verilog -formal <<EOT
module top(input clk);
reg good = 0;
always @(posedge clk) begin
case (4'sb1111) 15: good = 1; 4'b0000: ; endcase
assert (good);
end
endmodule
EOT
prep -top top
sim -n 3 -clock clk
design -reset
read_verilog -formal <<EOT
module top(input clk);
reg good = 1;
reg signed [1:0] case_value = -1;
always @(posedge clk) begin
case (4'sb1111) 4'b0000: ; case_value: good = 0; endcase
assert (good);
end
endmodule
EOT
prep -top top
sim -n 3 -clock clk