@@ -123,6 +123,8 @@ class ScElabModuleBuilder
123
123
ObjectView curScObj;
124
124
125
125
UniqueNamesGenerator modNameGen;
126
+ // Ports bound to dynamic allocated signal leaked, used for target/initiator
127
+ std::unordered_set<PortView> bindedDynamicPorts;
126
128
127
129
private:
128
130
@@ -846,16 +848,37 @@ void ScElabModuleBuilder::createPortBindingsKeepArrays(VerilogModule &verMod)
846
848
std::unordered_set<PortView> bindedPortsSet; // set of already bound ports
847
849
848
850
for (PortView port : verMod.getScPorts ()) {
849
-
851
+ // cout << "port " << port.getDebugString() << endl;
850
852
if (bindedPortsSet.count (port)) continue ;
851
853
852
854
// Get directly bound port/signal to this port
853
855
auto directBind = port.getDirectBind ();
854
- // If port is array element this function returns all elements with indices
855
- // Index object is vector contains all indices to support
856
- // multidimensional array
857
- auto allArrayPorts = port.getAllSimilarArrayElements ();
858
- auto allArrayBinds = directBind.getAllSimilarArrayElements ();
856
+ // cout << " directBind " << directBind.getDebugString() << endl;
857
+
858
+ ArrayElemVec allArrayPorts;
859
+ ArrayElemVec allArrayBinds;
860
+ if (directBind.isSignal () && directBind.isDynamic () &&
861
+ directBind.getPointers ().size () == 0 ) {
862
+ // Port bound to dynamic signal declared as local variable (leaked)
863
+ allArrayPorts = port.getAllSimilarArrayElements ();
864
+ for (auto p : directBind.getPorts ()) {
865
+ if (p != port) {
866
+ // cout << " portToBind " << p.getDebugString() << endl;
867
+ allArrayBinds = p.getAllSimilarArrayElements ();
868
+ bindedDynamicPorts.insert (p);
869
+ break ;
870
+ }
871
+ }
872
+ bindedDynamicPorts.insert (port);
873
+
874
+ } else {
875
+ // If port is array element this function returns all elements with indices
876
+ // Index object is vector contains all indices to support
877
+ // multidimensional array
878
+ allArrayPorts = port.getAllSimilarArrayElements ();
879
+ allArrayBinds = directBind.getAllSimilarArrayElements ();
880
+ }
881
+
859
882
// Check each element is bound to element with the same index
860
883
bool isFlattenBind = isFlattenArrayBind (allArrayPorts, allArrayBinds);
861
884
@@ -878,10 +901,22 @@ void ScElabModuleBuilder::uniformBind(const PortView &port)
878
901
auto verVars = portHostMod->getVerVariables (port);
879
902
auto bindDirection = getBindDirection (port);
880
903
881
- for (auto * verVar : verVars) {
882
- if (bindDirection == BIND_UP || bindDirection == BIND_CROSS || bindDirection == BIND_EXTERNAL) {
904
+ for (auto * verVar : verVars) {
905
+ if (bindDirection == BIND_EXTERNAL) {
906
+ // cout << " bind external" << endl;
883
907
portHostMod->convertToPort (verVar, port.getDirection ());
884
- } else if (bindDirection == BIND_DOWN || bindDirection == BIND_SAME) {
908
+
909
+ } else
910
+ if (bindDirection == BIND_CROSS || bindDirection == BIND_UP) {
911
+ // cout << " bind up/cross" << endl;
912
+ if (bindedDynamicPorts.count (port)) {
913
+ portHostMod->convertToSignal (verVar);
914
+ } else {
915
+ portHostMod->convertToPort (verVar, port.getDirection ());
916
+ }
917
+ } else
918
+ if (bindDirection == BIND_DOWN || bindDirection == BIND_SAME) {
919
+ // cout << " bind dowm/same" << endl;
885
920
portHostMod->convertToSignal (verVar);
886
921
}
887
922
}
@@ -998,11 +1033,15 @@ void ScElabModuleBuilder::bindPortUpAux(PortView portEl,
998
1033
const VerilogVarsVec &verPortVars, bool isUniformArrayBind)
999
1034
{
1000
1035
auto portHostMod = portEl.getParentModule ();
1001
- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1036
+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl );
1002
1037
auto topParentMod = bindedObj.obj .getParentModule ();
1038
+
1039
+ auto directBind = portEl.getDirectBind ();
1040
+ bool boundDynamicSig = directBind.isSignal () && directBind.isDynamic () &&
1041
+ directBind.getPointers ().size () == 0 ;
1003
1042
1004
1043
DEBUG_WITH_TYPE (DebugOptions::doPortBind,
1005
- llvm::outs () << " bindPortUpAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1044
+ llvm::outs () << " bindPortUpAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1006
1045
);
1007
1046
1008
1047
auto parentModsList = portEl.getParentModulesList (topParentMod);
@@ -1023,7 +1062,7 @@ void ScElabModuleBuilder::bindPortUpAux(PortView portEl,
1023
1062
parentModsList.at (i - 1 ));
1024
1063
VerilogModuleInstance *instance = hostVerMod->getInstance (
1025
1064
instanceModObj);
1026
-
1065
+
1027
1066
// We need to create auxiliary ports in all host modules except last one
1028
1067
// which contains a signal we will be binding to
1029
1068
if (!last) {
@@ -1043,9 +1082,12 @@ void ScElabModuleBuilder::bindPortUpAux(PortView portEl,
1043
1082
1044
1083
SCT_TOOL_ASSERT (hostVars.size () == instanceVars.size (), " " );
1045
1084
1046
- for (size_t i = 0 ; i < hostVars.size (); ++i) {
1047
- instance->addBinding (instanceVars[i], {hostVars[i], bindedIndexes});
1048
- hostVerMod->addVarBindedInMod (hostVars[i]);
1085
+ // Do not create duplicating port bindings as its created at parent
1086
+ if (!boundDynamicSig) {
1087
+ for (size_t i = 0 ; i < hostVars.size (); ++i) {
1088
+ instance->addBinding (instanceVars[i], {hostVars[i], bindedIndexes});
1089
+ hostVerMod->addVarBindedInMod (hostVars[i]);
1090
+ }
1049
1091
}
1050
1092
1051
1093
// on next iteration current host is an instance
@@ -1058,17 +1100,20 @@ void ScElabModuleBuilder::bindPortSameAux(PortView portEl,
1058
1100
const VerilogVarsVec &verPortVars,
1059
1101
bool isUniformArrayBind)
1060
1102
{
1061
- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1103
+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl );
1062
1104
IndexVec bindedIndices;
1063
1105
if (!isUniformArrayBind) {
1064
1106
bindedIndices = bindedObj.indices ;
1065
1107
}
1066
1108
1067
1109
DEBUG_WITH_TYPE (DebugOptions::doPortBind,
1068
- llvm::outs () << " bindPortSameAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1110
+ llvm::outs () << " bindPortSameAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1069
1111
);
1070
1112
1071
- auto *hostVerMod = elabDB->getVerilogModule (portEl.getParentModule ());
1113
+ auto * hostVerMod = elabDB->getVerilogModule (bindedObj.obj .getParentModule ());
1114
+ auto * portVerMod = elabDB->getVerilogModule (portEl.getParentModule ());
1115
+ // cout << "hostVerMod " << hostVerMod->getName() << endl;
1116
+
1072
1117
auto bindedVerVars = hostVerMod->getVerVariables (bindedObj.obj );
1073
1118
bool isPortInMIF = portEl.getParentModuleOrMIF ().isModularInterface ();
1074
1119
bool isIntrinsic = hostVerMod->isIntrinsic ();
@@ -1083,14 +1128,18 @@ void ScElabModuleBuilder::bindPortSameAux(PortView portEl,
1083
1128
SCT_TOOL_ASSERT (bindedVerVars.size () == verPortVars.size (),
1084
1129
" Different sizes of bind and target port variables" );
1085
1130
1086
- for (size_t i = 0 ; i < verPortVars.size (); ++i) {
1087
- if (portEl.isInput ()) {
1088
- hostVerMod->addAssignment ({verPortVars[i], {}},
1089
- {bindedVerVars[i], bindedIndices});
1090
- }
1091
- else if (portEl.isOutput ()) {
1092
- hostVerMod->addAssignment ({bindedVerVars[i], bindedIndices},
1093
- {verPortVars[i], {}});
1131
+ // Check port variable and bound variable are in the same module
1132
+ // Do not assign variables belongs to different modules, required for target/initiator
1133
+ if (*portVerMod == *hostVerMod) {
1134
+ for (size_t i = 0 ; i < verPortVars.size (); ++i) {
1135
+ if (portEl.isInput ()) {
1136
+ hostVerMod->addAssignment ({verPortVars[i], {}},
1137
+ {bindedVerVars[i], bindedIndices});
1138
+ }
1139
+ else if (portEl.isOutput ()) {
1140
+ hostVerMod->addAssignment ({bindedVerVars[i], bindedIndices},
1141
+ {verPortVars[i], {}});
1142
+ }
1094
1143
}
1095
1144
}
1096
1145
}
@@ -1099,11 +1148,12 @@ void ScElabModuleBuilder::bindPortDownAux(PortView portEl,
1099
1148
const VerilogVarsVec &verPortVars,
1100
1149
bool isUniformArrayBind)
1101
1150
{
1102
- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1103
- auto bindedParentMods = bindedObj.obj .getParentModulesList (portEl.getParentModule ());
1151
+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl);
1152
+ auto bindedParentMods = bindedObj.obj .getParentModulesList (
1153
+ portEl.getParentModule ());
1104
1154
1105
1155
DEBUG_WITH_TYPE (DebugOptions::doPortBind,
1106
- llvm::outs () << " bindPortDownAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1156
+ llvm::outs () << " bindPortDownAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1107
1157
);
1108
1158
1109
1159
PortDirection virtualDirection;
@@ -1120,15 +1170,14 @@ void ScElabModuleBuilder::bindPortDownAux(PortView portEl,
1120
1170
1121
1171
ModuleMIFView instModView = bindedParentMods[i];
1122
1172
VerilogModule *instVerMod = elabDB->getVerilogModule (instModView);
1123
- VerilogModule *hostVerMod = elabDB->getVerilogModule (
1124
- bindedParentMods[i - 1 ]);
1173
+ VerilogModule *hostVerMod = elabDB->getVerilogModule (bindedParentMods[i-1 ]);
1125
1174
VerilogModuleInstance *instance = hostVerMod->getInstance (instModView);
1126
1175
1127
1176
// create virtual ports inside instance module
1128
1177
for (const auto *verVar: verPortVars) {
1129
1178
auto *portVar = instVerMod->createAuxilaryPort (virtualDirection,
1130
- verVar->getName (), verVar->getBitwidth (), verVar-> getArrayDims (), verVar-> isSigned ());
1131
-
1179
+ verVar->getName (), verVar->getBitwidth (),
1180
+ verVar-> getArrayDims (), verVar-> isSigned ());
1132
1181
instanceVars.push_back (portVar);
1133
1182
}
1134
1183
@@ -1171,11 +1220,11 @@ void ScElabModuleBuilder::bindPortCrossAux(PortView portEl,
1171
1220
bool isUniformArrayBind)
1172
1221
{
1173
1222
// First bind up to common Parent, then bind down to bindedObj
1174
- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1223
+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl );
1175
1224
ModuleMIFView commonParentMod = portEl.nearestCommonParentModule (bindedObj.obj );
1176
1225
1177
1226
DEBUG_WITH_TYPE (DebugOptions::doPortBind,
1178
- llvm::outs () << " bindPortCrossAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1227
+ llvm::outs () << " bindPortCrossAux BIND " << portEl << " to " << bindedObj.obj << " \n " ;
1179
1228
);
1180
1229
1181
1230
VerilogVarsVec hostVars;
@@ -1380,7 +1429,7 @@ void ScElabModuleBuilder::bindPortExternalAux(PortView portEl,
1380
1429
auto topModView = elabDB->getTopModule ();
1381
1430
1382
1431
DEBUG_WITH_TYPE (DebugOptions::doPortBind,
1383
- llvm::outs () << " bindPortExternalAux BIND " << portEl << " \n " ;
1432
+ llvm::outs () << " bindPortExternalAux BIND " << portEl << " \n " ;
1384
1433
);
1385
1434
1386
1435
VerilogVarsVec hostVars;
@@ -1478,19 +1527,29 @@ bool ScElabModuleBuilder::isFlattenArrayBind (
1478
1527
return flattenArrayBind;
1479
1528
}
1480
1529
1481
- ScElabModuleBuilder::BindDirection ScElabModuleBuilder::getBindDirection (
1482
- PortView portView ) const
1530
+ ScElabModuleBuilder::BindDirection
1531
+ ScElabModuleBuilder::getBindDirection ( PortView port ) const
1483
1532
{
1484
- auto bindedObj = portView .getDirectBind ();
1533
+ auto bindedObj = port .getDirectBind ();
1485
1534
1535
+ // Replace dynamic signal with ports bound to it, required for target/initiator
1536
+ if (bindedObj.isSignal () && bindedObj.isDynamic () &&
1537
+ bindedObj.getPointers ().size () == 0 ) {
1538
+ for (auto p : bindedObj.getPorts ()) {
1539
+ if (p != port) {
1540
+ bindedObj = p;
1541
+ }
1542
+ }
1543
+ }
1544
+
1486
1545
if (bindedObj.hasNoParent ())
1487
1546
return BindDirection::BIND_EXTERNAL;
1488
1547
1489
- auto thisParentMod = portView .getParentModule ();
1548
+ auto thisParentMod = port .getParentModule ();
1490
1549
auto bindedParentMod = bindedObj.getParentModule ();
1491
1550
// Find common parent
1492
- auto commonParentMod = portView .nearestCommonParentModule (bindedObj);
1493
-
1551
+ auto commonParentMod = port .nearestCommonParentModule (bindedObj);
1552
+
1494
1553
if (bindedParentMod == thisParentMod)
1495
1554
return BindDirection::BIND_SAME;
1496
1555
else if (commonParentMod == thisParentMod)
0 commit comments