mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
Fix false ASSIGNIN on interface input ports driven from outside (#7322)
This commit is contained in:
+16
-1
@@ -241,6 +241,7 @@ class WidthVisitor final : public VNVisitor {
|
||||
std::map<const AstNode*, const AstClass*>
|
||||
m_containingClassp; // Containing class cache for containingClass() function
|
||||
std::unordered_set<AstVar*> m_aliasedVars; // Variables referenced in alias
|
||||
std::unordered_set<const AstVar*> m_curModVars; // Variables declared in current module
|
||||
|
||||
static constexpr int ENUM_LOOKUP_BITS = 16; // Maximum # bits to make enum lookup table
|
||||
|
||||
@@ -2835,7 +2836,18 @@ class WidthVisitor final : public VNVisitor {
|
||||
&& (!m_ftaskp || !m_ftaskp->isConstructor())
|
||||
&& !VN_IS(m_procedurep, InitialAutomatic) && !VN_IS(m_procedurep, InitialStatic)
|
||||
&& !VN_IS(nodep->abovep(), AssignForce) && !VN_IS(nodep->abovep(), Release)) {
|
||||
nodep->v3warn(ASSIGNIN, "Assigning to input/const variable: " << nodep->prettyNameQ());
|
||||
// Skip ASSIGNIN for continuous assignments to net-type input ports
|
||||
// via hierarchical reference. Net ports allow multiple continuous
|
||||
// drivers (IEEE 1800-2023 23.3.3.3). Input ports default to net
|
||||
// when port kind is omitted (23.2.2.3, PORT type).
|
||||
const bool hierRef = !m_curModVars.count(nodep->varp());
|
||||
const bool netPort
|
||||
= nodep->varp()->isNet() || nodep->varp()->varType() == VVarType::PORT;
|
||||
const bool contAssign = VN_IS(nodep->abovep(), AssignW);
|
||||
if (!(hierRef && netPort && contAssign)) {
|
||||
nodep->v3warn(ASSIGNIN,
|
||||
"Assigning to input/const variable: " << nodep->prettyNameQ());
|
||||
}
|
||||
} else if (nodep->access().isWriteOrRW() && nodep->varp()->isConst() && !m_paramsOnly
|
||||
&& (!m_ftaskp || !m_ftaskp->isConstructor())
|
||||
&& !VN_IS(m_procedurep, InitialAutomatic)
|
||||
@@ -7374,6 +7386,9 @@ class WidthVisitor final : public VNVisitor {
|
||||
} else {
|
||||
VL_RESTORER(m_modep);
|
||||
m_modep = nodep;
|
||||
// Collect local variables for ASSIGNIN hierarchical reference check
|
||||
m_curModVars.clear();
|
||||
nodep->foreach([this](const AstVar* varp) { m_curModVars.insert(varp); });
|
||||
userIterateChildren(nodep, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -1437,16 +1437,16 @@ port<nodep>: // ==IEEE: port
|
||||
{ $$ = $3; VARDTYPE($2); VARIOANSI();
|
||||
if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } }
|
||||
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
{ $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
|
||||
addNextNull($$, VARDONEP($$, $5, $6)); }
|
||||
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
{ $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
|
||||
if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
|
||||
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
{ $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
|
||||
addNextNull($$, VARDONEP($$, $5, $6)); }
|
||||
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
{ $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
|
||||
if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
|
||||
| portDirNetE signing portSig variable_dimensionListE sigAttrListE
|
||||
{ $$ = $3;
|
||||
@@ -1955,10 +1955,10 @@ port_declaration<nodep>: // ==IEEE: port_declaration
|
||||
/*mid*/ { VARDTYPE($3); }
|
||||
/*cont*/ list_of_variable_decl_assignments { $$ = $5; }
|
||||
| port_directionReset port_declNetE yVAR data_type
|
||||
/*mid*/ { VARDTYPE($4); }
|
||||
/*mid*/ { VARDECL(VAR); VARDTYPE($4); }
|
||||
/*cont*/ list_of_variable_decl_assignments { $$ = $6; }
|
||||
| port_directionReset port_declNetE yVAR implicit_typeE
|
||||
/*mid*/ { VARDTYPE($4); }
|
||||
/*mid*/ { VARDECL(VAR); VARDTYPE($4); }
|
||||
/*cont*/ list_of_variable_decl_assignments { $$ = $6; }
|
||||
| port_directionReset port_declNetE signingE rangeList
|
||||
/*mid*/ { AstNodeDType* const dtp = GRAMMARP->addRange(
|
||||
|
||||
Reference in New Issue
Block a user