From 5b989b53f59070d6e946f367744b2f5279f37272 Mon Sep 17 00:00:00 2001 From: xiota Date: Sat, 18 Oct 2025 00:48:23 +0000 Subject: [PATCH 1/2] 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 ef8427679f4..d27cf1003a4 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 port_rename_assigns; + std::vector port_rename_wires; + const AstNode *addIncOrDecStmt(std::unique_ptr>> stmt_attr, std::unique_ptr lhs, std::unique_ptr>> 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(@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(@7, AST_IDENTIFIER); + auto rhs = std::make_unique(@7, AST_IDENTIFIER); + lhs->str = alias; + rhs->str = real; + auto asn = std::make_unique(@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) From 60ae44dae8c5ba55e9f82aa50e46311fd2c498cc Mon Sep 17 00:00:00 2001 From: xiota Date: Sat, 18 Oct 2025 01:03:41 +0000 Subject: [PATCH 2/2] verilog_parser: add port renaming tests --- tests/verilog/port_rename_equivalence.ys | 22 ++++++++++++++++++++++ tests/verilog/port_rename_error_1.ys | 12 ++++++++++++ tests/verilog/port_rename_error_2.ys | 12 ++++++++++++ tests/verilog/port_rename_error_3.ys | 15 +++++++++++++++ tests/verilog/port_rename_error_4.ys | 16 ++++++++++++++++ tests/verilog/port_rename_error_5.ys | 14 ++++++++++++++ tests/verilog/port_rename_pass_1.ys | 14 ++++++++++++++ 7 files changed, 105 insertions(+) create mode 100644 tests/verilog/port_rename_equivalence.ys create mode 100644 tests/verilog/port_rename_error_1.ys create mode 100644 tests/verilog/port_rename_error_2.ys create mode 100644 tests/verilog/port_rename_error_3.ys create mode 100644 tests/verilog/port_rename_error_4.ys create mode 100644 tests/verilog/port_rename_error_5.ys create mode 100644 tests/verilog/port_rename_pass_1.ys diff --git a/tests/verilog/port_rename_equivalence.ys b/tests/verilog/port_rename_equivalence.ys new file mode 100644 index 00000000000..5dde84dbe53 --- /dev/null +++ b/tests/verilog/port_rename_equivalence.ys @@ -0,0 +1,22 @@ +# Equivalence +read_verilog << EOF +module gold(input a, input b, output c); + assign c = a + b; +endmodule + +module gate_header ( + .a(x), + .b(y), + .c(z) +); + input x; + input y; + output z; + + assign z = x + y; +endmodule +EOF + +equiv_make gold gate_header equiv_header +equiv_simple +equiv_status -assert diff --git a/tests/verilog/port_rename_error_1.ys b/tests/verilog/port_rename_error_1.ys new file mode 100644 index 00000000000..a0b36163f4a --- /dev/null +++ b/tests/verilog/port_rename_error_1.ys @@ -0,0 +1,12 @@ +# Multiple names for the same inout port +logger -expect error "Missing details for module port" 1 +read_verilog << EOF +module gate_multi_inout ( + .i(a), + .o(a) +); + inout a; +endmodule +EOF +logger -check-expected +design -reset diff --git a/tests/verilog/port_rename_error_2.ys b/tests/verilog/port_rename_error_2.ys new file mode 100644 index 00000000000..b635022a0ad --- /dev/null +++ b/tests/verilog/port_rename_error_2.ys @@ -0,0 +1,12 @@ +# Multiple names for the same input port +logger -expect error "Missing details for module port" 1 +read_verilog << EOF +module gate_multi_inout ( + .i(a), + .j(a) +); + input a; +endmodule +EOF +logger -check-expected +design -reset diff --git a/tests/verilog/port_rename_error_3.ys b/tests/verilog/port_rename_error_3.ys new file mode 100644 index 00000000000..b2867fbb030 --- /dev/null +++ b/tests/verilog/port_rename_error_3.ys @@ -0,0 +1,15 @@ +# Multiple names for an output port +logger -expect error "Missing details for module port" 1 +read_verilog << EOF +module gate_multi_output ( + a, + .c(b), + .b(b) +); + input a; + output b; + assign b = a; +endmodule +EOF +logger -check-expected +design -reset diff --git a/tests/verilog/port_rename_error_4.ys b/tests/verilog/port_rename_error_4.ys new file mode 100644 index 00000000000..e75acceaef0 --- /dev/null +++ b/tests/verilog/port_rename_error_4.ys @@ -0,0 +1,16 @@ +# Swapping names for two ports +logger -expect error "not declared in module header" 1 +read_verilog << EOF +module gate_swap ( + .a(b), + .b(a), + c +); + input a; + input b; + output c; + assign c = a & !b; +endmodule +EOF +logger -check-expected +design -reset diff --git a/tests/verilog/port_rename_error_5.ys b/tests/verilog/port_rename_error_5.ys new file mode 100644 index 00000000000..a1268437c6f --- /dev/null +++ b/tests/verilog/port_rename_error_5.ys @@ -0,0 +1,14 @@ +# ANSI-style renaming +logger -expect error "syntax error" 1 +read_verilog << EOF +module gate_ansi ( + input .alias_a(a), + output .alias_b(b) +); + wire a; + wire b; + assign b = a; +endmodule +EOF +logger -check-expected +design -reset diff --git a/tests/verilog/port_rename_pass_1.ys b/tests/verilog/port_rename_pass_1.ys new file mode 100644 index 00000000000..87aa8720069 --- /dev/null +++ b/tests/verilog/port_rename_pass_1.ys @@ -0,0 +1,14 @@ +# Partial aliasing +read_verilog << EOF +module gate_swap ( + .a(a), + .b(b), + c +); + input a; + input b; + output c; + assign c = a & !b; +endmodule +EOF +design -reset