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