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