@@ -984,90 +984,42 @@ class ParamVisitor final : public VNVisitor {
984
984
ParamProcessor m_processor; // De-parameterize a cell, build modules
985
985
UnrollStateful m_unroller; // Loop unroller
986
986
987
- bool m_iterateModule = false ; // Iterating module body
987
+ // bool m_iterateModule = false; // Iterating module body
988
988
string m_generateHierName; // Generate portion of hierarchy name
989
989
string m_unlinkedTxt; // Text for AstUnlinkedRef
990
990
AstNodeModule* m_modp; // Module iterating
991
991
std::vector<AstDot*> m_dots; // Dot references to process
992
- std::multimap<bool , AstNode*> m_cellps; // Cells left to process (in current module)
993
- std::multimap<int , AstNodeModule*> m_workQueue; // Modules left to process
992
+ // std::multimap<bool, AstNode*> m_cellps; // Cells left to process (in current module)
993
+ // std::multimap<int, AstNodeModule*> m_workQueue; // Modules left to process
994
994
std::vector<AstClass*> m_paramClasses; // Parameterized classes
995
995
996
996
// Map from AstNodeModule to set of all AstNodeModules that instantiates it.
997
997
std::unordered_map<AstNodeModule*, std::unordered_set<AstNodeModule*>> m_parentps;
998
998
999
999
// METHODS
1000
1000
1001
- void visitCells (AstNodeModule* nodep) {
1002
- UASSERT_OBJ (!m_iterateModule, nodep, " Should not nest" );
1003
- std::multimap<int , AstNodeModule*> workQueue;
1004
- workQueue.emplace (nodep->level (), nodep);
1005
- m_generateHierName = " " ;
1006
- m_iterateModule = true ;
1007
-
1008
- // Visit all cells under module, recursively
1009
- do {
1010
- const auto itm = workQueue.cbegin ();
1011
- AstNodeModule* const modp = itm->second ;
1012
- workQueue.erase (itm);
1013
-
1014
- // Process once; note user2 will be cleared on specialization, so we will do the
1015
- // specialized module if needed
1016
- if (!modp->user2SetOnce ()) {
1017
-
1018
- // TODO: this really should be an assert, but classes and hier_blocks are
1019
- // special...
1020
- if (modp->someInstanceName ().empty ()) modp->someInstanceName (modp->origName ());
1021
-
1022
- // Iterate the body
1023
- {
1024
- VL_RESTORER (m_modp);
1025
- m_modp = modp;
1026
- iterateChildren (modp);
1027
- }
1028
- }
1029
-
1030
- // Process interface cells, then non-interface cells, which may reference an interface
1031
- // cell.
1032
- while (!m_cellps.empty ()) {
1033
- const auto itim = m_cellps.cbegin ();
1034
- AstNode* const cellp = itim->second ;
1035
- m_cellps.erase (itim);
1036
-
1037
- AstNodeModule* srcModp = nullptr ;
1038
- if (const auto * modCellp = VN_CAST (cellp, Cell)) {
1039
- srcModp = modCellp->modp ();
1040
- } else if (const auto * classRefp = VN_CAST (cellp, ClassOrPackageRef)) {
1041
- srcModp = classRefp->classOrPackagep ();
1042
- if (VN_IS (classRefp->classOrPackageNodep (), ParamTypeDType)) continue ;
1043
- } else if (const auto * classRefp = VN_CAST (cellp, ClassRefDType)) {
1044
- srcModp = classRefp->classp ();
1045
- } else {
1046
- cellp->v3fatalSrc (" Expected module parameterization" );
1047
- }
1048
- UASSERT_OBJ (srcModp, cellp, " Unlinked class ref" );
1049
-
1050
- // Update path
1051
- string someInstanceName (modp->someInstanceName ());
1052
- if (const string* const genHierNamep = cellp->user2u ().to <string*>()) {
1053
- someInstanceName += *genHierNamep;
1054
- cellp->user2p (nullptr );
1055
- VL_DO_DANGLING (delete genHierNamep, genHierNamep);
1056
- }
1001
+ void visitModule (AstNodeModule* modp) {
1002
+ // m_generateHierName = "";
1003
+ UINFO (9 , " Visit module " << modp << endl);
1057
1004
1058
- // Apply parameter specialization
1059
- m_processor.nodeDeparam (cellp, srcModp /* ref */ , modp, someInstanceName);
1005
+ // Process once; note user2 will be cleared on specialization, so we will do the
1006
+ // specialized module if needed
1007
+ if (!modp->user2SetOnce ()) {
1008
+ // FIXME: move to visit(AstNodeModule*)
1060
1009
1061
- // Add the (now potentially specialized) child module to the work queue
1062
- workQueue.emplace (srcModp->level (), srcModp);
1010
+ // TODO: this really should be an assert, but classes and hier_blocks are
1011
+ // special...
1012
+ if (modp->someInstanceName ().empty ()) modp->someInstanceName (modp->origName ());
1063
1013
1064
- // Add to the hierarchy registry
1065
- m_parentps[srcModp].insert (modp);
1014
+ // Iterate the body
1015
+ {
1016
+ VL_RESTORER (m_modp);
1017
+ m_modp = modp;
1018
+ iterateChildren (modp);
1066
1019
}
1067
- if (workQueue.empty ()) std::swap (workQueue, m_workQueue);
1068
- } while (!workQueue.empty ());
1069
-
1070
- m_iterateModule = false ;
1020
+ }
1021
+ //
1022
+ // m_iterateModule = false;
1071
1023
}
1072
1024
1073
1025
// Fix up level of module, based on who instantiates it
@@ -1089,7 +1041,39 @@ class ParamVisitor final : public VNVisitor {
1089
1041
nodep->user2p (genHierNamep);
1090
1042
// Visit parameters in the instantiation.
1091
1043
iterateChildren (nodep);
1092
- m_cellps.emplace (!isIface, nodep);
1044
+ // m_cellps.emplace(!isIface, nodep);
1045
+ // const auto itim = m_cellps.cbegin();
1046
+ // AstNode* const cellp = itim->second;
1047
+ // m_cellps.erase(itim);
1048
+ AstNode* const cellp = nodep;
1049
+ AstNodeModule* srcModp = nullptr ;
1050
+ if (const auto * modCellp = VN_CAST (cellp, Cell)) {
1051
+ srcModp = modCellp->modp ();
1052
+ } else if (const auto * classRefp = VN_CAST (cellp, ClassOrPackageRef)) {
1053
+ srcModp = classRefp->classOrPackagep ();
1054
+ if (VN_IS (classRefp->classOrPackageNodep (), ParamTypeDType)) return ;
1055
+ } else if (const auto * classRefp = VN_CAST (cellp, ClassRefDType)) {
1056
+ srcModp = classRefp->classp ();
1057
+ } else {
1058
+ cellp->v3fatalSrc (" Expected module parameterization" );
1059
+ }
1060
+ UASSERT_OBJ (srcModp, cellp, " Unlinked class ref" );
1061
+
1062
+ // Update path
1063
+ string someInstanceName (m_modp->someInstanceName ());
1064
+ if (const string* const genHierNamep = cellp->user2u ().to <string*>()) {
1065
+ someInstanceName += *genHierNamep;
1066
+ cellp->user2p (nullptr );
1067
+ VL_DO_DANGLING (delete genHierNamep, genHierNamep);
1068
+ }
1069
+
1070
+ // Apply parameter specialization
1071
+ m_processor.nodeDeparam (cellp, srcModp /* ref */ , m_modp, someInstanceName);
1072
+
1073
+ visitModule (srcModp);
1074
+
1075
+ // // Add to the hierarchy registry
1076
+ // m_parentps[srcModp].insert(m_modp);
1093
1077
}
1094
1078
1095
1079
// RHSs of AstDots need a relink when LHS is a parameterized class reference
@@ -1113,25 +1097,14 @@ class ParamVisitor final : public VNVisitor {
1113
1097
if (nodep->dead ()) return ; // Marked by LinkDot (and above)
1114
1098
if (AstClass* const classp = VN_CAST (nodep, Class)) {
1115
1099
if (classp->isParameterized ()) {
1116
- // Don't enter into a definition.
1117
- // If a class is used, it will be visited through a reference
1100
+ // Collect param classes
1118
1101
m_paramClasses.push_back (classp);
1119
- return ;
1120
1102
}
1121
1103
}
1122
1104
1123
- if (m_iterateModule) { // Iterating body
1124
- UINFO (4 , " MOD-under-MOD. " << nodep << endl);
1125
- m_workQueue.emplace (nodep->level (), nodep); // Delay until current module is done
1126
- return ;
1127
- }
1128
-
1129
- // Start traversal at root-like things
1130
- if (nodep->level () <= 2 // Haven't added top yet, so level 2 is the top
1131
- || VN_IS (nodep, Class) // Nor moved classes
1132
- || VN_IS (nodep, Package)) { // Likewise haven't done wrapTopPackages yet
1133
- visitCells (nodep);
1134
- }
1105
+ // Only do root module & package here. Modules & classes used in parent module will be
1106
+ // visited from visitCellOrClassRef()
1107
+ if (nodep->level () <= 2 || VN_IS (nodep, Package)) visitModule (nodep);
1135
1108
}
1136
1109
1137
1110
void visit (AstCell* nodep) override {
@@ -1177,11 +1150,13 @@ class ParamVisitor final : public VNVisitor {
1177
1150
}
1178
1151
void visit (AstVarXRef* nodep) override {
1179
1152
// Check to see if the scope is just an interface because interfaces are special
1153
+ UINFO (9 , " Relink " << nodep << endl);
1180
1154
const string dotted = nodep->dotted ();
1181
1155
if (!dotted.empty () && nodep->varp () && nodep->varp ()->isParam ()) {
1182
1156
const AstNode* backp = nodep;
1183
1157
while ((backp = backp->backp ())) {
1184
1158
if (VN_IS (backp, NodeModule)) {
1159
+ nodep->v3error (" Failed to find referenced target" );
1185
1160
UINFO (9 , " Hit module boundary, done looking for interface" << endl);
1186
1161
break ;
1187
1162
}
@@ -1197,22 +1172,16 @@ class ParamVisitor final : public VNVisitor {
1197
1172
ifacerefp = VN_CAST (VN_CAST (backp, Var)->childDTypep ()->getChildDTypep (),
1198
1173
IfaceRefDType);
1199
1174
}
1175
+
1200
1176
// Interfaces passed in on the port map have ifaces
1201
- if (const AstIface* const ifacep = ifacerefp->ifacep ()) {
1202
- if (dotted == backp->name ()) {
1203
- UINFO (9 , " Iface matching scope: " << ifacep << endl);
1204
- if (ifaceParamReplace (nodep, ifacep->stmtsp ())) { //
1205
- return ;
1206
- }
1207
- }
1208
- }
1209
- // Interfaces declared in this module have cells
1210
- else if (const AstCell* const cellp = ifacerefp->cellp ()) {
1211
- if (dotted == cellp->name ()) {
1212
- UINFO (9 , " Iface matching scope: " << cellp << endl);
1213
- if (ifaceParamReplace (nodep, cellp->paramsp ())) { //
1214
- return ;
1215
- }
1177
+ const AstIface* ifacep = ifacerefp->ifaceViaCellp ();
1178
+ const string name
1179
+ = ifacerefp->cellp () ? ifacerefp->cellp ()->name () : backp->name ();
1180
+ if (dotted == name) {
1181
+ UINFO (9 , " Iface matching scope: " << ifacep << endl);
1182
+ if (ifaceParamReplace (nodep, ifacep->stmtsp ())) { //
1183
+ UINFO (9 , " Relpaced " << nodep << " -> iface " << ifacep << endl);
1184
+ return ;
1216
1185
}
1217
1186
}
1218
1187
}
0 commit comments