Fix false ASSIGNIN on functions with explicit port map (#5069).

This commit is contained in:
Wilson Snyder
2024-04-26 19:26:21 -04:00
parent 25fd8ef5c0
commit 4f3a816fb0
6 changed files with 136 additions and 27 deletions
+21 -12
View File
@@ -1589,14 +1589,13 @@ public:
const char* const V3Task::s_dpiTemporaryVarSuffix = "__Vcvt";
V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
V3TaskConnectState* statep) {
V3TaskConnectState* statep, bool makeChanges) {
// Output list will be in order of the port declaration variables (so
// func calls are made right in C)
// Missing pin/expr? We return (pinvar, nullptr)
// Extra pin/expr? We clean it up
UINFO(9, "taskConnects " << nodep << endl);
std::map<const std::string, int> nameToIndex;
std::set<const AstVar*> argWrap; // Which ports are defaulted, forcing arg wrapper creation
V3TaskConnects tconnects;
UASSERT_OBJ(nodep->taskp(), nodep, "unlinked");
@@ -1608,7 +1607,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
if (portp->isIO()) {
tconnects.emplace_back(portp, static_cast<AstArg*>(nullptr));
nameToIndex.emplace(portp->name(), tpinnum); // For name based connections
tpinnum++;
++tpinnum;
if (portp->attrSFormat()) {
sformatp = portp;
} else if (sformatp) {
@@ -1630,17 +1629,19 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
// By name
const auto it = nameToIndex.find(argp->name());
if (it == nameToIndex.end()) {
pinp->v3error("No such argument " << argp->prettyNameQ() << " in function call to "
<< nodep->taskp()->prettyTypeName());
// We'll just delete it; seems less error prone than making a false argument
VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp);
if (makeChanges) {
pinp->v3error("No such argument " << argp->prettyNameQ()
<< " in function call to "
<< nodep->taskp()->prettyTypeName());
// We'll just delete it; seems less error prone than making a false argument
VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp);
}
} else {
if (tconnects[it->second].second) {
if (tconnects[it->second].second && makeChanges) {
pinp->v3error("Duplicate argument " << argp->prettyNameQ()
<< " in function call to "
<< nodep->taskp()->prettyTypeName());
}
argp->name(""); // Can forget name as will add back in pin order
tconnects[it->second].second = argp;
reorganize = true;
}
@@ -1649,8 +1650,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
if (sformatp) {
tconnects.emplace_back(sformatp, static_cast<AstArg*>(nullptr));
tconnects[ppinnum].second = argp;
tpinnum++;
} else {
++tpinnum;
} else if (makeChanges) {
pinp->v3error("Too many arguments in function call to "
<< nodep->taskp()->prettyTypeName());
// We'll just delete it; seems less error prone than making a false argument
@@ -1660,10 +1661,13 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
tconnects[ppinnum].second = argp;
}
}
ppinnum++;
++ppinnum;
}
if (!makeChanges) return tconnects;
// Connect missing ones
std::set<const AstVar*> argWrap; // Which ports are defaulted, forcing arg wrapper creation
for (int i = 0; i < tpinnum; ++i) {
AstVar* const portp = tconnects[i].first;
if (!tconnects[i].second || !tconnects[i].second->exprp()) {
@@ -1723,6 +1727,11 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
}
}
for (const auto& tconnect : tconnects) {
AstArg* const argp = tconnect.second;
argp->name(""); // Can forget name as will add back in pin order
}
if (reorganize) {
// To simplify downstream, put argument list back into pure pinnumber ordering
while (nodep->pinsp()) {