Make AstTopScope accessible from AstNetlist
AstTopScope is a singleton node and making it accessible without a traversal simplifies some code and decouple some other.
This commit is contained in:
parent
381c87a1eb
commit
5515eed0b6
|
|
@ -45,19 +45,12 @@ private:
|
|||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstTopScope* m_topscopep = nullptr; // Top scope for adding sentrees under
|
||||
SenTreeFinder m_finder; // Find global sentree's and add them
|
||||
SenTreeFinder m_finder; // Find global sentree's / add them under the AstTopScope
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep) override {
|
||||
m_topscopep = nodep;
|
||||
m_finder.init(m_topscopep);
|
||||
iterateChildren(nodep);
|
||||
m_topscopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
// Create required actives and add to module
|
||||
// We can start ordering at a module, or a scope
|
||||
|
|
|
|||
|
|
@ -2333,19 +2333,22 @@ public:
|
|||
};
|
||||
|
||||
class AstTopScope final : public AstNode {
|
||||
// In the top level netlist, a complete scope tree
|
||||
// There may be two of these, when we support "rare" and "usual" splitting
|
||||
// Parents: topMODULE
|
||||
// Children: SCOPEs
|
||||
public:
|
||||
// A singleton, held under the top level AstModule. Holds the top level AstScope,
|
||||
// and after V3ActiveTop, the global list of AstSenTrees (list of unique sensitivity lists).
|
||||
// Parent: Top level AstModule
|
||||
// Children: AstSenTree, AstScope
|
||||
friend class AstNetlist; // Only the AstNetlist can create one
|
||||
AstTopScope(FileLine* fl, AstScope* ascopep)
|
||||
: ASTGEN_SUPER_TopScope(fl) {
|
||||
addNOp2p(ascopep);
|
||||
addOp2p(ascopep);
|
||||
}
|
||||
|
||||
public:
|
||||
ASTNODE_NODE_FUNCS(TopScope)
|
||||
AstNode* stmtsp() const { return op1p(); }
|
||||
void addStmtsp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstScope* scopep() const { return VN_AS(op2p(), Scope); } // op1 = AstVarScope's
|
||||
virtual bool maybePointedTo() const override { return true; }
|
||||
AstSenTree* senTreesp() const { return VN_AS(op1p(), SenTree); }
|
||||
void addSenTreep(AstSenTree* nodep) { addOp1p((AstNode*)nodep); }
|
||||
AstScope* scopep() const { return VN_AS(op2p(), Scope); }
|
||||
};
|
||||
|
||||
class AstVarScope final : public AstNode {
|
||||
|
|
@ -9191,6 +9194,7 @@ private:
|
|||
AstCFunc* m_evalp = nullptr; // The '_eval' function
|
||||
AstExecGraph* m_execGraphp = nullptr; // Execution MTask graph for threads>1 mode
|
||||
AstVarScope* m_dpiExportTriggerp = nullptr; // The DPI export trigger variable
|
||||
AstTopScope* m_topScopep = nullptr; // The singleton AstTopScope under the top module
|
||||
VTimescale m_timeunit; // Global time unit
|
||||
VTimescale m_timeprecision; // Global time precision
|
||||
bool m_changeRequest = false; // Have _change_request method
|
||||
|
|
@ -9202,6 +9206,7 @@ public:
|
|||
BROKEN_RTN(m_dollarUnitPkgp && !m_dollarUnitPkgp->brokeExists());
|
||||
BROKEN_RTN(m_evalp && !m_evalp->brokeExists());
|
||||
BROKEN_RTN(m_dpiExportTriggerp && !m_dpiExportTriggerp->brokeExists());
|
||||
BROKEN_RTN(m_topScopep && !m_topScopep->brokeExists());
|
||||
return nullptr;
|
||||
}
|
||||
virtual string name() const override { return "$root"; }
|
||||
|
|
@ -9239,6 +9244,13 @@ public:
|
|||
void execGraphp(AstExecGraph* graphp) { m_execGraphp = graphp; }
|
||||
AstVarScope* dpiExportTriggerp() const { return m_dpiExportTriggerp; }
|
||||
void dpiExportTriggerp(AstVarScope* varScopep) { m_dpiExportTriggerp = varScopep; }
|
||||
AstTopScope* topScopep() const { return m_topScopep; }
|
||||
void createTopScope(AstScope* scopep) {
|
||||
UASSERT(scopep, "Must not be nullptr");
|
||||
UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits");
|
||||
m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep};
|
||||
scopep->modp()->addStmtp(v3Global.rootp()->topScopep());
|
||||
}
|
||||
VTimescale timeunit() const { return m_timeunit; }
|
||||
void timeunit(const VTimescale& value) { m_timeunit = value; }
|
||||
VTimescale timeprecision() const { return m_timeprecision; }
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ private:
|
|||
// STATE
|
||||
AstActive* m_activep = nullptr; // Inside activate statement
|
||||
AstNodeModule* m_topModp; // Top module
|
||||
AstScope* m_scopetopp = nullptr; // Scope under TOPSCOPE
|
||||
AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
|
||||
// METHODS
|
||||
AstVarScope* genInpClk(AstVarScope* vscp) {
|
||||
|
|
@ -93,11 +93,6 @@ private:
|
|||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep) override {
|
||||
AstNode::user2ClearTree(); // user2p() used on entire tree
|
||||
|
||||
AstScope* scopep = nodep->scopep();
|
||||
UASSERT_OBJ(scopep, nodep, "No scope found on top level");
|
||||
m_scopetopp = scopep;
|
||||
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
//----
|
||||
|
|
|
|||
|
|
@ -941,8 +941,6 @@ private:
|
|||
m_activep = nullptr;
|
||||
m_topScopep = nodep;
|
||||
m_scopetopp = nodep->scopep();
|
||||
// Find global SenTrees
|
||||
m_finder.init(m_topScopep);
|
||||
// ProcessDomainsIterate will use these when it needs to move
|
||||
// something to a combodomain. This saves a ton of find() operations.
|
||||
AstSenTree* combp
|
||||
|
|
|
|||
|
|
@ -132,8 +132,7 @@ private:
|
|||
AstNode::user1ClearTree();
|
||||
m_modp = nodep;
|
||||
if (m_modp->isTop()) {
|
||||
AstTopScope* topscp = new AstTopScope(nodep->fileline(), m_scopep);
|
||||
m_modp->addStmtp(topscp);
|
||||
v3Global.rootp()->createTopScope(m_scopep);
|
||||
} else {
|
||||
m_modp->addStmtp(m_scopep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,14 +74,21 @@ private:
|
|||
class SenTreeFinder final {
|
||||
private:
|
||||
// STATE
|
||||
AstTopScope* m_topScopep = nullptr; // Top scope to add global SenTrees to
|
||||
AstTopScope* const m_topScopep; // Top scope to add global SenTrees to
|
||||
SenTreeSet m_trees; // Set of global SenTrees
|
||||
|
||||
VL_UNCOPYABLE(SenTreeFinder);
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
SenTreeFinder() = default;
|
||||
SenTreeFinder()
|
||||
: m_topScopep{v3Global.rootp()->topScopep()} {
|
||||
// Gather existing global SenTrees
|
||||
for (AstSenTree* nodep = m_topScopep->senTreesp(); nodep;
|
||||
nodep = VN_AS(nodep->nextp(), SenTree)) {
|
||||
m_trees.add(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
// METHODS
|
||||
AstSenTree* getSenTree(AstSenTree* senTreep) {
|
||||
|
|
@ -90,23 +97,13 @@ public:
|
|||
AstSenTree* treep = m_trees.find(senTreep);
|
||||
// Not found, form a new one
|
||||
if (!treep) {
|
||||
UASSERT(m_topScopep, "Never called init()");
|
||||
treep = senTreep->cloneTree(false);
|
||||
m_topScopep->addStmtsp(treep);
|
||||
m_topScopep->addSenTreep(treep);
|
||||
UINFO(8, " New SENTREE " << treep << endl);
|
||||
m_trees.add(treep);
|
||||
}
|
||||
return treep;
|
||||
}
|
||||
|
||||
void init(AstTopScope* topScopep) {
|
||||
// Keep hold of top scope so we can add global SenTrees later
|
||||
m_topScopep = topScopep;
|
||||
// Gather existing global SenTrees
|
||||
for (AstNode* nodep = topScopep->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstSenTree* senTreep = VN_CAST(nodep, SenTree)) m_trees.add(senTreep);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ private:
|
|||
// STATE
|
||||
TaskStateVisitor* m_statep; // Common state between visitors
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstTopScope* m_topScopep = nullptr; // Current top scope
|
||||
AstTopScope* const m_topScopep = v3Global.rootp()->topScopep(); // The AstTopScope
|
||||
AstScope* m_scopep = nullptr; // Current scope
|
||||
InsertMode m_insMode = IM_BEFORE; // How to insert
|
||||
AstNode* m_insStmtp = nullptr; // Where to insert statement
|
||||
|
|
@ -1392,10 +1392,6 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTopScope* nodep) override {
|
||||
m_topScopep = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
m_scopep = nodep;
|
||||
m_insStmtp = nullptr;
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ private:
|
|||
|
||||
// STATE
|
||||
AstNodeModule* m_topModp = nullptr; // Module to add variables to
|
||||
AstScope* m_topScopep = nullptr; // Scope to add variables to
|
||||
AstScope* const m_topScopep = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
AstCFunc* m_cfuncp = nullptr; // C function adding to graph
|
||||
AstCFunc* m_regFuncp = nullptr; // Trace registration function
|
||||
AstTraceDecl* m_tracep = nullptr; // Trace function adding to graph
|
||||
|
|
@ -808,12 +808,6 @@ private:
|
|||
if (nodep->isTop()) m_topModp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstTopScope* nodep) override {
|
||||
AstScope* const scopep = nodep->scopep();
|
||||
UASSERT_OBJ(scopep, nodep, "No scope found on top level");
|
||||
m_topScopep = scopep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
UINFO(8, " CCALL " << nodep << endl);
|
||||
if (!m_finding && !nodep->user2()) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ private:
|
|||
// NODE STATE
|
||||
|
||||
// STATE
|
||||
AstScope* m_topScopep = nullptr; // Current top scope
|
||||
AstScope* const m_topScopep = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
AstCFunc* m_initFuncp = nullptr; // Trace function being built
|
||||
AstCFunc* m_initSubFuncp = nullptr; // Trace function being built (under m_init)
|
||||
int m_initSubStmts = 0; // Number of statements in function
|
||||
|
|
@ -136,7 +136,6 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep) override {
|
||||
m_topScopep = nodep->scopep();
|
||||
// Create the trace init function
|
||||
m_initFuncp = newCFunc("trace_init_top");
|
||||
// Create initial sub function
|
||||
|
|
|
|||
Loading…
Reference in New Issue