diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index ba73c3854..887e93ba7 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -983,7 +983,6 @@ class AstIfaceRefDType final : public AstNodeDType { string m_cellName; // "" = no cell, such as when connects to 'input' iface string m_ifaceName; // Interface name string m_modportName; // "" = no modport - bool m_portDecl = false; // Interface_port_declaration bool m_virtual = false; // True if virtual interface public: AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName) @@ -1018,8 +1017,6 @@ public: bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } - bool isPortDecl() const { return m_portDecl; } - void isPortDecl(bool flag) { m_portDecl = flag; } bool isVirtual() const { return m_virtual; } void isVirtual(bool flag) { m_virtual = flag; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 595cc7af4..f500cf0c1 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1550,7 +1550,6 @@ void AstIfaceGenericDType::dumpSmall(std::ostream& str) const { } void AstIfaceRefDType::dump(std::ostream& str) const { Super::dump(str); - if (isPortDecl()) str << " [PORTDECL]"; if (isVirtual()) str << " [VIRT]"; if (cellName() != "") str << " cell=" << cellName(); if (ifaceName() != "") str << " if=" << ifaceName(); @@ -1566,7 +1565,6 @@ void AstIfaceRefDType::dump(std::ostream& str) const { } } void AstIfaceRefDType::dumpJson(std::ostream& str) const { - dumpJsonBoolFuncIf(str, isPortDecl); dumpJsonBoolFuncIf(str, isVirtual); dumpJsonStrFunc(str, cellName); dumpJsonStrFunc(str, ifaceName); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index f6a159eb8..68178d981 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -642,15 +642,13 @@ public: UINFO(9, " insAllIface se" << cvtToHex(varSymp) << " " << varp); AstIfaceRefDType* const ifacerefp = ifaceRefFromArray(varp->subDTypep()); UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!"); - const bool varGotPort = varp && varp->user4(); - if (ifacerefp->isPortDecl() && !varGotPort) { + if (!ifacerefp->cellp() && !ifacerefp->isVirtual() && (varp->pinNum() == 0)) { varp->v3error("Interface port declaration " << varp->prettyNameQ() << " doesn't have corresponding port\n" << varp->warnMore() + "... Perhaps intended an interface instantiation but " "are missing parenthesis (IEEE 1800-2023 25.3)?"); } - ifacerefp->isPortDecl(false); // Only needed for this warning; soon removing AstPort if (!ifacerefp->ifaceViaCellp()) { if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if // made mistake diff --git a/src/verilog.y b/src/verilog.y index 6d3de095e..f6dc00931 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1988,7 +1988,6 @@ port_declaration: // ==IEEE: port_declaration | id/*interface*/ '.' idAny/*modport*/ /*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF); AstIfaceRefDType* const dtp = new AstIfaceRefDType{$1, $3, "", *$1, *$3}; - dtp->isPortDecl(true); VARDTYPE(dtp); } /*cont*/ mpInstnameList { $$ = VARDONEP($5, nullptr, nullptr); DEL($5); } diff --git a/test_regress/t/t_interface_paren_missing_bad.out b/test_regress/t/t_interface_paren_missing_bad.out index 1ab8b865c..362af2c1c 100644 --- a/test_regress/t/t_interface_paren_missing_bad.out +++ b/test_regress/t/t_interface_paren_missing_bad.out @@ -1,7 +1,53 @@ -%Error: t/t_interface_paren_missing_bad.v:13:3: Interface 'intf' not connected as parent's interface not connected +%Error: t/t_interface_paren_missing_bad.v:37:8: Interface port declaration 'intf_t_not_port' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 37 | intf intf_t_not_port; + | ^~~~~~~~~~~~~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: t/t_interface_paren_missing_bad.v:38:10: Interface port declaration 'intf_t_not_port_mod' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 38 | intf.A intf_t_not_port_mod; + | ^~~~~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:39:20: Interface port declaration 'intf_no_instance_t_not_port' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 39 | intf_no_instance intf_no_instance_t_not_port; + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:39:3: Interface 'intf_no_instance' not connected as parent's interface not connected : ... Perhaps caused by another error on the parent interface that needs resolving : ... Or, perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? - 13 | intf intf_i; - | ^~~~ - ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. + 39 | intf_no_instance intf_no_instance_t_not_port; + | ^~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:23:8: Interface port declaration 'intf_b_not_port' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 23 | intf intf_b_not_port; + | ^~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:24:10: Interface port declaration 'intf_b_not_port_mod' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 24 | intf.A intf_b_not_port_mod; + | ^~~~~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:25:20: Interface port declaration 'intf_no_instance_b_not_port' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 25 | intf_no_instance intf_no_instance_b_not_port; + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:25:3: Interface 'intf_no_instance' not connected as parent's interface not connected + : ... Perhaps caused by another error on the parent interface that needs resolving + : ... Or, perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 25 | intf_no_instance intf_no_instance_b_not_port; + | ^~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:30:8: Interface port declaration 'intf_d_not_port' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 30 | intf intf_d_not_port; + | ^~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:32:10: Interface port declaration 'intf_d_not_port_mod' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 32 | intf.A intf_d_not_port_mod; + | ^~~~~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:33:20: Interface port declaration 'intf_no_instance_d_not_port' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 33 | intf_no_instance intf_no_instance_d_not_port; + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +%Error: t/t_interface_paren_missing_bad.v:33:3: Interface 'intf_no_instance' not connected as parent's interface not connected + : ... Perhaps caused by another error on the parent interface that needs resolving + : ... Or, perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? + 33 | intf_no_instance intf_no_instance_d_not_port; + | ^~~~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_interface_paren_missing_bad.v b/test_regress/t/t_interface_paren_missing_bad.v index d5a6be601..af3f63836 100644 --- a/test_regress/t/t_interface_paren_missing_bad.v +++ b/test_regress/t/t_interface_paren_missing_bad.v @@ -6,10 +6,55 @@ // Interface instantiation without parenthesis -interface intf; +interface intf_no_instance; endinterface +interface intf #( + parameter int par +); + logic in; + modport A(input in); +endinterface + +module b ( + intf intf_b_port, + intf.A intf_b_port_mod +); + intf intf_b_not_port; + intf.A intf_b_not_port_mod; + intf_no_instance intf_no_instance_b_not_port; +endmodule + +module d (intf_d_port, intf_d_port_mod); + intf intf_d_port; + intf intf_d_not_port; + intf.A intf_d_port_mod; + intf.A intf_d_not_port_mod; + intf_no_instance intf_no_instance_d_not_port; +endmodule + module t; - intf intf_i; + intf intf_t_not_port; + intf.A intf_t_not_port_mod; + intf_no_instance intf_no_instance_t_not_port; + intf #(.par(8)) intf_exists(); + b b1 ( + .intf_b_port(intf_exists), + .intf_b_port_mod(intf_exists.A), + .intf_b_not_port(intf_exists.A) + ); + b b2 ( + .intf_b_port(intf_exists), + .intf_b_port_mod(intf_exists.A) + ); + d d1 ( + .intf_d_port(intf_exists), + .intf_d_port_mod(intf_exists.A), + .intf_d_not_port(intf_exists.A) + ); + d d2 ( + .intf_d_port(intf_exists), + .intf_d_port_mod(intf_exists.A) + ); initial $finish; endmodule