Skip to content

Commit d6bb0ad

Browse files
Version 1.4.31. Port-to-port bound via dynamically allocated signal supported
1 parent e300fe9 commit d6bb0ad

File tree

6 files changed

+156
-63
lines changed

6 files changed

+156
-63
lines changed

sc_tool/lib/sc_tool/SCToolFrontendAction.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ Object* getOuterArray(SCDesign& designDB, Object* memberObj)
123123
return arrayObj;
124124
}
125125

126-
const std::string SCElabASTConsumer::TOOL_VERSION = "1.4.29";
127-
const std::string SCElabASTConsumer::TOOL_DATE = "Jun 08,2022";
126+
const std::string SCElabASTConsumer::TOOL_VERSION = "1.4.31";
127+
const std::string SCElabASTConsumer::TOOL_DATE = "Jun 17,2022";
128128

129129
void SCElabASTConsumer::HandleTranslationUnit(clang::ASTContext &astCtx)
130130
{
@@ -148,7 +148,7 @@ void SCElabASTConsumer::HandleTranslationUnit(clang::ASTContext &astCtx)
148148
//const char* optNames[] = {doGenTerm, doGenCfg, doGenStmt, doModuleBuilder};
149149
//const char* optNames[] = {doConstCfg, doConstLoop, doConstStmt, doConstBlock, doModuleBuilder};
150150
//const char* optNames[] = {doConstStmt, doGenStmt, doModuleBuilder};
151-
const char* optNames[] = {doModuleBuilder};
151+
const char* optNames[] = {doPortBind, doModuleBuilder};
152152
size_t optSize = sizeof(optNames)/sizeof(const char*);
153153
//DebugOptions::enable(optNames, optSize);
154154

@@ -264,8 +264,8 @@ SCElabASTConsumer::moveDynamicObjects(SCDesign& designDB)
264264
// Get one parent module
265265
if (parentMod == nullptr) {
266266
if (arrParentMod == nullptr) {
267-
// No pointers to this object, do not print error
268-
// as it is possible for SVA
267+
// No pointers to this object, do not print error
268+
// as it is possible for SVA
269269
i++; continue;
270270

271271
} else {

sc_tool/lib/sc_tool/elab/ScElabModuleBuilder.cpp

+101-42
Original file line numberDiff line numberDiff line change
@@ -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

127129
private:
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)

sc_tool/lib/sc_tool/elab/ScObjectView.cpp

+36-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
using namespace sc;
2727
using namespace llvm;
28+
using std::cout; using std::endl;
2829

2930
namespace sc_elab
3031
{
@@ -90,6 +91,19 @@ ElabObjVec ObjectView::getPointers() const
9091
return res;
9192
}
9293

94+
ElabObjVec ObjectView::getPorts() const
95+
{
96+
ElabObjVec res;
97+
98+
for (auto pointerID : obj->pointer_ids()) {
99+
ObjectView pointer = db->getObj(pointerID);
100+
if (pointer.primitive()->isPort())
101+
res.push_back(pointer);
102+
}
103+
104+
return res;
105+
}
106+
93107
ObjectView ObjectView::getParent() const
94108
{
95109
SCT_TOOL_ASSERT (!isTopMod(), "");
@@ -189,7 +203,7 @@ std::deque<NodeT> getHierarchyNodeVec(ObjectView obj)
189203
obj = firstEl.getPointers()[0];
190204
resPath.emplace_front(PtrNode());
191205
} else {
192-
llvm_unreachable("ObjectView: Can find pointer to object");
206+
llvm_unreachable("ObjectView: Can not find pointer to object");
193207
}
194208
} else {
195209

@@ -338,6 +352,20 @@ ArrayElemObjWithIndices ObjectView::getAsArrayElementWithIndicies() const
338352
return ArrayElemObjWithIndices{element, indices};
339353
}
340354

355+
ArrayElemObjWithIndices ObjectView::getAsArrayElementWithIndicies(PortView port) const
356+
{
357+
if (isSignal() && isDynamic() && getPointers().size() == 0) {
358+
for (auto p : getPorts()) {
359+
if (p != port) {
360+
return p.getAsArrayElementWithIndicies();
361+
}
362+
}
363+
llvm_unreachable("No bound port found for dynamic signal");
364+
} else {
365+
return getAsArrayElementWithIndicies();
366+
}
367+
}
368+
341369
llvm::Optional<ObjectView> ObjectView::derefRecursively() const
342370
{
343371
Optional<ObjectView> res = *this;
@@ -713,8 +741,13 @@ llvm::Optional<ObjectView> ObjectView::getTopmostParentArray() const
713741
ObjectView parent;
714742

715743
if (isDynamic()) {
716-
SCT_TOOL_ASSERT (getPointers().size() == 1, "Multiples pointers");
717-
parent = getPointers()[0];
744+
// Dynamically allocated signal with leaked pointer
745+
if (getPointers().size() == 0) {
746+
parent = getParent();
747+
} else {
748+
SCT_TOOL_ASSERT (getPointers().size() == 1, "Multiples pointers");
749+
parent = getPointers()[0];
750+
}
718751
} else {
719752
parent = getParent();
720753
}

sc_tool/lib/sc_tool/elab/ScObjectView.h

+3
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ class ObjectView
153153

154154
/// Get list of pointer/reference objects pointing to this object
155155
ElabObjVec getPointers() const;
156+
/// Get list of ports (not-pointers) bound to this object
157+
ElabObjVec getPorts() const;
156158

157159
/// If Object is not a top level module, returns parent Object.
158160
/// otherwise behavior undefined
@@ -197,6 +199,7 @@ class ObjectView
197199
/// Example: Path to this object is MOD.x.y[2].z[3].bob
198200
/// Result: ( MOD.x.y[0].z[0].bob , (2,3) )
199201
ArrayElemObjWithIndices getAsArrayElementWithIndicies() const;
202+
ArrayElemObjWithIndices getAsArrayElementWithIndicies(PortView port) const;
200203

201204
/// If Object is pointer or reference, recursively deferefence it
202205
/// at return pointee object

0 commit comments

Comments
 (0)