torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Flattening.cpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
16 #ifdef HAVE_CONFIG_H
17 #include "torc/generic/config.h"
18 #endif //HAVE_CONFIG_H
19 #include <algorithm>
20 #include <iterator>
21 #include <ostream>
22 #include <sstream>
23 
25 
26 #include "torc/generic/View.hpp"
30 #include "torc/generic/Port.hpp"
36 #include "torc/generic/Net.hpp"
37 #include "torc/generic/Log.hpp"
38 #include "torc/generic/Cloning.hpp"
39 
40 namespace {
41 
42 using namespace torc::generic;
43 
44 class FlatteningHelpers {
45 public:
46 
47  static FlatteningHelpers* instance();
48 
49  inline NetNamingFunction getNetNamingFunction();
50 
51  inline void setNetNamingFunction(const NetNamingFunction& inNamingFunction);
52 
53  inline NetRenamingFunction getNetRenamingFunction();
54 
55  inline void setNetRenamingFunction(const NetRenamingFunction& inRenamingFunction);
56 
57  inline InstanceNamingFunction getInstanceNamingFunction();
58 
59  inline void setInstanceNamingFunction(const InstanceNamingFunction& inNamingFunction);
60 
61  inline InstanceRenamingFunction getInstanceRenamingFunction();
62 
63  inline void setInstanceRenamingFunction(const InstanceRenamingFunction& inRenamingFunction);
64 
65  inline std::string getSeparator();
66 
67  inline void setSeparator(const std::string& inSeparator);
68 
69  inline void reset();
70 
71 private:
72  FlatteningHelpers();
73 
74  FlatteningHelpers(const FlatteningHelpers&);
75  FlatteningHelpers& operator =(const FlatteningHelpers&);
76 
77  NetNamingFunction mNetNamingFunction;
78  NetRenamingFunction mNetRenamingFunction;
79  InstanceNamingFunction mInstanceNamingFunction;
80  InstanceRenamingFunction mInstanceRenamingFunction;
81  std::string mSeparator;
82 };
83 
84 FlatteningHelpers* FlatteningHelpers::instance() {
85  static FlatteningHelpers obj;
86  return &obj;
87 }
88 
89 inline NetNamingFunction FlatteningHelpers::getNetNamingFunction() {
90  return mNetNamingFunction;
91 }
92 
93 inline void FlatteningHelpers::setNetNamingFunction(const NetNamingFunction& inNetNamingFunction) {
94  mNetNamingFunction = inNetNamingFunction;
95 }
96 
97 inline NetRenamingFunction FlatteningHelpers::getNetRenamingFunction() {
98  return mNetRenamingFunction;
99 }
100 
101 inline void FlatteningHelpers::setNetRenamingFunction(
102  const NetRenamingFunction& inNetRenamingFunction) {
103  mNetRenamingFunction = inNetRenamingFunction;
104 }
105 
106 inline InstanceNamingFunction FlatteningHelpers::getInstanceNamingFunction() {
107  return mInstanceNamingFunction;
108 }
109 
110 inline void FlatteningHelpers::setInstanceNamingFunction(
111  const InstanceNamingFunction& inInstanceNamingFunction) {
112  mInstanceNamingFunction = inInstanceNamingFunction;
113 }
114 
115 inline InstanceRenamingFunction FlatteningHelpers::getInstanceRenamingFunction() {
116  return mInstanceRenamingFunction;
117 }
118 
119 inline void FlatteningHelpers::setInstanceRenamingFunction(
120  const InstanceRenamingFunction& inInstanceRenamingFunction) {
121  mInstanceRenamingFunction = inInstanceRenamingFunction;
122 }
123 
124 inline std::string FlatteningHelpers::getSeparator() {
125  return mSeparator;
126 }
127 
128 inline void FlatteningHelpers::setSeparator(const std::string& inSeparator) {
129  mSeparator = inSeparator;
130 }
131 
132 inline void FlatteningHelpers::reset() {
133  mInstanceRenamingFunction = InstanceRenamingFunction(getRenamedName<InstanceSharedPtr>);
134  mNetRenamingFunction = NetRenamingFunction(getRenamedName<NetSharedPtr>);
135  mInstanceNamingFunction = InstanceNamingFunction(getModifiedName<InstanceSharedPtr>);
136  mNetNamingFunction = NetNamingFunction(getModifiedName<NetSharedPtr>);
137  mSeparator = "/";
138 }
139 
140 FlatteningHelpers::FlatteningHelpers() : mNetNamingFunction(), mNetRenamingFunction(),
141  mInstanceNamingFunction(), mInstanceRenamingFunction(), mSeparator() {}
142 
143 template <typename _Pointer> struct NameModifier {
144 public:
145  static NameModifier* instance() {
146  static NameModifier obj;
147  return &obj;
148  }
149  std::string operator()(const std::string& inInstName, const _Pointer& inNameable,
150  const std::vector<size_t>& inIndicesVector = std::vector<size_t>()) {
151  std::string name;
152  name = inInstName + "_";
153  if(inIndicesVector.empty()) {
154  name += inNameable->getName();
155  } else {
156  std::ostringstream indices;
157  copy(inIndicesVector.begin(), inIndicesVector.end(),
158  std::ostream_iterator < size_t > (indices, "_"));
159  name += indices.str();
160  name += inNameable->getName();
161  }
162  if(name.length() > 255) {
163  std::map<std::string, std::string>::iterator it = mNameMap.find(name);
164  if(it != mNameMap.end()) {
165  return (*it).second;
166  }
167 
168  std::ostringstream sout;
169  sout << "N";
170  sout.width(8);
171  sout.fill('0');
172  sout << mNumber++;
173  std::string numericName = sout.str();
174  mNameMap.insert(std::make_pair(name, numericName));
175  return numericName;
176  }
177  return name;
178  }
179  NameModifier() :
180  mNameMap(), mNumber(1) {
181  }
182 
183  ~NameModifier() {
184  mNameMap.clear();
185  }
186 private:
187  std::map<std::string, std::string> mNameMap;
188  uint64_t mNumber;
189 
190 };
191 
192 void replicatePortRefConnections(const NetSharedPtr& inOrigNet, const NetSharedPtr& outTargetNet,
193  const ViewSharedPtr& inCurrentView, const InstanceSharedPtr& inInstance) {
194  log("Replicating portRef connections for %s to %s\n", inOrigNet->getName().c_str(),
195  outTargetNet->getName().c_str());
196  std::vector<PortReferenceSharedPtr> portRefs;
197  bool isBit = eCompositionTypeVectorBit == inOrigNet->getCompositionType();
198  inOrigNet->getConnectedPortRefs(portRefs, !isBit);
199  for(std::vector<PortReferenceSharedPtr>::iterator ref = portRefs.begin(); ref != portRefs.end();
200  ++ref) {
201  std::vector < std::string > nestedNames;
202  PortReferenceSharedPtr actualPortRef = *ref;
203  PortReferenceSharedPtr portRef = actualPortRef;
204  InstanceSharedPtr instance;
205  while(portRef) {
206  if(eCompositionTypeVectorBit != portRef->getCompositionType()) {
207  nestedNames.push_back(portRef->getName());
208  instance = portRef->getParent();
209  }
210  portRef = portRef->getParentCollection();
211  }
212  std::vector < size_t > indices;
213  if(eCompositionTypeVectorBit == instance->getCompositionType()) {
214  indices = IndexFinder<Instance, InstanceArrayMember>()(instance);
215  instance = instance->getParentCollection();
216  }
217  std::vector < size_t > originalInstanceIndex;
218  if(eCompositionTypeVectorBit == inInstance->getCompositionType()) {
219  originalInstanceIndex = IndexFinder<Instance, InstanceArrayMember>()(inInstance);
220  }
221  std::string newInstName = FlatteningHelpers::instance()->getInstanceNamingFunction()(
222  inInstance->getName(), instance, originalInstanceIndex);
223  InstanceSharedPtr targetInst = inCurrentView->findInstance(newInstName);
224  if(!indices.empty()) {
225  targetInst = targetInst->get(indices);
226  }
227  std::string portName = *nestedNames.rbegin();
228  PortReferenceSharedPtr targetPortRef = targetInst->findPortReference(portName);
229  if(!targetPortRef) {
230  //TBD::ERROR
231  }
232  if(nestedNames.size() > 1) {
233  findLeafConnectable(nestedNames, targetPortRef);
234  }
235  if(eCompositionTypeVectorBit == actualPortRef->getCompositionType()) {
236  std::vector < size_t > portRefIndices = IndexFinder<PortReference,
237  VectorPortBitReference>()(actualPortRef);
238  targetPortRef = targetPortRef->get(portRefIndices);
239  }
240  log("\tConnecting %s to net %s\n", targetPortRef->getName().c_str(),
241  outTargetNet->getName().c_str());
242  log("\tIndices: ");
243  targetPortRef->connect(outTargetNet);
244  }
245 }
246 
247 class PortRefConnectionReplicator : ScalarNet::Visitor, VectorNet::Visitor, VectorNetBit::Visitor,
249 private:
250 
251 public:
252 
253  void visit(ScalarNet& inScalarNet) throw (Error) {
254  try {
255  replicatePortRefConnections(inScalarNet.getSharedThis(), mTargetNet, mCurrentView,
256  mOriginalInstance);
257  } catch(Error& e) {
258  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
259  throw;
260  }
261  }
262 
263  void visit(VectorNet& inVectorNet) throw (Error) {
264  try {
265  replicatePortRefConnections(inVectorNet.getSharedThis(), mTargetNet, mCurrentView,
266  mOriginalInstance);
267 #if 0
268  std::vector<NetSharedPtr> children;
269  inVectorNet.getCreatedChildren(children);
270  for(std::vector<NetSharedPtr>::iterator it = children.begin(); it != children.end(); ++it) {
271  NetSharedPtr childNet = *it;
272  PortRefConnectionReplicator()(childNet,
273  mTargetNet->get(IndexFinder<PortReference, VectorPortBitReference>()(childNet)),
274  mCurrentView, mInstName);
275  }
276 #endif
277  } catch(Error& e) {
278  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
279  throw;
280  }
281  }
282 
283  void visit(VectorNetBit& inVectorNetBit) throw (Error) {
284  try {
285  replicatePortRefConnections(inVectorNetBit.getSharedThis(), mTargetNet, mCurrentView,
286  mOriginalInstance);
287  } catch(Error& e) {
288  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
289  throw;
290  }
291  }
292 
293  void visit(NetBundle& inNetBundle) throw (Error) {
294  try {
295  replicatePortRefConnections(inNetBundle.getSharedThis(), mTargetNet, mCurrentView,
296  mOriginalInstance);
297 #if 0
298  std::vector< NetSharedPtr > children;
299  inNetBundle.getChildren(children);
300  std::vector< NetSharedPtr > targetChildren;
301  mTargetNet->getChildren(targetChildren);
302  std::vector< NetSharedPtr >::iterator target
303  = targetChildren.begin();
304  for( std::vector< NetSharedPtr >::iterator it
305  = children.begin(); it != children.end();
306  ++it, ++target )
307  {
308  PortRefConnectionReplicator()( *it, *target,
309  mCurrentView, mInstName );
310  }
311 #endif
312  } catch(Error& e) {
313  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
314  throw;
315  }
316  }
317 
318  void operator ()(const NetSharedPtr& inOrigNet, const NetSharedPtr& outTargetNet,
319  const ViewSharedPtr& inCurrentView, const InstanceSharedPtr& inOriginalInstance)
320  throw (Error) {
321  try {
322  mTargetNet = outTargetNet;
323  mCurrentView = inCurrentView;
324  mOriginalInstance = inOriginalInstance;
325  inOrigNet->accept(*this);
326  } catch(Error& e) {
327  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
328  throw;
329  }
330  }
331 
332  ~PortRefConnectionReplicator() throw () {
333  }
334 
335 private:
336  NetSharedPtr mTargetNet;
337  ViewSharedPtr mCurrentView;
338  InstanceSharedPtr mOriginalInstance;
339 };
340 
341 void replicateNetConnections(const NetSharedPtr& inOrigNet, const ViewSharedPtr& inCurrentView,
342  const InstanceSharedPtr& inInstance, const ObjectFactorySharedPtr& inFactory,
343  const std::string& inInstName, NetSharedPtr& outClonedNet, const NetSharedPtr& inTargetNet)
344  throw (Error) {
345  try {
346 
347  std::vector<PortSharedPtr> ports;
348  inOrigNet->getConnectedPorts(ports, true);
349  if(ports.empty()) {
350  NetSharedPtr targetNet;
351  if(inTargetNet) {
352  targetNet = inTargetNet;
353  } else {
354  NetSharedPtr clonedNet = clone(inOrigNet, inFactory);
355  std::vector < size_t > indices;
356  if(eCompositionTypeVectorBit == inInstance->getCompositionType()) {
357  indices = IndexFinder<Instance, InstanceArrayMember>()(inInstance);
358  }
359  clonedNet->setName(
360  FlatteningHelpers::instance()->getNetNamingFunction()(inInstName, inOrigNet,
361  indices));
362  Renamable::Name renamedName =
363  FlatteningHelpers::instance()->getNetRenamingFunction()(inInstance, inOrigNet,
364  indices);
365  clonedNet->setOriginalName(renamedName);
366  inCurrentView->addNet(clonedNet);
367  outClonedNet = clonedNet;
368  targetNet = clonedNet;
369  }
370  PortRefConnectionReplicator()(inOrigNet, targetNet, inCurrentView, inInstance);
371  } else {
372  for(std::vector<PortSharedPtr>::iterator port = ports.begin(); port != ports.end();
373  ++port) {
374  std::vector < std::string > nestedNames;
375  PortSharedPtr actualPortRef = *port;
376  PortSharedPtr portRef = actualPortRef;
377  while(portRef) {
378  if(eCompositionTypeVectorBit != portRef->getCompositionType()) {
379  nestedNames.push_back(portRef->getName());
380  }
381  portRef = portRef->getParentCollection();
382  }
383  std::string portName = *nestedNames.rbegin();
384  PortReferenceSharedPtr origPortRef = inInstance->findPortReference(portName);
385  if(nestedNames.size() > 1) {
386  findLeafConnectable(nestedNames, origPortRef);
387  }
388  if(eCompositionTypeVectorBit == actualPortRef->getCompositionType()) {
389  origPortRef = origPortRef->get(
390  IndexFinder<Port, VectorPortBit>()(actualPortRef));
391  }
392  std::vector<NetSharedPtr> nets;
393  origPortRef->getConnectedNets(nets);
394  for(std::vector<NetSharedPtr>::iterator myNet = nets.begin(); myNet != nets.end();
395  ++myNet) {
396  NetSharedPtr connectedNet = *myNet;
397  PortRefConnectionReplicator()(inOrigNet, connectedNet, inCurrentView,
398  inInstance);
399  origPortRef->disconnect(connectedNet);
400  }
401  }
402  }
403  } catch(Error& e) {
404  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
405  throw;
406  }
407 }
408 
409 class NetConnectionReplicator : ScalarNet::Visitor, VectorNet::Visitor, VectorNetBit::Visitor,
411 public:
412 
413  void visit(ScalarNet& inScalarNet) throw (Error) {
414  try {
415  replicateNetConnections(inScalarNet.getSharedThis(), mCurrentView, mInstance, mFactory,
416  mInstName, mClonedNet, mTargetNet);
417  } catch(Error& e) {
418  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
419  throw;
420  }
421  }
422  void visit(VectorNet& inVectorNet) throw (Error) {
423  try {
424  std::vector<NetSharedPtr> children;
425  inVectorNet.getCreatedChildren(children);
426  NetSharedPtr targetVector = mClonedNet;
427  for(std::vector<NetSharedPtr>::iterator it = children.begin(); it != children.end();
428  ++it) {
429  NetConnectionReplicator()(*it, mCurrentView, mInstance, mFactory, mClonedNet,
430  targetVector, mInstName);
431  }
432  replicateNetConnections(inVectorNet.getSharedThis(), mCurrentView, mInstance, mFactory,
433  mInstName, mClonedNet, mTargetNet);
434  } catch(Error& e) {
435  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
436  throw;
437  }
438  }
439  void visit(VectorNetBit& inVectorNetBit) throw (Error) {
440  try {
441 #if 0
442  replicateNetConnections(inVectorNetBit.getSharedThis(), mCurrentView, mInstance, mFactory,
443  mInstName, mClonedNet, mTargetNet->get(inVectorNetBit.getIndices()));
444 #endif
445  NetSharedPtr origNet = inVectorNetBit.getSharedThis();
446  std::vector<PortSharedPtr> ports;
447  inVectorNetBit.getConnectedPorts(ports);
448 
449  //We now create scalar net and move my connections
450  //to this one
451  ScalarNetSharedPtr newScalarNet;
452  mFactory->create(newScalarNet);
453  std::vector < size_t > indices = IndexFinder<Net, VectorNetBit>()(origNet);
454  /*
455  std::ostringstream sout;
456  sout<<mInstName<<"_"<<origNet->getName()<<"_";
457  copy(indices.begin(), indices.end(),
458  std::ostream_iterator<size_t>(sout, "_"));
459  */
460  std::string newName = FlatteningHelpers::instance()->getNetNamingFunction()(mInstName,
461  origNet, indices);
462  Renamable::Name renamedName = FlatteningHelpers::instance()->getNetRenamingFunction()(
463  mInstance, origNet, indices);
464  newScalarNet->setName(newName);
465  newScalarNet->setOriginalName(renamedName);
466  mCurrentView->addNet(newScalarNet);
467  PortRefConnectionReplicator()(origNet, newScalarNet, mCurrentView, mInstance);
468 
469  for(std::vector<PortSharedPtr>::iterator port = ports.begin(); port != ports.end();
470  ++port) {
471  std::vector < std::string > nestedNames;
472  PortSharedPtr actualPort = *port;
473  PortSharedPtr portRef = actualPort;
474  while(portRef) {
475  if(eCompositionTypeVectorBit != portRef->getCompositionType()) {
476  nestedNames.push_back(portRef->getName());
477  }
478  portRef = portRef->getParentCollection();
479  }
480  std::string portName = *nestedNames.rbegin();
481  PortReferenceSharedPtr origPortRef = mInstance->findPortReference(portName);
482  if(nestedNames.size() > 1) {
483  findLeafConnectable(nestedNames, origPortRef);
484  }
485  if(eCompositionTypeVectorBit == actualPort->getCompositionType()) {
486  origPortRef = origPortRef->get(IndexFinder<Port, VectorPortBit>()(actualPort));
487  }
488  //Now have the port ref for this bit
489  //find all ports and refs that are connected to
490  //this ref and connect them to the newly created
491  //net
492  std::vector<NetSharedPtr> nets;
493  origPortRef->getConnectedNets(nets);
494  for(std::vector<NetSharedPtr>::iterator myNet = nets.begin(); myNet != nets.end();
495  myNet++) {
496  std::vector<PortSharedPtr> cPorts;
497  (*myNet)->getConnectedPorts(cPorts);
498  for(std::vector<PortSharedPtr>::iterator it = cPorts.begin();
499  it != cPorts.end(); ++it) {
500  (*it)->connect(newScalarNet);
501  }
502  std::vector<PortReferenceSharedPtr> cPortReferences;
503  (*myNet)->getConnectedPortRefs(cPortReferences);
504  for(std::vector<PortReferenceSharedPtr>::iterator it = cPortReferences.begin();
505  it != cPortReferences.end(); ++it) {
506  if(*it == origPortRef)
507  continue;
508  (*it)->connect(newScalarNet);
509  }
510  /*bool toDisconnect = true;*/
511  if(eCompositionTypeVectorBit == (*myNet)->getCompositionType()
512  && eCompositionTypeVectorBit == origPortRef->getCompositionType()) {
513  std::vector < size_t > netIdx = IndexFinder<Net, VectorNetBit>()(*myNet);
514  std::vector < size_t > portIdx = IndexFinder<PortReference,
515  VectorPortBitReference>()(origPortRef);
516  /*toDisconnect = !(netIdx == portIdx);*/
517  }
518  }
519  }
520  } catch(Error& e) {
521  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
522  throw;
523  }
524  }
525 
526  void visit(NetBundle& inNetBundle) throw (Error) {
527  try {
528  replicateNetConnections(inNetBundle.getSharedThis(), mCurrentView, mInstance, mFactory,
529  mInstName, mClonedNet, mTargetNet);
530  std::vector<NetSharedPtr> children;
531  inNetBundle.getChildren(children);
532  std::vector<NetSharedPtr> tChildren;
533  mClonedNet->getChildren(tChildren);
534  std::vector<NetSharedPtr>::iterator tNet = tChildren.begin();
535  for(std::vector<NetSharedPtr>::iterator it = children.begin(); it != children.end();
536  ++it, ++tNet) {
537  NetConnectionReplicator()(*it, mCurrentView, mInstance, mFactory, mClonedNet, *tNet,
538  mInstName);
539  }
540  } catch(Error& e) {
541  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
542  throw;
543  }
544  }
545 
546  void operator ()(const NetSharedPtr& inOrigNet, const ViewSharedPtr& inCurrentView,
547  const InstanceSharedPtr& inInstance, const ObjectFactorySharedPtr& inFactory,
548  NetSharedPtr& outClonedNet, NetSharedPtr& inTargetNet, const std::string& inInstName =
549  std::string()) throw (Error) {
550  try {
551  mCurrentView = inCurrentView;
552  mInstance = inInstance;
553  mFactory = inFactory;
554  mInstName = (inInstName.empty()) ? inInstance->getName() : inInstName;
555  mTargetNet = inTargetNet;
556  inOrigNet->accept(*this);
557  outClonedNet = mClonedNet;
558  } catch(Error& e) {
559  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
560  throw;
561  }
562  }
563 
564  ~NetConnectionReplicator() throw () {
565  }
566 
567 private:
568  ViewSharedPtr mCurrentView;
569  InstanceSharedPtr mInstance;
570  ObjectFactorySharedPtr mFactory;
571  std::string mInstName;
572  NetSharedPtr mClonedNet;
573  NetSharedPtr mTargetNet;
574 };
575 
576 // Add all flatten instances of a target instance
577 bool addFlattenInstances(const ViewSharedPtr& inParentView, const InstanceSharedPtr& inInstance,
578  const ObjectFactorySharedPtr& inFactory, std::list<InstanceSharedPtr>& outAddedInstances)
579  throw (Error) {
580  std::string name = inInstance->getName();
581  ViewSharedPtr masterView = inInstance->getMaster();
582  log("Flattening instance with name %s\n", name.c_str());
583 
584  log("Copying instantiations... ");
585  std::vector<InstanceSharedPtr> childInstances;
586  masterView->getInstances(childInstances);
587  if(childInstances.empty()) {
588  log("Leaf node.. cannot flatten\n");
589  return false;
590  }
591  std::vector<PortReferenceSharedPtr> portRefs;
592  inInstance->getPortReferences(portRefs);
593  std::string flatInstName;
594  std::vector < size_t > indices;
595  if(eCompositionTypeVectorBit == inInstance->getCompositionType()) {
596  indices = IndexFinder<Instance, InstanceArrayMember>()(inInstance);
597  }
598 
599  for(std::vector<InstanceSharedPtr>::iterator it = childInstances.begin();
600  it != childInstances.end(); ++it) {
601  InstanceSharedPtr inst = clone(*it, inFactory);
602  std::string instName;
603  instName = FlatteningHelpers::instance()->getInstanceNamingFunction()(name, inst, indices);
604  Renamable::Name renamedName = FlatteningHelpers::instance()->getInstanceRenamingFunction()(
605  inInstance, inst, indices);
606  log("Added Instance Name :: %s\n", instName.c_str());
607  inst->setName(instName);
608  inst->setOriginalName(renamedName);
609  inParentView->addInstance(inst);
610  outAddedInstances.push_back(inst);
611  }
612  log("Done\n");
613  return true;
614 }
615 
616 void flattenInstance(const ViewSharedPtr& inParentView, const InstanceSharedPtr& inInstance,
617  const ObjectFactorySharedPtr& inFactory, const std::string& inName = std::string())
618  throw (Error) {
619  std::string name = (!inName.empty()) ? inName : inInstance->getName();
620  ViewSharedPtr masterView = inInstance->getMaster();
621  std::vector<InstanceSharedPtr> childInstances;
622  masterView->getInstances(childInstances);
623  std::vector<PortReferenceSharedPtr> portRefs;
624  inInstance->getPortReferences(portRefs);
625 
626  //First we copy nets in the instance that are not connected
627  //to it's ports
628  log("Copying internal nets... ");
629  std::vector<NetSharedPtr> allNets;
630  masterView->getNets(allNets);
631  for(std::vector<NetSharedPtr>::iterator it = allNets.begin(); it != allNets.end(); ++it) {
632  NetSharedPtr origNet = *it;
633  NetSharedPtr clonedNet;
634  NetSharedPtr dummy;
635  NetConnectionReplicator()(origNet, inParentView, inInstance, inFactory, clonedNet, dummy);
636  }
637  log("Done\n");
638 }
639 
640 bool flatten_impl(const InstanceSharedPtr& inInstance, const ObjectFactorySharedPtr& inFactory,
641  std::list<InstanceSharedPtr>& outAddedInstances) throw (Error) {
642  if(!inInstance) {
643  //TBD::ERROR
644  return false;
645  }
646  ViewSharedPtr parentView = inInstance->getParent();
647  if(!parentView || !parentView->findInstance(inInstance->getName())) {
648  //TBD::ERROR
649  return false;
650  }
651  switch(inInstance->getCompositionType()) {
652  case eCompositionTypeScalar: {
653  try {
654  bool added = addFlattenInstances(parentView, inInstance, inFactory, outAddedInstances);
655  if(added) {
656  flattenInstance(parentView, inInstance, inFactory);
657  parentView->removeInstance(inInstance->getName());
658  } else {
659  return false;
660  }
661  break;
662  } catch(Error& e) {
663  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
664  throw;
665  }
666 
667  }
668  case eCompositionTypeVector: {
669  try {
670  std::vector<InstanceSharedPtr> children;
671  inInstance->getChildren(children);
672  bool added = false;
673  for(std::vector<InstanceSharedPtr>::iterator it = children.begin();
674  it != children.end(); ++it) {
675  added = addFlattenInstances(parentView, (*it), inFactory, outAddedInstances);
676  if(!added) {
677  break;
678  }
679  }
680  if(added) {
681  for(std::vector<InstanceSharedPtr>::iterator it = children.begin();
682  it != children.end(); ++it) {
683  flattenInstance(parentView, (*it), inFactory);
684  }
685  parentView->removeInstance(inInstance->getName());
686  } else {
687  return false;
688  }
689  } catch(Error& e) {
690  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
691  throw;
692  }
693  break;
694  }
695  default: {
696  throw Error(eMessageIdErrorUnsupoortedOperation, __FUNCTION__, __FILE__, __LINE__);
697  }
698  }
699  return true;
700 }
701 
702 }
703 
704 namespace torc {
705 namespace generic {
706 
707 template <typename _Pointer> std::string getModifiedName(const std::string& inInstName,
708  const _Pointer& inNameable, const std::vector<size_t>& inIndicesVector =
709  std::vector<size_t>()) {
710  return (*NameModifier<_Pointer>::instance())(inInstName, inNameable, inIndicesVector);
711 }
712 
713 template <typename _Pointer> std::string getRenamedName(const InstanceSharedPtr& inParentInstance,
714  const _Pointer& inRenamable, const std::vector<size_t>& inIndicesVector =
715  std::vector<size_t>()) {
716  std::string sep = FlatteningHelpers::instance()->getSeparator();
717  Renamable::Name originalName = inRenamable->getOriginalName();
718  if(originalName.empty()) {
719  originalName = inRenamable->getName();
720  }
721  std::string parentInstanceName = inParentInstance->getOriginalName();
722  if(parentInstanceName.empty()) {
723  parentInstanceName = inParentInstance->getName();
724  }
725  if(!inIndicesVector.empty()) {
726  parentInstanceName += "[ ";
727  std::ostringstream sout;
728  copy(inIndicesVector.begin(), inIndicesVector.end(),
729  std::ostream_iterator < size_t > (sout, " "));
730  parentInstanceName += sout.str();
731  parentInstanceName += "]";
732  }
733  std::ostringstream sout;
734  sout << ((parentInstanceName.find_first_of(sep)) ? sep : "") << parentInstanceName << sep
735  << originalName;
736  return sout.str();
737 }
738 
739 void flatten(const InstanceSharedPtr& inInstance, const ObjectFactorySharedPtr& inFactory,
740  bool inRecursive, const std::string& inSeparator,
741  const InstanceRenamingFunction& inInstanceRenameFunc,
742  const NetRenamingFunction& inNetRenameFunc, const InstanceNamingFunction& inInstanceNameFunc,
743  const NetNamingFunction& inNetNameFunc) throw (Error) {
744  FlatteningHelpers *pHelper = FlatteningHelpers::instance();
745  pHelper->setSeparator(inSeparator);
746  pHelper->setInstanceRenamingFunction(inInstanceRenameFunc);
747  pHelper->setNetRenamingFunction(inNetRenameFunc);
748  pHelper->setInstanceNamingFunction(inInstanceNameFunc);
749  pHelper->setNetNamingFunction(inNetNameFunc);
750  if(inRecursive) {
751  std::list<InstanceSharedPtr> newInstances;
752  if(!flatten_impl(inInstance, inFactory, newInstances)) {
753  return;
754  }
755  while(!newInstances.empty()) {
756  std::list<InstanceSharedPtr>::iterator top = newInstances.begin();
757  InstanceSharedPtr inst = *top;
758  newInstances.erase(top);
759  flatten_impl(inst, inFactory, newInstances);
760  }
761  } else {
762  std::list < InstanceSharedPtr > dummy;
763  flatten_impl(inInstance, inFactory, dummy);
764  }
765  pHelper->reset();
766  return;
767 }
768 
769 void flatten(const ViewSharedPtr& inView, const ObjectFactorySharedPtr& inFactory, bool inRecursive,
770  const std::string& inSeparator, const InstanceRenamingFunction& inInstanceRenameFunc,
771  const NetRenamingFunction& inNetRenameFunc, const InstanceNamingFunction& inInstanceNameFunc,
772  const NetNamingFunction& inNetNameFunc) throw (Error) {
773  if(!inView || !inFactory) {
774  return;
775  }
776  std::vector<InstanceSharedPtr> outInstances;
777  inView->getInstances(outInstances);
778  std::vector<InstanceSharedPtr>::iterator instIt = outInstances.begin();
779  for(; instIt != outInstances.end(); instIt++) {
780  InstanceSharedPtr inst = *instIt;
781  if(inst) {
782  flatten(inst, inFactory, inRecursive, inSeparator, inInstanceRenameFunc,
783  inNetRenameFunc, inInstanceNameFunc, inNetNameFunc);
784  }
785  }
786  return;
787 }
788 
789 void flatten(const DesignSharedPtr& inDesign, const ObjectFactorySharedPtr& inFactory,
790  bool inRecursive, const std::string& inSeparator,
791  const InstanceRenamingFunction& inInstanceRenameFunc,
792  const NetRenamingFunction& inNetRenameFunc, const InstanceNamingFunction& inInstanceNameFunc,
793  const NetNamingFunction& inNetNameFunc) throw (Error) {
794  if(!inDesign || !inFactory) {
795  return;
796  }
797  std::string cellName = inDesign->getCellRefName();
798  std::string libName = inDesign->getLibraryRefName();
799  RootSharedPtr root = inDesign->getParent();
800  if(!root) {
801  Error e(eMessageIdErrorPointerToItemDoesNotExist, __FUNCTION__, __FILE__, __LINE__);
802  e.saveContextData("Pointer to Root", root);
803  throw e;
804  }
805  LibrarySharedPtr library = root->findLibrary(libName);
806  if(!library) {
807  Error e(eMessageIdErrorPointerToItemDoesNotExist, __FUNCTION__, __FILE__, __LINE__);
808  e.saveContextData("Pointer to Library", library);
809  throw e;
810  }
811  CellSharedPtr cell = library->findCell(cellName);
812  if(!cell) {
813  Error e(eMessageIdErrorPointerToItemDoesNotExist, __FUNCTION__, __FILE__, __LINE__);
814  e.saveContextData("Pointer to Cell", cell);
815  throw e;
816  }
817 
818  std::vector<ViewSharedPtr> outViews;
819  cell->getViews(outViews);
820  std::vector<ViewSharedPtr>::iterator viewIt = outViews.begin();
821  for(; viewIt != outViews.end(); viewIt++) {
822  ViewSharedPtr view = *viewIt;
823  if(View::eTypeNetlist != view->getType()) {
824  continue;
825  }
826  flatten(view, inFactory, inRecursive, inSeparator, inInstanceRenameFunc, inNetRenameFunc,
827  inInstanceNameFunc, inNetNameFunc);
828  }
829 }
830 
831 template std::string getModifiedName(const std::string& inInstName, const NetSharedPtr& inNameable,
832  const std::vector<size_t>& inIndicesVector);
833 
834 template std::string getModifiedName(const std::string& inInstName,
835  const InstanceSharedPtr& inNameable, const std::vector<size_t>& inIndicesVector);
836 
837 template std::string getRenamedName(const InstanceSharedPtr& inParentInstance,
838  const NetSharedPtr& inRenamable, const std::vector<size_t>& inIndicesVector);
839 
840 template std::string getRenamedName(const InstanceSharedPtr& inParentInstance,
841  const InstanceSharedPtr& inRenamable, const std::vector<size_t>& inIndicesVector);
842 
843 } //namespace generic
844 } //namespace torc
An acyclic inoutVisitor implementation.
Definition: VisitorType.hpp:57
void log(const char *fmt,...)
Definition: Log.cpp:89
Represents a bit of a net array.
boost::shared_ptr< Instance > InstanceSharedPtr
void findLeafConnectable(std::vector< std::string > &nestedNames, boost::shared_ptr< _Connectable > &conn)
Represents the usable instance of a port of a cell in another cell.
boost::shared_ptr< ScalarNet > ScalarNetSharedPtr
std::string getModifiedName(const std::string &inInstName, const _Pointer &inNameable, const std::vector< size_t > &inIndicesVector=std::vector< size_t >())
Definition: Flattening.cpp:707
boost::shared_ptr< ObjectFactory > ObjectFactorySharedPtr
std::string string
boost::shared_ptr< Design > DesignSharedPtr
boost::shared_ptr< _Tp > clone(const boost::shared_ptr< _Tp > &inPointer, const ObjectFactorySharedPtr &inFactory)
Definition: Cloning.hpp:63
The Error object thrown by different methods of EdifOM.
Definition: Error.hpp:41
boost::shared_ptr< Net > NetSharedPtr
boost::shared_ptr< Library > LibrarySharedPtr
boost::shared_ptr< PortReference > PortReferenceSharedPtr
Represents a net array.
Definition: VectorNet.hpp:42
Contains functions for flattening a design.
Represents a standalone net.
Definition: ScalarNet.hpp:42
void saveContextData(const std::string &inName, const boost::any &inSource)
Definition: Error.cpp:79
boost::function< std::string(const InstanceSharedPtr &inParentInstance, const NetSharedPtr &inNet, const std::vector< size_t > &inIndicesVector)> NetRenamingFunction
Function to create names of nets that are set in rename constructs.
Definition: Flattening.hpp:54
boost::function< std::string(const InstanceSharedPtr &inParentInstance, const InstanceSharedPtr &inInstance, const std::vector< size_t > &inIndicesVector)> InstanceRenamingFunction
Function to create names of nets that are set in rename constructs.
Definition: Flattening.hpp:62
Represents a reference to a bit of a port.
std::string getRenamedName(const InstanceSharedPtr &inParentInstance, const _Pointer &inRenamable, const std::vector< size_t > &inIndicesVector=std::vector< size_t >())
Definition: Flattening.cpp:713
Represents a bundle of nets.
Definition: NetBundle.hpp:43
boost::shared_ptr< View > ViewSharedPtr
boost::shared_ptr< Cell > CellSharedPtr
boost::shared_ptr< Port > PortSharedPtr
boost::function< std::string(const std::string &inParentInstanceName, const NetSharedPtr &inNet, const std::vector< size_t > &inIndicesVector)> NetNamingFunction
Function to create net names during flattening.
Definition: Flattening.hpp:39
void flatten(const InstanceSharedPtr &inInstance, const ObjectFactorySharedPtr &inFactory, bool inRecursive, const std::string &inSeparator, const InstanceRenamingFunction &inInstanceRenameFunc, const NetRenamingFunction &inNetRenameFunc, const InstanceNamingFunction &inInstanceNameFunc, const NetNamingFunction &inNetNameFunc)
Definition: Flattening.cpp:739
boost::function< std::string(const std::string &inParentInstanceName, const InstanceSharedPtr &inInstance, const std::vector< size_t > &inIndicesVector)> InstanceNamingFunction
Function to create instance names during flattening.
Definition: Flattening.hpp:47
boost::shared_ptr< Root > RootSharedPtr
void setCurrentLocation(const std::string &inFunction, const std::string &inFile, uint32_t inLine)
Definition: Error.cpp:73