fix local name resolution in prefix constructs
authorZachary Snow <zach@zachjs.com>
Tue, 19 Mar 2019 00:34:21 +0000 (20:34 -0400)
committerZachary Snow <zach@zachjs.com>
Tue, 19 Mar 2019 00:43:20 +0000 (20:43 -0400)
frontends/ast/simplify.cc
tests/simple/generate.v

index 1c9932ee0913eee8dacfff8728fcd2f8eb6d3986..d525c6b8a8fc864d781290ebcb7343bc2a0d106f 100644 (file)
@@ -2863,7 +2863,11 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
 
        for (size_t i = 0; i < children.size(); i++) {
                AstNode *child = children[i];
-               if (child->type != AST_FUNCTION && child->type != AST_TASK && child->type != AST_PREFIX)
+               // AST_PREFIX member names should not be prefixed; a nested AST_PREFIX
+               // still needs to recursed-into
+               if (type == AST_PREFIX && i == 1 && child->type == AST_IDENTIFIER)
+                       continue;
+               if (child->type != AST_FUNCTION && child->type != AST_TASK)
                        child->expand_genblock(index_var, prefix, name_map);
        }
 
index 24eb4462cd5d159aa63ee069e82ad99b98df3540..3c55682cbfce8982dba4a6cd5cf8ead71a9921dd 100644 (file)
@@ -90,5 +90,61 @@ generate
                endcase
        end
 endgenerate
+endmodule
+
+// ------------------------------------------
+
+module gen_test4(a, b);
+
+input [3:0] a;
+output [3:0] b;
+
+genvar i;
+generate
+       for (i=0; i < 3; i=i+1) begin : foo
+               localparam PREV = i - 1;
+               wire temp;
+               if (i == 0)
+                       assign temp = a[0];
+               else
+                       assign temp = foo[PREV].temp & a[i];
+               assign b[i] = temp;
+       end
+endgenerate
+endmodule
+
+// ------------------------------------------
+
+module gen_test5(input_bits, out);
+
+parameter WIDTH = 256;
+parameter CHUNK = 4;
 
+input [WIDTH-1:0] input_bits;
+output out;
+
+genvar step, i, j;
+generate
+       for (step = 1; step <= WIDTH; step = step * CHUNK) begin : steps
+               localparam PREV = step / CHUNK;
+               localparam DIM = WIDTH / step;
+               for (i = 0; i < DIM; i = i + 1) begin : outer
+                       localparam LAST_START = i * CHUNK;
+                       for (j = 0; j < CHUNK; j = j + 1) begin : inner
+                               wire temp;
+                               if (step == 1)
+                                       assign temp = input_bits[i];
+                               else if (j == 0)
+                                       assign temp = steps[PREV].outer[LAST_START].val;
+                               else
+                                       assign temp
+                                               = steps[step].outer[i].inner[j-1].temp
+                                               & steps[PREV].outer[LAST_START + j].val;
+                       end
+                       wire val;
+                       assign val = steps[step].outer[i].inner[CHUNK - 1].temp;
+               end
+       end
+endgenerate
+assign out = steps[WIDTH].outer[0].val;
 endmodule