From a5f4b836376e1457847da4946c1e12d2d41dc4f4 Mon Sep 17 00:00:00 2001
From: Zachary Snow <zach@zachjs.com>
Date: Mon, 18 Mar 2019 20:34:21 -0400
Subject: [PATCH] fix local name resolution in prefix constructs

---
 frontends/ast/simplify.cc |  6 +++-
 tests/simple/generate.v   | 58 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 1c9932ee0..d525c6b8a 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -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);
 	}
 
diff --git a/tests/simple/generate.v b/tests/simple/generate.v
index 24eb4462c..3c55682cb 100644
--- a/tests/simple/generate.v
+++ b/tests/simple/generate.v
@@ -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