1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 //   list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 //   this list of conditions and the following disclaimer in the documentation
15 //   and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 //   contributors may be used to endorse or promote products derived from
19 //   this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 
33 #include "dbInst.h"
34 
35 #include <algorithm>
36 
37 #include "db.h"
38 #include "dbArrayTable.h"
39 #include "dbArrayTable.hpp"
40 #include "dbBTerm.h"
41 #include "dbBlock.h"
42 #include "dbBlockCallBackObj.h"
43 #include "dbBox.h"
44 #include "dbChip.h"
45 #include "dbCommon.h"
46 #include "dbDatabase.h"
47 #include "dbDiff.hpp"
48 #include "dbGroup.h"
49 #include "dbHier.h"
50 #include "dbITerm.h"
51 #include "dbITermItr.h"
52 #include "dbInstHdr.h"
53 #include "dbJournal.h"
54 #include "dbLib.h"
55 #include "dbMTerm.h"
56 #include "dbMaster.h"
57 #include "dbModule.h"
58 #include "dbNet.h"
59 #include "dbNullIterator.h"
60 #include "dbRegion.h"
61 #include "dbSet.h"
62 #include "dbTable.h"
63 #include "dbTable.hpp"
64 #include "dbTransform.h"
65 #include "utl/Logger.h"
66 
67 namespace odb {
68 
69 template class dbTable<_dbInst>;
70 
71 class sortMTerm
72 {
73  public:
operator ()(_dbMTerm * m1,_dbMTerm * m2)74   bool operator()(_dbMTerm* m1, _dbMTerm* m2)
75   {
76     return strcmp(m1->_name, m2->_name) < 0;
77   }
78 };
79 
80 class sortITerm
81 {
82   _dbBlock* _block;
83 
84  public:
sortITerm(_dbBlock * block)85   sortITerm(_dbBlock* block) { _block = block; }
86 
operator ()(uint it1,uint it2)87   bool operator()(uint it1, uint it2)
88   {
89     _dbITerm* iterm1 = _block->_iterm_tbl->getPtr(it1);
90     _dbITerm* iterm2 = _block->_iterm_tbl->getPtr(it2);
91     return iterm1->_flags._mterm_idx < iterm2->_flags._mterm_idx;
92   }
93 };
94 
setInstBBox(_dbInst * inst)95 void _dbInst::setInstBBox(_dbInst* inst)
96 {
97   _dbBlock* block = (_dbBlock*) inst->getOwner();
98   _dbBox* box = block->_box_tbl->getPtr(inst->_bbox);
99   block->remove_rect(box->_shape._rect);
100 
101   dbMaster* master = ((dbInst*) inst)->getMaster();
102   master->getPlacementBoundary(box->_shape._rect);
103   dbTransform transform(inst->_flags._orient, Point(inst->_x, inst->_y));
104   transform.apply(box->_shape._rect);
105   block->add_rect(box->_shape._rect);
106 }
107 
_dbInst(_dbDatabase *)108 _dbInst::_dbInst(_dbDatabase*)
109 {
110   _flags._orient = dbOrientType::R0;
111   _flags._status = dbPlacementStatus::NONE;
112   _flags._user_flag_1 = 0;
113   _flags._user_flag_2 = 0;
114   _flags._user_flag_3 = 0;
115   _flags._size_only = 0;
116   _flags._dont_touch = 0;
117   _flags._dont_size = 0;
118   _flags._eco_create = 0;
119   _flags._eco_destroy = 0;
120   _flags._eco_modify = 0;
121   _flags._source = dbSourceType::NONE;
122   //_flags._spare_bits = 0;
123   _flags._level = 0;
124   _flags._input_cone = 0;
125   _flags._inside_cone = 0;
126   _name = 0;
127   _x = 0;
128   _y = 0;
129   _weight = 0;
130 }
131 
_dbInst(_dbDatabase *,const _dbInst & i)132 _dbInst::_dbInst(_dbDatabase*, const _dbInst& i)
133     : _flags(i._flags),
134       _name(NULL),
135       _x(i._x),
136       _y(i._y),
137       _weight(i._weight),
138       _next_entry(i._next_entry),
139       _inst_hdr(i._inst_hdr),
140       _bbox(i._bbox),
141       _region(i._region),
142       _module(i._module),
143       _group(i._group),
144       _region_next(i._region_next),
145       _module_next(i._module_next),
146       _group_next(i._group_next),
147       _region_prev(i._region_prev),
148       _hierarchy(i._hierarchy),
149       _iterms(i._iterms),
150       _halo(i._halo)
151 {
152   if (i._name) {
153     _name = strdup(i._name);
154     ZALLOCATED(_name);
155   }
156 }
157 
~_dbInst()158 _dbInst::~_dbInst()
159 {
160   if (_name)
161     free((void*) _name);
162 }
163 
operator <<(dbOStream & stream,const _dbInst & inst)164 dbOStream& operator<<(dbOStream& stream, const _dbInst& inst)
165 {
166   uint* bit_field = (uint*) &inst._flags;
167   stream << *bit_field;
168   stream << inst._name;
169   stream << inst._x;
170   stream << inst._y;
171   stream << inst._weight;
172   stream << inst._next_entry;
173   stream << inst._inst_hdr;
174   stream << inst._bbox;
175   stream << inst._region;
176   stream << inst._module;
177   stream << inst._group;
178   stream << inst._region_next;
179   stream << inst._module_next;
180   stream << inst._group_next;
181   stream << inst._region_prev;
182   stream << inst._hierarchy;
183   stream << inst._iterms;
184   stream << inst._halo;
185   return stream;
186 }
187 
operator >>(dbIStream & stream,_dbInst & inst)188 dbIStream& operator>>(dbIStream& stream, _dbInst& inst)
189 {
190   uint* bit_field = (uint*) &inst._flags;
191   stream >> *bit_field;
192   stream >> inst._name;
193   stream >> inst._x;
194   stream >> inst._y;
195   stream >> inst._weight;
196   stream >> inst._next_entry;
197   stream >> inst._inst_hdr;
198   stream >> inst._bbox;
199   stream >> inst._region;
200   stream >> inst._module;
201   stream >> inst._group;
202   stream >> inst._region_next;
203   stream >> inst._module_next;
204   stream >> inst._group_next;
205   stream >> inst._region_prev;
206   stream >> inst._hierarchy;
207   stream >> inst._iterms;
208   stream >> inst._halo;
209 
210   return stream;
211 }
212 
operator <(const _dbInst & rhs) const213 bool _dbInst::operator<(const _dbInst& rhs) const
214 {
215   return strcmp(_name, rhs._name) < 0;
216 }
217 
operator ==(const _dbInst & rhs) const218 bool _dbInst::operator==(const _dbInst& rhs) const
219 {
220   if (_flags._orient != rhs._flags._orient)
221     return false;
222 
223   if (_flags._status != rhs._flags._status)
224     return false;
225 
226   if (_flags._user_flag_1 != rhs._flags._user_flag_1)
227     return false;
228 
229   if (_flags._user_flag_2 != rhs._flags._user_flag_2)
230     return false;
231 
232   if (_flags._user_flag_3 != rhs._flags._user_flag_3)
233     return false;
234 
235   if (_flags._size_only != rhs._flags._size_only)
236     return false;
237 
238   if (_flags._dont_size != rhs._flags._dont_size)
239     return false;
240 
241   if (_flags._dont_touch != rhs._flags._dont_touch)
242     return false;
243 
244   if (_flags._source != rhs._flags._source)
245     return false;
246 
247   if (_name && rhs._name) {
248     if (strcmp(_name, rhs._name) != 0)
249       return false;
250   } else if (_name || rhs._name)
251     return false;
252 
253   if (_x != rhs._x)
254     return false;
255 
256   if (_y != rhs._y)
257     return false;
258 
259   if (_weight != rhs._weight)
260     return false;
261 
262   if (_next_entry != rhs._next_entry)
263     return false;
264 
265   if (_inst_hdr != rhs._inst_hdr)
266     return false;
267 
268   if (_bbox != rhs._bbox)
269     return false;
270 
271   if (_region != rhs._region)
272     return false;
273 
274   if (_module != rhs._module)
275     return false;
276 
277   if (_group != rhs._group)
278     return false;
279 
280   if (_region_next != rhs._region_next)
281     return false;
282 
283   if (_module_next != rhs._module_next)
284     return false;
285 
286   if (_group_next != rhs._group_next)
287     return false;
288 
289   if (_region_prev != rhs._region_prev)
290     return false;
291 
292   if (_hierarchy != rhs._hierarchy)
293     return false;
294 
295   if (_iterms != rhs._iterms)
296     return false;
297 
298   if (_halo != rhs._halo)
299     return false;
300 
301   return true;
302 }
303 
differences(dbDiff & diff,const char * field,const _dbInst & rhs) const304 void _dbInst::differences(dbDiff& diff,
305                           const char* field,
306                           const _dbInst& rhs) const
307 {
308   _dbBlock* lhs_blk = (_dbBlock*) getOwner();
309   _dbBlock* rhs_blk = (_dbBlock*) rhs.getOwner();
310 
311   DIFF_BEGIN
312   DIFF_FIELD(_name);
313   DIFF_FIELD(_flags._orient);
314   DIFF_FIELD(_flags._status);
315   DIFF_FIELD(_flags._user_flag_1);
316   DIFF_FIELD(_flags._user_flag_2);
317   DIFF_FIELD(_flags._user_flag_3);
318   DIFF_FIELD(_flags._size_only);
319   DIFF_FIELD(_flags._dont_touch);
320   DIFF_FIELD(_flags._dont_size);
321   DIFF_FIELD(_flags._source);
322   DIFF_FIELD(_x);
323   DIFF_FIELD(_y);
324   DIFF_FIELD(_weight);
325   DIFF_FIELD_NO_DEEP(_next_entry);
326   DIFF_FIELD_NO_DEEP(_inst_hdr);
327   DIFF_OBJECT(_bbox, lhs_blk->_box_tbl, rhs_blk->_box_tbl);
328   DIFF_FIELD(_region);
329   DIFF_FIELD(_module);
330   DIFF_FIELD(_group);
331   DIFF_FIELD(_region_next);
332   DIFF_FIELD(_module_next);
333   DIFF_FIELD(_group_next);
334   DIFF_FIELD(_region_prev);
335   DIFF_FIELD(_hierarchy);
336   DIFF_OBJECT(_halo, lhs_blk->_box_tbl, rhs_blk->_box_tbl);
337 
338   if (!diff.deepDiff()) {
339     DIFF_VECTOR(_iterms);
340   } else {
341     dbSet<_dbITerm>::iterator itr;
342 
343     dbSet<_dbITerm> lhs_set((dbObject*) this, lhs_blk->_inst_iterm_itr);
344     std::vector<_dbITerm*> lhs_vec;
345 
346     for (itr = lhs_set.begin(); itr != lhs_set.end(); ++itr)
347       lhs_vec.push_back(*itr);
348 
349     dbSet<_dbITerm> rhs_set((dbObject*) &rhs, rhs_blk->_inst_iterm_itr);
350     std::vector<_dbITerm*> rhs_vec;
351 
352     for (itr = rhs_set.begin(); itr != rhs_set.end(); ++itr)
353       rhs_vec.push_back(*itr);
354 
355 #ifndef WIN32  // This line cause a compiler error in visual stdio 6.0
356     set_symmetric_diff(diff, "_iterms", lhs_vec, rhs_vec);
357 #endif
358   }
359 
360   DIFF_END
361 }
362 
out(dbDiff & diff,char side,const char * field) const363 void _dbInst::out(dbDiff& diff, char side, const char* field) const
364 {
365   _dbBlock* blk = (_dbBlock*) getOwner();
366   DIFF_OUT_BEGIN
367   DIFF_OUT_FIELD(_name);
368   DIFF_OUT_FIELD(_flags._orient);
369   DIFF_OUT_FIELD(_flags._status);
370   DIFF_OUT_FIELD(_flags._user_flag_1);
371   DIFF_OUT_FIELD(_flags._user_flag_2);
372   DIFF_OUT_FIELD(_flags._user_flag_3);
373   DIFF_OUT_FIELD(_flags._size_only);
374   DIFF_OUT_FIELD(_flags._dont_touch);
375   DIFF_OUT_FIELD(_flags._dont_size);
376   DIFF_OUT_FIELD(_flags._source);
377   DIFF_OUT_FIELD(_x);
378   DIFF_OUT_FIELD(_y);
379   DIFF_OUT_FIELD(_weight);
380   DIFF_OUT_FIELD_NO_DEEP(_next_entry);
381   DIFF_OUT_FIELD_NO_DEEP(_inst_hdr);
382   DIFF_OUT_OBJECT(_bbox, blk->_box_tbl);
383   DIFF_OUT_FIELD(_region);
384   DIFF_OUT_FIELD(_module);
385   DIFF_OUT_FIELD(_group);
386   DIFF_OUT_FIELD(_region_next);
387   DIFF_OUT_FIELD(_module_next);
388   DIFF_OUT_FIELD(_group_next);
389   DIFF_OUT_FIELD(_region_prev);
390   DIFF_OUT_FIELD(_hierarchy);
391 
392   if (!diff.deepDiff()) {
393     DIFF_OUT_VECTOR(_iterms);
394   } else {
395     dbSet<_dbITerm>::iterator itr;
396     dbSet<_dbITerm> insts((dbObject*) this, blk->_inst_iterm_itr);
397     diff.begin_object("%c _iterms\n", side);
398 
399     for (itr = insts.begin(); itr != insts.end(); ++itr)
400       (*itr)->out(diff, side, "");
401 
402     diff.end_object();
403   }
404 
405   DIFF_OUT_OBJECT(_halo, blk->_box_tbl);
406 
407   DIFF_END
408 }
409 
410 ////////////////////////////////////////////////////////////////////
411 //
412 // dbInst - Methods
413 //
414 ////////////////////////////////////////////////////////////////////
415 
getName()416 std::string dbInst::getName()
417 {
418   _dbInst* inst = (_dbInst*) this;
419   return inst->_name;
420 }
421 
getConstName()422 const char* dbInst::getConstName()
423 {
424   _dbInst* inst = (_dbInst*) this;
425   return inst->_name;
426 }
427 
isNamed(const char * name)428 bool dbInst::isNamed(const char* name)
429 {
430   _dbInst* inst = (_dbInst*) this;
431   if (!strcmp(inst->_name, name))
432     return true;
433   return false;
434 }
435 
rename(const char * name)436 bool dbInst::rename(const char* name)
437 {
438   _dbInst* inst = (_dbInst*) this;
439   _dbBlock* block = (_dbBlock*) inst->getOwner();
440 
441   if (block->_inst_hash.hasMember(name))
442     return false;
443 
444   block->_inst_hash.remove(inst);
445   free((void*) inst->_name);
446   inst->_name = strdup(name);
447   ZALLOCATED(inst->_name);
448   block->_inst_hash.insert(inst);
449 
450   return true;
451 }
452 
getOrigin(int & x,int & y)453 void dbInst::getOrigin(int& x, int& y)
454 {
455   _dbInst* inst = (_dbInst*) this;
456   x = inst->_x;
457   y = inst->_y;
458 }
459 
setOrigin(int x,int y)460 void dbInst::setOrigin(int x, int y)
461 {
462   _dbInst* inst = (_dbInst*) this;
463   _dbBlock* block = (_dbBlock*) inst->getOwner();
464   int prev_x = inst->_x;
465   int prev_y = inst->_y;
466   // Do Nothin if same origin, But What if uninitialized and x=y=0
467   if (prev_x == x && prev_y == y)
468     return;
469   for (auto callback : block->_callbacks)
470     callback->inDbPreMoveInst(this);
471 
472   inst->_x = x;
473   inst->_y = y;
474   _dbInst::setInstBBox(inst);
475 
476   if (block->_journal) {
477     debugPrint(getImpl()->getLogger(),
478                utl::ODB,
479                "DB_ECO",
480                1,
481                "ECO: setOrigin {}, {}",
482                x,
483                y);
484     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
485     block->_journal->pushParam(inst->getObjectType());
486     block->_journal->pushParam(inst->getId());
487     block->_journal->pushParam(_dbInst::ORIGIN);
488     block->_journal->pushParam(prev_x);
489     block->_journal->pushParam(prev_y);
490     block->_journal->pushParam(inst->_x);
491     block->_journal->pushParam(inst->_y);
492     block->_journal->endAction();
493   }
494 
495   block->_flags._valid_bbox = 0;
496   for (auto callback : block->_callbacks)
497     callback->inDbPostMoveInst(this);
498 }
499 
setLocationOrient(dbOrientType orient)500 void dbInst::setLocationOrient(dbOrientType orient)
501 {
502   int x, y;
503   getLocation(x, y);
504   setOrient(orient);
505   setLocation(x, y);
506 }
507 
getLocation(int & x,int & y) const508 void dbInst::getLocation(int& x, int& y) const
509 {
510   const _dbInst* inst = (const _dbInst*) this;
511   _dbBlock* block = (_dbBlock*) inst->getOwner();
512   _dbBox* bbox = block->_box_tbl->getPtr(inst->_bbox);
513   x = bbox->_shape._rect.xMin();
514   y = bbox->_shape._rect.yMin();
515 }
516 
setLocation(int x,int y)517 void dbInst::setLocation(int x, int y)
518 {
519   dbMaster* master = getMaster();
520   Rect bbox;
521   master->getPlacementBoundary(bbox);
522   dbTransform t(getOrient());
523   t.apply(bbox);
524   setOrigin(x - bbox.xMin(), y - bbox.yMin());
525 }
526 
getBBox()527 dbBox* dbInst::getBBox()
528 {
529   _dbInst* inst = (_dbInst*) this;
530   _dbBlock* block = (_dbBlock*) inst->getOwner();
531   return (dbBox*) block->_box_tbl->getPtr(inst->_bbox);
532 }
533 
getOrient()534 dbOrientType dbInst::getOrient()
535 {
536   _dbInst* inst = (_dbInst*) this;
537   return dbOrientType(inst->_flags._orient);
538 }
539 
setOrient(dbOrientType orient)540 void dbInst::setOrient(dbOrientType orient)
541 {
542   if (orient == getOrient())
543     return;
544   _dbInst* inst = (_dbInst*) this;
545   _dbBlock* block = (_dbBlock*) inst->getOwner();
546   for (auto callback : block->_callbacks)
547     callback->inDbPreMoveInst(this);
548   uint prev_flags = flagsToUInt(inst);
549   inst->_flags._orient = orient.getValue();
550   _dbInst::setInstBBox(inst);
551 
552   if (block->_journal) {
553     debugPrint(getImpl()->getLogger(),
554                utl::ODB,
555                "DB_ECO",
556                1,
557                "ECO: setOrient {}",
558                orient.getValue());
559     block->_journal->updateField(
560         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
561   }
562 
563   block->_flags._valid_bbox = 0;
564   for (auto callback : block->_callbacks)
565     callback->inDbPostMoveInst(this);
566 }
567 
getPlacementStatus()568 dbPlacementStatus dbInst::getPlacementStatus()
569 {
570   _dbInst* inst = (_dbInst*) this;
571   return dbPlacementStatus(inst->_flags._status);
572 }
573 
setPlacementStatus(dbPlacementStatus status)574 void dbInst::setPlacementStatus(dbPlacementStatus status)
575 {
576   _dbInst* inst = (_dbInst*) this;
577   _dbBlock* block = (_dbBlock*) inst->getOwner();
578 
579   for (auto callback : block->_callbacks) {
580     callback->inDbInstPlacementStatusBefore(this, status);
581   }
582 
583   uint prev_flags = flagsToUInt(inst);
584   inst->_flags._status = status.getValue();
585   block->_flags._valid_bbox = 0;
586   if (block->_journal) {
587     debugPrint(getImpl()->getLogger(),
588                utl::ODB,
589                "DB_ECO",
590                1,
591                "ECO: setPlacementStatus {}",
592                status.getValue());
593     block->_journal->updateField(
594         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
595   }
596 }
597 
getTransform(dbTransform & t)598 void dbInst::getTransform(dbTransform& t)
599 {
600   _dbInst* inst = (_dbInst*) this;
601   t = dbTransform(inst->_flags._orient, Point(inst->_x, inst->_y));
602   return;
603 }
604 
setTransform(dbTransform & t)605 void dbInst::setTransform(dbTransform& t)
606 {
607   setOrient(t.getOrient());
608   Point offset = t.getOffset();
609   setOrigin(offset.x(), offset.y());
610   return;
611 }
612 
getParentTransform(dbInst * inst,dbTransform & t)613 static void getParentTransform(dbInst* inst, dbTransform& t)
614 {
615   dbInst* parent = inst->getParent();
616 
617   if (parent == NULL)
618     t = dbTransform();
619   else {
620     getParentTransform(parent, t);
621     dbTransform x;
622     parent->getTransform(x);
623     x.concat(t);
624     t = x;
625   }
626 }
627 
getHierTransform(dbTransform & t)628 void dbInst::getHierTransform(dbTransform& t)
629 {
630   getParentTransform(this, t);
631   dbTransform x;
632   getTransform(x);
633   x.concat(t);
634   t = x;
635   return;
636 }
637 
getLevel()638 int dbInst::getLevel()
639 {
640   _dbInst* inst = (_dbInst*) this;
641 
642   if (inst->_flags._inside_cone > 0)
643     return inst->_flags._level;
644   if (inst->_flags._input_cone > 0)
645     return -inst->_flags._level;
646 
647   return 0;
648 }
setLevel(uint v,bool fromPI)649 void dbInst::setLevel(uint v, bool fromPI)
650 {
651   _dbInst* inst = (_dbInst*) this;
652   if (v > 255) {
653     getImpl()->getLogger()->info(
654         utl::ODB,
655         36,
656         "setLevel {} greater than 255 is illegal! inst {}",
657         v,
658         getId());
659     return;
660   }
661   inst->_flags._level = v;
662   inst->_flags._input_cone = 0;
663   inst->_flags._inside_cone = 0;
664 
665   if (fromPI)
666     inst->_flags._input_cone = 1;
667   else
668     inst->_flags._inside_cone = 1;
669 }
getEcoCreate()670 bool dbInst::getEcoCreate()
671 {
672   _dbInst* inst = (_dbInst*) this;
673   return inst->_flags._eco_create;
674 }
setEcoCreate(bool v)675 void dbInst::setEcoCreate(bool v)
676 {
677   _dbInst* inst = (_dbInst*) this;
678   // _dbBlock * block = (_dbBlock *) getOwner();
679   // uint prev_flags = flagsToUInt(inst);
680   if (v)
681     inst->_flags._eco_create = 1;
682   else
683     inst->_flags._eco_create = 0;
684 }
getEcoDestroy()685 bool dbInst::getEcoDestroy()
686 {
687   _dbInst* inst = (_dbInst*) this;
688   return inst->_flags._eco_destroy;
689 }
setEcoDestroy(bool v)690 void dbInst::setEcoDestroy(bool v)
691 {
692   _dbInst* inst = (_dbInst*) this;
693   // _dbBlock * block = (_dbBlock *) getOwner();
694   // uint prev_flags = flagsToUInt(inst);
695   if (v)
696     inst->_flags._eco_destroy = 1;
697   else
698     inst->_flags._eco_destroy = 0;
699 }
getEcoModify()700 bool dbInst::getEcoModify()
701 {
702   _dbInst* inst = (_dbInst*) this;
703   return inst->_flags._eco_modify;
704 }
setEcoModify(bool v)705 void dbInst::setEcoModify(bool v)
706 {
707   _dbInst* inst = (_dbInst*) this;
708   // _dbBlock * block = (_dbBlock *) getOwner();
709   // uint prev_flags = flagsToUInt(inst);
710   if (v)
711     inst->_flags._eco_modify = 1;
712   else
713     inst->_flags._eco_modify = 0;
714 }
getUserFlag1()715 bool dbInst::getUserFlag1()
716 {
717   _dbInst* inst = (_dbInst*) this;
718   return inst->_flags._user_flag_1 == 1;
719 }
720 
setUserFlag1()721 void dbInst::setUserFlag1()
722 {
723   _dbInst* inst = (_dbInst*) this;
724   _dbBlock* block = (_dbBlock*) inst->getOwner();
725   uint prev_flags = flagsToUInt(inst);
726   inst->_flags._user_flag_1 = 1;
727 
728   if (block->_journal)
729     block->_journal->updateField(
730         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
731 }
732 
clearUserFlag1()733 void dbInst::clearUserFlag1()
734 {
735   _dbInst* inst = (_dbInst*) this;
736   _dbBlock* block = (_dbBlock*) inst->getOwner();
737   uint prev_flags = flagsToUInt(inst);
738   inst->_flags._user_flag_1 = 0;
739 
740   if (block->_journal)
741     block->_journal->updateField(
742         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
743 }
744 
getUserFlag2()745 bool dbInst::getUserFlag2()
746 {
747   _dbInst* inst = (_dbInst*) this;
748   return inst->_flags._user_flag_2 == 1;
749 }
750 
setUserFlag2()751 void dbInst::setUserFlag2()
752 {
753   _dbInst* inst = (_dbInst*) this;
754   _dbBlock* block = (_dbBlock*) inst->getOwner();
755   uint prev_flags = flagsToUInt(inst);
756   inst->_flags._user_flag_2 = 1;
757 
758   if (block->_journal)
759     block->_journal->updateField(
760         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
761 }
762 
clearUserFlag2()763 void dbInst::clearUserFlag2()
764 {
765   _dbInst* inst = (_dbInst*) this;
766   _dbBlock* block = (_dbBlock*) inst->getOwner();
767   uint prev_flags = flagsToUInt(inst);
768   inst->_flags._user_flag_2 = 0;
769 
770   if (block->_journal)
771     block->_journal->updateField(
772         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
773 }
774 
getUserFlag3()775 bool dbInst::getUserFlag3()
776 {
777   _dbInst* inst = (_dbInst*) this;
778   return inst->_flags._user_flag_3 == 1;
779 }
780 
setUserFlag3()781 void dbInst::setUserFlag3()
782 {
783   _dbInst* inst = (_dbInst*) this;
784   _dbBlock* block = (_dbBlock*) inst->getOwner();
785   uint prev_flags = flagsToUInt(inst);
786   inst->_flags._user_flag_3 = 1;
787 
788   if (block->_journal)
789     block->_journal->updateField(
790         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
791 }
792 
clearUserFlag3()793 void dbInst::clearUserFlag3()
794 {
795   _dbInst* inst = (_dbInst*) this;
796   _dbBlock* block = (_dbBlock*) inst->getOwner();
797   uint prev_flags = flagsToUInt(inst);
798   inst->_flags._user_flag_3 = 0;
799 
800   if (block->_journal)
801     block->_journal->updateField(
802         this, _dbInst::FLAGS, prev_flags, flagsToUInt(inst));
803 }
804 
setSizeOnly(bool v)805 void dbInst::setSizeOnly(bool v)
806 {
807   _dbInst* inst = (_dbInst*) this;
808   inst->_flags._size_only = v;
809 }
810 
isSizeOnly()811 bool dbInst::isSizeOnly()
812 {
813   _dbInst* inst = (_dbInst*) this;
814   return inst->_flags._size_only == 1;
815 }
816 
setDoNotTouch(bool v)817 void dbInst::setDoNotTouch(bool v)
818 {
819   _dbInst* inst = (_dbInst*) this;
820   inst->_flags._dont_touch = v;
821 }
822 
isDoNotTouch()823 bool dbInst::isDoNotTouch()
824 {
825   _dbInst* inst = (_dbInst*) this;
826   return inst->_flags._dont_touch == 1;
827 }
828 
setDoNotSize(bool v)829 void dbInst::setDoNotSize(bool v)
830 {
831   _dbInst* inst = (_dbInst*) this;
832   inst->_flags._dont_size = v;
833 }
834 
isDoNotSize()835 bool dbInst::isDoNotSize()
836 {
837   _dbInst* inst = (_dbInst*) this;
838   return inst->_flags._dont_size == 1;
839 }
840 
getBlock()841 dbBlock* dbInst::getBlock()
842 {
843   return (dbBlock*) getImpl()->getOwner();
844 }
845 
getMaster() const846 dbMaster* dbInst::getMaster() const
847 {
848   _dbInst* inst = (_dbInst*) this;
849   _dbBlock* block = (_dbBlock*) inst->getOwner();
850   _dbInstHdr* inst_hdr = block->_inst_hdr_tbl->getPtr(inst->_inst_hdr);
851   _dbDatabase* db = inst->getDatabase();
852   _dbLib* lib = db->_lib_tbl->getPtr(inst_hdr->_lib);
853   return (dbMaster*) lib->_master_tbl->getPtr(inst_hdr->_master);
854 }
855 
isBlock() const856 bool dbInst::isBlock() const
857 {
858   return getMaster()->isBlock();
859 }
860 
isCore() const861 bool dbInst::isCore() const
862 {
863   return getMaster()->isCore();
864 }
865 
isPad() const866 bool dbInst::isPad() const
867 {
868   return getMaster()->isPad();
869 }
870 
isEndCap() const871 bool dbInst::isEndCap() const
872 {
873   return getMaster()->isEndCap();
874 }
875 
getClockedTerm()876 dbITerm* dbInst::getClockedTerm()
877 {
878   dbMaster* m = getMaster();
879   if (m->getType() != dbMasterType::CORE)
880     return NULL;
881   int ii = m->getClockedIndex();
882   if (ii < 0)
883     return NULL;
884   return getITerm(ii);
885 }
getOutputTerm()886 dbITerm* dbInst::getOutputTerm()
887 {
888   dbMaster* m = getMaster();
889   int ii = m->getOutputIndex();
890   if (ii < 0)
891     return NULL;
892   return getITerm(ii);
893 }
894 
getITerms()895 dbSet<dbITerm> dbInst::getITerms()
896 {
897   _dbInst* inst = (_dbInst*) this;
898   _dbBlock* block = (_dbBlock*) inst->getOwner();
899   return dbSet<dbITerm>(inst, block->_inst_iterm_itr);
900 }
901 
findITerm(const char * name)902 dbITerm* dbInst::findITerm(const char* name)
903 {
904   _dbInst* inst = (_dbInst*) this;
905   _dbBlock* block = (_dbBlock*) inst->getOwner();
906   dbMaster* master = getMaster();
907   _dbMTerm* mterm = (_dbMTerm*) master->findMTerm((dbBlock*) block, name);
908 
909   if (mterm == NULL)
910     return NULL;
911 
912   return (dbITerm*) block->_iterm_tbl->getPtr(inst->_iterms[mterm->_order_id]);
913 }
914 
getRegion()915 dbRegion* dbInst::getRegion()
916 {
917   _dbInst* inst = (_dbInst*) this;
918 
919   if (inst->_region == 0)
920     return NULL;
921 
922   _dbBlock* block = (_dbBlock*) inst->getOwner();
923   _dbRegion* r = block->_region_tbl->getPtr(inst->_region);
924   return (dbRegion*) r;
925 }
926 
getModule()927 dbModule* dbInst::getModule()
928 {
929   _dbInst* inst = (_dbInst*) this;
930 
931   if (inst->_module == 0)
932     return NULL;
933 
934   _dbBlock* block = (_dbBlock*) inst->getOwner();
935   _dbModule* module = block->_module_tbl->getPtr(inst->_module);
936   return (dbModule*) module;
937 }
938 
getGroup()939 dbGroup* dbInst::getGroup()
940 {
941   _dbInst* inst = (_dbInst*) this;
942 
943   if (inst->_group == 0)
944     return NULL;
945 
946   _dbBlock* block = (_dbBlock*) inst->getOwner();
947   _dbGroup* group = block->_group_tbl->getPtr(inst->_group);
948   return (dbGroup*) group;
949 }
950 
getHalo()951 dbBox* dbInst::getHalo()
952 {
953   _dbInst* inst = (_dbInst*) this;
954 
955   if (inst->_halo == 0)
956     return NULL;
957 
958   _dbBlock* block = (_dbBlock*) inst->getOwner();
959   _dbBox* b = block->_box_tbl->getPtr(inst->_halo);
960   return (dbBox*) b;
961 }
962 
getConnectivity(std::vector<dbInst * > & result,dbSigType::Value type)963 void dbInst::getConnectivity(std::vector<dbInst*>& result,
964                              dbSigType::Value type)
965 {
966   dbSet<dbITerm> iterms = getITerms();
967   dbSet<dbITerm>::iterator iterm_itr;
968 
969   for (iterm_itr = iterms.begin(); iterm_itr != iterms.end(); ++iterm_itr) {
970     dbITerm* iterm = *iterm_itr;
971     dbNet* net = iterm->getNet();
972 
973     if (net == NULL)
974       continue;
975 
976     if ((net != NULL) && (((_dbNet*) net)->_flags._sig_type != type))
977       continue;
978 
979     dbSet<dbITerm> net_iterms = net->getITerms();
980     dbSet<dbITerm>::iterator net_iterm_itr;
981 
982     for (net_iterm_itr = net_iterms.begin(); net_iterm_itr != net_iterms.end();
983          ++net_iterm_itr) {
984       dbITerm* net_iterm = *net_iterm_itr;
985       dbInst* inst = net_iterm->getInst();
986 
987       if (inst != this)
988         result.push_back(inst);
989     }
990   }
991 
992   // remove duplicates
993   std::sort(result.begin(), result.end());
994   std::vector<dbInst*>::iterator end_itr;
995   end_itr = std::unique(result.begin(), result.end());
996   result.erase(end_itr, result.end());
997 }
998 
resetHierarchy(bool verbose)999 bool dbInst::resetHierarchy(bool verbose)
1000 {
1001   _dbInst* inst = (_dbInst*) this;
1002   //_dbBlock * block = (_dbBlock *) block_;
1003 
1004   if (inst->_hierarchy) {
1005     if (verbose)
1006       getImpl()->getLogger()->info(
1007           utl::ODB, 37, "instance bound to a block {}", inst->_hierarchy.id());
1008     inst->_hierarchy = 0;
1009     return true;
1010   }
1011   /*
1012       if ( block->_parent_inst ) {
1013           warning(0, "block already bound to an instance %d\n",
1014      block->_parent_inst.id()); if (force) { warning(0, "Forced Initialize to
1015      0\n"); block->_parent_inst= 0; } else { return false;
1016           }
1017       }
1018   */
1019   return false;
1020 }
bindBlock(dbBlock * block_,bool force)1021 bool dbInst::bindBlock(dbBlock* block_, bool force)
1022 {
1023   _dbInst* inst = (_dbInst*) this;
1024   _dbBlock* block = (_dbBlock*) block_;
1025 
1026   if (inst->_hierarchy) {
1027     getImpl()->getLogger()->warn(utl::ODB,
1028                                  38,
1029                                  "instance already bound to a block {}",
1030                                  inst->_hierarchy.id());
1031     if (force) {
1032       getImpl()->getLogger()->warn(utl::ODB, 39, "Forced Initialize to 0");
1033       inst->_hierarchy = 0;
1034     } else {
1035       return false;
1036     }
1037   }
1038 
1039   if (block->_parent_inst) {
1040     getImpl()->getLogger()->warn(utl::ODB,
1041                                  40,
1042                                  "block already bound to an instance {}",
1043                                  block->_parent_inst.id());
1044     if (force) {
1045       getImpl()->getLogger()->warn(utl::ODB, 41, "Forced Initialize to 0");
1046       block->_parent_inst = 0;
1047     } else {
1048       return false;
1049     }
1050   }
1051 
1052   if (block_->getParent() != getBlock()) {
1053     getImpl()->getLogger()->warn(
1054         utl::ODB, 42, "block not a direct child of instance owner");
1055     return false;
1056   }
1057 
1058   _dbHier* hier = _dbHier::create(this, block_);
1059 
1060   // _dbHier::create fails if bterms cannot be mapped (1-to-1) to mterms
1061   if (hier == NULL) {
1062     getImpl()->getLogger()->warn(utl::ODB, 43, "_dbHier::create fails");
1063     return false;
1064   }
1065   return true;
1066 }
1067 
unbindBlock()1068 void dbInst::unbindBlock()
1069 {
1070   _dbInst* inst = (_dbInst*) this;
1071 
1072   if (inst->_hierarchy) {
1073     _dbBlock* block = (_dbBlock*) inst->getOwner();
1074     _dbHier* hier = block->_hier_tbl->getPtr(inst->_hierarchy);
1075     _dbHier::destroy(hier);
1076   }
1077 }
1078 
getChild()1079 dbBlock* dbInst::getChild()
1080 {
1081   _dbInst* inst = (_dbInst*) this;
1082 
1083   if (inst->_hierarchy == 0)
1084     return NULL;
1085 
1086   _dbBlock* block = (_dbBlock*) inst->getOwner();
1087   _dbChip* chip = (_dbChip*) block->getOwner();
1088   _dbHier* hier = block->_hier_tbl->getPtr(inst->_hierarchy);
1089   _dbBlock* child = chip->_block_tbl->getPtr(hier->_child_block);
1090   return (dbBlock*) child;
1091 }
1092 
isHierarchical()1093 bool dbInst::isHierarchical()
1094 {
1095   _dbInst* inst = (_dbInst*) this;
1096   return inst->_hierarchy != 0;
1097 }
1098 
getParent()1099 dbInst* dbInst::getParent()
1100 {
1101   dbBlock* block = (dbBlock*) getImpl()->getOwner();
1102   return block->getParentInst();
1103 }
1104 
getChildren()1105 dbSet<dbInst> dbInst::getChildren()
1106 {
1107   dbBlock* child = getChild();
1108 
1109   if (child == NULL)
1110     return dbSet<dbInst>(child, &dbNullIterator::null_iterator);
1111 
1112   return child->getInsts();
1113 }
1114 
getWeight()1115 int dbInst::getWeight()
1116 {
1117   _dbInst* inst = (_dbInst*) this;
1118   return inst->_weight;
1119 }
1120 
setWeight(int weight)1121 void dbInst::setWeight(int weight)
1122 {
1123   _dbInst* inst = (_dbInst*) this;
1124   inst->_weight = weight;
1125 }
1126 
getSourceType()1127 dbSourceType dbInst::getSourceType()
1128 {
1129   _dbInst* inst = (_dbInst*) this;
1130   dbSourceType t(inst->_flags._source);
1131   return t;
1132 }
1133 
setSourceType(dbSourceType type)1134 void dbInst::setSourceType(dbSourceType type)
1135 {
1136   _dbInst* inst = (_dbInst*) this;
1137   inst->_flags._source = type;
1138 }
1139 
getITerm(dbMTerm * mterm_)1140 dbITerm* dbInst::getITerm(dbMTerm* mterm_)
1141 {
1142   _dbInst* inst = (_dbInst*) this;
1143   _dbBlock* block = (_dbBlock*) inst->getOwner();
1144   _dbMTerm* mterm = (_dbMTerm*) mterm_;
1145   _dbITerm* iterm = block->_iterm_tbl->getPtr(inst->_iterms[mterm->_order_id]);
1146   return (dbITerm*) iterm;
1147 }
getITerm(uint mterm_order_id)1148 dbITerm* dbInst::getITerm(uint mterm_order_id)
1149 {
1150   _dbInst* inst = (_dbInst*) this;
1151   _dbBlock* block = (_dbBlock*) inst->getOwner();
1152   _dbITerm* iterm = block->_iterm_tbl->getPtr(inst->_iterms[mterm_order_id]);
1153   return (dbITerm*) iterm;
1154 }
swapMaster(dbMaster * new_master_)1155 bool dbInst::swapMaster(dbMaster* new_master_)
1156 {
1157   const char* newMasterName = new_master_->getConstName();
1158   const char* oldMasterName = this->getMaster()->getConstName();
1159 
1160   /*
1161   if (strcmp(this->getConstName(), "BW1_BUF440357")==0) {
1162       notice(0, "Trying to swapMaster FROM %s TO %s %s\n",
1163   new_master_->getConstName(), this->getMaster()->getConstName(),
1164           new_master_->getConstName(),
1165           this->getConstName());
1166   }
1167   */
1168   _dbInst* inst = (_dbInst*) this;
1169   _dbBlock* block = (_dbBlock*) inst->getOwner();
1170   dbMaster* old_master_ = getMaster();
1171 
1172   if (inst->_hierarchy) {
1173     getImpl()->getLogger()->warn(utl::ODB,
1174                                  44,
1175                                  "Failed(_hierarchy) to swap: {} -> {} {}",
1176                                  oldMasterName,
1177                                  newMasterName,
1178                                  this->getConstName());
1179     return false;
1180   }
1181 
1182   if (block->_journal) {
1183     debugPrint(
1184         getImpl()->getLogger(), utl::ODB, "DB_ECO", 1, "ECO: swapMaster");
1185     dbLib* old_lib = old_master_->getLib();
1186     dbLib* new_lib = new_master_->getLib();
1187     block->_journal->beginAction(dbJournal::SWAP_OBJECT);
1188     block->_journal->pushParam(dbInstObj);
1189     block->_journal->pushParam(inst->getId());
1190     block->_journal->pushParam(old_lib->getId());
1191     block->_journal->pushParam(old_master_->getId());
1192     block->_journal->pushParam(new_lib->getId());
1193     block->_journal->pushParam(new_master_->getId());
1194     block->_journal->endAction();
1195   }
1196 
1197   // Notification - payam 01/18/2006
1198   std::list<dbBlockCallBackObj*>::iterator cbitr;
1199   for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1200        ++cbitr)
1201     (**cbitr)().inDbInstSwapMasterBefore(
1202         this, new_master_);  // client ECO initialization - payam
1203 
1204   //
1205   // Ensure the mterms are equivalent
1206   //
1207   dbSet<dbMTerm>::iterator itr;
1208   dbSet<dbMTerm> mterms = new_master_->getMTerms();
1209   std::vector<_dbMTerm*> new_terms;
1210 
1211   for (itr = mterms.begin(); itr != mterms.end(); ++itr)
1212     new_terms.push_back((_dbMTerm*) *itr);
1213 
1214   mterms = old_master_->getMTerms();
1215   std::vector<_dbMTerm*> old_terms;
1216 
1217   for (itr = mterms.begin(); itr != mterms.end(); ++itr)
1218     old_terms.push_back((_dbMTerm*) *itr);
1219 
1220   if (old_terms.size() != new_terms.size()) {
1221     getImpl()->getLogger()->warn(utl::ODB,
1222                                  45,
1223                                  "Failed(termSize) to swap: {} -> {} {}",
1224                                  oldMasterName,
1225                                  newMasterName,
1226                                  this->getConstName());
1227     return false;
1228   }
1229 
1230   std::vector<uint> idx_map(old_terms.size());
1231   std::sort(new_terms.begin(), new_terms.end(), sortMTerm());
1232   std::sort(old_terms.begin(), old_terms.end(), sortMTerm());
1233   std::vector<_dbMTerm*>::iterator i1 = new_terms.begin();
1234   std::vector<_dbMTerm*>::iterator i2 = old_terms.begin();
1235 
1236   for (; i1 != new_terms.end() && i2 != old_terms.end(); ++i1, ++i2) {
1237     _dbMTerm* t1 = *i1;
1238     _dbMTerm* t2 = *i2;
1239 
1240     if (strcmp(t1->_name, t2->_name) != 0)
1241       break;
1242 
1243     idx_map[t2->_order_id] = t1->_order_id;
1244   }
1245 
1246   // mterms are not equivalent
1247   if (i1 != new_terms.end() || i2 != old_terms.end()) {
1248     getImpl()->getLogger()->warn(utl::ODB,
1249                                  46,
1250                                  "Failed(mtermEquiv) to swap: {} -> {} {}",
1251                                  oldMasterName,
1252                                  newMasterName,
1253                                  this->getConstName());
1254     return false;
1255   }
1256 
1257   // remove reference to inst_hdr
1258   _dbInstHdr* old_inst_hdr
1259       = block->_inst_hdr_hash.find(((_dbMaster*) old_master_)->_id);
1260   old_inst_hdr->_inst_cnt--;
1261 
1262   // delete the old-inst-hdr if required
1263   if (old_inst_hdr->_inst_cnt == 0)
1264     dbInstHdr::destroy((dbInstHdr*) old_inst_hdr);
1265 
1266   // add reference to new inst_hdr
1267   _dbInstHdr* new_inst_hdr
1268       = block->_inst_hdr_hash.find(((_dbMaster*) new_master_)->_id);
1269 
1270   // create a new inst-hdr if needed
1271   if (new_inst_hdr == NULL) {
1272     new_inst_hdr = (_dbInstHdr*) dbInstHdr::create((dbBlock*) block,
1273                                                    (dbMaster*) new_master_);
1274     ZASSERT(new_inst_hdr);
1275   }
1276 
1277   new_inst_hdr->_inst_cnt++;
1278   inst->_inst_hdr = new_inst_hdr->getOID();
1279 
1280   // The next two steps invalidates any dbSet<dbITerm> iterators.
1281 
1282   // 1) update the iterm-mterm-idx
1283   uint cnt = inst->_iterms.size();
1284 
1285   uint i;
1286   for (i = 0; i < cnt; ++i) {
1287     _dbITerm* it = block->_iterm_tbl->getPtr(inst->_iterms[i]);
1288     uint old_idx = it->_flags._mterm_idx;
1289     it->_flags._mterm_idx = idx_map[old_idx];
1290   }
1291 
1292   // 2) reorder the iterms vector
1293   sortITerm itermCmp(block);
1294   std::sort(inst->_iterms.begin(), inst->_iterms.end(), itermCmp);
1295 
1296   // Notification - payam 01/18/2006
1297   for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1298        ++cbitr)
1299     (*cbitr)->inDbInstSwapMasterAfter(this);
1300 
1301   // notice(0, "dbSwap_END %s -> %s %s\n", old_master_->getConstName(),
1302   // this->getMaster()->getConstName(), this->getConstName());
1303 
1304   return true;
1305 }
1306 
create(dbBlock * block_,dbMaster * master_,const char * name_)1307 dbInst* dbInst::create(dbBlock* block_, dbMaster* master_, const char* name_)
1308 {
1309   return create(block_, master_, name_, NULL);
1310 }
1311 
create(dbBlock * block_,dbMaster * master_,const char * name_,dbRegion * region)1312 dbInst* dbInst::create(dbBlock* block_,
1313                        dbMaster* master_,
1314                        const char* name_,
1315                        dbRegion* region)
1316 {
1317   _dbBlock* block = (_dbBlock*) block_;
1318   _dbMaster* master = (_dbMaster*) master_;
1319   _dbInstHdr* inst_hdr = block->_inst_hdr_hash.find(master->_id);
1320   if (inst_hdr == NULL) {
1321     inst_hdr
1322         = (_dbInstHdr*) dbInstHdr::create((dbBlock*) block, (dbMaster*) master);
1323     ZASSERT(inst_hdr);
1324   }
1325 
1326   if (block->_inst_hash.hasMember(name_))
1327     return NULL;
1328 
1329   if (block->_journal) {
1330     debugPrint(block->getImpl()->getLogger(),
1331                utl::ODB,
1332                "DB_ECO",
1333                1,
1334                "ECO: dbInst:create");
1335     dbLib* lib = master_->getLib();
1336     block->_journal->beginAction(dbJournal::CREATE_OBJECT);
1337     block->_journal->pushParam(dbInstObj);
1338     block->_journal->pushParam(lib->getId());
1339     block->_journal->pushParam(master_->getId());
1340     block->_journal->pushParam(name_);
1341     block->_journal->endAction();
1342   }
1343 
1344   _dbInst* inst = block->_inst_tbl->create();
1345   inst->_name = strdup(name_);
1346   ZALLOCATED(inst->_name);
1347   inst->_inst_hdr = inst_hdr->getOID();
1348   block->_inst_hash.insert(inst);
1349   inst_hdr->_inst_cnt++;
1350 
1351   // create the iterms
1352   uint mterm_cnt = inst_hdr->_mterms.size();
1353   inst->_iterms.resize(mterm_cnt);
1354 
1355   uint i;
1356   for (i = 0; i < mterm_cnt; ++i) {
1357     _dbITerm* iterm = block->_iterm_tbl->create();
1358     inst->_iterms[i] = iterm->getOID();
1359     iterm->_flags._mterm_idx = i;
1360     iterm->_inst = inst->getOID();
1361   }
1362 
1363   _dbBox* box = block->_box_tbl->create();
1364   box->_shape._rect.init(0, 0, master->_width, master->_height);
1365   box->_flags._owner_type = dbBoxOwner::INST;
1366   box->_owner = inst->getOID();
1367   inst->_bbox = box->getOID();
1368 
1369   block->add_rect(box->_shape._rect);
1370 
1371   if (region) {
1372     region->addInst((dbInst*) inst);
1373     std::list<dbBlockCallBackObj*>::iterator cbitr;
1374     for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1375          ++cbitr)
1376       (**cbitr)().inDbInstCreate((dbInst*) inst,
1377                                  region);  // client ECO initialization - payam
1378   } else {
1379     std::list<dbBlockCallBackObj*>::iterator cbitr;
1380     for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1381          ++cbitr)
1382       (**cbitr)().inDbInstCreate(
1383           (dbInst*) inst);  // client ECO initialization - payam
1384   }
1385 
1386   for (i = 0; i < mterm_cnt; ++i) {
1387     _dbITerm* iterm = block->_iterm_tbl->getPtr(inst->_iterms[i]);
1388     std::list<dbBlockCallBackObj*>::iterator cbitr;
1389     for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1390          ++cbitr)
1391       (**cbitr)().inDbITermCreate(
1392           (dbITerm*) iterm);  // client ECO initialization - payam
1393   }
1394 
1395   return (dbInst*) inst;
1396 }
1397 
destroy(dbInst * inst_)1398 void dbInst::destroy(dbInst* inst_)
1399 {
1400   _dbInst* inst = (_dbInst*) inst_;
1401   _dbBlock* block = (_dbBlock*) inst->getOwner();
1402 
1403   dbRegion* region = inst_->getRegion();
1404 
1405   if (region)
1406     region->removeInst(inst_);
1407 
1408   dbModule* module = inst_->getModule();
1409   if (module)
1410     module->removeInst(inst_);
1411 
1412   if (inst->_group)
1413     inst_->getGroup()->removeInst(inst_);
1414 
1415   uint i;
1416   uint n = inst->_iterms.size();
1417 
1418   for (i = 0; i < n; ++i) {
1419     dbId<_dbITerm> id = inst->_iterms[i];
1420     _dbITerm* it = block->_iterm_tbl->getPtr(id);
1421     dbITerm::disconnect((dbITerm*) it);
1422 
1423     // Bugzilla #7: notify when pins are deleted (assumption: pins
1424     // are destroyed only when the related instance is destroyed)
1425     // payam 01/10/2006
1426     std::list<dbBlockCallBackObj*>::iterator cbitr;
1427     for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1428          ++cbitr)
1429       (**cbitr)().inDbITermDestroy(
1430           (dbITerm*) it);  // client ECO optimization - payam
1431 
1432     dbProperty::destroyProperties(it);
1433     block->_iterm_tbl->destroy(it);
1434   }
1435 
1436   //    Move this part after inDbInstDestroy
1437   //    ----------------------------------------
1438   //    _dbMaster * master = (_dbMaster *) inst_->getMaster();
1439   //    _dbInstHdr * inst_hdr = block->_inst_hdr_hash.find(master->_id);
1440   //    inst_hdr->_inst_cnt--;
1441   //
1442   //    if ( inst_hdr->_inst_cnt == 0 )
1443   //        dbInstHdr::destroy( (dbInstHdr *) inst_hdr );
1444 
1445   if (block->_journal) {
1446     debugPrint(block->getImpl()->getLogger(),
1447                utl::ODB,
1448                "DB_ECO",
1449                1,
1450                "ECO: dbInst:destroy");
1451     block->_journal->beginAction(dbJournal::DELETE_OBJECT);
1452     block->_journal->pushParam(dbInstObj);
1453     block->_journal->pushParam(inst->getId());
1454     block->_journal->endAction();
1455   }
1456 
1457   // Bugzilla #7: The notification of the the instance destruction must
1458   // be done after pin manipulation is completed. The notification is
1459   // now after the pin disconnection - payam 01/10/2006
1460   std::list<dbBlockCallBackObj*>::iterator cbitr;
1461   for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
1462        ++cbitr)
1463     (**cbitr)().inDbInstDestroy(inst_);  // client ECO optimization - payam
1464 
1465   _dbMaster* master = (_dbMaster*) inst_->getMaster();
1466   _dbInstHdr* inst_hdr = block->_inst_hdr_hash.find(master->_id);
1467   inst_hdr->_inst_cnt--;
1468 
1469   if (inst_hdr->_inst_cnt == 0)
1470     dbInstHdr::destroy((dbInstHdr*) inst_hdr);
1471 
1472   if (inst->_halo) {
1473     _dbBox* halo = block->_box_tbl->getPtr(inst->_halo);
1474     dbProperty::destroyProperties(halo);
1475     block->_box_tbl->destroy(halo);
1476   }
1477 
1478   _dbBox* box = block->_box_tbl->getPtr(inst->_bbox);
1479   block->remove_rect(box->_shape._rect);
1480   block->_inst_hash.remove(inst);
1481   dbProperty::destroyProperties(inst);
1482   block->_inst_tbl->destroy(inst);
1483   dbProperty::destroyProperties(box);
1484   block->_box_tbl->destroy(box);
1485 }
1486 
destroy(dbSet<dbInst>::iterator & itr)1487 dbSet<dbInst>::iterator dbInst::destroy(dbSet<dbInst>::iterator& itr)
1488 {
1489   dbInst* bt = *itr;
1490   dbSet<dbInst>::iterator next = ++itr;
1491   destroy(bt);
1492   return next;
1493 }
1494 
getInst(dbBlock * block_,uint dbid_)1495 dbInst* dbInst::getInst(dbBlock* block_, uint dbid_)
1496 {
1497   _dbBlock* block = (_dbBlock*) block_;
1498   return (dbInst*) block->_inst_tbl->getPtr(dbid_);
1499 }
1500 
getValidInst(dbBlock * block_,uint dbid_)1501 dbInst* dbInst::getValidInst(dbBlock* block_, uint dbid_)
1502 {
1503   _dbBlock* block = (_dbBlock*) block_;
1504   if (!block->_inst_tbl->validId(dbid_))
1505     return NULL;
1506   return (dbInst*) block->_inst_tbl->getPtr(dbid_);
1507 }
getFirstOutput()1508 dbITerm* dbInst::getFirstOutput()
1509 {
1510   dbSet<dbITerm> iterms = getITerms();
1511   dbSet<dbITerm>::iterator iitr;
1512 
1513   for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
1514     dbITerm* tr = *iitr;
1515 
1516     if ((tr->getSigType() == dbSigType::GROUND)
1517         || (tr->getSigType() == dbSigType::POWER))
1518       continue;
1519 
1520     if (tr->getIoType() != dbIoType::OUTPUT)
1521       continue;
1522 
1523     return tr;
1524   }
1525   getImpl()->getLogger()->warn(
1526       utl::ODB, 47, "instance {} has no output pin", getConstName());
1527   return NULL;
1528 }
1529 
1530 }  // namespace odb
1531