Allow constant function calls in for loops and generate if and case
authorZachary Snow <zach@zachjs.com>
Sat, 27 Jun 2020 02:52:36 +0000 (19:52 -0700)
committerZachary Snow <zach@zachjs.com>
Mon, 29 Jun 2020 22:06:17 +0000 (16:06 -0600)
frontends/ast/simplify.cc
tests/various/const_func.v [new file with mode: 0644]
tests/various/const_func.ys [new file with mode: 0644]

index 55e7da0aa88669e99b99612ce0fe2977aa8f4e55..c819924a00c24af1571bbbbf21da3851c815ef80 100644 (file)
@@ -1126,6 +1126,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                        bool in_param_here = in_param;
                        if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE))
                                const_fold_here = true, in_param_here = true;
+                       if (i == 0 && (type == AST_GENIF || type == AST_GENCASE))
+                               in_param_here = true;
+                       if (i == 1 && (type == AST_FOR || type == AST_GENFOR))
+                               in_param_here = true;
                        if (type == AST_PARAMETER || type == AST_LOCALPARAM)
                                const_fold_here = true;
                        if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
@@ -1942,7 +1946,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                                        continue;
 
                                buf = child->clone();
-                               while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
+                               while (buf->simplify(true, false, false, stage, width_hint, sign_hint, true)) { }
                                if (buf->type != AST_CONSTANT) {
                                        // for (auto f : log_files)
                                        //      dumpAst(f, "verilog-ast> ");
diff --git a/tests/various/const_func.v b/tests/various/const_func.v
new file mode 100644 (file)
index 0000000..76cdc38
--- /dev/null
@@ -0,0 +1,75 @@
+module Example(outA, outB, outC, outD);
+    parameter OUTPUT = "FOO";
+    output wire [23:0] outA;
+    output wire [23:0] outB;
+    output reg outC, outD;
+    function automatic [23:0] flip;
+        input [23:0] inp;
+        flip = ~inp;
+    endfunction
+
+    generate
+        if (flip(OUTPUT) == flip("BAR"))
+            assign outA = OUTPUT;
+        else
+            assign outA = 0;
+
+        case (flip(OUTPUT))
+            flip("FOO"): assign outB = OUTPUT;
+            flip("BAR"): assign outB = 0;
+            flip("BAZ"): assign outB = "HI";
+        endcase
+
+        genvar i;
+        initial outC = 0;
+        for (i = 0; i != flip(flip(OUTPUT[15:8])); i = i + 1)
+            if (i + 1 == flip(flip("O")))
+                initial outC = 1;
+    endgenerate
+
+    integer j;
+    initial begin
+        outD = 1;
+        for (j = 0; j != flip(flip(OUTPUT[15:8])); j = j + 1)
+            if (j + 1 == flip(flip("O")))
+                outD = 0;
+    end
+endmodule
+
+module top(out);
+    wire [23:0] a1, a2, a3, a4;
+    wire [23:0] b1, b2, b3, b4;
+    wire        c1, c2, c3, c4;
+    wire        d1, d2, d3, d4;
+    Example          e1(a1, b1, c1, d1);
+    Example #("FOO") e2(a2, b2, c2, d2);
+    Example #("BAR") e3(a3, b3, c3, d3);
+    Example #("BAZ") e4(a4, b4, c4, d4);
+
+    output wire [24 * 8 - 1 + 4 :0] out;
+    assign out = {
+        a1, a2, a3, a4,
+        b1, b2, b3, b4,
+        c1, c2, c3, c4,
+        d1, d2, d3, d4};
+
+// `define VERIFY
+`ifdef VERIFY
+    assert property (a1 == 0);
+    assert property (a2 == 0);
+    assert property (a3 == "BAR");
+    assert property (a4 == 0);
+    assert property (b1 == "FOO");
+    assert property (b2 == "FOO");
+    assert property (b3 == 0);
+    assert property (b4 == "HI");
+    assert property (c1 == 1);
+    assert property (c2 == 1);
+    assert property (c3 == 0);
+    assert property (c4 == 0);
+    assert property (d1 == 0);
+    assert property (d2 == 0);
+    assert property (d3 == 1);
+    assert property (d4 == 1);
+`endif
+endmodule
diff --git a/tests/various/const_func.ys b/tests/various/const_func.ys
new file mode 100644 (file)
index 0000000..5e3c041
--- /dev/null
@@ -0,0 +1 @@
+read_verilog const_func.v