3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-13 04:28:18 +00:00

verilog: fix size and signedness of array querying functions

genrtlil.cc and simplify.cc had inconsistent and slightly broken
handling of signedness for array querying functions. These functions are
defined to return a signed result. Simplify always produced an unsigned
and genrtlil always a signed 32-bit result ignoring the context.

Includes tests for the the relvant edge cases for context dependent
conversions.
This commit is contained in:
Jannis Harder 2022-05-20 21:46:39 +02:00 committed by Zachary Snow
parent ce24208a8b
commit 4bfaaea0d5
4 changed files with 56 additions and 3 deletions

View file

@ -12,6 +12,8 @@ Yosys 0.17 .. Yosys 0.17-dev
- Fixed an issue where simplifying case statements by removing unreachable - Fixed an issue where simplifying case statements by removing unreachable
cases could result in the wrong signedness being used for comparison with cases could result in the wrong signedness being used for comparison with
the remaining cases the remaining cases
- Fixed size and signedness computation for expressions containing array
querying functions
Yosys 0.16 .. Yosys 0.17 Yosys 0.16 .. Yosys 0.17
-------------------------- --------------------------

View file

@ -1089,8 +1089,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
break; break;
} }
if (str == "\\$size" || str == "\\$bits" || str == "\\$high" || str == "\\$low" || str == "\\$left" || str == "\\$right") { if (str == "\\$size" || str == "\\$bits" || str == "\\$high" || str == "\\$low" || str == "\\$left" || str == "\\$right") {
width_hint = 32; width_hint = max(width_hint, 32);
sign_hint = true;
break; break;
} }
if (current_scope.count(str)) if (current_scope.count(str))

View file

@ -3450,7 +3450,7 @@ skip_dynamic_range_lvalue_expansion:;
else { else {
result = width * mem_depth; result = width * mem_depth;
} }
newNode = mkconst_int(result, false); newNode = mkconst_int(result, true);
goto apply_newNode; goto apply_newNode;
} }

View file

@ -0,0 +1,52 @@
logger -expect-no-warnings
read_verilog -formal <<EOT
module top(input clk);
reg [-1:-1] x;
reg good = 0;
reg signed [31:0] zero = 0;
always @(posedge clk) begin
case ($left(x) + zero) 36'shfffffffff: good = 1; 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 [-1:-1] x;
reg good = 0;
always @(posedge clk) begin
case ($left(x)) 36'sh0ffffffff: good = 1; (32'h0 + $left(good)): ; 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 [-1:-1] x;
reg good = 1;
always @(posedge clk) begin
case (36'sh100000000 + $left(x)) -1: good = 0; endcase
assert (good);
end
endmodule
EOT
prep -top top
sim -n 3 -clock clk