summarylogtreecommitdiffstats
path: root/0001-verilog-port-renaming.patch
blob: 568b35da7cc858f4dbe26e2f2137bddae7d8ae54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
From 00e488ef4d53c44c1692a7f0d1c26eef295ef1d3 Mon Sep 17 00:00:00 2001
From: xiota <>
Date: Sat, 18 Oct 2025 00:48:23 +0000
Subject: verilog_parser: add port renaming

---
 frontends/verilog/verilog_parser.y | 50 ++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index ef8427679..d27cf1003 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -98,6 +98,11 @@
 			bool isInLocalScope(const std::string *name);
 			void rewriteGenForDeclInit(AstNode *loop);
 			void ensureAsgnExprAllowed(const parser::location_type loc, bool sv_mode);
+
+			// for header port renames (.alias(real))
+			dict<std::string,std::string> port_rename_assigns;
+			std::vector<std::string> port_rename_wires;
+
 			const AstNode *addIncOrDecStmt(std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> stmt_attr,
 									std::unique_ptr<AstNode> lhs,
 									std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> op_attr, AST::AstNodeType op,
@@ -700,12 +705,31 @@ module:
 		extra->current_ast_mod = mod;
 		extra->port_stubs.clear();
 		extra->port_counter = 0;
+		extra->port_rename_assigns.clear();
+		extra->port_rename_wires.clear();
 		mod->str = *$4;
 		append_attr(mod, std::move($1));
 	} module_para_opt module_args_opt TOK_SEMICOL module_body TOK_ENDMODULE opt_label {
 		if (extra->port_stubs.size() != 0)
-			err_at_loc(@7, "Missing details for module port `%s'.",
-					extra->port_stubs.begin()->first.c_str());
+			err_at_loc(@7, "Missing details for module port `%s'.", extra->port_stubs.begin()->first.c_str());
+
+		// inject alias wires and assignments for header renames
+		for (auto &alias : extra->port_rename_wires) {
+			auto w = std::make_unique<AstNode>(@7, AST_WIRE);
+			w->str = alias;
+			extra->ast_stack.back()->children.push_back(std::move(w));
+		}
+		for (auto &kv : extra->port_rename_assigns) {
+			const std::string &real = kv.first;
+			const std::string &alias = kv.second;
+			auto lhs = std::make_unique<AstNode>(@7, AST_IDENTIFIER);
+			auto rhs = std::make_unique<AstNode>(@7, AST_IDENTIFIER);
+			lhs->str = alias;
+			rhs->str = real;
+			auto asn = std::make_unique<AstNode>(@7, AST_ASSIGN, std::move(lhs), std::move(rhs));
+			extra->ast_stack.back()->children.push_back(std::move(asn));
+		}
+
 		SET_AST_NODE_LOC(extra->ast_stack.back(), @2, @$);
 		extra->ast_stack.pop_back();
 		log_assert(extra->ast_stack.size() == 1);
@@ -805,6 +829,13 @@ module_arg:
 	} module_arg_opt_assignment |
 	TOK_DOT TOK_DOT TOK_DOT {
 		extra->do_not_require_port_stubs = true;
+	} |
+	TOK_DOT TOK_ID TOK_LPAREN TOK_ID TOK_RPAREN {
+		// header‑side alias: .alias(real)
+		extra->port_rename_assigns[*$4] = *$2;
+		extra->port_rename_wires.push_back(*$4);
+		extra->port_stubs[*$2] = ++extra->port_counter;
+		extra->port_stubs[*$4] = extra->port_counter;
 	};
 
 package:
@@ -2166,7 +2197,22 @@ wire_name:
 					err_at_loc(@1, "Module port `%s' is neither input nor output.", *$1);
 				if (node->is_reg && node->is_input && !node->is_output && !mode->sv)
 					err_at_loc(@1, "Input port `%s' is declared as register.", *$1);
+
 				node->port_id = extra->port_stubs[*$1];
+				// check if there is an alias with same port_id
+				for (auto it = extra->port_stubs.begin(); it != extra->port_stubs.end(); ) {
+					if (it->second == node->port_id && it->first != *$1) {
+						node->str = it->first;
+						it = extra->port_stubs.erase(it);
+						// flip mapping for outputs
+						if (node->is_output) {
+							extra->port_rename_assigns[node->str] = *$1;
+						}
+						break;
+					} else {
+						++it;
+					}
+				}
 				extra->port_stubs.erase(*$1);
 			} else {
 				if (node->is_input || node->is_output)
-- 
2.51.1.dirty