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:
parent
ce24208a8b
commit
4bfaaea0d5
|
@ -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
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
tests/verilog/sign_array_query.ys
Normal file
52
tests/verilog/sign_array_query.ys
Normal 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
|
Loading…
Reference in a new issue