Fix scope creating extra vars for package variables. See next trace commit for test.

This commit is contained in:
Wilson Snyder 2014-03-14 20:24:00 -04:00
parent ca57edfa0b
commit ba8c11b25d
1 changed files with 36 additions and 11 deletions

View File

@ -46,10 +46,13 @@ private:
// NODE STATE // NODE STATE
// AstVar::user1p -> AstVarScope replacement for this variable // AstVar::user1p -> AstVarScope replacement for this variable
// AstTask::user2p -> AstTask*. Replacement task // AstTask::user2p -> AstTask*. Replacement task
// AstVar::user3p -> AstVarScope for packages
AstUser1InUse m_inuser1; AstUser1InUse m_inuser1;
AstUser2InUse m_inuser2; AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
// TYPES
typedef map<AstPackage*, AstScope*> PackageScopeMap;
typedef map<pair<AstVar*, AstScope*>, AstVarScope*> VarScopeMap;
typedef set<pair<AstVarRef*, AstScope*> > VarRefScopeSet;
// STATE, inside processing a single module // STATE, inside processing a single module
AstNodeModule* m_modp; // Current module AstNodeModule* m_modp; // Current module
@ -57,6 +60,10 @@ private:
// STATE, for passing down one level of hierarchy (may need save/restore) // STATE, for passing down one level of hierarchy (may need save/restore)
AstCell* m_aboveCellp; // Cell that instantiates this module AstCell* m_aboveCellp; // Cell that instantiates this module
AstScope* m_aboveScopep; // Scope that instantiates this scope AstScope* m_aboveScopep; // Scope that instantiates this scope
PackageScopeMap m_packageScopes; // Scopes for each package
VarScopeMap m_varScopes; // Varscopes created for each scope and var
VarRefScopeSet m_varRefScopes; // Varrefs-in-scopes needing fixup when donw
// METHODS // METHODS
static int debug() { static int debug() {
@ -65,6 +72,23 @@ private:
return level; return level;
} }
void cleanupVarRefs() {
for (VarRefScopeSet::iterator it = m_varRefScopes.begin();
it!=m_varRefScopes.end(); ++it) {
AstVarRef* nodep = it->first;
AstScope* scopep = it->second;
if (nodep->packagep()) {
PackageScopeMap::iterator it = m_packageScopes.find(nodep->packagep());
if (it==m_packageScopes.end()) nodep->v3fatalSrc("Can't locate package scope");
scopep = it->second;
}
VarScopeMap::iterator it = m_varScopes.find(make_pair(nodep->varp(), scopep));
if (it==m_varScopes.end()) nodep->v3fatalSrc("Can't locate varref scope");
AstVarScope* varscp = it->second;
nodep->varScopep(varscp);
}
}
// VISITORS // VISITORS
virtual void visit(AstNetlist* nodep, AstNUser*) { virtual void visit(AstNetlist* nodep, AstNUser*) {
AstNodeModule* modp = nodep->topModulep(); AstNodeModule* modp = nodep->topModulep();
@ -73,6 +97,7 @@ private:
m_aboveCellp = NULL; m_aboveCellp = NULL;
m_aboveScopep = NULL; m_aboveScopep = NULL;
modp->accept(*this); modp->accept(*this);
cleanupVarRefs();
} }
virtual void visit(AstNodeModule* nodep, AstNUser*) { virtual void visit(AstNodeModule* nodep, AstNUser*) {
// Create required blocks and add to module // Create required blocks and add to module
@ -85,6 +110,7 @@ private:
m_scopep = new AstScope((m_aboveCellp?(AstNode*)m_aboveCellp:(AstNode*)nodep)->fileline(), m_scopep = new AstScope((m_aboveCellp?(AstNode*)m_aboveCellp:(AstNode*)nodep)->fileline(),
nodep, scopename, m_aboveScopep, m_aboveCellp); nodep, scopename, m_aboveScopep, m_aboveCellp);
if (nodep->castPackage()) m_packageScopes.insert(make_pair(nodep->castPackage(), m_scopep));
// Now for each child cell, iterate the module this cell points to // Now for each child cell, iterate the module this cell points to
for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) { for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) {
@ -211,12 +237,13 @@ private:
} }
virtual void visit(AstVar* nodep, AstNUser*) { virtual void visit(AstVar* nodep, AstNUser*) {
// Make new scope variable // Make new scope variable
if (m_modp->castPackage() // This is called cross-module by AstVar, so we cannot trust any m_ variables
? !nodep->user3p() : !nodep->user1p()) { if (!nodep->user1p()) {
AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep); AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep);
UINFO(6," New scope "<<varscp<<endl); UINFO(6," New scope "<<varscp<<endl);
nodep->user1p(varscp); nodep->user1p(varscp);
if (m_modp->castPackage()) nodep->user3p(varscp); if (!m_scopep) nodep->v3fatalSrc("No scope for var");
m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp));
m_scopep->addVarp(varscp); m_scopep->addVarp(varscp);
} }
} }
@ -227,12 +254,10 @@ private:
if (nodep->varp()->isIfaceRef()) { if (nodep->varp()->isIfaceRef()) {
nodep->varScopep(NULL); nodep->varScopep(NULL);
} else { } else {
nodep->varp()->accept(*this); // We may have not made the variable yet, and we can't make it now as
AstVarScope* varscp = nodep->packagep() // the var's referenced package etc might not be created yet.
? (AstVarScope*)nodep->varp()->user3p() // So push to a list and post-correct
: (AstVarScope*)nodep->varp()->user1p(); m_varRefScopes.insert(make_pair(nodep, m_scopep));
if (!varscp) nodep->v3fatalSrc("Can't locate varref scope");
nodep->varScopep(varscp);
} }
} }
virtual void visit(AstScopeName* nodep, AstNUser*) { virtual void visit(AstScopeName* nodep, AstNUser*) {