fix width detection of array querying function in case and case item expressions
authorZachary Snow <zach@zachjs.com>
Thu, 16 Dec 2021 01:15:09 +0000 (18:15 -0700)
committerZachary Snow <zachary.j.snow@gmail.com>
Sat, 18 Dec 2021 04:22:08 +0000 (21:22 -0700)
I also removed the unnecessary shadowing of `width_hint` and `sign_hint`
in the corresponding case in `simplify()`.

CHANGELOG
frontends/ast/genrtlil.cc
frontends/ast/simplify.cc
tests/simple/case_expr_extend.sv [new file with mode: 0644]
tests/simple/case_expr_query.sv [new file with mode: 0644]

index 902fe727b42adafe084139eff4c325ce2fd78b33..ab1632a09b6983cec1d8f2189abffa106eb79584 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,8 @@ Yosys 0.11 .. Yosys 0.12
 
  * SystemVerilog
     - Support parameters using struct as a wiretype
+    - Fixed regression preventing the use array querying functions in case
+      expressions and case item expressions
 
  * New commands and options
     - Added "-genlib" option to "abc" pass
index ed709aa33d34c726a2e3fecc5c78208c55849197..1fe74bb729a3406b5a22f7fa3d1a598e71555ed0 100644 (file)
@@ -1087,6 +1087,11 @@ 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;
+                       break;
+               }
                if (current_scope.count(str))
                {
                        // This width detection is needed for function calls which are
index 777f46bd7d3b55d73a25b6b95be17de57e6dcb6f..cb47e641aaab9e45704e2393203bceec093fd402 100644 (file)
@@ -1389,8 +1389,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 
        if (const_fold && type == AST_CASE)
        {
-               int width_hint;
-               bool sign_hint;
                detectSignWidth(width_hint, sign_hint);
                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()) {
diff --git a/tests/simple/case_expr_extend.sv b/tests/simple/case_expr_extend.sv
new file mode 100644 (file)
index 0000000..61bd14d
--- /dev/null
@@ -0,0 +1,11 @@
+module top(
+    output logic [5:0] out
+);
+always_comb begin
+    out = '0;
+    case (1'b1 << 1)
+        2'b10: out = '1;
+        default: out = '0;
+    endcase
+end
+endmodule
diff --git a/tests/simple/case_expr_query.sv b/tests/simple/case_expr_query.sv
new file mode 100644 (file)
index 0000000..63a0a8b
--- /dev/null
@@ -0,0 +1,32 @@
+module top(
+    output logic [5:0] out
+);
+always_comb begin
+    out = '0;
+    case ($bits (out)) 6:
+    case ($size (out)) 6:
+    case ($high (out)) 5:
+    case ($low  (out)) 0:
+    case ($left (out)) 5:
+    case ($right(out)) 0:
+    case (6) $bits (out):
+    case (6) $size (out):
+    case (5) $high (out):
+    case (0) $low  (out):
+    case (5) $left (out):
+    case (0) $right(out):
+        out = '1;
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+    endcase
+end
+endmodule