mirror of
https://github.com/verilator/verilator.git
synced 2025-01-09 16:17:36 +00:00
Partial cleanup of V3Param. No functional change.
This commit is contained in:
parent
5f0e1fae7f
commit
8189416d0c
137
src/V3Param.cpp
137
src/V3Param.cpp
@ -847,78 +847,74 @@ class ParamVisitor final : public VNVisitor {
|
|||||||
ParamProcessor m_processor; // De-parameterize a cell, build modules
|
ParamProcessor m_processor; // De-parameterize a cell, build modules
|
||||||
UnrollStateful m_unroller; // Loop unroller
|
UnrollStateful m_unroller; // Loop unroller
|
||||||
|
|
||||||
AstNodeModule* m_modp = nullptr; // Current module being processed
|
bool m_iterateModule = false; // Iterating module body
|
||||||
string m_generateHierName; // Generate portion of hierarchy name
|
string m_generateHierName; // Generate portion of hierarchy name
|
||||||
string m_unlinkedTxt; // Text for AstUnlinkedRef
|
string m_unlinkedTxt; // Text for AstUnlinkedRef
|
||||||
std::deque<AstCell*> m_cellps; // Cells left to process (in this module)
|
std::deque<AstCell*> m_cellps; // Cells left to process (in current module)
|
||||||
|
|
||||||
std::multimap<int, AstNodeModule*> m_todoModps; // Modules left to process
|
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
||||||
void visitCellDeparam(AstCell* nodep, const string& someInstanceName) {
|
void visitCells(AstNodeModule* nodep) {
|
||||||
// Cell: Check for parameters in the instantiation.
|
UASSERT_OBJ(!m_iterateModule, nodep, "Should not nest");
|
||||||
iterateChildren(nodep);
|
std::multimap<int, AstNodeModule*> workQueue;
|
||||||
UASSERT_OBJ(nodep->modp(), nodep, "Not linked?");
|
workQueue.emplace(nodep->level(), nodep);
|
||||||
m_processor.cellDeparam(nodep, m_modp, someInstanceName);
|
m_generateHierName = "";
|
||||||
// Remember to process the child module at the end of the module
|
m_iterateModule = true;
|
||||||
m_todoModps.emplace(nodep->modp()->level(), nodep->modp());
|
|
||||||
}
|
|
||||||
void visitModules() {
|
|
||||||
// Loop on all modules left to process
|
|
||||||
// Hitting a cell adds to the appropriate level of this level-sorted list,
|
|
||||||
// so since cells originally exist top->bottom we process in top->bottom order too.
|
|
||||||
while (!m_todoModps.empty()) {
|
|
||||||
const auto itm = m_todoModps.cbegin();
|
|
||||||
AstNodeModule* const nodep = itm->second;
|
|
||||||
m_todoModps.erase(itm);
|
|
||||||
if (!nodep->user5SetOnce()) { // Process once; note clone() must clear so we do it
|
|
||||||
// again
|
|
||||||
m_modp = nodep;
|
|
||||||
UINFO(4, " MOD " << nodep << endl);
|
|
||||||
if (m_modp->someInstanceName().empty()) {
|
|
||||||
m_modp->someInstanceName(m_modp->origName());
|
|
||||||
}
|
|
||||||
iterateChildren(nodep);
|
|
||||||
|
|
||||||
// Note above iterate may add to m_todoModps
|
// Visit all cells under module, recursively
|
||||||
//
|
do {
|
||||||
// Process interface cells, then non-interface which may ref an interface cell
|
const auto itm = workQueue.cbegin();
|
||||||
for (int nonIf = 0; nonIf < 2; ++nonIf) {
|
AstNodeModule* const modp = itm->second;
|
||||||
for (AstCell* const cellp : m_cellps) {
|
workQueue.erase(itm);
|
||||||
if ((nonIf == 0 && VN_IS(cellp->modp(), Iface))
|
|
||||||
|| (nonIf == 1 && !VN_IS(cellp->modp(), Iface))) {
|
// Process once; note user5 will be cleared on specialization, so we will do the
|
||||||
string someInstanceName(m_modp->someInstanceName());
|
// specialized module if needed
|
||||||
if (const string* const genHierNamep = (string*)cellp->user5p()) {
|
if (modp->user5SetOnce()) continue;
|
||||||
someInstanceName += *genHierNamep;
|
|
||||||
cellp->user5p(nullptr);
|
// TODO: this really should be an assert, but classes and hier_blocks are special...
|
||||||
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
|
if (modp->someInstanceName().empty()) modp->someInstanceName(modp->origName());
|
||||||
}
|
|
||||||
VL_DO_DANGLING(visitCellDeparam(cellp, someInstanceName), cellp);
|
// Iterate the body
|
||||||
}
|
iterateChildren(modp);
|
||||||
|
|
||||||
|
// Process interface cells, then non-interface cells, which may reference an interface
|
||||||
|
// cell.
|
||||||
|
for (bool doInterface : {true, false}) {
|
||||||
|
for (AstCell* const cellp : m_cellps) {
|
||||||
|
if (doInterface != VN_IS(cellp->modp(), Iface)) continue;
|
||||||
|
|
||||||
|
// Visit parameters in the instantiation.
|
||||||
|
iterateChildren(cellp);
|
||||||
|
|
||||||
|
// Update path
|
||||||
|
string someInstanceName(modp->someInstanceName());
|
||||||
|
if (const string* const genHierNamep = cellp->user5u().to<string*>()) {
|
||||||
|
someInstanceName += *genHierNamep;
|
||||||
|
cellp->user5p(nullptr);
|
||||||
|
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply parameter specialization
|
||||||
|
m_processor.cellDeparam(cellp, modp, someInstanceName);
|
||||||
|
|
||||||
|
// Add the (now potentially specialized) child module to the work queue
|
||||||
|
workQueue.emplace(cellp->modp()->level(), cellp->modp());
|
||||||
}
|
}
|
||||||
m_cellps.clear();
|
|
||||||
m_modp = nullptr;
|
|
||||||
UINFO(4, " MOD-done\n");
|
|
||||||
}
|
}
|
||||||
}
|
m_cellps.clear();
|
||||||
|
} while (!workQueue.empty());
|
||||||
|
|
||||||
|
m_iterateModule = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstNodeModule* nodep) override {
|
virtual void visit(AstNodeModule* nodep) override {
|
||||||
if (nodep->dead()) {
|
if (nodep->recursiveClone()) nodep->dead(true); // Fake, made for recursive elimination
|
||||||
UINFO(4, " MOD-dead. " << nodep << endl); // Marked by LinkDot
|
if (nodep->dead()) return; // Marked by LinkDot (and above)
|
||||||
return;
|
|
||||||
} else if (nodep->recursiveClone()) {
|
// Warn on unsupported parametrised class
|
||||||
// Fake, made for recursive elimination
|
if (VN_IS(nodep, Class)) {
|
||||||
UINFO(4, " MOD-recursive-dead. " << nodep << endl);
|
|
||||||
nodep->dead(true); // So Dead checks won't count references to it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (!nodep->dead() && VN_IS(nodep, Class)) {
|
|
||||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||||
if (const AstVar* const varp = VN_CAST(stmtp, Var)) {
|
if (const AstVar* const varp = VN_CAST(stmtp, Var)) {
|
||||||
if (varp->isParam()) {
|
if (varp->isParam()) {
|
||||||
@ -927,24 +923,21 @@ class ParamVisitor final : public VNVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
if (m_modp) {
|
if (m_iterateModule) { // Iterating body
|
||||||
UINFO(4, " MOD-under-MOD. " << nodep << endl);
|
UINFO(4, " MOD-under-MOD. " << nodep << endl);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
} else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|
return;
|
||||||
|| VN_IS(nodep, Class) // Nor moved classes
|
}
|
||||||
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
|
|
||||||
// Add request to END of modules left to process
|
// Start traversal at root-like things
|
||||||
m_todoModps.emplace(nodep->level(), nodep);
|
if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|
||||||
m_generateHierName = "";
|
|| VN_IS(nodep, Class) // Nor moved classes
|
||||||
visitModules();
|
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
|
||||||
} else if (nodep->user5()) {
|
visitCells(nodep);
|
||||||
UINFO(4, " MOD-done " << nodep << endl); // Already did it
|
|
||||||
} else {
|
|
||||||
// Should have been done by now, if not dead
|
|
||||||
UINFO(4, " MOD-dead? " << nodep << endl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstCell* nodep) override {
|
virtual void visit(AstCell* nodep) override {
|
||||||
// Must do ifaces first, so push to list and do in proper order
|
// Must do ifaces first, so push to list and do in proper order
|
||||||
string* const genHierNamep = new string(m_generateHierName);
|
string* const genHierNamep = new string(m_generateHierName);
|
||||||
|
Loading…
Reference in New Issue
Block a user