torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ModuleTransformer.hpp
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 /// \file
17 /// \brief ModuleTransformer class to modularize/flatten designs.
18 
19 #ifndef TORC_PHYSICAL_MODULETRANSFORMER_HPP
20 #define TORC_PHYSICAL_MODULETRANSFORMER_HPP
21 
22 #include "torc/Architecture.hpp"
24 #include <boost/lexical_cast.hpp>
25 
26 using namespace std;
27 using namespace torc::architecture;
28 using namespace torc::architecture::xilinx;
29 
30 namespace torc {
31 namespace physical {
32 
33  /// \brief Utility class to modularize/flatten designs.
35 
36  protected:
37  // typedefs
38  /// \brief Imported type.
40  /// \brief Imported type.
42  /// \brief Imported type.
44  /// \brief Imported type.
46  /// \brief Imported type.
48  /// \brief Imported type.
50  /// \brief Imported type.
52  /// \brief Imported type.
54  // members
55  /// \brief Design pointer.
57  /// \brief Hierarchy separator.
58  static const string sHierarchySeparator;
59  /// \brief Port index separator.
60  static const string sPortIndexSeparator;
61  /// \brief Valid characters in a pin name.
62  static const boost::regex sValidPinNameCharactersRegEx;
63  /// \brief Invalid first characters in a pin name.
64  static const boost::regex sInvalidPinNameFirstCharactersRegEx;
65  // types
66  /// \brief Net connectivity with respect to module instance, either not connected
67  /// to module, internal to module, or external to module.
69  eNetConnectivityNotConnected = 0, eNetConnectivityInternal, eNetConnectivityExternal
70  };
71 
72  public:
73  // constructors
74  /// \brief Public constructor.
75  /// \param inDesignPtr Pointer to the design.
76  ModuleTransformer(DesignSharedPtr& inDesignPtr) : mDesignPtr(inDesignPtr) {}
77 
78  /// \brief Group a set of instances into a module.
79  /// \param inInstances The vector of instances to group.
80  /// \param inModuleDefinitionName The module definition name.
81  /// \param inModuleInstanceName The module instance name.
82  /// \param inKeepPlacement A flag specifying whether placement should be retained after
83  /// modularization. Default to false.
84  /// \param inKeepRouting A flag specifying whether routing should be retained afer
85  /// modularization. Defaults to false.
86  /*
87  * Function pseudocode
88  *
89  * bool modularize(InstanceSharedPtrVector inInstances,
90  * string inModuleDefinitionName,
91  * string inModuleInstanceNamebool,
92  * bool inKeepPlacement = false,
93  * bool inKeepRouting = false)
94  * {
95  * if(inInstances size == 0)
96  * {
97  * warn user that inInstances is empty;
98  * return false;
99  * }
100  * create module definition, anchor point is first instance in inInstances;
101  * create module instance, placed where anchor point is placed;
102  * //handle instances
103  * iterate over inInstances
104  * {
105  * if(instance not found)
106  * {
107  * warn user that instance not found;
108  * return false;
109  * }
110  * if(!inKeepPlacement) unplace instance;
111  * move instance from design to module definition;
112  * }
113  * //handle nets
114  * iterate over design nets
115  * {
116  * if(!inKeepRouting) unroute net;
117  * if(net is internal to module)
118  * {
119  * move net from design to module definition;
120  * }
121  * else if(net is external to module)
122  * {
123  * //handle net sources
124  * iterate over net sources
125  * {
126  * if(source connects to instance in module definition)
127  * {
128  * create port for module definition;
129  * update net outpin;
130  * }
131  * }
132  * //handle net sinks
133  * iterate over net sinks
134  * {
135  * if(sink connects to instance in module definition)
136  * {
137  * create port for module definition;
138  * update net inpin;
139  * }
140  * }
141  * }
142  * }
143  * add module definition and instance to design;
144  * return true;
145  * }
146  */
147  bool modularize(const InstanceSharedPtrVector& inInstances,
148  const string& inModuleDefinitionName, const string& inModuleInstanceName,
149  bool inKeepPlacement = false, bool inKeepRouting = false) {
150 
151  // Get a current iterator to inInstances
152  InstanceSharedPtrConstIterator inInstanceSharedPtrConstIter = inInstances.begin();
153  // Get an end iterator to inInstances
154  InstanceSharedPtrConstIterator inInstanceSharedPtrConstEnd = inInstances.end();
155 
156  // Check if inInstances is empty
157  if(inInstanceSharedPtrConstIter == inInstanceSharedPtrConstEnd) {
158 
159  // Warn the user that none of the instances specified are found in the design
160  std::clog << "WARNING: There were no instances specified to be modularized. "
161  << std::endl;
162 
163  // Operation did not complete successfully
164  return false;
165 
166  }
167 
168  // Set the first returned instance as a reference point
169  InstanceSharedPtr moduleReferenceInst = *inInstanceSharedPtrConstIter;
170  // Create module definition
171  ModuleSharedPtr moduleDefinition = Factory::newModulePtr(inModuleDefinitionName,
172  moduleReferenceInst->getName());
173  // Create module instance
174  InstanceSharedPtr moduleInst = Factory::newInstancePtr(inModuleInstanceName,
175  inModuleDefinitionName, moduleReferenceInst->getTile(),
176  moduleReferenceInst->getSite());
177 
178  // Unplace module instance if so requested
179  if(!inKeepPlacement) moduleInst->unplace();
180 
181  // Begin handle instances
182  // Iterate over all instances in inInstances
183  while(inInstanceSharedPtrConstIter != inInstanceSharedPtrConstEnd) {
184 
185  // Get a pointer to the current instance
186  InstanceSharedPtr instPtr = *inInstanceSharedPtrConstIter;
187 
188  // Look for the current instance in the design
189  InstanceSharedPtrConstIterator instPtrIter
190  = mDesignPtr->findInstance(instPtr->getName());
191 
192  // Warn if the instance was not found
193  if(instPtrIter == mDesignPtr->instancesEnd()) {
194 
195  // Warn the user that the instance was not found in the design.
196  std::clog << "WARNING: Instance " << instPtr->getName()
197  << "was not found in design " << mDesignPtr->getName() << std::endl;
198  // Operation did not complete successfully
199  return false;
200 
201  }
202 
203  // Get a pointer to the looked up instance
204  InstanceSharedPtr designInstPtr = *instPtrIter;
205 
206  // Unplace instance if so requested
207  if(!inKeepPlacement) designInstPtr->unplace();
208 
209  // Add instance to module
210  moduleDefinition->addInstance(designInstPtr);
211  // Remove instance from design
212  mDesignPtr->removeInstance(designInstPtr);
213 
214  // Move to next instance
215  inInstanceSharedPtrConstIter++;
216 
217  } // while(inInstanceSharedPtrConstIter != inInstanceSharedPtrConstEnd)
218  // End handle instances
219 
220  // Begin handle connectivity
221  // Get a begin iterator to design nets
222  NetSharedPtrIterator designNetsIter = mDesignPtr->netsBegin();
223  // Get an end iterator to design nets
224  NetSharedPtrIterator designNetsEnd = mDesignPtr->netsEnd();
225  // Get a begin iterator to module hosted instances
226  InstanceSharedPtrConstIterator modHostedInstPtrConstBegin
227  = moduleDefinition->instancesBegin();
228  // Get an end iterator to module hosted instances
229  InstanceSharedPtrConstIterator modHostedInstPtrConstEnd
230  = moduleDefinition->instancesEnd();
231  // Module instance source pins
232  InstancePinSharedPtrVector modInstSourcePinPtrVector;
233  // Module instance sink pins
234  InstancePinSharedPtrVector modInstSinkPinPtrVector;
235 
236  // Iterate over all design nets
237  while(designNetsIter != designNetsEnd) {
238 
239  // Get a pointer to the current net
240  NetSharedPtr designNetPtr = *designNetsIter;
241  // Compute net connectivity type
242  ENetConnectivity eNet = getNetConnectivity(modHostedInstPtrConstBegin,
243  modHostedInstPtrConstEnd, designNetPtr);
244 
245  // For internal nets, move net from design to module
246  if(eNet == eNetConnectivityInternal) {
247 
248  // Unroute the net if so requested
249  if(!inKeepRouting) designNetPtr->unroute();
250 
251  // Add net to module
252  moduleDefinition->addNet(designNetPtr);
253  // Remove net from design
254  mDesignPtr->removeNet(designNetPtr);
255  // Update designNetsEnd iterator
256  designNetsEnd = mDesignPtr->netsEnd();
257 
258  } else {
259 
260  // For unconnected nets, increment the iterator and continue looping
261  if(eNet == eNetConnectivityNotConnected) {
262 
263  // Move to next net
264  designNetsIter++;
265  continue;
266 
267  }
268 
269  // For external nets, expose corresponding pins and update connectivity
270  // Unroute the net if so requested
271  if(!inKeepRouting) designNetPtr->unroute();
272 
273  // Get a begin iterator to net sources
274  InstancePinSharedPtrIterator designNetSourcesIter
275  = designNetPtr->sourcesBegin();
276  // Get an end iterator to net sources
277  InstancePinSharedPtrIterator designNetSourcesEnd = designNetPtr->sourcesEnd();
278  // Wire index used when creating ports
279  u_int32_t portIndex = 0;
280 
281  // Iterate over all net sources
282  while(designNetSourcesIter != designNetSourcesEnd) {
283 
284  // Get a pointer to the current net source pin
285  InstancePinSharedPtr instPinPtr = *designNetSourcesIter;
286  // Get a pointer to the instance hosting the net source pin
287  InstanceSharedPtr pinInstPtr = instPinPtr->getInstancePtr().lock();
288 
289  // Look for the instance in the vector of instances
290  if((std::find(modHostedInstPtrConstBegin, modHostedInstPtrConstEnd,
291  pinInstPtr)) != modHostedInstPtrConstEnd) {
292 
293  // Build port name: netName_portIndex
294  string portName = sanitizePinName(designNetPtr->getName())
295  + sPortIndexSeparator
296  + boost::lexical_cast<std::string>(portIndex++);
297  // Create port
298  PortSharedPtr portPtr = Factory::newPortPtr(portName, *(std::find(
299  modHostedInstPtrConstBegin, modHostedInstPtrConstEnd,
300  pinInstPtr)), instPinPtr->getPinName());
301  // Add port to module
302  moduleDefinition->addPort(portPtr);
303  // Create source pin from the module instance
304  modInstSourcePinPtrVector.push_back(
305  Factory::newInstancePinPtr(moduleInst, portName));
306  // Remove old source pin from net
307  designNetPtr->removeSource(instPinPtr);
308  // Update designNetSourcesEnd iterator
309  designNetSourcesEnd = designNetPtr->sourcesEnd();
310 
311  } else {
312 
313  // Move to next source
314  designNetSourcesIter++;
315 
316  }
317  } // while(designNetSourcesIter != designNetSourcesEnd)
318 
319  // Get a begin iterator to module source pins
320  InstancePinSharedPtrIterator modInstSourcesIter =
321  modInstSourcePinPtrVector.begin();
322  // Get an end iterator to module source pins
323  InstancePinSharedPtrIterator modInstSourcesEnd =
324  modInstSourcePinPtrVector.end();
325 
326  // Update net sources with new source pins
327  while(modInstSourcesIter != modInstSourcesEnd) {
328 
329  // Add source pin to net
330  designNetPtr->addSource(*modInstSourcesIter);
331  // Move to next source
332  modInstSourcesIter++;
333 
334  }
335 
336  // Reset module instance source pins vector
337  modInstSourcePinPtrVector.clear();
338  // Get a begin iterator to net sinks
339  InstancePinSharedPtrIterator designNetSinksIter = designNetPtr->sinksBegin();
340  // Get an end iterator to net sinks
341  InstancePinSharedPtrIterator designNetSinksEnd = designNetPtr->sinksEnd();
342 
343  // Iterate over all net sinks
344  while(designNetSinksIter != designNetSinksEnd) {
345 
346  // Get a pointer to the current net sink pin
347  InstancePinSharedPtr instPinPtr = *designNetSinksIter;
348  // Get a pointer to the instance hosting the net source pin
349  InstanceSharedPtr pinInstPtr = instPinPtr->getInstancePtr().lock();
350 
351  // Look for the instance in the vector of instances
352  if((std::find(modHostedInstPtrConstBegin, modHostedInstPtrConstEnd,
353  pinInstPtr)) != modHostedInstPtrConstEnd) {
354 
355  // Build port name: netName_portIndex
356  string portName = sanitizePinName(designNetPtr->getName())
357  + sPortIndexSeparator + boost::lexical_cast<std::string>(
358  portIndex++);
359  // Create port
360  PortSharedPtr portPtr = Factory::newPortPtr(portName, *(std::find(
361  modHostedInstPtrConstBegin, modHostedInstPtrConstEnd,
362  pinInstPtr)), instPinPtr->getPinName());
363  // Add port to module
364  moduleDefinition->addPort(portPtr);
365  // Create sink pin to the module instance
366  modInstSinkPinPtrVector.push_back(Factory::newInstancePinPtr(
367  moduleInst, portName));
368  // Remove old sink pin from net
369  designNetPtr->removeSink(instPinPtr);
370  // Update designNetSinksEnd iterator
371  designNetSinksEnd = designNetPtr->sinksEnd();
372 
373  } else {
374 
375  // Move to next sink
376  designNetSinksIter++;
377 
378  }
379  } // while(designNetSinksIter != designNetSinksEnd)
380 
381  // Get a begin iterator to module sink pins
382  InstancePinSharedPtrIterator modInstSinksIter =
383  modInstSinkPinPtrVector.begin();
384  // Get an end iterator to module sink pins
385  InstancePinSharedPtrIterator modInstSinksEnd =
386  modInstSinkPinPtrVector.end();
387 
388  // Update net sources with new source pins
389  while(modInstSinksIter != modInstSinksEnd) {
390 
391  // Add sink pin to net
392  designNetPtr->addSink(*modInstSinksIter);
393  // Move to next sink
394  modInstSinksIter++;
395 
396  }
397 
398  // Reset module instance sink pins vector
399  modInstSinkPinPtrVector.clear();
400 
401  // Move to next net
402  designNetsIter++;
403 
404  } // else
405  } // while(designNetsIter != designNetsEnd)
406  // End handle connectivity
407 
408  // Add module to design
409  mDesignPtr->addModule(moduleDefinition);
410  // Add module instance to design
411  mDesignPtr->addInstance(moduleInst);
412 
413  // Operation successfully completed
414  return true;
415  }
416 
417  /// \brief Flatten a module instance in a design.
418  /// \param inModuleInstanceName The name of the module instance to be flattened.
419  /// \param inKeepPlacement A flag specifying whether placement should be retained after
420  /// flattening. Default to false.
421  /// \param inKeepRouting A flag specifying whether routing should be retained afer
422  /// flattening. Defaults to false.
423  /*
424  * Function pseudocode
425  *
426  * bool flatten(const string& inModuleInstanceName, bool inKeepPlacement = false,
427  * bool inKeepRouting = false)
428  * {
429  * locate module instance in design;
430  * if(module instance not found)
431  * {
432  * warn user that module instance was not found;
433  * return false;
434  * }
435  * locate module definition corresponding to module instance in design;
436  * if(module definition not found)
437  * {
438  * warn user that module definition was not found;
439  * return false;
440  * }
441  * //handle instances
442  * iterate over module definition instances
443  * {
444  * clone every instance and set its name to moduleInstance/instanceName;
445  * if(!inKeepPlacement) unplace instance;
446  * add instance clone to design;
447  * }
448  * //handle internal nets
449  * iterate over module definition internal nets
450  * {
451  * clone every net and set its name to moduleInstance/netName;
452  * if(!inKeepRouting) unroute net;
453  * add net clone to design;
454  * }
455  * //handle external nets
456  * iterate over all design nets
457  * {
458  * if(!inKeepRouting) unroute net;
459  * //handle net sources
460  * iterate over all sources of a net
461  * {
462  * if(source is a port of the module)
463  * {
464  * update net outpin to reflect the flattened instance and the corresponding pin
465  * that matches the port;
466  * }
467  * }
468  * //handle net sinks
469  * iterate over all sinks of a net
470  * {
471  * if(sink is a port of the module)
472  * {
473  * update net inpin to reflect the flattened instance and the corresponding pin
474  * that matches the port;
475  * }
476  * }
477  * }
478  * remove module instance from design;
479  * }
480  */
481  bool flatten(const string& inModuleInstanceName, bool inKeepPlacement = false,
482  bool inKeepRouting = false) {
483 
484  // Flattened module source pins
485  InstancePinSharedPtrVector flattenedModuleSourcePinPtrVector;
486  // Flattened module sink pins
487  InstancePinSharedPtrVector flattenedModuleSinkPinPtrVector;
488  // Look for the module instance in the design
489  InstanceSharedPtrConstIterator designModInstPtrConstIter
490  = mDesignPtr->findInstance(inModuleInstanceName);
491 
492  // Check for a non-existent module instance
493  if(designModInstPtrConstIter == mDesignPtr->instancesEnd()) {
494 
495  // Warn the user that the module instance was not found in the design
496  std::clog << "WARNING: Module instance of name " << inModuleInstanceName
497  << " was not found in design " << mDesignPtr->getName() << "." << std::endl;
498 
499  // Operation did not complete successfully
500  return false;
501 
502  }
503 
504  // Get a pointer to the instance
505  InstanceSharedPtr instPtr = *designModInstPtrConstIter;
506  // Look for the module in the design
507  ModuleSharedPtrIterator designModPtrConstIter
508  = mDesignPtr->findModule(instPtr->getType());
509 
510  // Check for a non-existent module
511  if(designModPtrConstIter == mDesignPtr->modulesEnd()) {
512 
513  // Warn the user that the module was not found in the design
514  std::clog << "WARNING: Module of name " << instPtr->getType()
515  << " was not found in design " << mDesignPtr->getName() << "." << std::endl;
516 
517  // Operation did not complete successfully
518  return false;
519 
520  }
521 
522  // Current design module
523  ModuleSharedPtr module = *designModPtrConstIter;
524 
525  // Check whether tile/site for module instance is same as tile/site for module def.
526  // In case they don't match, the flattened module instance will be unplaced and any
527  // external/internal nets to the module instance will be unrouted.
528  InstanceSharedPtrIterator moduleAnchorInstIterator
529  = module->findInstance(module->getAnchor());
530  InstanceSharedPtr moduleAnchorInst = *moduleAnchorInstIterator;
531  // Begin handle instances inside module
532  // Get a begin iterator to module instances
533  InstanceSharedPtrIterator moduleInstancesIter = module->instancesBegin();
534  // Get an end iterator to module instances
535  InstanceSharedPtrIterator moduleInstancesEnd = module->instancesEnd();
536 
537  // Iterate over all instances hosted by the module
538  while(moduleInstancesIter != moduleInstancesEnd) {
539 
540  // Get a pointer to the current instance hosted by the module
541  InstanceSharedPtr modInstPtr = *moduleInstancesIter;
542  // Clone the instance
543  InstanceSharedPtr modInstPtrClone = cloneInstance(modInstPtr,
544  inModuleInstanceName + sHierarchySeparator + modInstPtr->getName());
545  // Set clone instance reference
546  modInstPtrClone->setInstanceReferencePtr(Factory::newInstanceReferencePtr(
547  inModuleInstanceName, module, modInstPtr));
548 
549  // Unplace the instance if so requested
550  if(!inKeepPlacement) modInstPtrClone->unplace();
551 
552  // Add clone of instance to design
553  mDesignPtr->addInstance(modInstPtrClone);
554 
555  // Next instance
556  moduleInstancesIter++;
557 
558  } // while(moduleInstancesIter != moduleInstancesEnd)
559  // End handle instances inside module
560 
561  // Begin handle internal module nets
562  // Get a begin iterator to module nets
563  NetSharedPtrIterator moduleNetsIter = module->netsBegin();
564  // Get an end iterator to module nets
565  NetSharedPtrIterator moduleNetsEnd = module->netsEnd();
566 
567  // Iterate over all nets inside module
568  while(moduleNetsIter != moduleNetsEnd) {
569 
570  // Get a pointer to the current net
571  NetSharedPtr moduleNetPtr = *moduleNetsIter;
572  // Clone the net
573  NetSharedPtr moduleNetPtrClone = cloneNet(moduleNetPtr, inModuleInstanceName
574  + sHierarchySeparator + moduleNetPtr->getName(), inModuleInstanceName);
575 
576  // Unroute the net if so requested
577  if(!inKeepRouting) moduleNetPtrClone->unroute();
578 
579  // Add net to design
580  mDesignPtr->addNet(moduleNetPtrClone);
581  // Next net
582  moduleNetsIter++;
583 
584  } // End handle internal module nets
585 
586  // Begin handle external module nets
587  // Get a begin iterator to design nets
588  NetSharedPtrIterator designNetsIter = mDesignPtr->netsBegin();
589  // Get an end iterator to design nets
590  NetSharedPtrIterator designNetsEnd = mDesignPtr->netsEnd();
591 
592  // Iterate over all nets connected to module and other instances outside module
593  while(designNetsIter != designNetsEnd) {
594 
595  // Get a pointer to the current net
596  NetSharedPtr designNetPtr = *designNetsIter;
597 
598  // Get a begin iterator to net sources
599  InstancePinSharedPtrIterator designNetSourcesIter = designNetPtr->sourcesBegin();
600  // Get an end iterator to net sources
601  InstancePinSharedPtrIterator designNetSourcesEnd = designNetPtr->sourcesEnd();
602 
603  // Iterate over all net sources
604  while(designNetSourcesIter != designNetSourcesEnd) {
605 
606  // Net pin
607  InstancePinSharedPtr instPinPtr = *designNetSourcesIter;
608  // Pin instance
609  InstanceSharedPtr pinInstPtr = instPinPtr->getInstancePtr().lock();
610 
611  // Net connects to module instance
612  if(pinInstPtr == instPtr) {
613 
614  // Unroute the net if so requested
615  if(!inKeepRouting) designNetPtr->unroute();
616 
617  // Look for the port in the module
618  PortSharedPtrConstIterator modulePortConstIter
619  = module->findPort(instPinPtr->getPinName());
620 
621  // Check if port was found
622  if(modulePortConstIter != module->portsEnd()) {
623 
624  // Get a pointer to the current port
625  PortSharedPtr modPortPtr = *modulePortConstIter;
626  // Get module port reference instance
627  InstanceSharedPtr portInstPtr = modPortPtr->getInstancePtr().lock();
628  // Find the cloned instance corresponding to the pin reference instance
629  InstanceSharedPtrIterator pinInstPtrCloneItr
630  = mDesignPtr->findInstance(inModuleInstanceName
631  + sHierarchySeparator + portInstPtr->getName());
632  // Create new pin referencing the port reference instance
633  flattenedModuleSourcePinPtrVector.push_back(
634  Factory::newInstancePinPtr(*pinInstPtrCloneItr,
635  modPortPtr->getPinName()));
636  // Remove pin reference module instance
637  designNetPtr->removeSource(instPinPtr);
638  // Update designNetSourcesEnd iterator
639  designNetSourcesEnd = designNetPtr->sourcesEnd();
640 
641  }
642 
643  } else {
644 
645  // Move to next source
646  designNetSourcesIter++;
647 
648  }
649  } // while(designNetSourcesIter != designNetSourcesEnd)
650 
651  // Get a begin iterator to flattened module source pins
652  InstancePinSharedPtrIterator flattenedModuleSourcesIter
653  = flattenedModuleSourcePinPtrVector.begin();
654  // Get an end iterator to flattened module source pins
655  InstancePinSharedPtrIterator flattenedModuleSourcesEnd
656  = flattenedModuleSourcePinPtrVector.end();
657 
658  // Update net sources with new source pins
659  while(flattenedModuleSourcesIter != flattenedModuleSourcesEnd) {
660 
661  // Add source pin to net
662  designNetPtr->addSource(*flattenedModuleSourcesIter);
663  // Move to next source
664  flattenedModuleSourcesIter++;
665  }
666 
667  // Reset vector
668  flattenedModuleSourcePinPtrVector.clear();
669  // Get a begin iterator to net sinks
670  InstancePinSharedPtrIterator designNetSinksIter = designNetPtr->sinksBegin();
671  // Get an end iterator to net sinks
672  InstancePinSharedPtrIterator designNetSinksEnd = designNetPtr->sinksEnd();
673 
674  // Iterate over all net sinks
675  while(designNetSinksIter != designNetSinksEnd) {
676 
677  // Net pin
678  InstancePinSharedPtr instPinPtr = *designNetSinksIter;
679  // Pin instance
680  InstanceSharedPtr pinInstPtr = instPinPtr->getInstancePtr().lock();
681 
682  // Net connets to module instance
683  if(pinInstPtr == instPtr) {
684 
685  // Unroute the net if so requested
686  if(!inKeepRouting) designNetPtr->unroute();
687 
688  // Look for the port in the module
689  PortSharedPtrConstIterator modulePortConstIter
690  = module->findPort(instPinPtr->getPinName());
691 
692  // Check if port was found
693  if(modulePortConstIter != module->portsEnd()) {
694 
695  // Get a pointer to the current port
696  PortSharedPtr modPortPtr = *modulePortConstIter;
697  // Get module port reference instance
698  InstanceSharedPtr portInstPtr = modPortPtr->getInstancePtr().lock();
699  // Find the cloned instance corresponding to the pin reference instance
700  InstanceSharedPtrIterator pinInstPtrCloneItr
701  = mDesignPtr->findInstance(inModuleInstanceName
702  + sHierarchySeparator + portInstPtr->getName());
703  // Create new pin referencing the port reference instance
704  flattenedModuleSinkPinPtrVector.push_back(
705  Factory::newInstancePinPtr(*pinInstPtrCloneItr,
706  modPortPtr->getPinName()));
707  // Remove pin reference module instance
708  designNetPtr->removeSink(instPinPtr);
709  // Update designNetSinksEnd iterator
710  designNetSinksEnd = designNetPtr->sinksEnd();
711  }
712 
713  } else {
714 
715  // Move to next source
716  designNetSinksIter++;
717 
718  }
719  } // while(designNetSinksIter != designNetSinksEnd)
720 
721  // Get a begin iterator to flattened module sink pins
722  InstancePinSharedPtrIterator flattenedModuleSinksBegin
723  = flattenedModuleSinkPinPtrVector.begin();
724  // Get an end iterator to flattened module sink pins
725  InstancePinSharedPtrIterator flattenedModuleSinksEnd
726  = flattenedModuleSinkPinPtrVector.end();
727 
728  // Update net sources with new source pins
729  while(flattenedModuleSinksBegin != flattenedModuleSinksEnd) {
730 
731  // Add sink pin to net
732  designNetPtr->addSink(*flattenedModuleSinksBegin);
733  // Move to next sink
734  flattenedModuleSinksBegin++;
735 
736  }
737 
738  // Reset vector
739  flattenedModuleSinkPinPtrVector.clear();
740 
741  // Move to next net
742  designNetsIter++;
743 
744  } // while(designNetsIter != designNetsEnd)
745  // End handle external module nets
746 
747  // Remove module instance from design
748  mDesignPtr->removeInstance(instPtr);
749 
750  // Operation successfully completed
751  return true;
752  }
753 
754  private:
755 
756  /// \brief Generate net connectivity type based on module boundary.
757  /// \param inInstanceSharedPtrConstBegin A begin iterator to instances contained in module.
758  /// \param inInstanceSharedPtrConstEnd An end iterator to instances contained in module.
759  /// \param inNetPtr A pointer to a net.
761  InstanceSharedPtrConstIterator inInstanceSharedPtrConstBegin,
762  InstanceSharedPtrConstIterator inInstanceSharedPtrConstEnd, NetSharedPtr inNetPtr) {
763 
764  // Net connectivity type
765  ENetConnectivity netConnectivity = eNetConnectivityNotConnected;
766  // Is net connected to module?
767  bool isNetConnectedToModule = false;
768  // Is net crossing module boundary?
769  bool isNetInterToModule = false;
770  // Get a begin iterator to net sources
771  InstancePinSharedPtrIterator sourcesBegin = inNetPtr->sourcesBegin();
772  // Get an end iterator to net sources
773  InstancePinSharedPtrIterator sourcesEnd = inNetPtr->sourcesEnd();
774 
775  // Iterate over all sources
776  while(sourcesBegin != sourcesEnd) {
777 
778  // Get a pointer to the current source pin
779  InstancePinSharedPtr instPinPtr = *sourcesBegin;
780  // Get a pointer to the instance that hosts the pin
781  InstanceSharedPtr pinInst = instPinPtr->getInstancePtr().lock();
782 
783  // Look for the instance in the vector of instances
784  if((std::find(inInstanceSharedPtrConstBegin, inInstanceSharedPtrConstEnd, pinInst))
785  != inInstanceSharedPtrConstEnd) {
786 
787  // Net connects to instance inside module boundary
788  isNetConnectedToModule = true;
789 
790  } else {
791 
792  // Net connects to instance outside module boundary
793  isNetInterToModule = true;
794 
795  }
796 
797  // Move to next source
798  sourcesBegin++;
799  }
800 
801  // Get a begin iterator to net sinks
802  InstancePinSharedPtrIterator sinksBegin = inNetPtr->sinksBegin();
803  // Get an end iterator to net sinks
804  InstancePinSharedPtrIterator sinksEnd = inNetPtr->sinksEnd();
805 
806  // Iterate over all sinks
807  while(sinksBegin != sinksEnd) {
808 
809  // Get a pointer to the current sink pin
810  InstancePinSharedPtr instPinPtr = *sinksBegin;
811  // Get a pointer to the instance that hosts the pin
812  InstanceSharedPtr pinInst = instPinPtr->getInstancePtr().lock();
813  // Look for the instance in the vector of instances
814  if((std::find(inInstanceSharedPtrConstBegin, inInstanceSharedPtrConstEnd, pinInst))
815  != inInstanceSharedPtrConstEnd) {
816  // Net connects to instance inside module boundary
817  isNetConnectedToModule = true;
818  } else {
819  // Net connects to instance outside module boundary
820  isNetInterToModule = true;
821  }
822  // Move to the next sink
823  sinksBegin++;
824  }
825 
826  if(isNetConnectedToModule) { // Net connects to module
827  if(isNetInterToModule) {
828  netConnectivity = eNetConnectivityExternal; // Net crosses module boundary
829  } else {
830  netConnectivity = eNetConnectivityInternal; // Net lies within module boundary
831  }
832  }
833 
834  // Return net connectivity type
835  return netConnectivity;
836  }
837 
838  /// \brief Sanitize a pin name.
839  /// \param inPinName The pin name to be sanitized.
840  string sanitizePinName(string inPinName) {
841 
842  // Sanitized pin name
843  string sanitizedPinName;
844 
845  // Iterate over all characters in inString
846  for(u_int32_t i = 0; i < inPinName.length(); i++) {
847 
848  // Match character against valid characters
849  if(boost::regex_match(inPinName.substr(i, 1), sValidPinNameCharactersRegEx)) {
850  sanitizedPinName += inPinName.substr(i, 1);
851  }
852  }
853 
854  // Make sure sanitizedPinName does not start with an invalid first character
855  while(sanitizedPinName.size() > 0 && boost::regex_match(sanitizedPinName.substr(0, 1),
856  sInvalidPinNameFirstCharactersRegEx)) {
857 
858  // Remove invalid character
859  sanitizedPinName = sanitizedPinName.substr(1, sanitizedPinName.size() - 1);
860 
861  }
862 
863  // Return sanitizedPinName
864  return sanitizedPinName;
865  }
866 
867  /// \brief Clone an instance.
868  /// \param inIntancePtr A pointer to the instance to be cloned.
869  /// \param inCloneInstanceName The name of the clone.
870  /// \details Clone an instance and its configuration. This function does not clone the
871  /// instance pins. Instance pins are handled when cloning nets, in function cloneNet.
873  const string& inCloneInstanceName) {
874 
875  // Clone inInstancePtr
876  InstanceSharedPtr inInstanceClonePtr = Factory::newInstancePtr(inCloneInstanceName,
877  inIntancePtr->getType(), inIntancePtr->getTile(), inIntancePtr->getSite(),
878  inIntancePtr->getBonding());
879 
880  // Begin clone inIntance configuration
881  // Get a begin iterator to inIntance config
882  ConfigMap::const_iterator instanceConfigBegin = inIntancePtr->configBegin();
883  // Get an end iterator to inIntance config
884  ConfigMap::const_iterator instanceConfigEnd = inIntancePtr->configEnd();
885  // Configuration map
886  ConfigMap configMap;
887 
888  // Iterate over all configuration
889  while(instanceConfigBegin != instanceConfigEnd) {
890 
891  // Get current setting
892  const string setting = instanceConfigBegin->first;
893  // Get current configuration
894  const Config config = instanceConfigBegin->second;
895  // Add (setting,configuration) to configuration map
896  configMap.setConfig(setting, config);
897  // Move to the next configuration
898  instanceConfigBegin++;
899 
900  }
901 
902  // Add configurations to instance clone
903  inInstanceClonePtr->addConfigs(configMap);
904  // End clone inInstance configuration
905 
906  // Return cloned instance
907  return inInstanceClonePtr;
908  }
909 
910  /// \brief Clone a net.
911  /// \param inNetPtr A pointer to the net to be cloned.
912  /// \param inNetCloneName The name of the clone.
913  /// \param inModuleInstanceName The module instance name.
914  /// \details Clone a net, its configuration, its sources, sinks and pips. For pips, the
915  /// routethrough instances are droppped and not cloned.
916  NetSharedPtr cloneNet(NetSharedPtr inNetPtr, const string& inNetCloneName,
917  const string& inModuleInstanceName) {
918 
919  // Clone inNetPtr
920  NetSharedPtr inNetClonePtr = Factory::newNetPtr(inNetCloneName, inNetPtr->getNetType());
921 
922  // Begin clone inNetPtr configuration
923  // Get a begin iterator to net config
924  ConfigMap::const_iterator netConfigBegin = inNetPtr->configBegin();
925  // Get an end iterator to net config
926  ConfigMap::const_iterator netConfigEnd = inNetPtr->configEnd();
927  // Configuration map
928  ConfigMap configMap;
929 
930  // Iterate over all configuration
931  while(netConfigBegin != netConfigEnd) {
932 
933  // Get current setting
934  const string setting = netConfigBegin->first;
935  // Get current configuration
936  const Config config = netConfigBegin->second;
937  // Add (setting,configuration) to configuration map
938  configMap.setConfig(setting, config);
939  // Move to the next configuration
940  netConfigBegin++;
941 
942  }
943 
944  // Add configurations to net clone
945  inNetClonePtr->addConfigs(configMap);
946  // End clone inNetPtr configuration
947 
948  // Begin clone inNetPtr sources
949  // Get a begin iterator to net sources
950  InstancePinSharedPtrConstIterator inNetSourcesBegin = inNetPtr->sourcesBegin();
951  // Get an end iterator to net sources
952  InstancePinSharedPtrConstIterator inNetSourcesEnd = inNetPtr->sourcesEnd();
953 
954  // Iterate over all source pins
955  while(inNetSourcesBegin != inNetSourcesEnd) {
956 
957  // Get pointer to current net pin
958  InstancePinSharedPtr instPinPtr = *inNetSourcesBegin;
959  // Get net pin reference instance
960  InstanceSharedPtr pinInstPtr = instPinPtr->getInstancePtr().lock();
961  // Find the cloned instance that correspond to the pin reference instance
962  InstanceSharedPtrIterator pinInstPtrCloneItr = mDesignPtr->findInstance(
963  inModuleInstanceName + sHierarchySeparator + pinInstPtr->getName());
964  // Clone source pin
965  InstancePinSharedPtr instPinPtrClone
966  = Factory::newInstancePinPtr(*pinInstPtrCloneItr, instPinPtr->getPinName());
967  // Add pin clone to the net clone
968  inNetClonePtr->addSource(instPinPtrClone);
969  // Move to next source
970  inNetSourcesBegin++;
971 
972  }
973  // End clone inNetPtr sources
974 
975  // Begin clone inNetPtr sinks
976  // Get a begin iterator to net sinks
977  InstancePinSharedPtrConstIterator inNetSinksBegin = inNetPtr->sinksBegin();
978  // Get an end iterator to net sinks
979  InstancePinSharedPtrConstIterator inNetSinksEnd = inNetPtr->sinksEnd();
980 
981  // Iterate over all sink pins
982  while(inNetSinksBegin != inNetSinksEnd) {
983 
984  // Get pointer to current net pin
985  InstancePinSharedPtr instPinPtr = *inNetSinksBegin;
986  // Get net pin reference instance
987  InstanceSharedPtr pinInstPtr = instPinPtr->getInstancePtr().lock();
988  // Find the cloned instance that correspond to the pin reference instance
989  InstanceSharedPtrIterator pinInstPtrCloneItr = mDesignPtr->findInstance(
990  inModuleInstanceName + sHierarchySeparator + pinInstPtr->getName());
991  // Clone sink pin
992  InstancePinSharedPtr instPinPtrClone
993  = Factory::newInstancePinPtr(*pinInstPtrCloneItr, instPinPtr->getPinName());
994  // Add pin clone to the net clone
995  inNetClonePtr->addSink(instPinPtrClone);
996  // Move to next sink
997  inNetSinksBegin++;
998 
999  }
1000  // End clone inNetPtr sinks
1001 
1002  // Begin clone inNetPtr pips
1003  // Get a begin iterator to net pips
1004  PipConstIterator inNetPipsBegin = inNetPtr->pipsBegin();
1005  // Get an end iterator to net pips
1006  PipConstIterator inNetPipsEnd = inNetPtr->pipsEnd();
1007 
1008  // Iterate over all pips
1009  while(inNetPipsBegin != inNetPipsEnd) {
1010 
1011  // Get a pointer to the current pip
1012  Pip pipPtr = *inNetPipsBegin;
1013  /// \todo We are dropping routethrough instances.
1014  // Clone the pip
1015  Pip pipClone = Factory::newPip(pipPtr.getTileName(), pipPtr.getSourceWireName(),
1016  pipPtr.getSinkWireName(), pipPtr.getDirection());
1017  // Add pip clone to cloned net
1018  inNetClonePtr->addPip(pipClone);
1019  // Move to next pip
1020  inNetPipsBegin++;
1021 
1022  }
1023  // End clone inNetPtr pips
1024 
1025  // Return cloned net
1026  return inNetClonePtr;
1027  }
1028  };
1029 
1030 } // namespace physical
1031 } // namespace torc
1032 
1033 #endif // TORC_PHYSICAL_MODULETRANSFORMER_HPP
Utility class to modularize/flatten designs.
void setConfig(const string &inSetting, const Config &inConfig)
Sets the configuration for the given setting.
Definition: ConfigMap.hpp:119
Design::NetSharedPtrIterator NetSharedPtrIterator
Imported type.
std::vector< InstanceSharedPtr > InstanceSharedPtrVector
Vector of Instance shared pointers.
Main torc::architecture namespace header.
PortSharedPtrVector::const_iterator PortSharedPtrConstIterator
Constant iterator to Port shared pointers.
Definition: Module.hpp:55
static const boost::regex sValidPinNameCharactersRegEx
Valid characters in a pin name.
Module::PortSharedPtrConstIterator PortSharedPtrConstIterator
Imported type.
PipVector::const_iterator PipConstIterator
Constant iterator to Pip objects.
Design::InstanceSharedPtrIterator InstanceSharedPtrIterator
Imported type.
boost::shared_ptr< Port > PortSharedPtr
Shared pointer encapsulation of a Port.
string sanitizePinName(string inPinName)
Sanitize a pin name.
InstancePinSharedPtrVector::iterator InstancePinSharedPtrIterator
Non-constant iterator to InstancePin shared pointer objects.
InstanceSharedPtrVector::const_iterator InstanceSharedPtrConstIterator
Constant iterator to Instance shared pointers.
Definition: Circuit.hpp:72
DesignSharedPtr mDesignPtr
Design pointer.
std::vector< InstancePinSharedPtr > InstancePinSharedPtrVector
Vector of InstancePin shared pointers.
ENetConnectivity getNetConnectivity(InstanceSharedPtrConstIterator inInstanceSharedPtrConstBegin, InstanceSharedPtrConstIterator inInstanceSharedPtrConstEnd, NetSharedPtr inNetPtr)
Generate net connectivity type based on module boundary.
InstanceSharedPtr cloneInstance(InstanceSharedPtr inIntancePtr, const string &inCloneInstanceName)
Clone an instance.
Design::ModuleSharedPtrIterator ModuleSharedPtrIterator
Imported type.
boost::shared_ptr< class InstancePin > InstancePinSharedPtr
Shared pointer encapsulation of an InstancePin.
Net::PipConstIterator PipConstIterator
Imported type.
const_iterator const_iterator
Constant iterator to {setting,Config} pairs.
Definition: ConfigMap.hpp:52
Net::InstancePinSharedPtrIterator InstancePinSharedPtrIterator
Imported type.
boost::shared_ptr< Module > ModuleSharedPtr
Shared pointer encapsulation of a Module.
Definition: Module.hpp:114
ENetConnectivity
Net connectivity with respect to module instance, either not connected to module, internal to module...
const WireName & getSinkWireName(void) const
Returns the pip sink wire.
Definition: Pip.hpp:77
Net::InstancePinSharedPtrConstIterator InstancePinSharedPtrConstIterator
Imported type.
Configuration. A {name:value} pair.
Definition: Config.hpp:39
bool flatten(const string &inModuleInstanceName, bool inKeepPlacement=false, bool inKeepRouting=false)
Flatten a module instance in a design.
boost::shared_ptr< Net > NetSharedPtr
Shared pointer encapsulation of a Net.
boost::shared_ptr< Instance > InstanceSharedPtr
Shared pointer encapsulation of an Instance.
boost::shared_ptr< Design > DesignSharedPtr
Shared pointer encapsulation of a Design.
InstancePinSharedPtrVector::const_iterator InstancePinSharedPtrConstIterator
Constant iterator to InstancePin shared pointer objects.
NetSharedPtrVector::iterator NetSharedPtrIterator
Non-constant iterator to Net shared pointers.
Definition: Circuit.hpp:78
const TileName & getTileName(void) const
Returns the pip tile.
Definition: Pip.hpp:73
EPipDirection getDirection(void) const
Returns the pip directionality.
Definition: Pip.hpp:79
Physical design programmable interconnect point.
Definition: Pip.hpp:34
NetSharedPtr cloneNet(NetSharedPtr inNetPtr, const string &inNetCloneName, const string &inModuleInstanceName)
Clone a net.
const WireName & getSourceWireName(void) const
Returns the pip source wire.
Definition: Pip.hpp:75
bool modularize(const InstanceSharedPtrVector &inInstances, const string &inModuleDefinitionName, const string &inModuleInstanceName, bool inKeepPlacement=false, bool inKeepRouting=false)
Group a set of instances into a module.
ModuleTransformer(DesignSharedPtr &inDesignPtr)
Public constructor.
Configuration setting map.
Definition: ConfigMap.hpp:39
Design::InstanceSharedPtrConstIterator InstanceSharedPtrConstIterator
Imported type.
ModuleSharedPtrVector::iterator ModuleSharedPtrIterator
Non-constant iterator for Module shared pointers.
Header for the Factory class.
static const string sPortIndexSeparator
Port index separator.
static const string sHierarchySeparator
Hierarchy separator.
static const boost::regex sInvalidPinNameFirstCharactersRegEx
Invalid first characters in a pin name.
InstanceSharedPtrVector::iterator InstanceSharedPtrIterator
Non-constant iterator to Instance shared pointers.
Definition: Circuit.hpp:74
static const string sHierarchySeparator