From c92f1a36f00d6a70e18c896b6a4f2644457bd50f Mon Sep 17 00:00:00 2001 From: MikePopoloski Date: Sat, 19 Oct 2024 18:12:41 -0400 Subject: [PATCH] Fix connection of interface arrays to ports with different declared dimensions --- source/ast/symbols/PortSymbols.cpp | 23 +++++++++++++++++++++-- tests/unittests/ast/InterfaceTests.cpp | 22 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/source/ast/symbols/PortSymbols.cpp b/source/ast/symbols/PortSymbols.cpp index 71ec46aa7..c1ee69a84 100644 --- a/source/ast/symbols/PortSymbols.cpp +++ b/source/ast/symbols/PortSymbols.cpp @@ -1111,6 +1111,25 @@ class PortConnectionBuilder { return true; } + const Symbol* rewireIfaceArrayIndices(const Symbol* sym, std::string_view name, + SourceLocation loc, + std::span portDims) { + if (!sym || sym->kind != SymbolKind::InstanceArray) + return sym; + + // The port dimensions are guaranteed to have the same count and width as + // the instance array dimensions but their indices may differ, so this + // function creates a new array with the correct range. + SLANG_ASSERT(!portDims.empty()); + auto subPortDims = portDims.subspan(1); + + SmallVector newElems; + for (auto elem : sym->as().elements) + newElems.push_back(rewireIfaceArrayIndices(elem, ""sv, loc, subPortDims)); + + return comp.emplace(comp, name, loc, newElems.copy(comp), portDims[0]); + } + PortConnection::IfaceConn getInterfaceConn(ASTContext& context, const InterfacePortSymbol& port, const ExpressionSyntax& syntax) { SLANG_ASSERT(!port.isInvalid()); @@ -1169,7 +1188,7 @@ class PortConnectionBuilder { // Make the connection if the dimensions match exactly what the port is expecting. const Symbol* symbol = expr->as().symbol; if (areDimSizesEqual(*portDims, dims)) - return {symbol, modport}; + return {rewireIfaceArrayIndices(symbol, port.name, port.location, *portDims), modport}; // Otherwise, if the instance being instantiated is part of an array of instances *and* // the symbol we're connecting to is an array of interfaces, we need to check to see whether @@ -1198,7 +1217,7 @@ class PortConnectionBuilder { symbol = array.elements[size_t(index)]; } - return {symbol, modport}; + return {rewireIfaceArrayIndices(symbol, port.name, port.location, *portDims), modport}; } auto& diag = scope.addDiag(diag::PortConnDimensionsMismatch, syntax.sourceRange()) diff --git a/tests/unittests/ast/InterfaceTests.cpp b/tests/unittests/ast/InterfaceTests.cpp index 402ec8a6d..c17443e67 100644 --- a/tests/unittests/ast/InterfaceTests.cpp +++ b/tests/unittests/ast/InterfaceTests.cpp @@ -724,3 +724,25 @@ endmodule REQUIRE(diags.size() == 1); CHECK(diags[0].code == diag::UndeclaredIdentifier); } + +TEST_CASE("Iface array with different declared indices regress -- GH #1152") { + auto tree = SyntaxTree::fromText(R"( +interface bus(); + logic a; + logic b; +endinterface + +module submodule(bus iface [3:2]); + assign iface[2].a = iface[3].b; +endmodule + +module top(); + bus iface[1:0](); + submodule inst(iface); +endmodule +)"); + + Compilation compilation; + compilation.addSyntaxTree(tree); + NO_COMPILATION_ERRORS; +}