aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG2
-rw-r--r--frontends/ast/genrtlil.cc3
-rw-r--r--frontends/ast/simplify.cc2
-rw-r--r--tests/verilog/sign_array_query.ys52
4 files changed, 56 insertions, 3 deletions
diff --git a/CHANGELOG b/CHANGELOG
index d64d592d2..4ee364a57 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,8 @@ Yosys 0.17 .. Yosys 0.17-dev
- 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
+ - Fixed size and signedness computation for expressions containing array
+ querying functions
Yosys 0.16 .. Yosys 0.17
--------------------------
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 6ef7da7a9..a569c5ae2 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -1089,8 +1089,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
break;
}
if (str == "\\$size" || str == "\\$bits" || str == "\\$high" || str == "\\$low" || str == "\\$left" || str == "\\$right") {
- width_hint = 32;
- sign_hint = true;
+ width_hint = max(width_hint, 32);
break;
}
if (current_scope.count(str))
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index c2adcafd0..2d9d6dc79 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -3450,7 +3450,7 @@ skip_dynamic_range_lvalue_expansion:;
else {
result = width * mem_depth;
}
- newNode = mkconst_int(result, false);
+ newNode = mkconst_int(result, true);
goto apply_newNode;
}
diff --git a/tests/verilog/sign_array_query.ys b/tests/verilog/sign_array_query.ys
new file mode 100644
index 000000000..f955450b7
--- /dev/null
+++ b/tests/verilog/sign_array_query.ys
@@ -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