@@ -123,6 +123,8 @@ class ScElabModuleBuilder
123123 ObjectView curScObj;
124124
125125 UniqueNamesGenerator modNameGen;
126+ // Ports bound to dynamic allocated signal leaked, used for target/initiator
127+ std::unordered_set<PortView> bindedDynamicPorts;
126128
127129private:
128130
@@ -846,16 +848,37 @@ void ScElabModuleBuilder::createPortBindingsKeepArrays(VerilogModule &verMod)
846848 std::unordered_set<PortView> bindedPortsSet; // set of already bound ports
847849
848850 for (PortView port : verMod.getScPorts ()) {
849-
851+ // cout << "port " << port.getDebugString() << endl;
850852 if (bindedPortsSet.count (port)) continue ;
851853
852854 // Get directly bound port/signal to this port
853855 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+
859882 // Check each element is bound to element with the same index
860883 bool isFlattenBind = isFlattenArrayBind (allArrayPorts, allArrayBinds);
861884
@@ -878,10 +901,22 @@ void ScElabModuleBuilder::uniformBind(const PortView &port)
878901 auto verVars = portHostMod->getVerVariables (port);
879902 auto bindDirection = getBindDirection (port);
880903
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;
883907 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;
885920 portHostMod->convertToSignal (verVar);
886921 }
887922 }
@@ -998,11 +1033,15 @@ void ScElabModuleBuilder::bindPortUpAux(PortView portEl,
9981033 const VerilogVarsVec &verPortVars, bool isUniformArrayBind)
9991034{
10001035 auto portHostMod = portEl.getParentModule ();
1001- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1036+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl );
10021037 auto topParentMod = bindedObj.obj .getParentModule ();
1038+
1039+ auto directBind = portEl.getDirectBind ();
1040+ bool boundDynamicSig = directBind.isSignal () && directBind.isDynamic () &&
1041+ directBind.getPointers ().size () == 0 ;
10031042
10041043 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 " ;
10061045 );
10071046
10081047 auto parentModsList = portEl.getParentModulesList (topParentMod);
@@ -1023,7 +1062,7 @@ void ScElabModuleBuilder::bindPortUpAux(PortView portEl,
10231062 parentModsList.at (i - 1 ));
10241063 VerilogModuleInstance *instance = hostVerMod->getInstance (
10251064 instanceModObj);
1026-
1065+
10271066 // We need to create auxiliary ports in all host modules except last one
10281067 // which contains a signal we will be binding to
10291068 if (!last) {
@@ -1043,9 +1082,12 @@ void ScElabModuleBuilder::bindPortUpAux(PortView portEl,
10431082
10441083 SCT_TOOL_ASSERT (hostVars.size () == instanceVars.size (), " " );
10451084
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+ }
10491091 }
10501092
10511093 // on next iteration current host is an instance
@@ -1058,17 +1100,20 @@ void ScElabModuleBuilder::bindPortSameAux(PortView portEl,
10581100 const VerilogVarsVec &verPortVars,
10591101 bool isUniformArrayBind)
10601102{
1061- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1103+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl );
10621104 IndexVec bindedIndices;
10631105 if (!isUniformArrayBind) {
10641106 bindedIndices = bindedObj.indices ;
10651107 }
10661108
10671109 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 " ;
10691111 );
10701112
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+
10721117 auto bindedVerVars = hostVerMod->getVerVariables (bindedObj.obj );
10731118 bool isPortInMIF = portEl.getParentModuleOrMIF ().isModularInterface ();
10741119 bool isIntrinsic = hostVerMod->isIntrinsic ();
@@ -1083,14 +1128,18 @@ void ScElabModuleBuilder::bindPortSameAux(PortView portEl,
10831128 SCT_TOOL_ASSERT (bindedVerVars.size () == verPortVars.size (),
10841129 " Different sizes of bind and target port variables" );
10851130
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+ }
10941143 }
10951144 }
10961145}
@@ -1099,11 +1148,12 @@ void ScElabModuleBuilder::bindPortDownAux(PortView portEl,
10991148 const VerilogVarsVec &verPortVars,
11001149 bool isUniformArrayBind)
11011150{
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 ());
11041154
11051155 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 " ;
11071157 );
11081158
11091159 PortDirection virtualDirection;
@@ -1120,15 +1170,14 @@ void ScElabModuleBuilder::bindPortDownAux(PortView portEl,
11201170
11211171 ModuleMIFView instModView = bindedParentMods[i];
11221172 VerilogModule *instVerMod = elabDB->getVerilogModule (instModView);
1123- VerilogModule *hostVerMod = elabDB->getVerilogModule (
1124- bindedParentMods[i - 1 ]);
1173+ VerilogModule *hostVerMod = elabDB->getVerilogModule (bindedParentMods[i-1 ]);
11251174 VerilogModuleInstance *instance = hostVerMod->getInstance (instModView);
11261175
11271176 // create virtual ports inside instance module
11281177 for (const auto *verVar: verPortVars) {
11291178 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 ());
11321181 instanceVars.push_back (portVar);
11331182 }
11341183
@@ -1171,11 +1220,11 @@ void ScElabModuleBuilder::bindPortCrossAux(PortView portEl,
11711220 bool isUniformArrayBind)
11721221{
11731222 // First bind up to common Parent, then bind down to bindedObj
1174- auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies ();
1223+ auto bindedObj = portEl.getDirectBind ().getAsArrayElementWithIndicies (portEl );
11751224 ModuleMIFView commonParentMod = portEl.nearestCommonParentModule (bindedObj.obj );
11761225
11771226 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 " ;
11791228 );
11801229
11811230 VerilogVarsVec hostVars;
@@ -1380,7 +1429,7 @@ void ScElabModuleBuilder::bindPortExternalAux(PortView portEl,
13801429 auto topModView = elabDB->getTopModule ();
13811430
13821431 DEBUG_WITH_TYPE (DebugOptions::doPortBind,
1383- llvm::outs () << " bindPortExternalAux BIND " << portEl << " \n " ;
1432+ llvm::outs () << " bindPortExternalAux BIND " << portEl << " \n " ;
13841433 );
13851434
13861435 VerilogVarsVec hostVars;
@@ -1478,19 +1527,29 @@ bool ScElabModuleBuilder::isFlattenArrayBind (
14781527 return flattenArrayBind;
14791528}
14801529
1481- ScElabModuleBuilder::BindDirection ScElabModuleBuilder::getBindDirection (
1482- PortView portView ) const
1530+ ScElabModuleBuilder::BindDirection
1531+ ScElabModuleBuilder::getBindDirection ( PortView port ) const
14831532{
1484- auto bindedObj = portView .getDirectBind ();
1533+ auto bindedObj = port .getDirectBind ();
14851534
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+
14861545 if (bindedObj.hasNoParent ())
14871546 return BindDirection::BIND_EXTERNAL;
14881547
1489- auto thisParentMod = portView .getParentModule ();
1548+ auto thisParentMod = port .getParentModule ();
14901549 auto bindedParentMod = bindedObj.getParentModule ();
14911550 // Find common parent
1492- auto commonParentMod = portView .nearestCommonParentModule (bindedObj);
1493-
1551+ auto commonParentMod = port .nearestCommonParentModule (bindedObj);
1552+
14941553 if (bindedParentMod == thisParentMod)
14951554 return BindDirection::BIND_SAME;
14961555 else if (commonParentMod == thisParentMod)
0 commit comments