mirror of
https://github.com/verilator/verilator.git
synced 2025-04-30 20:46:54 +00:00
Internals: Refactor V3Param through code movement only. No functional change intended.
This commit is contained in:
parent
1299b70945
commit
e14319b401
108
src/V3Param.cpp
108
src/V3Param.cpp
@ -307,7 +307,7 @@ class ParamProcessor final {
|
|||||||
}
|
}
|
||||||
return string("z") + cvtToStr(num);
|
return string("z") + cvtToStr(num);
|
||||||
}
|
}
|
||||||
string moduleCalcName(AstNodeModule* srcModp, AstCell* cellp, const string& longname) {
|
string moduleCalcName(AstNodeModule* srcModp, AstPin* paramsp, const string& longname) {
|
||||||
string newname = longname;
|
string newname = longname;
|
||||||
if (longname.length() > 30 || srcModp->hierBlock()) {
|
if (longname.length() > 30 || srcModp->hierBlock()) {
|
||||||
const auto iter = m_longMap.find(longname);
|
const auto iter = m_longMap.find(longname);
|
||||||
@ -315,7 +315,7 @@ class ParamProcessor final {
|
|||||||
newname = iter->second;
|
newname = iter->second;
|
||||||
} else {
|
} else {
|
||||||
if (srcModp->hierBlock()) {
|
if (srcModp->hierBlock()) {
|
||||||
newname = parametrizedHierBlockName(srcModp, cellp->paramsp());
|
newname = parametrizedHierBlockName(srcModp, paramsp);
|
||||||
} else {
|
} else {
|
||||||
newname = srcModp->name();
|
newname = srcModp->name();
|
||||||
// We use all upper case above, so lower here can't conflict
|
// We use all upper case above, so lower here can't conflict
|
||||||
@ -324,6 +324,7 @@ class ParamProcessor final {
|
|||||||
m_longMap.insert(make_pair(longname, newname));
|
m_longMap.insert(make_pair(longname, newname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UINFO(4, "Name: " << srcModp->name() << "->" << longname << "->" << newname << endl);
|
||||||
return newname;
|
return newname;
|
||||||
}
|
}
|
||||||
AstNodeDType* arraySubDTypep(AstNodeDType* nodep) {
|
AstNodeDType* arraySubDTypep(AstNodeDType* nodep) {
|
||||||
@ -358,7 +359,7 @@ class ParamProcessor final {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void relinkPins(CloneMap* clonemapp, AstPin* startpinp) {
|
void relinkPins(const CloneMap* clonemapp, AstPin* startpinp) {
|
||||||
for (AstPin* pinp = startpinp; pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
for (AstPin* pinp = startpinp; pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
||||||
if (pinp->modVarp()) {
|
if (pinp->modVarp()) {
|
||||||
// Find it in the clone structure
|
// Find it in the clone structure
|
||||||
@ -419,6 +420,7 @@ class ParamProcessor final {
|
|||||||
if (m_modNameMap.find(modName) != m_modNameMap.end()) return true;
|
if (m_modNameMap.find(modName) != m_modNameMap.end()) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string parametrizedHierBlockName(const AstNodeModule* modp, AstPin* paramPinsp) const {
|
string parametrizedHierBlockName(const AstNodeModule* modp, AstPin* paramPinsp) const {
|
||||||
VHashSha256 hash;
|
VHashSha256 hash;
|
||||||
// Calculate hash using module name, parameter name, and parameter value
|
// Calculate hash using module name, parameter name, and parameter value
|
||||||
@ -446,8 +448,8 @@ class ParamProcessor final {
|
|||||||
hash.insert(V3Os::trueRandom(64));
|
hash.insert(V3Os::trueRandom(64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AstNodeModule* deepCloneModule(AstNodeModule* srcModp, AstCell* cellp, const string& newname,
|
void deepCloneModule(AstNodeModule* srcModp, AstNode* cellp, AstPin* paramsp,
|
||||||
const IfaceRefRefs& ifaceRefRefs) {
|
const string& newname, const IfaceRefRefs& ifaceRefRefs) {
|
||||||
// Deep clone of new module
|
// Deep clone of new module
|
||||||
// Note all module internal variables will be re-linked to the new modules by clone
|
// Note all module internal variables will be re-linked to the new modules by clone
|
||||||
// However links outside the module (like on the upper cells) will not.
|
// However links outside the module (like on the upper cells) will not.
|
||||||
@ -458,7 +460,6 @@ class ParamProcessor final {
|
|||||||
newmodp->recursiveClone(false);
|
newmodp->recursiveClone(false);
|
||||||
// Only the first generation of clone holds this property
|
// Only the first generation of clone holds this property
|
||||||
newmodp->hierBlock(srcModp->hierBlock() && !srcModp->recursiveClone());
|
newmodp->hierBlock(srcModp->hierBlock() && !srcModp->recursiveClone());
|
||||||
cellp->recursive(false);
|
|
||||||
// Recursion may need level cleanups
|
// Recursion may need level cleanups
|
||||||
if (newmodp->level() <= m_modp->level()) newmodp->level(m_modp->level() + 1);
|
if (newmodp->level() <= m_modp->level()) newmodp->level(m_modp->level() + 1);
|
||||||
if ((newmodp->level() - srcModp->level()) >= (v3Global.opt.moduleRecursionDepth() - 2)) {
|
if ((newmodp->level() - srcModp->level()) >= (v3Global.opt.moduleRecursionDepth() - 2)) {
|
||||||
@ -483,7 +484,7 @@ class ParamProcessor final {
|
|||||||
// thus we need to stash this info.
|
// thus we need to stash this info.
|
||||||
collectPins(clonemapp, newmodp);
|
collectPins(clonemapp, newmodp);
|
||||||
// Relink parameter vars to the new module
|
// Relink parameter vars to the new module
|
||||||
relinkPins(clonemapp, cellp->paramsp());
|
relinkPins(clonemapp, paramsp);
|
||||||
// Fix any interface references
|
// Fix any interface references
|
||||||
for (auto it = ifaceRefRefs.cbegin(); it != ifaceRefRefs.cend(); ++it) {
|
for (auto it = ifaceRefRefs.cbegin(); it != ifaceRefRefs.cend(); ++it) {
|
||||||
AstIfaceRefDType* portIrefp = it->first;
|
AstIfaceRefDType* portIrefp = it->first;
|
||||||
@ -498,7 +499,7 @@ class ParamProcessor final {
|
|||||||
}
|
}
|
||||||
// Assign parameters to the constants specified
|
// Assign parameters to the constants specified
|
||||||
// DOES clone() so must be finished with module clonep() before here
|
// DOES clone() so must be finished with module clonep() before here
|
||||||
for (AstPin* pinp = cellp->paramsp(); pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
for (AstPin* pinp = paramsp; pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
||||||
if (pinp->exprp()) {
|
if (pinp->exprp()) {
|
||||||
if (newmodp->hierBlock()) checkSupportedParam(newmodp, pinp);
|
if (newmodp->hierBlock()) checkSupportedParam(newmodp, pinp);
|
||||||
if (AstVar* modvarp = pinp->modVarp()) {
|
if (AstVar* modvarp = pinp->modVarp()) {
|
||||||
@ -519,19 +520,30 @@ class ParamProcessor final {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newmodp;
|
}
|
||||||
|
const ModInfo* moduleFindOrClone(AstNodeModule* srcModp, AstNode* cellp, AstPin* paramsp,
|
||||||
|
const string& newname, const IfaceRefRefs& ifaceRefRefs) {
|
||||||
|
// Already made this flavor?
|
||||||
|
auto it = m_modNameMap.find(newname);
|
||||||
|
if (it != m_modNameMap.end()) {
|
||||||
|
UINFO(4, " De-parameterize to old: " << it->second.m_modp << endl);
|
||||||
|
} else {
|
||||||
|
deepCloneModule(srcModp, cellp, paramsp, newname, ifaceRefRefs);
|
||||||
|
it = m_modNameMap.find(newname);
|
||||||
|
UASSERT(it != m_modNameMap.end(), "should find just-made module");
|
||||||
|
}
|
||||||
|
const ModInfo* modInfop = &(it->second);
|
||||||
|
return modInfop;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cellPinCleanup(AstCell* nodep, string& longnamer, bool& any_overridesr) {
|
void cellPinCleanup(AstNode* nodep, AstPin* pinp, AstNodeModule* srcModp, string& longnamer,
|
||||||
AstNodeModule* srcModp = nodep->modp();
|
bool& any_overridesr) {
|
||||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
if (!pinp->exprp()) return; // No-connect
|
||||||
if (!pinp->exprp()) continue; // No-connect
|
|
||||||
if (AstVar* modvarp = pinp->modVarp()) {
|
if (AstVar* modvarp = pinp->modVarp()) {
|
||||||
if (!modvarp->isGParam()) {
|
if (!modvarp->isGParam()) {
|
||||||
pinp->v3error("Attempted parameter setting of non-parameter: Param "
|
pinp->v3error("Attempted parameter setting of non-parameter: Param "
|
||||||
<< pinp->prettyNameQ() << " of " << nodep->prettyNameQ());
|
<< pinp->prettyNameQ() << " of " << nodep->prettyNameQ());
|
||||||
} else if (VN_IS(pinp->exprp(), InitArray)
|
} else if (VN_IS(pinp->exprp(), InitArray) && arraySubDTypep(modvarp->subDTypep())) {
|
||||||
&& arraySubDTypep(modvarp->subDTypep())) {
|
|
||||||
// Array assigned to array
|
// Array assigned to array
|
||||||
AstNode* exprp = pinp->exprp();
|
AstNode* exprp = pinp->exprp();
|
||||||
longnamer += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp);
|
longnamer += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp);
|
||||||
@ -555,8 +567,8 @@ class ParamProcessor final {
|
|||||||
+= ("_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp));
|
+= ("_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp));
|
||||||
any_overridesr = true;
|
any_overridesr = true;
|
||||||
} else {
|
} else {
|
||||||
longnamer += ("_" + paramSmallName(srcModp, modvarp)
|
longnamer
|
||||||
+ exprp->num().ascii(false));
|
+= ("_" + paramSmallName(srcModp, modvarp) + exprp->num().ascii(false));
|
||||||
any_overridesr = true;
|
any_overridesr = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -570,16 +582,14 @@ class ParamProcessor final {
|
|||||||
pinp->v3error("Parameter type variable isn't a type: Param "
|
pinp->v3error("Parameter type variable isn't a type: Param "
|
||||||
<< modvarp->prettyNameQ());
|
<< modvarp->prettyNameQ());
|
||||||
} else {
|
} else {
|
||||||
UINFO(9,
|
UINFO(9, "Parameter type assignment expr=" << exprp << " to " << origp << endl);
|
||||||
"Parameter type assignment expr=" << exprp << " to " << origp << endl);
|
|
||||||
if (exprp->sameTree(origp)) {
|
if (exprp->sameTree(origp)) {
|
||||||
// Setting parameter to its default value. Just ignore it.
|
// Setting parameter to its default value. Just ignore it.
|
||||||
// This prevents making additional modules, and makes coverage more
|
// This prevents making additional modules, and makes coverage more
|
||||||
// obvious as it won't show up under a unique module page name.
|
// obvious as it won't show up under a unique module page name.
|
||||||
} else {
|
} else {
|
||||||
V3Const::constifyParamsEdit(exprp);
|
V3Const::constifyParamsEdit(exprp);
|
||||||
longnamer
|
longnamer += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp);
|
||||||
+= "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp);
|
|
||||||
any_overridesr = true;
|
any_overridesr = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -588,11 +598,9 @@ class ParamProcessor final {
|
|||||||
<< pinp->prettyNameQ() << " of " << nodep->prettyNameQ());
|
<< pinp->prettyNameQ() << " of " << nodep->prettyNameQ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void cellInterfaceCleanup(AstCell* nodep, string& longnamer, bool& any_overridesr,
|
void cellInterfaceCleanup(AstCell* nodep, AstNodeModule* srcModp, string& longnamer,
|
||||||
IfaceRefRefs& ifaceRefRefs) {
|
bool& any_overridesr, IfaceRefRefs& ifaceRefRefs) {
|
||||||
AstNodeModule* srcModp = nodep->modp();
|
|
||||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
||||||
AstVar* modvarp = pinp->modVarp();
|
AstVar* modvarp = pinp->modVarp();
|
||||||
if (modvarp->isIfaceRef()) {
|
if (modvarp->isIfaceRef()) {
|
||||||
@ -670,16 +678,18 @@ public:
|
|||||||
// Make sure constification worked
|
// Make sure constification worked
|
||||||
// Must be a separate loop, as constant conversion may have changed some pointers.
|
// Must be a separate loop, as constant conversion may have changed some pointers.
|
||||||
// if (debug()) nodep->dumpTree(cout, "-cel2: ");
|
// if (debug()) nodep->dumpTree(cout, "-cel2: ");
|
||||||
string longname = srcModp->name();
|
string longname = srcModp->name() + "_";
|
||||||
bool any_overrides = false;
|
bool any_overrides = false;
|
||||||
// Must always clone __Vrcm (recursive modules)
|
// Must always clone __Vrcm (recursive modules)
|
||||||
if (nodep->recursive()) any_overrides = true;
|
if (nodep->recursive()) any_overrides = true;
|
||||||
longname += "_";
|
|
||||||
if (debug() > 8) nodep->paramsp()->dumpTreeAndNext(cout, "-cellparams: ");
|
if (debug() > 8) nodep->paramsp()->dumpTreeAndNext(cout, "-cellparams: ");
|
||||||
|
|
||||||
cellPinCleanup(nodep, longname /*ref*/, any_overrides /*ref*/);
|
for (AstPin* pinp = nodep->paramsp(); pinp; pinp = VN_CAST(pinp->nextp(), Pin)) {
|
||||||
|
cellPinCleanup(nodep, pinp, srcModp, longname /*ref*/, any_overrides /*ref*/);
|
||||||
|
}
|
||||||
IfaceRefRefs ifaceRefRefs;
|
IfaceRefRefs ifaceRefRefs;
|
||||||
cellInterfaceCleanup(nodep, longname /*ref*/, any_overrides /*ref*/, ifaceRefRefs /*ref*/);
|
cellInterfaceCleanup(nodep, srcModp, longname /*ref*/, any_overrides /*ref*/,
|
||||||
|
ifaceRefRefs /*ref*/);
|
||||||
|
|
||||||
if (!any_overrides) {
|
if (!any_overrides) {
|
||||||
UINFO(8, "Cell parameters all match original values, skipping expansion.\n");
|
UINFO(8, "Cell parameters all match original values, skipping expansion.\n");
|
||||||
@ -691,32 +701,16 @@ public:
|
|||||||
// We need to relink the pins to the new module
|
// We need to relink the pins to the new module
|
||||||
relinkPinsByName(nodep->pinsp(), modp);
|
relinkPinsByName(nodep->pinsp(), modp);
|
||||||
} else {
|
} else {
|
||||||
// If the name is very long, we don't want to overwhelm the filename limit
|
string newname = moduleCalcName(srcModp, nodep->paramsp(), longname);
|
||||||
// We don't do this always, as it aids debugability to have intuitive naming.
|
const ModInfo* modInfop
|
||||||
// TODO can use new V3Name hash replacement instead of this
|
= moduleFindOrClone(srcModp, nodep, nodep->paramsp(), newname, ifaceRefRefs);
|
||||||
// Shorter name is convenient for hierarchical block
|
|
||||||
string newname = moduleCalcName(srcModp, nodep, longname);
|
|
||||||
UINFO(4, "Name: " << srcModp->name() << "->" << longname << "->" << newname << endl);
|
|
||||||
//
|
|
||||||
// Already made this flavor?
|
|
||||||
AstNodeModule* cellmodp = nullptr;
|
|
||||||
auto iter = m_modNameMap.find(newname);
|
|
||||||
if (iter != m_modNameMap.end()) cellmodp = iter->second.m_modp;
|
|
||||||
if (!cellmodp) {
|
|
||||||
cellmodp = deepCloneModule(srcModp, nodep, newname, ifaceRefRefs);
|
|
||||||
iter = m_modNameMap.find(newname);
|
|
||||||
UASSERT(iter != m_modNameMap.end(), "should find just-made module");
|
|
||||||
} else {
|
|
||||||
UINFO(4, " De-parameterize to old: " << cellmodp << endl);
|
|
||||||
}
|
|
||||||
// Have child use this module instead.
|
// Have child use this module instead.
|
||||||
nodep->modp(cellmodp);
|
nodep->modp(modInfop->m_modp);
|
||||||
nodep->modName(newname);
|
nodep->modName(newname);
|
||||||
// We need to relink the pins to the new module
|
// We need to relink the pins to the new module
|
||||||
CloneMap* clonemapp = &(iter->second.m_cloneMap);
|
relinkPins(&(modInfop->m_cloneMap), nodep->pinsp());
|
||||||
relinkPins(clonemapp, nodep->pinsp());
|
UINFO(8, " Done with " << modInfop->m_modp << endl);
|
||||||
UINFO(8, " Done with " << cellmodp << endl);
|
}
|
||||||
} // if any_overrides
|
|
||||||
|
|
||||||
nodep->recursive(false);
|
nodep->recursive(false);
|
||||||
|
|
||||||
@ -788,19 +782,17 @@ class ParamVisitor final : public AstNVisitor {
|
|||||||
if ((nonIf == 0 && VN_IS(cellp->modp(), Iface))
|
if ((nonIf == 0 && VN_IS(cellp->modp(), Iface))
|
||||||
|| (nonIf == 1 && !VN_IS(cellp->modp(), Iface))) {
|
|| (nonIf == 1 && !VN_IS(cellp->modp(), Iface))) {
|
||||||
string fullName(m_modp->hierName());
|
string fullName(m_modp->hierName());
|
||||||
if (string* genHierNamep = (string*)cellp->user5p()) {
|
if (const string* genHierNamep = (string*)cellp->user5p()) {
|
||||||
fullName += *genHierNamep;
|
fullName += *genHierNamep;
|
||||||
}
|
}
|
||||||
visitCellDeparam(cellp, fullName);
|
visitCellDeparam(cellp, fullName);
|
||||||
}
|
if (const string* genHierNamep = (string*)cellp->user5p()) {
|
||||||
}
|
|
||||||
}
|
|
||||||
for (AstCell* cellp : m_cellps) {
|
|
||||||
if (string* genHierNamep = (string*)cellp->user5p()) {
|
|
||||||
cellp->user5p(nullptr);
|
cellp->user5p(nullptr);
|
||||||
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
|
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
m_cellps.clear();
|
m_cellps.clear();
|
||||||
m_modp = nullptr;
|
m_modp = nullptr;
|
||||||
UINFO(4, " MOD-done\n");
|
UINFO(4, " MOD-done\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user