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 "dbITerm.h"
34
35 #include "db.h"
36 #include "dbArrayTable.h"
37 #include "dbBTerm.h"
38 #include "dbBlock.h"
39 #include "dbBlockCallBackObj.h"
40 #include "dbChip.h"
41 #include "dbCommon.h"
42 #include "dbDatabase.h"
43 #include "dbDiff.hpp"
44 #include "dbHier.h"
45 #include "dbInst.h"
46 #include "dbInstHdr.h"
47 #include "dbJournal.h"
48 #include "dbLib.h"
49 #include "dbMTerm.h"
50 #include "dbMaster.h"
51 #include "dbNet.h"
52 #include "dbShape.h"
53 #include "dbTable.h"
54 #include "dbTable.hpp"
55 #include "utl/Logger.h"
56
57 namespace odb {
58
59 template class dbTable<_dbITerm>;
60
operator ==(const _dbITerm & rhs) const61 bool _dbITerm::operator==(const _dbITerm& rhs) const
62 {
63 if (_flags._mterm_idx != rhs._flags._mterm_idx)
64 return false;
65
66 if (_flags._spef != rhs._flags._spef)
67 return false;
68
69 if (_flags._special != rhs._flags._special)
70 return false;
71
72 if (_flags._connected != rhs._flags._connected)
73 return false;
74
75 if (_ext_id != rhs._ext_id)
76 return false;
77
78 if (_net != rhs._net)
79 return false;
80
81 if (_inst != rhs._inst)
82 return false;
83
84 if (_next_net_iterm != rhs._next_net_iterm)
85 return false;
86
87 if (_prev_net_iterm != rhs._prev_net_iterm)
88 return false;
89
90 return true;
91 }
92
operator <(const _dbITerm & rhs) const93 bool _dbITerm::operator<(const _dbITerm& rhs) const
94 {
95 _dbBlock* lhs_blk = (_dbBlock*) getOwner();
96 _dbBlock* rhs_blk = (_dbBlock*) rhs.getOwner();
97
98 _dbInst* lhs_inst = lhs_blk->_inst_tbl->getPtr(_inst);
99 _dbInst* rhs_inst = rhs_blk->_inst_tbl->getPtr(rhs._inst);
100 int r = strcmp(lhs_inst->_name, rhs_inst->_name);
101
102 if (r < 0)
103 return true;
104
105 if (r > 0)
106 return false;
107
108 _dbMTerm* lhs_mterm = getMTerm();
109 _dbMTerm* rhs_mterm = rhs.getMTerm();
110 return strcmp(lhs_mterm->_name, rhs_mterm->_name) < 0;
111 }
112
differences(dbDiff & diff,const char * field,const _dbITerm & rhs) const113 void _dbITerm::differences(dbDiff& diff,
114 const char* field,
115 const _dbITerm& rhs) const
116 {
117 if (!diff.deepDiff()) {
118 DIFF_BEGIN
119 DIFF_FIELD(_net);
120 DIFF_FIELD(_inst);
121 DIFF_FIELD(_flags._mterm_idx);
122 DIFF_FIELD(_flags._spef);
123 DIFF_FIELD(_flags._special);
124 DIFF_FIELD(_flags._connected);
125 DIFF_FIELD(_ext_id);
126 DIFF_FIELD(_next_net_iterm);
127 DIFF_FIELD(_prev_net_iterm);
128 DIFF_END
129 } else {
130 _dbBlock* lhs_blk = (_dbBlock*) getOwner();
131 _dbBlock* rhs_blk = (_dbBlock*) rhs.getOwner();
132 _dbInst* lhs_inst = lhs_blk->_inst_tbl->getPtr(_inst);
133 _dbInst* rhs_inst = rhs_blk->_inst_tbl->getPtr(rhs._inst);
134 _dbMTerm* lhs_mterm = getMTerm();
135 _dbMTerm* rhs_mterm = rhs.getMTerm();
136 ZASSERT(strcmp(lhs_inst->_name, rhs_inst->_name) == 0);
137 ZASSERT(strcmp(lhs_mterm->_name, rhs_mterm->_name) == 0);
138
139 diff.begin_object("<> %s (_dbITerm)\n", lhs_mterm->_name);
140
141 if ((_net != 0) && (rhs._net != 0)) {
142 _dbNet* lhs_net = lhs_blk->_net_tbl->getPtr(_net);
143 _dbNet* rhs_net = rhs_blk->_net_tbl->getPtr(rhs._net);
144 diff.diff("_net", lhs_net->_name, rhs_net->_name);
145 } else if (_net != 0) {
146 _dbNet* lhs_net = lhs_blk->_net_tbl->getPtr(_net);
147 diff.out(dbDiff::LEFT, "_net", lhs_net->_name);
148 } else if (rhs._net != 0) {
149 _dbNet* rhs_net = rhs_blk->_net_tbl->getPtr(rhs._net);
150 diff.out(dbDiff::RIGHT, "_net", rhs_net->_name);
151 }
152
153 DIFF_FIELD(_flags._spef);
154 DIFF_FIELD(_flags._special);
155 DIFF_FIELD(_flags._connected);
156 DIFF_FIELD(_ext_id);
157 diff.end_object();
158 }
159 }
160
out(dbDiff & diff,char side,const char * field) const161 void _dbITerm::out(dbDiff& diff, char side, const char* field) const
162 {
163 if (!diff.deepDiff()) {
164 DIFF_OUT_BEGIN
165 DIFF_OUT_FIELD(_net);
166 DIFF_OUT_FIELD(_inst);
167 DIFF_OUT_FIELD(_flags._mterm_idx);
168 DIFF_OUT_FIELD(_flags._spef);
169 DIFF_OUT_FIELD(_flags._special);
170 DIFF_OUT_FIELD(_flags._connected);
171 DIFF_OUT_FIELD(_ext_id);
172 DIFF_OUT_FIELD(_next_net_iterm);
173 DIFF_OUT_FIELD(_prev_net_iterm);
174 DIFF_END
175 } else {
176 _dbMTerm* mterm = getMTerm();
177 diff.begin_object("%c %s (_dbITerm)\n", side, mterm->_name);
178 _dbBlock* blk = (_dbBlock*) getOwner();
179
180 if (_net != 0) {
181 _dbNet* net = blk->_net_tbl->getPtr(_net);
182 diff.out(side, "_net", net->_name);
183 }
184
185 DIFF_OUT_FIELD(_flags._spef);
186 DIFF_OUT_FIELD(_flags._special);
187 DIFF_OUT_FIELD(_flags._connected);
188 DIFF_OUT_FIELD(_ext_id);
189 diff.end_object();
190 }
191 }
192
getMTerm() const193 _dbMTerm* _dbITerm::getMTerm() const
194 {
195 _dbBlock* block = (_dbBlock*) getOwner();
196 _dbInst* inst = block->_inst_tbl->getPtr(_inst);
197 _dbInstHdr* inst_hdr = block->_inst_hdr_tbl->getPtr(inst->_inst_hdr);
198 _dbDatabase* db = getDatabase();
199 _dbLib* lib = db->_lib_tbl->getPtr(inst_hdr->_lib);
200 _dbMaster* master = lib->_master_tbl->getPtr(inst_hdr->_master);
201 dbId<_dbMTerm> mterm = inst_hdr->_mterms[_flags._mterm_idx];
202 return master->_mterm_tbl->getPtr(mterm);
203 }
204
getInst() const205 _dbInst* _dbITerm::getInst() const
206 {
207 _dbBlock* block = (_dbBlock*) getOwner();
208 _dbInst* inst = block->_inst_tbl->getPtr(_inst);
209 return inst;
210 }
211
212 ////////////////////////////////////////////////////////////////////
213 //
214 // dbITerm - Methods
215 //
216 ////////////////////////////////////////////////////////////////////
217
getInst()218 dbInst* dbITerm::getInst()
219 {
220 _dbITerm* iterm = (_dbITerm*) this;
221 _dbBlock* block = (_dbBlock*) iterm->getOwner();
222 _dbInst* inst = block->_inst_tbl->getPtr(iterm->_inst);
223 return (dbInst*) inst;
224 }
225
getNet()226 dbNet* dbITerm::getNet()
227 {
228 _dbITerm* iterm = (_dbITerm*) this;
229 _dbBlock* block = (_dbBlock*) iterm->getOwner();
230
231 if (iterm->_net == 0)
232 return NULL;
233
234 _dbNet* net = block->_net_tbl->getPtr(iterm->_net);
235 return (dbNet*) net;
236 }
237
getMTerm()238 dbMTerm* dbITerm::getMTerm()
239 {
240 _dbITerm* iterm = (_dbITerm*) this;
241 _dbBlock* block = (_dbBlock*) iterm->getOwner();
242 _dbInst* inst = block->_inst_tbl->getPtr(iterm->_inst);
243 _dbInstHdr* inst_hdr = block->_inst_hdr_tbl->getPtr(inst->_inst_hdr);
244 _dbDatabase* db = iterm->getDatabase();
245 _dbLib* lib = db->_lib_tbl->getPtr(inst_hdr->_lib);
246 _dbMaster* master = lib->_master_tbl->getPtr(inst_hdr->_master);
247 dbId<_dbMTerm> mterm = inst_hdr->_mterms[iterm->_flags._mterm_idx];
248 return (dbMTerm*) master->_mterm_tbl->getPtr(mterm);
249 }
250
getBTerm()251 dbBTerm* dbITerm::getBTerm()
252 {
253 _dbITerm* iterm = (_dbITerm*) this;
254 _dbBlock* block = (_dbBlock*) iterm->getOwner();
255 _dbInst* inst = block->_inst_tbl->getPtr(iterm->_inst);
256
257 if (inst->_hierarchy == 0)
258 return NULL;
259
260 _dbHier* hier = block->_hier_tbl->getPtr(inst->_hierarchy);
261
262 _dbChip* chip = (_dbChip*) block->getOwner();
263 _dbBlock* child = chip->_block_tbl->getPtr(hier->_child_block);
264 dbId<_dbBTerm> bterm = hier->_child_bterms[iterm->_flags._mterm_idx];
265 return (dbBTerm*) child->_bterm_tbl->getPtr(bterm);
266 }
267
getBlock()268 dbBlock* dbITerm::getBlock()
269 {
270 return (dbBlock*) getImpl()->getOwner();
271 }
setClocked(bool v)272 void dbITerm::setClocked(bool v)
273 {
274 _dbITerm* iterm = (_dbITerm*) this;
275 iterm->_flags._clocked = v;
276 }
isClocked()277 bool dbITerm::isClocked()
278 {
279 bool masterFlag = getMTerm()->getSigType() == dbSigType::CLOCK ? true : false;
280 _dbITerm* iterm = (_dbITerm*) this;
281 return iterm->_flags._clocked > 0 || masterFlag ? true : false;
282 }
setMark(uint v)283 void dbITerm::setMark(uint v)
284 {
285 _dbITerm* iterm = (_dbITerm*) this;
286 iterm->_flags._mark = v;
287 }
isSetMark()288 bool dbITerm::isSetMark()
289 {
290 _dbITerm* iterm = (_dbITerm*) this;
291 return iterm->_flags._mark > 0 ? true : false;
292 }
293
isSpecial()294 bool dbITerm::isSpecial()
295 {
296 _dbITerm* iterm = (_dbITerm*) this;
297 return iterm->_flags._special == 1;
298 }
299
setSpecial()300 void dbITerm::setSpecial()
301 {
302 _dbITerm* iterm = (_dbITerm*) this;
303 //_dbBlock * block = (_dbBlock *) getOwner();
304 // dimitri_fix: need to FIX on FULL_ECO uint prev_flags = flagsToUInt(iterm);
305 #ifdef FULL_ECO
306 uint prev_flags = flagsToUInt(iterm);
307 #endif
308
309 iterm->_flags._special = 1;
310
311 #ifdef FULL_ECO
312 if (block->_journal) {
313 debugPrint(getImpl()->getLogger(),
314 utl::ODB,
315 "DB_ECO",
316 1,
317 "ECO: Iterm {}, setSpecial",
318 getId());
319 block->_journal->updateField(
320 this, _dbNet::FLAGS, prev_flags, flagsToUInt(iterm));
321 }
322 #endif
323 }
324
clearSpecial()325 void dbITerm::clearSpecial()
326 {
327 _dbITerm* iterm = (_dbITerm*) this;
328 //_dbBlock * block = (_dbBlock *) getOwner();
329 // dimitri_fix: need to FIX on FULL_ECO //uint prev_flags =
330 // flagsToUInt(iterm);
331 #ifdef FULL_ECO
332 uint prev_flags = flagsToUInt(iterm);
333 #endif
334
335 iterm->_flags._special = 0;
336
337 #ifdef FULL_ECO
338 if (block->_journal) {
339 debugPrint(getImpl()->getLogger(),
340 utl::ODB,
341 "DB_ECO",
342 1,
343 "ECO: Iterm {}, clearSpecial\n",
344 getId());
345 block->_journal->updateField(
346 this, _dbNet::FLAGS, prev_flags, flagsToUInt(iterm));
347 }
348 #endif
349 }
350
setSpef(uint v)351 void dbITerm::setSpef(uint v)
352 {
353 _dbITerm* iterm = (_dbITerm*) this;
354 //_dbBlock * block = (_dbBlock *) getOwner();
355 // dimitri_fix: need to FIX on FULL_ECO //uint prev_flags =
356 // flagsToUInt(iterm);
357 #ifdef FULL_ECO
358 uint prev_flags = flagsToUInt(iterm);
359 #endif
360
361 iterm->_flags._spef = v;
362
363 #ifdef FULL_ECO
364 if (block->_journal) {
365 debugPrint(getImpl()->getLogger(),
366 utl::ODB,
367 "DB_ECO",
368 1,
369 "ECO: Iterm {}, setSpef",
370 getId());
371 block->_journal->updateField(
372 this, _dbNet::FLAGS, prev_flags, flagsToUInt(iterm));
373 }
374 #endif
375 }
376
isSpef()377 bool dbITerm::isSpef()
378 {
379 _dbITerm* iterm = (_dbITerm*) this;
380 return (iterm->_flags._spef > 0) ? true : false;
381 }
382
setExtId(uint v)383 void dbITerm::setExtId(uint v)
384 {
385 _dbITerm* iterm = (_dbITerm*) this;
386 iterm->_ext_id = v;
387 }
388
getExtId()389 uint dbITerm::getExtId()
390 {
391 _dbITerm* iterm = (_dbITerm*) this;
392 return iterm->_ext_id;
393 }
394
isConnected()395 bool dbITerm::isConnected()
396 {
397 _dbITerm* iterm = (_dbITerm*) this;
398 return iterm->_flags._connected == 1;
399 }
400
setConnected()401 void dbITerm::setConnected()
402 {
403 _dbITerm* iterm = (_dbITerm*) this;
404 // dimitri_fix: need to FIX on FULL_ECO uint prev_flags = flagsToUInt(iterm);
405 #ifdef FULL_ECO
406 _dbBlock* block = (_dbBlock*) getOwner();
407 uint prev_flags = flagsToUInt(iterm);
408 #endif
409
410 iterm->_flags._connected = 1;
411
412 #ifdef FULL_ECO
413 if (block->_journal) {
414 debugPrint(getImpl()->getLogger(),
415 utl::ODB,
416 "DB_ECO",
417 1,
418 "ECO: Iterm {}, setConnected",
419 getId());
420 block->_journal->updateField(
421 this, _dbNet::FLAGS, prev_flags, flagsToUInt(iterm));
422 }
423 #endif
424 }
425
clearConnected()426 void dbITerm::clearConnected()
427 {
428 _dbITerm* iterm = (_dbITerm*) this;
429 // uint prev_flags = flagsToUInt(iterm);
430 #ifdef FULL_ECO
431 _dbBlock* block = (_dbBlock*) getOwner();
432 uint prev_flags = flagsToUInt(iterm);
433 #endif
434
435 iterm->_flags._connected = 0;
436
437 #ifdef FULL_ECO
438 if (block->_journal) {
439 debugPrint(getImpl()->getLogger(),
440 utl::ODB,
441 "DB_ECO",
442 1,
443 "ECO: Iterm {}, clearConnected",
444 getId());
445 block->_journal->updateField(
446 this, _dbNet::FLAGS, prev_flags, flagsToUInt(iterm));
447 }
448 #endif
449 }
450
connect(dbInst * inst_,dbNet * net_,dbMTerm * mterm_)451 dbITerm* dbITerm::connect(dbInst* inst_, dbNet* net_, dbMTerm* mterm_)
452 {
453 _dbInst* inst = (_dbInst*) inst_;
454 //_dbNet * net = (_dbNet *) net_;
455 _dbMTerm* mterm = (_dbMTerm*) mterm_;
456 _dbBlock* block = (_dbBlock*) inst->getOwner();
457 _dbITerm* iterm = block->_iterm_tbl->getPtr(inst->_iterms[mterm->_order_id]);
458 connect((dbITerm*) iterm, net_);
459 return (dbITerm*) iterm;
460 }
461
connect(dbITerm * iterm_,dbNet * net_)462 void dbITerm::connect(dbITerm* iterm_, dbNet* net_)
463 {
464 _dbITerm* iterm = (_dbITerm*) iterm_;
465 _dbNet* net = (_dbNet*) net_;
466 _dbBlock* block = (_dbBlock*) iterm->getOwner();
467
468 // Do Nothing if already connected
469 if (iterm->_net == net->getOID())
470 return;
471 for (auto callback : block->_callbacks)
472 callback->inDbITermPreConnect(iterm_, net_);
473
474 if (iterm->_net != 0)
475 disconnect(iterm_);
476
477 if (block->_journal) {
478 debugPrint(iterm->getImpl()->getLogger(),
479 utl::ODB,
480 "DB_ECO",
481 1,
482 "ECO: connect Iterm {} to net {}",
483 iterm_->getId(),
484 net_->getId());
485 block->_journal->beginAction(dbJournal::CONNECT_OBJECT);
486 block->_journal->pushParam(dbITermObj);
487 block->_journal->pushParam(iterm_->getId());
488 block->_journal->pushParam(net_->getId());
489 block->_journal->endAction();
490 }
491
492 iterm->_net = net->getOID();
493
494 if (net->_iterms != 0) {
495 _dbITerm* tail = block->_iterm_tbl->getPtr(net->_iterms);
496 iterm->_next_net_iterm = net->_iterms;
497 iterm->_prev_net_iterm = 0;
498 tail->_prev_net_iterm = iterm->getOID();
499 } else {
500 iterm->_next_net_iterm = 0;
501 iterm->_prev_net_iterm = 0;
502 }
503
504 net->_iterms = iterm->getOID();
505
506 for (auto callback : block->_callbacks)
507 callback->inDbITermPostConnect(iterm_);
508 }
509
disconnect(dbITerm * iterm_)510 void dbITerm::disconnect(dbITerm* iterm_)
511 {
512 _dbITerm* iterm = (_dbITerm*) iterm_;
513
514 if (iterm->_net == 0)
515 return;
516
517 _dbBlock* block = (_dbBlock*) iterm->getOwner();
518 _dbNet* net = block->_net_tbl->getPtr(iterm->_net);
519 for (auto callback : block->_callbacks)
520 callback->inDbITermPreDisconnect(iterm_);
521 if (block->_journal) {
522 debugPrint(iterm->getImpl()->getLogger(),
523 utl::ODB,
524 "DB_ECO",
525 1,
526 "ECO: disconnect Iterm {}",
527 iterm_->getId());
528 block->_journal->beginAction(dbJournal::DISCONNECT_OBJECT);
529 block->_journal->pushParam(dbITermObj);
530 block->_journal->pushParam(iterm_->getId());
531 block->_journal->endAction();
532 }
533
534 uint id = iterm->getOID();
535
536 if (net->_iterms == id) {
537 net->_iterms = iterm->_next_net_iterm;
538
539 if (net->_iterms != 0) {
540 _dbITerm* t = block->_iterm_tbl->getPtr(net->_iterms);
541 t->_prev_net_iterm = 0;
542 }
543 } else {
544 if (iterm->_next_net_iterm != 0) {
545 _dbITerm* next = block->_iterm_tbl->getPtr(iterm->_next_net_iterm);
546 next->_prev_net_iterm = iterm->_prev_net_iterm;
547 }
548
549 if (iterm->_prev_net_iterm != 0) {
550 _dbITerm* prev = block->_iterm_tbl->getPtr(iterm->_prev_net_iterm);
551 prev->_next_net_iterm = iterm->_next_net_iterm;
552 }
553 }
554
555 iterm->_net = 0;
556 for (auto callback : block->_callbacks)
557 callback->inDbITermPostDisconnect(iterm_, (dbNet*) net);
558 }
559
disconnect(dbSet<dbITerm>::iterator & itr)560 dbSet<dbITerm>::iterator dbITerm::disconnect(dbSet<dbITerm>::iterator& itr)
561 {
562 dbITerm* it = *itr;
563 dbSet<dbITerm>::iterator next = ++itr;
564 disconnect(it);
565 return next;
566 }
567
getSigType()568 dbSigType dbITerm::getSigType()
569 {
570 _dbMTerm* mterm = (_dbMTerm*) getMTerm();
571 return dbSigType(mterm->_flags._sig_type);
572 }
getIoType()573 dbIoType dbITerm::getIoType()
574 {
575 _dbMTerm* mterm = (_dbMTerm*) getMTerm();
576 return dbIoType(mterm->_flags._io_type);
577 }
isOutputSignal(bool io)578 bool dbITerm::isOutputSignal(bool io)
579 {
580 _dbMTerm* mterm = (_dbMTerm*) getMTerm();
581 dbSigType sType = dbSigType(mterm->_flags._sig_type);
582 dbIoType ioType = dbIoType(mterm->_flags._io_type);
583
584 if ((sType == dbSigType::GROUND) || (sType == dbSigType::POWER))
585 return false;
586
587 if (ioType == dbIoType::OUTPUT)
588 return true;
589
590 if (io && (ioType == dbIoType::INOUT))
591 return true;
592
593 return false;
594 }
isInputSignal(bool io)595 bool dbITerm::isInputSignal(bool io)
596 {
597 _dbMTerm* mterm = (_dbMTerm*) getMTerm();
598 dbSigType sType = dbSigType(mterm->_flags._sig_type);
599 dbIoType ioType = dbIoType(mterm->_flags._io_type);
600
601 if ((sType == dbSigType::GROUND) || (sType == dbSigType::POWER))
602 return false;
603
604 if (ioType == dbIoType::INPUT)
605 return true;
606
607 if (io && (ioType == dbIoType::INOUT))
608 return true;
609
610 return false;
611 }
612
getITerm(dbBlock * block_,uint dbid)613 dbITerm* dbITerm::getITerm(dbBlock* block_, uint dbid)
614 {
615 _dbBlock* block = (_dbBlock*) block_;
616 return (dbITerm*) block->_iterm_tbl->getPtr(dbid);
617 }
618
getBBox()619 Rect dbITerm::getBBox()
620 {
621 dbMTerm* term = getMTerm();
622 Rect bbox = term->getBBox();
623 odb::dbTransform inst_xfm;
624 getInst()->getTransform(inst_xfm);
625 inst_xfm.apply(bbox);
626 return bbox;
627 }
628
getAvgXY(int * x,int * y)629 bool dbITerm::getAvgXY(int* x, int* y)
630 {
631 dbMTerm* mterm = getMTerm();
632 int nn = 0;
633 double xx = 0.0;
634 double yy = 0.0;
635 int px;
636 int py;
637 dbInst* inst = getInst();
638 inst->getOrigin(px, py);
639 Point origin = Point(px, py);
640 dbOrientType orient = inst->getOrient();
641 dbTransform transform(orient, origin);
642
643 dbSet<dbMPin> mpins = mterm->getMPins();
644 dbSet<dbMPin>::iterator mpin_itr;
645 for (mpin_itr = mpins.begin(); mpin_itr != mpins.end(); mpin_itr++) {
646 dbMPin* mpin = *mpin_itr;
647 dbSet<dbBox> boxes = mpin->getGeometry();
648 dbSet<dbBox>::iterator box_itr;
649 for (box_itr = boxes.begin(); box_itr != boxes.end(); box_itr++) {
650 dbBox* box = *box_itr;
651 Rect rect;
652 box->getBox(rect);
653 transform.apply(rect);
654 xx += rect.xMin() + rect.xMax();
655 yy += rect.yMin() + rect.yMax();
656 nn += 2;
657 }
658 }
659 if (!nn) {
660 getImpl()->getLogger()->warn(
661 utl::ODB,
662 34,
663 "Can not find physical location of iterm {}/{}",
664 getInst()->getConstName(),
665 getMTerm()->getConstName());
666 return false;
667 }
668 xx /= nn;
669 yy /= nn;
670 *x = int(xx);
671 *y = int(yy);
672 return true;
673 }
674
staVertexId()675 uint32_t dbITerm::staVertexId()
676 {
677 _dbITerm* iterm = (_dbITerm*) this;
678 return iterm->_sta_vertex_id;
679 }
680
staSetVertexId(uint32_t id)681 void dbITerm::staSetVertexId(uint32_t id)
682 {
683 _dbITerm* iterm = (_dbITerm*) this;
684 iterm->_sta_vertex_id = id;
685 }
686
687 } // namespace odb
688