1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2021, Parallax Software, Inc.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17 #include "ConcreteNetwork.hh"
18 
19 #include "DisallowCopyAssign.hh"
20 #include "PatternMatch.hh"
21 #include "Report.hh"
22 #include "Liberty.hh"
23 #include "PortDirection.hh"
24 #include "ConcreteLibrary.hh"
25 #include "Network.hh"
26 
27 namespace sta {
28 
29 static void
30 makeChildNetwork(Instance *proto,
31 		 Instance *parent,
32 		 ConcreteBindingTbl *parent_bindings,
33 		 NetworkReader *network);
34 static void
35 makeClonePins(Instance *proto,
36 	      Instance *clone,
37 	      Instance *clone_view,
38 	      ConcreteBindingTbl *bindings,
39 	      Instance *parent,
40 	      ConcreteBindingTbl *parent_bindings,
41 	      NetworkReader *network);
42 
43 NetworkReader *
makeConcreteNetwork()44 makeConcreteNetwork()
45 {
46   return new ConcreteNetwork;
47 }
48 
49 class ConcreteInstanceChildIterator : public InstanceChildIterator
50 {
51 public:
52   explicit ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map);
53   bool hasNext();
54   Instance *next();
55 
56 private:
57   ConcreteInstanceChildMap::ConstIterator iter_;
58 };
59 
60 ConcreteInstanceChildIterator::
ConcreteInstanceChildIterator(ConcreteInstanceChildMap * map)61 ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map) :
62   iter_(map)
63 {
64 }
65 
66 bool
hasNext()67 ConcreteInstanceChildIterator::hasNext()
68 {
69   return iter_.hasNext();
70 }
71 
72 Instance *
next()73 ConcreteInstanceChildIterator::next()
74 {
75   return reinterpret_cast<Instance*>(iter_.next());
76 }
77 
78 class ConcreteInstanceNetIterator : public InstanceNetIterator
79 {
80 public:
81   explicit ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets);
82   bool hasNext();
83   Net *next();
84 
85 private:
86   DISALLOW_COPY_AND_ASSIGN(ConcreteInstanceNetIterator);
87   void findNext();
88 
89   ConcreteInstanceNetMap::Iterator iter_;
90   ConcreteNet *next_;
91 };
92 
93 ConcreteInstanceNetIterator::
ConcreteInstanceNetIterator(ConcreteInstanceNetMap * nets)94 ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets):
95   iter_(nets),
96   next_(nullptr)
97 {
98   findNext();
99 }
100 
101 bool
hasNext()102 ConcreteInstanceNetIterator::hasNext()
103 {
104   return next_ != nullptr;
105 }
106 
107 // Skip nets that have been merged.
108 void
findNext()109 ConcreteInstanceNetIterator::findNext()
110 {
111   while (iter_.hasNext()) {
112     next_ = iter_.next();
113     if (next_->mergedInto() == nullptr)
114       return;
115   }
116   next_ = nullptr;
117 }
118 
119 Net *
next()120 ConcreteInstanceNetIterator::next()
121 {
122   ConcreteNet *next = next_;
123   findNext();
124   return reinterpret_cast<Net*>(next);
125 }
126 
127 ////////////////////////////////////////////////////////////////
128 
129 class ConcreteInstancePinIterator : public InstancePinIterator
130 {
131 public:
132   ConcreteInstancePinIterator(const ConcreteInstance *inst,
133 			      int pin_count);
134   bool hasNext();
135   Pin *next();
136 
137 private:
138   DISALLOW_COPY_AND_ASSIGN(ConcreteInstancePinIterator);
139   void findNext();
140 
141   ConcretePin **pins_;
142   int pin_count_;
143   int pin_index_;
144   ConcretePin *next_;
145 };
146 
147 ConcreteInstancePinIterator::
ConcreteInstancePinIterator(const ConcreteInstance * inst,int pin_count)148 ConcreteInstancePinIterator(const ConcreteInstance *inst,
149 			    int pin_count) :
150   pins_(inst->pins_),
151   pin_count_(pin_count),
152   pin_index_(0)
153 {
154   findNext();
155 }
156 
157 bool
hasNext()158 ConcreteInstancePinIterator::hasNext()
159 {
160   return next_ != nullptr;
161 }
162 
163 Pin *
next()164 ConcreteInstancePinIterator::next()
165 {
166   ConcretePin *next = next_;
167   findNext();
168   return reinterpret_cast<Pin*>(next);
169 }
170 
171 // Skip over missing pins.
172 void
findNext()173 ConcreteInstancePinIterator::findNext()
174 {
175   while (pin_index_ < pin_count_) {
176     next_ = pins_[pin_index_++];
177     if (next_)
178       return;
179   }
180   next_ = nullptr;
181 }
182 
183 ////////////////////////////////////////////////////////////////
184 
185 class ConcreteNetPinIterator : public NetPinIterator
186 {
187 public:
188   explicit ConcreteNetPinIterator(const ConcreteNet *net);
189   bool hasNext();
190   Pin *next();
191 
192 private:
193   DISALLOW_COPY_AND_ASSIGN(ConcreteNetPinIterator);
194 
195   ConcretePin *next_;
196 };
197 
ConcreteNetPinIterator(const ConcreteNet * net)198 ConcreteNetPinIterator::ConcreteNetPinIterator(const ConcreteNet *net) :
199   next_(net->pins_)
200 {
201 }
202 
203 bool
hasNext()204 ConcreteNetPinIterator::hasNext()
205 {
206   return next_ != nullptr;
207 }
208 
209 Pin *
next()210 ConcreteNetPinIterator::next()
211 {
212   ConcretePin *next = next_;
213   next_ = next_->net_next_;
214   return reinterpret_cast<Pin*>(next);
215 }
216 
217 ////////////////////////////////////////////////////////////////
218 
219 class ConcreteNetTermIterator : public NetTermIterator
220 {
221 public:
222   explicit ConcreteNetTermIterator(const ConcreteNet *net);
223   bool hasNext();
224   Term *next();
225 
226 private:
227   DISALLOW_COPY_AND_ASSIGN(ConcreteNetTermIterator);
228 
229   ConcreteTerm *next_;
230 };
231 
ConcreteNetTermIterator(const ConcreteNet * net)232 ConcreteNetTermIterator::ConcreteNetTermIterator(const ConcreteNet *net) :
233   next_(net->terms_)
234 {
235 }
236 
237 bool
hasNext()238 ConcreteNetTermIterator::hasNext()
239 {
240   return next_ != nullptr;
241 }
242 
243 Term *
next()244 ConcreteNetTermIterator::next()
245 {
246   ConcreteTerm *next = next_;
247   next_ = next_->net_next_;
248   return reinterpret_cast<Term*>(next);
249 }
250 
251 ////////////////////////////////////////////////////////////////
252 
ConcreteNetwork()253 ConcreteNetwork::ConcreteNetwork() :
254   NetworkReader(),
255   top_instance_(nullptr),
256   link_func_(nullptr)
257 {
258 }
259 
~ConcreteNetwork()260 ConcreteNetwork::~ConcreteNetwork()
261 {
262   clear();
263 }
264 
265 void
clear()266 ConcreteNetwork::clear()
267 {
268   deleteTopInstance();
269   deleteCellNetworkViews();
270   library_seq_.deleteContentsClear();
271   library_map_.clear();
272   Network::clear();
273 }
274 
275 void
deleteTopInstance()276 ConcreteNetwork::deleteTopInstance()
277 {
278   if (top_instance_) {
279     deleteInstance(top_instance_);
280     top_instance_ = nullptr;
281   }
282 }
283 
284 void
deleteCellNetworkViews()285 ConcreteNetwork::deleteCellNetworkViews()
286 {
287   CellNetworkViewMap::Iterator view_iter(cell_network_view_map_);
288   while (view_iter.hasNext()) {
289     Instance *view = view_iter.next();
290     if (view)
291       deleteInstance(view);
292   }
293   cell_network_view_map_.clear();
294 }
295 
296 Instance *
topInstance() const297 ConcreteNetwork::topInstance() const
298 {
299   return top_instance_;
300 }
301 
302 ////////////////////////////////////////////////////////////////
303 
304 class ConcreteLibraryIterator1 : public Iterator<Library*>
305 {
306 public:
307   explicit ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_);
308   virtual bool hasNext();
309   virtual Library *next();
310 
311 private:
312   DISALLOW_COPY_AND_ASSIGN(ConcreteLibraryIterator1);
313 
314   ConcreteLibraryIterator iter_;
315 };
316 
ConcreteLibraryIterator1(const ConcreteLibrarySeq & lib_seq_)317 ConcreteLibraryIterator1::ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_):
318   iter_(lib_seq_)
319 {
320 }
321 
322 bool
hasNext()323 ConcreteLibraryIterator1::hasNext()
324 {
325   return iter_.hasNext();
326 }
327 
328 Library *
next()329 ConcreteLibraryIterator1::next()
330 {
331   return reinterpret_cast<Library*>(iter_.next());
332 }
333 
334 LibraryIterator *
libraryIterator() const335 ConcreteNetwork::libraryIterator() const
336 {
337   return new ConcreteLibraryIterator1(library_seq_);
338 }
339 
340 ////////////////////////////////////////////////////////////////
341 
342 class ConcreteLibertyLibraryIterator : public Iterator<LibertyLibrary*>
343 {
344 public:
345   explicit ConcreteLibertyLibraryIterator(const ConcreteNetwork *network);
346   virtual ~ConcreteLibertyLibraryIterator();
347   virtual bool hasNext();
348   virtual LibertyLibrary *next();
349 
350 private:
351   DISALLOW_COPY_AND_ASSIGN(ConcreteLibertyLibraryIterator);
352   void findNext();
353 
354   ConcreteLibrarySeq::ConstIterator iter_;
355   LibertyLibrary *next_;
356 };
357 
358 ConcreteLibertyLibraryIterator::
ConcreteLibertyLibraryIterator(const ConcreteNetwork * network)359 ConcreteLibertyLibraryIterator(const ConcreteNetwork *network):
360   iter_(network->library_seq_),
361   next_(nullptr)
362 {
363   findNext();
364 }
365 
~ConcreteLibertyLibraryIterator()366 ConcreteLibertyLibraryIterator::~ConcreteLibertyLibraryIterator()
367 {
368 }
369 
370 bool
hasNext()371 ConcreteLibertyLibraryIterator::hasNext()
372 {
373   return next_ != nullptr;
374 }
375 
376 LibertyLibrary *
next()377 ConcreteLibertyLibraryIterator::next()
378 {
379   LibertyLibrary *next = next_;
380   findNext();
381   return next;
382 }
383 
384 void
findNext()385 ConcreteLibertyLibraryIterator::findNext()
386 {
387   next_ = nullptr;
388   while (iter_.hasNext()) {
389     ConcreteLibrary *lib = iter_.next();
390     if (lib->isLiberty()) {
391       LibertyLibrary *liberty = static_cast<LibertyLibrary*>(lib);
392       if (liberty) {
393 	next_ = liberty;
394 	break;
395       }
396     }
397   }
398 }
399 
400 LibertyLibraryIterator *
libertyLibraryIterator() const401 ConcreteNetwork::libertyLibraryIterator() const
402 {
403   return new ConcreteLibertyLibraryIterator(this);
404 }
405 
406 ////////////////////////////////////////////////////////////////
407 
408 Library *
makeLibrary(const char * name,const char * filename)409 ConcreteNetwork::makeLibrary(const char *name,
410 			     const char *filename)
411 {
412   ConcreteLibrary *library = new ConcreteLibrary(name, filename, false);
413   addLibrary(library);
414   return reinterpret_cast<Library*>(library);
415 }
416 
417 LibertyLibrary *
makeLibertyLibrary(const char * name,const char * filename)418 ConcreteNetwork::makeLibertyLibrary(const char *name,
419 				    const char *filename)
420 {
421   LibertyLibrary *library = new LibertyLibrary(name, filename);
422   addLibrary(library);
423   return library;
424 }
425 
426 void
addLibrary(ConcreteLibrary * library)427 ConcreteNetwork::addLibrary(ConcreteLibrary *library)
428 {
429   library_seq_.push_back(library);
430   library_map_[library->name()] = library;
431 }
432 
433 Library *
findLibrary(const char * name)434 ConcreteNetwork::findLibrary(const char *name)
435 {
436   return reinterpret_cast<Library*>(library_map_.findKey(name));
437 }
438 
439 void
deleteLibrary(ConcreteLibrary * library)440 ConcreteNetwork::deleteLibrary(ConcreteLibrary *library)
441 {
442   library_map_.erase(library->name());
443   library_seq_.eraseObject(library);
444   delete library;
445 }
446 
447 const char *
name(const Library * library) const448 ConcreteNetwork::name(const Library *library) const
449 {
450   const ConcreteLibrary *clib =
451     reinterpret_cast<const ConcreteLibrary*>(library);
452   return clib->name();
453 }
454 
455 LibertyLibrary *
findLiberty(const char * name)456 ConcreteNetwork::findLiberty(const char *name)
457 {
458   ConcreteLibrary *lib =  library_map_.findKey(name);
459   if (lib) {
460     if (lib->isLiberty())
461       return static_cast<LibertyLibrary*>(lib);
462     // Potential name conflict
463     else {
464       for (ConcreteLibrary *lib : library_seq_) {
465 	if (stringEq(lib->name(), name)
466 	    && lib->isLiberty())
467 	  return static_cast<LibertyLibrary*>(lib);
468       }
469     }
470   }
471   return nullptr;
472 }
473 
474 LibertyLibrary *
libertyLibrary(Library * library) const475 ConcreteNetwork::libertyLibrary(Library *library) const
476 {
477   ConcreteLibrary *lib = reinterpret_cast<ConcreteLibrary*>(library);
478   return static_cast<LibertyLibrary*>(lib);
479 }
480 
481 Cell *
makeCell(Library * library,const char * name,bool is_leaf,const char * filename)482 ConcreteNetwork::makeCell(Library *library,
483 			  const char *name,
484 			  bool is_leaf,
485 			  const char *filename)
486 {
487   ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
488   return reinterpret_cast<Cell*>(clib->makeCell(name, is_leaf, filename));
489 }
490 
491 Cell *
findCell(const Library * library,const char * name) const492 ConcreteNetwork::findCell(const Library *library,
493 			  const char *name) const
494 {
495   const ConcreteLibrary *clib =
496     reinterpret_cast<const ConcreteLibrary*>(library);
497   return reinterpret_cast<Cell*>(clib->findCell(name));
498 }
499 
500 Cell *
findAnyCell(const char * name)501 ConcreteNetwork::findAnyCell(const char *name)
502 {
503   ConcreteLibrarySeq::Iterator lib_iter(library_seq_);
504   while (lib_iter.hasNext()) {
505     ConcreteLibrary *lib = lib_iter.next();
506     ConcreteCell *cell = lib->findCell(name);
507     if (cell)
508       return reinterpret_cast<Cell*>(cell);
509   }
510   return nullptr;
511 }
512 
513 void
findCellsMatching(const Library * library,const PatternMatch * pattern,CellSeq * cells) const514 ConcreteNetwork::findCellsMatching(const Library *library,
515 				   const PatternMatch *pattern,
516 				   CellSeq *cells) const
517 {
518   const ConcreteLibrary *clib =
519     reinterpret_cast<const ConcreteLibrary*>(library);
520   clib->findCellsMatching(pattern, cells);
521 }
522 
523 void
deleteCell(Cell * cell)524 ConcreteNetwork::deleteCell(Cell *cell)
525 {
526   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
527   ConcreteLibrary *clib = ccell->library();
528   clib->deleteCell(ccell);
529 }
530 
531 ////////////////////////////////////////////////////////////////
532 
533 const char *
name(const Cell * cell) const534 ConcreteNetwork::name(const Cell *cell) const
535 {
536   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
537   return ccell->name();
538 }
539 
540 void
setName(Cell * cell,const char * name)541 ConcreteNetwork::setName(Cell *cell,
542 			 const char *name)
543 {
544   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
545   ccell->setName(name);
546 }
547 
548 void
setIsLeaf(Cell * cell,bool is_leaf)549 ConcreteNetwork::setIsLeaf(Cell *cell,
550 			   bool is_leaf)
551 {
552   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
553   ccell->setIsLeaf(is_leaf);
554 }
555 
556 Library *
library(const Cell * cell) const557 ConcreteNetwork::library(const Cell *cell) const
558 {
559   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
560   return reinterpret_cast<Library*>(ccell->library());
561 }
562 
563 LibertyCell *
libertyCell(Cell * cell) const564 ConcreteNetwork::libertyCell(Cell *cell) const
565 {
566   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
567   return ccell->libertyCell();
568 }
569 
570 const LibertyCell *
libertyCell(const Cell * cell) const571 ConcreteNetwork::libertyCell(const Cell *cell) const
572 {
573   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
574   return ccell->libertyCell();
575 }
576 
577 Cell *
cell(LibertyCell * cell) const578 ConcreteNetwork::cell(LibertyCell *cell) const
579 {
580   return reinterpret_cast<Cell*>(cell);
581 }
582 
583 const Cell *
cell(const LibertyCell * cell) const584 ConcreteNetwork::cell(const LibertyCell *cell) const
585 {
586   return reinterpret_cast<const Cell*>(cell);
587 }
588 
589 const char *
filename(const Cell * cell)590 ConcreteNetwork::filename(const Cell *cell)
591 {
592   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
593   return ccell->filename();
594 }
595 
596 Port *
findPort(const Cell * cell,const char * name) const597 ConcreteNetwork::findPort(const Cell *cell,
598 			  const char *name) const
599 {
600   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
601   return reinterpret_cast<Port*>(ccell->findPort(name));
602 }
603 
604 void
findPortsMatching(const Cell * cell,const PatternMatch * pattern,PortSeq * ports) const605 ConcreteNetwork::findPortsMatching(const Cell *cell,
606 				   const PatternMatch *pattern,
607 				   PortSeq *ports) const
608 {
609   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
610   ccell->findPortsMatching(pattern, ports);
611 }
612 
613 bool
isLeaf(const Cell * cell) const614 ConcreteNetwork::isLeaf(const Cell *cell) const
615 {
616   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
617   return ccell->isLeaf();
618 }
619 
620 Port *
makePort(Cell * cell,const char * name)621 ConcreteNetwork::makePort(Cell *cell,
622 			  const char *name)
623 {
624   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
625   ConcretePort *port = ccell->makePort(name);
626   return reinterpret_cast<Port*>(port);
627 }
628 
629 Port *
makeBusPort(Cell * cell,const char * name,int from_index,int to_index)630 ConcreteNetwork::makeBusPort(Cell *cell,
631 			     const char *name,
632 			     int from_index,
633 			     int to_index)
634 {
635   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
636   ConcretePort *port = ccell->makeBusPort(name, from_index, to_index);
637   return reinterpret_cast<Port*>(port);
638 }
639 
640 void
groupBusPorts(Cell * cell)641 ConcreteNetwork::groupBusPorts(Cell *cell)
642 {
643   Library *lib = library(cell);
644   ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(lib);
645   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
646   ccell->groupBusPorts(clib->busBrktLeft(), clib->busBrktRight());
647 }
648 
649 Port *
makeBundlePort(Cell * cell,const char * name,PortSeq * members)650 ConcreteNetwork::makeBundlePort(Cell *cell,
651 				const char *name,
652 				PortSeq *members)
653 {
654   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
655   ConcretePortSeq *cmembers = reinterpret_cast<ConcretePortSeq*>(members);
656   ConcretePort *port = ccell->makeBundlePort(name, cmembers);
657   return reinterpret_cast<Port*>(port);
658 }
659 
660 void
setDirection(Port * port,PortDirection * dir)661 ConcreteNetwork::setDirection(Port *port,
662 			      PortDirection *dir)
663 {
664   ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
665   cport->setDirection(dir);
666 }
667 
668 ////////////////////////////////////////////////////////////////
669 
670 class ConcreteCellPortIterator1 : public CellPortIterator
671 {
672 public:
673   explicit ConcreteCellPortIterator1(const ConcreteCell *cell);
674   ~ConcreteCellPortIterator1();
hasNext()675   virtual bool hasNext() { return iter_->hasNext(); }
676   virtual Port *next();
677 
678 private:
679   DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortIterator1);
680 
681   ConcreteCellPortIterator *iter_;
682 };
683 
ConcreteCellPortIterator1(const ConcreteCell * cell)684 ConcreteCellPortIterator1::ConcreteCellPortIterator1(const ConcreteCell *cell):
685   iter_(cell->portIterator())
686 {
687 }
688 
~ConcreteCellPortIterator1()689 ConcreteCellPortIterator1::~ConcreteCellPortIterator1()
690 {
691   delete iter_;
692 }
693 
694 Port *
next()695 ConcreteCellPortIterator1::next()
696 {
697   return reinterpret_cast<Port*>(iter_->next());
698 }
699 
700 CellPortIterator *
portIterator(const Cell * cell) const701 ConcreteNetwork::portIterator(const Cell *cell) const
702 {
703   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
704   return new ConcreteCellPortIterator1(ccell);
705 }
706 
707 ////////////////////////////////////////////////////////////////
708 
709 class ConcreteCellPortBitIterator1 : public CellPortIterator
710 {
711 public:
712   explicit ConcreteCellPortBitIterator1(const ConcreteCell *cell);
713   ~ConcreteCellPortBitIterator1();
hasNext()714   virtual bool hasNext() { return iter_->hasNext(); }
715   virtual Port *next();
716 
717 private:
718   DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortBitIterator1);
719 
720   ConcreteCellPortBitIterator *iter_;
721 };
722 
ConcreteCellPortBitIterator1(const ConcreteCell * cell)723 ConcreteCellPortBitIterator1::ConcreteCellPortBitIterator1(const ConcreteCell *cell):
724   iter_(cell->portBitIterator())
725 {
726 }
727 
~ConcreteCellPortBitIterator1()728 ConcreteCellPortBitIterator1::~ConcreteCellPortBitIterator1()
729 {
730   delete iter_;
731 }
732 
733 Port *
next()734 ConcreteCellPortBitIterator1::next()
735 {
736   return reinterpret_cast<Port*>(iter_->next());
737 }
738 
739 CellPortBitIterator *
portBitIterator(const Cell * cell) const740 ConcreteNetwork::portBitIterator(const Cell *cell) const
741 {
742   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
743   return new ConcreteCellPortBitIterator1(ccell);
744 }
745 
746 int
portBitCount(const Cell * cell) const747 ConcreteNetwork::portBitCount(const Cell *cell) const
748 {
749   const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
750   return ccell->portBitCount();
751 }
752 
753 ////////////////////////////////////////////////////////////////
754 
755 const char *
name(const Port * port) const756 ConcreteNetwork::name(const Port *port) const
757 {
758   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
759   return cport->name();
760 }
761 
762 Cell *
cell(const Port * port) const763 ConcreteNetwork::cell(const Port *port) const
764 {
765   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
766   return cport->cell();
767 }
768 
769 LibertyPort *
libertyPort(const Port * port) const770 ConcreteNetwork::libertyPort(const Port *port) const
771 {
772   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
773   return cport->libertyPort();
774 }
775 
776 PortDirection *
direction(const Port * port) const777 ConcreteNetwork::direction(const Port *port) const
778 {
779   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
780   return cport->direction();
781 }
782 
783 bool
isBundle(const Port * port) const784 ConcreteNetwork::isBundle(const Port *port) const
785 {
786   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
787   return cport->isBundle();
788 }
789 
790 bool
isBus(const Port * port) const791 ConcreteNetwork::isBus(const Port *port) const
792 {
793   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
794   return cport->isBus();
795 }
796 
797 const char *
busName(const Port * port) const798 ConcreteNetwork::busName(const Port *port) const
799 {
800   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
801   return cport->busName();
802 }
803 
804 int
size(const Port * port) const805 ConcreteNetwork::size(const Port *port) const
806 {
807   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
808   return cport->size();
809 }
810 
811 int
fromIndex(const Port * port) const812 ConcreteNetwork::fromIndex(const Port *port) const
813 {
814   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
815   return cport->fromIndex();
816 }
817 
818 int
toIndex(const Port * port) const819 ConcreteNetwork::toIndex(const Port *port) const
820 {
821   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
822   return cport->toIndex();
823 }
824 
825 Port *
findBusBit(const Port * port,int index) const826 ConcreteNetwork::findBusBit(const Port *port,
827 			    int index) const
828 {
829   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
830   return reinterpret_cast<Port*>(cport->findBusBit(index));
831 }
832 
833 Port *
findMember(const Port * port,int index) const834 ConcreteNetwork::findMember(const Port *port,
835 			    int index) const
836 {
837   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
838   return reinterpret_cast<Port*>(cport->findMember(index));
839 }
840 
841 bool
hasMembers(const Port * port) const842 ConcreteNetwork::hasMembers(const Port *port) const
843 {
844   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
845   return cport->hasMembers();
846 }
847 
848 ////////////////////////////////////////////////////////////////
849 
850 class ConcretePortMemberIterator1 : public PortMemberIterator
851 {
852 public:
853   explicit ConcretePortMemberIterator1(const ConcretePort *port);
854   ~ConcretePortMemberIterator1();
hasNext()855   virtual bool hasNext() { return iter_->hasNext(); }
856   virtual Port *next();
857 
858 private:
859   DISALLOW_COPY_AND_ASSIGN(ConcretePortMemberIterator1);
860 
861   ConcretePortMemberIterator *iter_;
862 };
863 
ConcretePortMemberIterator1(const ConcretePort * port)864 ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort *
865 							 port) :
866   iter_(port->memberIterator())
867 {
868 }
869 
~ConcretePortMemberIterator1()870 ConcretePortMemberIterator1::~ConcretePortMemberIterator1()
871 {
872   delete iter_;
873 }
874 
875 Port *
next()876 ConcretePortMemberIterator1::next()
877 {
878   return reinterpret_cast<Port*>(iter_->next());
879 }
880 
881 PortMemberIterator *
memberIterator(const Port * port) const882 ConcreteNetwork::memberIterator(const Port *port) const
883 {
884   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
885   return new ConcretePortMemberIterator1(cport);
886 }
887 
888 ////////////////////////////////////////////////////////////////
889 
890 const char *
name(const Instance * instance) const891 ConcreteNetwork::name(const Instance *instance) const
892 {
893   const ConcreteInstance *inst =
894     reinterpret_cast<const ConcreteInstance*>(instance);
895   return inst->name();
896 }
897 
898 Cell *
cell(const Instance * instance) const899 ConcreteNetwork::cell(const Instance *instance) const
900 {
901   const ConcreteInstance *inst =
902     reinterpret_cast<const ConcreteInstance*>(instance);
903   return inst->cell();
904 }
905 
906 Instance *
parent(const Instance * instance) const907 ConcreteNetwork::parent(const Instance *instance) const
908 {
909   const ConcreteInstance *inst =
910     reinterpret_cast<const ConcreteInstance*>(instance);
911   return reinterpret_cast<Instance*>(inst->parent());
912 }
913 
914 bool
isLeaf(const Instance * instance) const915 ConcreteNetwork::isLeaf(const Instance *instance) const
916 {
917   const ConcreteInstance *inst =
918     reinterpret_cast<const ConcreteInstance*>(instance);
919   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(inst->cell());
920   return ccell->isLeaf();
921 }
922 
923 Instance *
findChild(const Instance * parent,const char * name) const924 ConcreteNetwork::findChild(const Instance *parent,
925 			   const char *name) const
926 {
927   const ConcreteInstance *inst =
928     reinterpret_cast<const ConcreteInstance*>(parent);
929   return inst->findChild(name);
930 }
931 
932 Pin *
findPin(const Instance * instance,const char * port_name) const933 ConcreteNetwork::findPin(const Instance *instance,
934 			 const char *port_name) const
935 {
936   const ConcreteInstance *inst =
937     reinterpret_cast<const ConcreteInstance*>(instance);
938   return reinterpret_cast<Pin*>(inst->findPin(port_name));
939 }
940 
941 Pin *
findPin(const Instance * instance,const Port * port) const942 ConcreteNetwork::findPin(const Instance *instance,
943 			 const Port *port) const
944 {
945   const ConcreteInstance *inst =
946     reinterpret_cast<const ConcreteInstance*>(instance);
947   return reinterpret_cast<Pin*>(inst->findPin(port));
948 }
949 
950 Net *
findNet(const Instance * instance,const char * net_name) const951 ConcreteNetwork::findNet(const Instance *instance,
952 			 const char *net_name) const
953 {
954   const ConcreteInstance *inst =
955     reinterpret_cast<const ConcreteInstance*>(instance);
956   return reinterpret_cast<Net*>(inst->findNet(net_name));
957 }
958 
959 void
findInstNetsMatching(const Instance * instance,const PatternMatch * pattern,NetSeq * nets) const960 ConcreteNetwork::findInstNetsMatching(const Instance *instance,
961 				      const PatternMatch *pattern,
962 				      NetSeq *nets) const
963 {
964   const ConcreteInstance *inst =
965     reinterpret_cast<const ConcreteInstance*>(instance);
966   inst->findNetsMatching(pattern, nets);
967 }
968 
969 ////////////////////////////////////////////////////////////////
970 
971 InstanceChildIterator *
childIterator(const Instance * instance) const972 ConcreteNetwork::childIterator(const Instance *instance) const
973 {
974   const ConcreteInstance *inst =
975     reinterpret_cast<const ConcreteInstance*>(instance);
976   return inst->childIterator();
977 }
978 
979 InstancePinIterator *
pinIterator(const Instance * instance) const980 ConcreteNetwork::pinIterator(const Instance *instance) const
981 {
982   const ConcreteInstance *inst =
983     reinterpret_cast<const ConcreteInstance*>(instance);
984   ConcreteCell *cell = reinterpret_cast<ConcreteCell*>(inst->cell());
985   int pin_count = cell->portBitCount();
986   return new ConcreteInstancePinIterator(inst, pin_count);
987 }
988 
989 InstanceNetIterator *
netIterator(const Instance * instance) const990 ConcreteNetwork::netIterator(const Instance *instance) const
991 {
992   const ConcreteInstance *inst =
993     reinterpret_cast<const ConcreteInstance*>(instance);
994   return inst->netIterator();
995 }
996 
997 ////////////////////////////////////////////////////////////////
998 
999 Instance *
instance(const Pin * pin) const1000 ConcreteNetwork::instance(const Pin *pin) const
1001 {
1002   const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
1003   return reinterpret_cast<Instance*>(cpin->instance());
1004 }
1005 
1006 Net *
net(const Pin * pin) const1007 ConcreteNetwork::net(const Pin *pin) const
1008 {
1009   const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
1010   return reinterpret_cast<Net*>(cpin->net());
1011 }
1012 
1013 Term *
term(const Pin * pin) const1014 ConcreteNetwork::term(const Pin *pin) const
1015 {
1016   const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
1017   return reinterpret_cast<Term*>(cpin->term());
1018 }
1019 
1020 Port *
port(const Pin * pin) const1021 ConcreteNetwork::port(const Pin *pin) const
1022 {
1023   const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
1024   return reinterpret_cast<Port*>(cpin->port());
1025 }
1026 
1027 PortDirection *
direction(const Pin * pin) const1028 ConcreteNetwork::direction(const Pin *pin) const
1029 {
1030   const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
1031   const ConcretePort *cport = cpin->port();
1032   return cport->direction();
1033 }
1034 
1035 VertexId
vertexId(const Pin * pin) const1036 ConcreteNetwork::vertexId(const Pin *pin) const
1037 {
1038   const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
1039   return cpin->vertexId();
1040 }
1041 
1042 void
setVertexId(Pin * pin,VertexId id)1043 ConcreteNetwork::setVertexId(Pin *pin,
1044 			     VertexId id)
1045 {
1046   ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
1047   cpin->setVertexId(id);
1048 }
1049 
1050 ////////////////////////////////////////////////////////////////
1051 
1052 Net *
net(const Term * term) const1053 ConcreteNetwork::net(const Term *term) const
1054 {
1055   const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
1056   return reinterpret_cast<Net*>(cterm->net());
1057 }
1058 
1059 Pin *
pin(const Term * term) const1060 ConcreteNetwork::pin(const Term *term) const
1061 {
1062   const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
1063   return reinterpret_cast<Pin*>(cterm->pin());
1064 }
1065 
1066 ////////////////////////////////////////////////////////////////
1067 
1068 const char *
name(const Net * net) const1069 ConcreteNetwork::name(const Net *net) const
1070 {
1071   const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
1072   return cnet->name();
1073 }
1074 
1075 Instance *
instance(const Net * net) const1076 ConcreteNetwork::instance(const Net *net) const
1077 {
1078   const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
1079   return reinterpret_cast<Instance*>(cnet->instance());
1080 }
1081 
1082 bool
isPower(const Net * net) const1083 ConcreteNetwork::isPower(const Net *net) const
1084 {
1085   return constant_nets_[int(LogicValue::one)].hasKey(const_cast<Net*>(net));
1086 }
1087 
1088 bool
isGround(const Net * net) const1089 ConcreteNetwork::isGround(const Net *net) const
1090 {
1091   return constant_nets_[int(LogicValue::zero)].hasKey(const_cast<Net*>(net));
1092 }
1093 
1094 NetPinIterator *
pinIterator(const Net * net) const1095 ConcreteNetwork::pinIterator(const Net *net) const
1096 {
1097   const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
1098   return new ConcreteNetPinIterator(cnet);
1099 }
1100 
1101 NetTermIterator *
termIterator(const Net * net) const1102 ConcreteNetwork::termIterator(const Net *net) const
1103 {
1104   const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
1105   return new ConcreteNetTermIterator(cnet);
1106 }
1107 
1108 void
mergeInto(Net * net,Net * into_net)1109 ConcreteNetwork::mergeInto(Net *net,
1110 			   Net *into_net)
1111 {
1112   ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
1113   ConcreteNet *cinto_net = reinterpret_cast<ConcreteNet*>(into_net);
1114   cnet->mergeInto(cinto_net);
1115   clearNetDrvrPinMap();
1116 }
1117 
1118 Net *
mergedInto(Net * net)1119 ConcreteNetwork::mergedInto(Net *net)
1120 {
1121   ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
1122   return reinterpret_cast<Net*>(cnet->mergedInto());
1123 }
1124 
1125 ////////////////////////////////////////////////////////////////
1126 
1127 Cell *
cell() const1128 ConcreteInstance::cell() const
1129 {
1130   return reinterpret_cast<Cell*>(cell_);
1131 }
1132 
1133 Instance *
makeInstance(Cell * cell,const char * name,Instance * parent)1134 ConcreteNetwork::makeInstance(Cell *cell,
1135 			      const char *name,
1136 			      Instance *parent)
1137 {
1138   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
1139   return makeConcreteInstance(ccell, name, parent);
1140 }
1141 
1142 Instance *
makeInstance(LibertyCell * cell,const char * name,Instance * parent)1143 ConcreteNetwork::makeInstance(LibertyCell *cell,
1144 			      const char *name,
1145 			      Instance *parent)
1146 {
1147   return makeConcreteInstance(cell, name, parent);
1148 }
1149 
1150 Instance *
makeConcreteInstance(ConcreteCell * cell,const char * name,Instance * parent)1151 ConcreteNetwork::makeConcreteInstance(ConcreteCell *cell,
1152 				      const char *name,
1153 				      Instance *parent)
1154 {
1155   ConcreteInstance *cparent =
1156     reinterpret_cast<ConcreteInstance*>(parent);
1157   ConcreteInstance *inst = new ConcreteInstance(cell, name, cparent);
1158   if (parent)
1159     cparent->addChild(inst);
1160   return reinterpret_cast<Instance*>(inst);
1161 }
1162 
1163 void
makePins(Instance * inst)1164 ConcreteNetwork::makePins(Instance *inst)
1165 {
1166   CellPortBitIterator *port_iterator = portBitIterator(cell(inst));
1167   while (port_iterator->hasNext()) {
1168     Port *port = port_iterator->next();
1169     makePin(inst, port, nullptr);
1170   }
1171   delete port_iterator;
1172 }
1173 
1174 void
replaceCell(Instance * inst,Cell * cell)1175 ConcreteNetwork::replaceCell(Instance *inst,
1176 			     Cell *cell)
1177 {
1178   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
1179   int port_count = ccell->portBitCount();
1180   ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
1181   ConcretePin **pins = cinst->pins_;
1182   ConcretePin **rpins = new ConcretePin*[port_count];
1183   for (int i = 0; i < port_count; i++)
1184     rpins[i] = nullptr;
1185   for (int i = 0; i < port_count; i++) {
1186     ConcretePin *cpin = pins[i];
1187     if (cpin) {
1188       ConcretePort *pin_cport = reinterpret_cast<ConcretePort*>(cpin->port());
1189       ConcretePort *cport = ccell->findPort(pin_cport->name());
1190       rpins[cport->pinIndex()] = cpin;
1191       cpin->port_ = cport;
1192     }
1193   }
1194   delete [] pins;
1195   cinst->pins_ = rpins;
1196   cinst->setCell(ccell);
1197 }
1198 
1199 void
deleteInstance(Instance * inst)1200 ConcreteNetwork::deleteInstance(Instance *inst)
1201 {
1202   ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
1203 
1204   // Delete nets first (so children pin deletes are not required).
1205   ConcreteInstanceNetMap::Iterator net_iter(cinst->nets_);
1206   while (net_iter.hasNext()) {
1207     ConcreteNet *cnet = net_iter.next();
1208     Net *net = reinterpret_cast<Net*>(cnet);
1209     // Delete terminals connected to net.
1210     NetTermIterator *term_iter = termIterator(net);
1211     while (term_iter->hasNext()) {
1212       ConcreteTerm *term = reinterpret_cast<ConcreteTerm*>(term_iter->next());
1213       delete term;
1214     }
1215     delete term_iter;
1216     deleteNet(net);
1217   }
1218 
1219   // Delete children.
1220   InstanceChildIterator *child_iter = childIterator(inst);
1221   while (child_iter->hasNext()) {
1222     Instance *child = child_iter->next();
1223     deleteInstance(child);
1224   }
1225   delete child_iter;
1226 
1227   InstancePinIterator *pin_iter = pinIterator(inst);
1228   while (pin_iter->hasNext()) {
1229     Pin *pin = pin_iter->next();
1230     deletePin(pin);
1231   }
1232   delete pin_iter;
1233 
1234   Instance *parent_inst = parent(inst);
1235   if (parent_inst) {
1236     ConcreteInstance *cparent =
1237       reinterpret_cast<ConcreteInstance*>(parent_inst);
1238     cparent->deleteChild(cinst);
1239   }
1240   delete cinst;
1241 }
1242 
1243 Pin *
makePin(Instance * inst,Port * port,Net * net)1244 ConcreteNetwork::makePin(Instance *inst,
1245 			 Port *port,
1246 			 Net *net)
1247 {
1248   ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
1249   ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
1250   ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
1251   ConcretePin *cpin = new ConcretePin(cinst, cport, cnet);
1252   cinst->addPin(cpin);
1253   if (cnet)
1254     connectNetPin(cnet, cpin);
1255   return reinterpret_cast<Pin*>(cpin);
1256 }
1257 
1258 Term *
makeTerm(Pin * pin,Net * net)1259 ConcreteNetwork::makeTerm(Pin *pin,
1260 			  Net *net)
1261 {
1262   ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
1263   ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
1264   ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
1265   if (cnet)
1266     cnet->addTerm(cterm);
1267   cpin->term_ = cterm;
1268   return reinterpret_cast<Term*>(cterm);
1269 }
1270 
1271 Pin *
connect(Instance * inst,LibertyPort * port,Net * net)1272 ConcreteNetwork::connect(Instance *inst,
1273 			 LibertyPort *port,
1274 			 Net *net)
1275 {
1276   return connect(inst, reinterpret_cast<Port*>(port), net);
1277 }
1278 
1279 Pin *
connect(Instance * inst,Port * port,Net * net)1280 ConcreteNetwork::connect(Instance *inst,
1281 			 Port *port,
1282 			 Net *net)
1283 {
1284   ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
1285   ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
1286   ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
1287   ConcretePin *cpin = cinst->findPin(port);
1288   if (cpin) {
1289     ConcreteNet *prev_net = cpin->net_;
1290     if (prev_net)
1291       disconnectNetPin(prev_net, cpin);
1292   }
1293   else {
1294     cpin = new ConcretePin(cinst, cport, cnet);
1295     cinst->addPin(cpin);
1296   }
1297   if (inst == top_instance_) {
1298     // makeTerm
1299     ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
1300     cnet->addTerm(cterm);
1301     cpin->term_ = cterm;
1302     cpin->net_ = nullptr;
1303   }
1304   else {
1305     cpin->net_ = cnet;
1306     connectNetPin(cnet, cpin);
1307   }
1308   return reinterpret_cast<Pin*>(cpin);
1309 }
1310 
1311 void
connectNetPin(ConcreteNet * cnet,ConcretePin * cpin)1312 ConcreteNetwork::connectNetPin(ConcreteNet *cnet,
1313 			       ConcretePin *cpin)
1314 {
1315   cnet->addPin(cpin);
1316 
1317   // If there are no terminals the net does not span hierarchy levels
1318   // and it is safe to incrementally update the drivers.
1319   Pin *pin = reinterpret_cast<Pin*>(cpin);
1320   if (isDriver(pin)) {
1321     if (cnet->terms_ == nullptr) {
1322       Net *net = reinterpret_cast<Net*>(cnet);
1323       PinSet *drvrs = net_drvr_pin_map_.findKey(net);
1324       if (drvrs)
1325 	drvrs->insert(pin);
1326     }
1327     else
1328       clearNetDrvrPinMap();
1329   }
1330 }
1331 
1332 void
disconnectPin(Pin * pin)1333 ConcreteNetwork::disconnectPin(Pin *pin)
1334 {
1335   ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
1336   if (reinterpret_cast<Instance*>(cpin->instance()) == top_instance_) {
1337     ConcreteTerm *cterm = cpin->term_;
1338     if (cterm) {
1339       ConcreteNet *cnet = cterm->net_;
1340       if (cnet) {
1341 	cnet->deleteTerm(cterm);
1342 	clearNetDrvrPinMap();
1343       }
1344       cpin->term_ = nullptr;
1345       delete cterm;
1346     }
1347   }
1348   else {
1349     ConcreteNet *cnet = cpin->net();
1350     if (cnet)
1351       disconnectNetPin(cnet, cpin);
1352     cpin->net_ = nullptr;
1353   }
1354 }
1355 
1356 void
disconnectNetPin(ConcreteNet * cnet,ConcretePin * cpin)1357 ConcreteNetwork::disconnectNetPin(ConcreteNet *cnet,
1358 				  ConcretePin *cpin)
1359 {
1360   cnet->deletePin(cpin);
1361 
1362   Pin *pin = reinterpret_cast<Pin*>(cpin);
1363   if (isDriver(pin)) {
1364     ConcreteNet *cnet = cpin->net();
1365     // If there are no terminals the net does not span hierarchy levels
1366     // and it is safe to incrementally update the drivers.
1367     if (cnet->terms_ == nullptr) {
1368       Net *net = reinterpret_cast<Net*>(cnet);
1369       PinSet *drvrs = net_drvr_pin_map_.findKey(net);
1370       if (drvrs)
1371 	drvrs->erase(pin);
1372     }
1373     else
1374       clearNetDrvrPinMap();
1375   }
1376 }
1377 
1378 void
deletePin(Pin * pin)1379 ConcreteNetwork::deletePin(Pin *pin)
1380 {
1381   ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
1382   ConcreteNet *cnet = cpin->net();
1383   if (cnet)
1384     disconnectNetPin(cnet, cpin);
1385   ConcreteInstance *cinst =
1386     reinterpret_cast<ConcreteInstance*>(cpin->instance());
1387   if (cinst)
1388     cinst->deletePin(cpin);
1389   delete cpin;
1390 }
1391 
1392 Net *
makeNet(const char * name,Instance * parent)1393 ConcreteNetwork::makeNet(const char *name,
1394 			 Instance *parent)
1395 {
1396   ConcreteInstance *cparent = reinterpret_cast<ConcreteInstance*>(parent);
1397   ConcreteNet *net = new ConcreteNet(name, cparent);
1398   cparent->addNet(net);
1399   return reinterpret_cast<Net*>(net);
1400 }
1401 
1402 void
deleteNet(Net * net)1403 ConcreteNetwork::deleteNet(Net *net)
1404 {
1405   ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
1406   ConcreteNetPinIterator pin_iter(cnet);
1407   while (pin_iter.hasNext()) {
1408     ConcretePin *pin = reinterpret_cast<ConcretePin*>(pin_iter.next());
1409     // Do NOT use net->disconnectPin because it would be N^2
1410     // to delete all of the pins from the net.
1411     pin->net_ = nullptr;
1412   }
1413 
1414   constant_nets_[int(LogicValue::zero)].erase(net);
1415   constant_nets_[int(LogicValue::one)].erase(net);
1416   PinSet *drvrs = net_drvr_pin_map_.findKey(net);
1417   if (drvrs) {
1418     delete drvrs;
1419     net_drvr_pin_map_.erase(net);
1420   }
1421 
1422   ConcreteInstance *cinst =
1423     reinterpret_cast<ConcreteInstance*>(cnet->instance());
1424   cinst->deleteNet(cnet);
1425   delete cnet;
1426 }
1427 
1428 void
clearConstantNets()1429 ConcreteNetwork::clearConstantNets()
1430 {
1431   constant_nets_[int(LogicValue::zero)].clear();
1432   constant_nets_[int(LogicValue::one)].clear();
1433 }
1434 
1435 void
addConstantNet(Net * net,LogicValue value)1436 ConcreteNetwork::addConstantNet(Net *net,
1437 				LogicValue value)
1438 {
1439   constant_nets_[int(value)].insert(net);
1440 }
1441 
1442 ConstantPinIterator *
constantPinIterator()1443 ConcreteNetwork::constantPinIterator()
1444 {
1445   return new NetworkConstantPinIterator(this,
1446 					constant_nets_[int(LogicValue::zero)],
1447 					constant_nets_[int(LogicValue::one)]);
1448 }
1449 
1450 ////////////////////////////////////////////////////////////////
1451 
1452 // Optimized version of Network::visitConnectedPins.
1453 void
visitConnectedPins(const Net * net,PinVisitor & visitor,ConstNetSet & visited_nets) const1454 ConcreteNetwork::visitConnectedPins(const Net *net,
1455 				    PinVisitor &visitor,
1456 				    ConstNetSet &visited_nets) const
1457 {
1458   if (!visited_nets.hasKey(net)) {
1459     visited_nets.insert(net);
1460     // Search up from net terminals.
1461     const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
1462     for (ConcreteTerm *term = cnet->terms_; term; term = term->net_next_) {
1463       ConcretePin *above_pin = term->pin_;
1464       if (above_pin) {
1465 	ConcreteNet *above_net = above_pin->net_;
1466 	if (above_net)
1467 	  visitConnectedPins(reinterpret_cast<Net*>(above_net),
1468 			     visitor, visited_nets);
1469 	else
1470 	  visitor(reinterpret_cast<Pin*>(above_pin));
1471       }
1472     }
1473 
1474     // Search down from net pins.
1475     for (ConcretePin *pin = cnet->pins_; pin; pin = pin->net_next_) {
1476       visitor(reinterpret_cast<Pin*>(pin));
1477       ConcreteTerm *below_term = pin->term_;
1478       if (below_term) {
1479 	ConcreteNet *below_net = below_term->net_;
1480 	if (below_net)
1481 	  visitConnectedPins(reinterpret_cast<Net*>(below_net),
1482 			     visitor, visited_nets);
1483       }
1484     }
1485   }
1486 }
1487 
1488 ////////////////////////////////////////////////////////////////
1489 
ConcreteInstance(ConcreteCell * cell,const char * name,ConcreteInstance * parent)1490 ConcreteInstance::ConcreteInstance(ConcreteCell *cell,
1491 				   const char *name,
1492 				   ConcreteInstance *parent) :
1493   cell_(cell),
1494   name_(stringCopy(name)),
1495   parent_(parent),
1496   children_(nullptr),
1497   nets_(nullptr)
1498 {
1499   initPins();
1500 }
1501 
1502 void
initPins()1503 ConcreteInstance::initPins()
1504 {
1505   int pin_count = reinterpret_cast<ConcreteCell*>(cell_)->portBitCount();
1506   if (pin_count) {
1507     pins_ = new ConcretePin*[pin_count];
1508     for (int i = 0; i < pin_count; i++)
1509       pins_[i] = nullptr;
1510   }
1511   else
1512     pins_ = nullptr;
1513 }
1514 
~ConcreteInstance()1515 ConcreteInstance::~ConcreteInstance()
1516 {
1517   stringDelete(name_);
1518   delete [] pins_;
1519   delete children_;
1520   delete nets_;
1521 }
1522 
1523 Instance *
findChild(const char * name) const1524 ConcreteInstance::findChild(const char *name) const
1525 {
1526   if (children_)
1527     return reinterpret_cast<Instance*>(children_->findKey(name));
1528   else
1529     return nullptr;
1530 }
1531 
1532 ConcretePin *
findPin(const char * port_name) const1533 ConcreteInstance::findPin(const char *port_name) const
1534 {
1535   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell_);
1536   const ConcretePort *cport =
1537     reinterpret_cast<const ConcretePort*>(ccell->findPort(port_name));
1538   if (cport
1539       && !cport->isBus())
1540     return pins_[cport->pinIndex()];
1541   else
1542     return nullptr;
1543 }
1544 
1545 ConcretePin *
findPin(const Port * port) const1546 ConcreteInstance::findPin(const Port *port) const
1547 {
1548   const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
1549   return pins_[cport->pinIndex()];
1550 }
1551 
1552 ConcreteNet *
findNet(const char * net_name) const1553 ConcreteInstance::findNet(const char *net_name) const
1554 {
1555   ConcreteNet *net = nullptr;
1556   if (nets_) {
1557     net = nets_->findKey(net_name);
1558     // Follow merge pointer to surviving net.
1559     if (net) {
1560       while (net->mergedInto())
1561 	net = net->mergedInto();
1562     }
1563   }
1564   return net;
1565 }
1566 
1567 void
findNetsMatching(const PatternMatch * pattern,NetSeq * nets) const1568 ConcreteInstance::findNetsMatching(const PatternMatch *pattern,
1569 				   NetSeq *nets) const
1570 {
1571   if (pattern->hasWildcards()) {
1572     ConcreteInstanceNetMap::Iterator net_iter(nets_);
1573     while (net_iter.hasNext()) {
1574       const char *net_name;
1575       ConcreteNet *cnet;
1576       net_iter.next(net_name, cnet);
1577       if (pattern->match(net_name))
1578 	nets->push_back(reinterpret_cast<Net*>(cnet));
1579     }
1580   }
1581   else {
1582     ConcreteNet *cnet = findNet(pattern->pattern());
1583     if (cnet)
1584       nets->push_back(reinterpret_cast<Net*>(cnet));
1585   }
1586 }
1587 
1588 InstanceNetIterator *
netIterator() const1589 ConcreteInstance::netIterator() const
1590 {
1591   return reinterpret_cast<InstanceNetIterator*>
1592     (new ConcreteInstanceNetIterator(nets_));
1593 }
1594 
1595 InstanceChildIterator *
childIterator() const1596 ConcreteInstance::childIterator() const
1597 {
1598   return new ConcreteInstanceChildIterator(children_);
1599 }
1600 
1601 void
addChild(ConcreteInstance * child)1602 ConcreteInstance::addChild(ConcreteInstance *child)
1603 {
1604   if (children_ == nullptr)
1605     children_ = new ConcreteInstanceChildMap;
1606   (*children_)[child->name()] = child;
1607 }
1608 
1609 void
deleteChild(ConcreteInstance * child)1610 ConcreteInstance::deleteChild(ConcreteInstance *child)
1611 {
1612   children_->erase(child->name());
1613 }
1614 
1615 void
addPin(ConcretePin * pin)1616 ConcreteInstance::addPin(ConcretePin *pin)
1617 {
1618   ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
1619   pins_[cport->pinIndex()] = pin;
1620 }
1621 
1622 void
deletePin(ConcretePin * pin)1623 ConcreteInstance::deletePin(ConcretePin *pin)
1624 {
1625   ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
1626   pins_[cport->pinIndex()] = nullptr;
1627 }
1628 
1629 void
addNet(ConcreteNet * net)1630 ConcreteInstance::addNet(ConcreteNet *net)
1631 {
1632   if (nets_ == nullptr)
1633     nets_ = new ConcreteInstanceNetMap;
1634   (*nets_)[net->name()] = net;
1635 }
1636 
1637 void
addNet(const char * name,ConcreteNet * net)1638 ConcreteInstance::addNet(const char *name,
1639 			 ConcreteNet *net)
1640 {
1641   if (nets_ == nullptr)
1642     nets_ = new ConcreteInstanceNetMap;
1643   (*nets_)[name] = net;
1644 }
1645 
1646 void
deleteNet(ConcreteNet * net)1647 ConcreteInstance::deleteNet(ConcreteNet *net)
1648 {
1649   nets_->erase(net->name());
1650 }
1651 
1652 void
setCell(ConcreteCell * cell)1653 ConcreteInstance::setCell(ConcreteCell *cell)
1654 {
1655   cell_ = cell;
1656 }
1657 
1658 ////////////////////////////////////////////////////////////////
1659 
ConcretePin(ConcreteInstance * instance,ConcretePort * port,ConcreteNet * net)1660 ConcretePin::ConcretePin(ConcreteInstance *instance,
1661 			 ConcretePort *port,
1662 			 ConcreteNet *net) :
1663   instance_(instance),
1664   port_(port),
1665   net_(net),
1666   term_(nullptr),
1667   net_next_(nullptr),
1668   net_prev_(nullptr),
1669   vertex_id_(vertex_id_null)
1670 {
1671 }
1672 
1673 const char *
name() const1674 ConcretePin::name() const
1675 {
1676   return port_->name();
1677 }
1678 
1679 void
setVertexId(VertexId id)1680 ConcretePin::setVertexId(VertexId id)
1681 {
1682   vertex_id_ = id;
1683 }
1684 
1685 ////////////////////////////////////////////////////////////////
1686 
1687 const char *
name() const1688 ConcreteTerm::name() const
1689 {
1690   ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin_);
1691   const ConcretePort *cport =
1692     reinterpret_cast<const ConcretePort*>(cpin->port());
1693   return cport->name();
1694 }
1695 
ConcreteTerm(ConcretePin * pin,ConcreteNet * net)1696 ConcreteTerm::ConcreteTerm(ConcretePin *pin,
1697 			   ConcreteNet *net) :
1698   pin_(pin),
1699   net_(net),
1700   net_next_(nullptr)
1701 {
1702 }
1703 
1704 ////////////////////////////////////////////////////////////////
1705 
ConcreteNet(const char * name,ConcreteInstance * instance)1706 ConcreteNet::ConcreteNet(const char *name,
1707 			 ConcreteInstance *instance) :
1708   name_(stringCopy(name)),
1709   instance_(instance),
1710   pins_(nullptr),
1711   terms_(nullptr),
1712   merged_into_(nullptr)
1713 {
1714 }
1715 
~ConcreteNet()1716 ConcreteNet::~ConcreteNet()
1717 {
1718   stringDelete(name_);
1719 }
1720 
1721 // Merged nets are kept around to serve as name aliases.
1722 // Only Instance::findNet and InstanceNetIterator need to know
1723 // the net has been merged.
1724 void
mergeInto(ConcreteNet * net)1725 ConcreteNet::mergeInto(ConcreteNet *net)
1726 {
1727   ConcreteNetPinIterator pin_iter(this);
1728   while (pin_iter.hasNext()) {
1729     Pin *pin = pin_iter.next();
1730     ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
1731     net->addPin(cpin);
1732     cpin->net_ = net;
1733   }
1734   pins_ = nullptr;
1735   ConcreteNetTermIterator term_iter(this);
1736   while (term_iter.hasNext()) {
1737     Term *term = term_iter.next();
1738     ConcreteTerm *cterm = reinterpret_cast<ConcreteTerm*>(term);
1739     net->addTerm(cterm);
1740     cterm->net_ = net;
1741   }
1742   terms_ = nullptr;
1743   // Leave name map pointing to merged net because otherwise a top
1744   // level merged net has no pointer to it and it is leaked.
1745   merged_into_ = net;
1746 }
1747 
1748 void
addPin(ConcretePin * pin)1749 ConcreteNet::addPin(ConcretePin *pin)
1750 {
1751   if (pins_)
1752     pins_->net_prev_ = pin;
1753   pin->net_next_ = pins_;
1754   pin->net_prev_ = nullptr;
1755   pins_ = pin;
1756 }
1757 
1758 void
deletePin(ConcretePin * pin)1759 ConcreteNet::deletePin(ConcretePin *pin)
1760 {
1761   ConcretePin *prev = pin->net_prev_;
1762   ConcretePin *next = pin->net_next_;
1763   if (prev)
1764     prev->net_next_ = next;
1765   if (next)
1766     next->net_prev_ = prev;
1767   if (pins_ == pin)
1768     pins_ = next;
1769 }
1770 
1771 void
addTerm(ConcreteTerm * term)1772 ConcreteNet::addTerm(ConcreteTerm *term)
1773 {
1774   ConcreteTerm *next = terms_;
1775   terms_ = term;
1776   term->net_next_ = next;
1777 }
1778 
1779 void
deleteTerm(ConcreteTerm * term)1780 ConcreteNet::deleteTerm(ConcreteTerm *term)
1781 {
1782   ConcreteTerm *net_prev_term = nullptr;
1783   for (ConcreteTerm *net_term=terms_;net_term;net_term=net_term->net_next_) {
1784     if (net_term == term) {
1785       if (net_prev_term)
1786 	net_prev_term->net_next_ = term->net_next_;
1787       else
1788 	terms_ = term->net_next_;
1789       break;
1790     }
1791     net_prev_term = net_term;
1792   }
1793 }
1794 
1795 ////////////////////////////////////////////////////////////////
1796 
1797 typedef Map<Net*, Net*> BindingMap;
1798 
1799 // Binding table used for linking/expanding network.
1800 class ConcreteBindingTbl
1801 {
1802 public:
1803   explicit ConcreteBindingTbl(NetworkEdit *network);
1804   Net *ensureBinding(Net *proto_net,
1805 		     Instance *parent);
1806   Net *find(Net *net);
1807   void bind(Net *proto_net,
1808 	    Net *clone_net);
1809 
1810 private:
1811   DISALLOW_COPY_AND_ASSIGN(ConcreteBindingTbl);
1812 
1813   BindingMap map_;
1814   NetworkEdit *network_;
1815 };
1816 
1817 void
setCellNetworkView(Cell * cell,Instance * inst)1818 ConcreteNetwork::setCellNetworkView(Cell *cell,
1819 				    Instance *inst)
1820 {
1821   cell_network_view_map_[cell] = inst;
1822 }
1823 
1824 Instance *
cellNetworkView(Cell * cell)1825 ConcreteNetwork::cellNetworkView(Cell *cell)
1826 {
1827   return cell_network_view_map_.findKey(cell);
1828 }
1829 
1830 void
readNetlistBefore()1831 ConcreteNetwork::readNetlistBefore()
1832 {
1833   clearConstantNets();
1834   deleteTopInstance();
1835   clearNetDrvrPinMap();
1836 }
1837 
1838 void
setTopInstance(Instance * top_inst)1839 ConcreteNetwork::setTopInstance(Instance *top_inst)
1840 {
1841   if (top_instance_) {
1842     deleteInstance(top_instance_);
1843     clearConstantNets();
1844     clearNetDrvrPinMap();
1845   }
1846   top_instance_ = top_inst;
1847 }
1848 
1849 void
setLinkFunc(LinkNetworkFunc * link)1850 ConcreteNetwork::setLinkFunc(LinkNetworkFunc *link)
1851 {
1852   link_func_ = link;
1853 }
1854 
1855 bool
linkNetwork(const char * top_cell_name,bool make_black_boxes,Report * report)1856 ConcreteNetwork::linkNetwork(const char *top_cell_name,
1857 			     bool make_black_boxes,
1858 			     Report *report)
1859 {
1860   if (link_func_) {
1861     clearConstantNets();
1862     deleteTopInstance();
1863     top_instance_ = link_func_(top_cell_name, make_black_boxes, report, this);
1864     return top_instance_ != nullptr;
1865   }
1866   else {
1867     report->error(8, "cell type %s can not be linked.", top_cell_name);
1868     return false;
1869   }
1870 }
1871 
1872 Instance *
linkReaderNetwork(Cell * top_cell,bool,Report *,NetworkReader * network)1873 linkReaderNetwork(Cell *top_cell,
1874 		  bool, Report *,
1875 		  NetworkReader *network)
1876 {
1877   Instance *view = network->cellNetworkView(top_cell);
1878   if (view) {
1879     // Seed the recursion for expansion with the top level instance.
1880     Instance *top_instance = network->makeInstance(top_cell, "", nullptr);
1881     ConcreteBindingTbl bindings(network);
1882     makeClonePins(view, top_instance, view, &bindings, nullptr, nullptr, network);
1883     InstanceChildIterator *child_iter = network->childIterator(view);
1884     while (child_iter->hasNext()) {
1885       Instance *child = child_iter->next();
1886       makeChildNetwork(child, top_instance, &bindings, network);
1887     }
1888     delete child_iter;
1889     network->deleteCellNetworkViews();
1890     return top_instance;
1891   }
1892   return nullptr;
1893 }
1894 
1895 static void
makeChildNetwork(Instance * proto,Instance * parent,ConcreteBindingTbl * parent_bindings,NetworkReader * network)1896 makeChildNetwork(Instance *proto,
1897 		 Instance *parent,
1898 		 ConcreteBindingTbl *parent_bindings,
1899 		 NetworkReader *network)
1900 {
1901   Cell *proto_cell = network->cell(proto);
1902   Instance *clone = network->makeInstance(proto_cell, network->name(proto),
1903 					  parent);
1904   if (network->isLeaf(proto_cell))
1905     makeClonePins(proto, clone, nullptr, nullptr, parent, parent_bindings, network);
1906   else {
1907     // Recurse if this isn't a leaf cell.
1908     ConcreteBindingTbl bindings(network);
1909     Instance *clone_view = network->cellNetworkView(proto_cell);
1910     makeClonePins(proto, clone, clone_view, &bindings, parent,
1911 		  parent_bindings, network);
1912     if (clone_view) {
1913       InstanceChildIterator *child_iter = network->childIterator(clone_view);
1914       while (child_iter->hasNext()) {
1915 	Instance *child = child_iter->next();
1916 	makeChildNetwork(child, clone, &bindings, network);
1917       }
1918       delete child_iter;
1919     }
1920   }
1921 }
1922 
1923 static void
makeClonePins(Instance * proto,Instance * clone,Instance * clone_view,ConcreteBindingTbl * bindings,Instance * parent,ConcreteBindingTbl * parent_bindings,NetworkReader * network)1924 makeClonePins(Instance *proto,
1925 	      Instance *clone,
1926 	      Instance *clone_view,
1927 	      ConcreteBindingTbl *bindings,
1928 	      Instance *parent,
1929 	      ConcreteBindingTbl *parent_bindings,
1930 	      NetworkReader *network)
1931 {
1932   InstancePinIterator *proto_pin_iter = network->pinIterator(proto);
1933   while (proto_pin_iter->hasNext()) {
1934     Pin *proto_pin = proto_pin_iter->next();
1935     Net *proto_net = network->net(proto_pin);
1936     Port *proto_port = network->port(proto_pin);
1937     Net *clone_net = nullptr;
1938     if (proto_net && parent_bindings)
1939       clone_net = parent_bindings->ensureBinding(proto_net, parent);
1940     Pin *clone_pin = network->connect(clone, proto_port, clone_net);
1941     if (clone_view) {
1942       Pin *clone_proto_pin = network->findPin(clone_view, proto_port);
1943       Net *clone_proto_net = network->net(clone_proto_pin);
1944       Net *clone_child_net = nullptr;
1945       if (clone_proto_net)
1946 	clone_child_net = bindings->ensureBinding(clone_proto_net, clone);
1947       network->makeTerm(clone_pin, clone_child_net);
1948     }
1949   }
1950   delete proto_pin_iter;
1951 }
1952 
1953 ////////////////////////////////////////////////////////////////
1954 
ConcreteBindingTbl(NetworkEdit * network)1955 ConcreteBindingTbl::ConcreteBindingTbl(NetworkEdit *network) :
1956   network_(network)
1957 {
1958 }
1959 
1960 // Follow the merged_into pointers rather than update the
1961 // binding tables up the call tree when nodes are merged
1962 // because the name changes up the hierarchy.
1963 Net *
find(Net * proto_net)1964 ConcreteBindingTbl::find(Net *proto_net)
1965 {
1966   ConcreteNet *net = reinterpret_cast<ConcreteNet*>(map_.findKey(proto_net));
1967   while (net && net->mergedInto())
1968     net = net->mergedInto();
1969   return reinterpret_cast<Net*>(net);
1970 }
1971 
1972 void
bind(Net * proto_net,Net * net)1973 ConcreteBindingTbl::bind(Net *proto_net,
1974 			 Net *net)
1975 {
1976   map_[proto_net] = net;
1977 }
1978 
1979 Net *
ensureBinding(Net * proto_net,Instance * parent)1980 ConcreteBindingTbl::ensureBinding(Net *proto_net,
1981 				  Instance *parent)
1982 {
1983   Net *net = find(proto_net);
1984   if (net == nullptr) {
1985     net = network_->makeNet(network_->name(proto_net), parent);
1986     map_[proto_net] = net;
1987   }
1988   return net;
1989 }
1990 
1991 } // namespace
1992