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 "dbCapNode.h"
34
35 #include "db.h"
36 #include "dbBlock.h"
37 #include "dbCCSeg.h"
38 #include "dbCCSegItr.h"
39 #include "dbCommon.h"
40 #include "dbDatabase.h"
41 #include "dbJournal.h"
42 #include "dbNet.h"
43 #include "dbTable.h"
44 #include "dbTable.hpp"
45 #include "utl/Logger.h"
46
47 namespace odb {
48
49 double getExtCCmult(dbNet* aggressor);
50
51 template class dbTable<_dbCapNode>;
52
operator ==(const _dbCapNode & rhs) const53 bool _dbCapNode::operator==(const _dbCapNode& rhs) const
54 {
55 if (_flags._name != rhs._flags._name)
56 return false;
57
58 if (_flags._internal != rhs._flags._internal)
59 return false;
60
61 if (_flags._iterm != rhs._flags._iterm)
62 return false;
63
64 if (_flags._bterm != rhs._flags._bterm)
65 return false;
66
67 if (_flags._branch != rhs._flags._branch)
68 return false;
69
70 if (_flags._foreign != rhs._flags._foreign)
71 return false;
72
73 if (_flags._childrenCnt != rhs._flags._childrenCnt)
74 return false;
75
76 if (_flags._select != rhs._flags._select)
77 return false;
78
79 if (_node_num != rhs._node_num)
80 return false;
81
82 if (_net != rhs._net)
83 return false;
84
85 if (_next != rhs._next)
86 return false;
87
88 if (_cc_segs != rhs._cc_segs)
89 return false;
90
91 return true;
92 }
93
differences(dbDiff & diff,const char * field,const _dbCapNode & rhs) const94 void _dbCapNode::differences(dbDiff& diff,
95 const char* field,
96 const _dbCapNode& rhs) const
97 {
98 DIFF_BEGIN
99 DIFF_FIELD(_flags._internal);
100 DIFF_FIELD(_flags._iterm);
101 DIFF_FIELD(_flags._bterm);
102 DIFF_FIELD(_flags._branch);
103 DIFF_FIELD(_flags._foreign);
104 DIFF_FIELD(_flags._childrenCnt);
105 DIFF_FIELD(_flags._select);
106
107 // if (stream.getDatabase()->isSchema(ADS_DB_CAPNODE_NAME))
108 DIFF_FIELD(_flags._name);
109
110 DIFF_FIELD(_node_num);
111 DIFF_FIELD(_net);
112 DIFF_FIELD(_next);
113 DIFF_FIELD(_cc_segs);
114 DIFF_END
115 }
116
out(dbDiff & diff,char side,const char * field) const117 void _dbCapNode::out(dbDiff& diff, char side, const char* field) const
118 {
119 DIFF_OUT_BEGIN
120 DIFF_OUT_FIELD(_flags._internal);
121 DIFF_OUT_FIELD(_flags._iterm);
122 DIFF_OUT_FIELD(_flags._bterm);
123 DIFF_OUT_FIELD(_flags._branch);
124 DIFF_OUT_FIELD(_flags._foreign);
125 DIFF_OUT_FIELD(_flags._childrenCnt);
126 DIFF_OUT_FIELD(_flags._select);
127
128 // if (stream.getDatabase()->isSchema(ADS_DB_CAPNODE_NAME))
129 DIFF_OUT_FIELD(_flags._name);
130
131 DIFF_OUT_FIELD(_node_num);
132 DIFF_OUT_FIELD(_net);
133 DIFF_OUT_FIELD(_next);
134 DIFF_OUT_FIELD(_cc_segs);
135 DIFF_END
136 }
137
138 ////////////////////////////////////////////////////////////////////
139 //
140 // dbCapNode - Methods
141 //
142 ////////////////////////////////////////////////////////////////////
143
needAdjustCC(double ccThreshHold)144 bool dbCapNode::needAdjustCC(double ccThreshHold)
145 {
146 dbSet<dbCCSeg> ccSegs = getCCSegs();
147 dbSet<dbCCSeg>::iterator ccitr;
148 uint cornerCnt = ((dbBlock*) getImpl()->getOwner())->getCornerCount();
149 uint corner;
150 uint cid;
151 for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
152 dbCCSeg* cc = *ccitr;
153 for (corner = 0; corner < cornerCnt; corner++) {
154 if (cc->getTheOtherCapn(this, cid)->getNet()->getCcAdjustFactor() > 0)
155 continue;
156 if (cc->getCapacitance(corner) >= ccThreshHold)
157 return true;
158 }
159 }
160 return false;
161 }
162
groundCC(float gndFactor)163 bool dbCapNode::groundCC(float gndFactor)
164 {
165 bool grounded = false;
166 uint vicNetId = getNet()->getId();
167 uint agrNetId;
168 dbCapNode* agrNode;
169 double deltaC;
170 uint cid;
171 _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
172 uint cornerCnt = block->_corners_per_block;
173 dbSet<dbCCSeg> ccSegs = getCCSegs();
174 dbSet<dbCCSeg>::iterator ccitr;
175 for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
176 dbCCSeg* cc = *ccitr;
177 agrNode = cc->getTheOtherCapn(this, cid);
178 agrNetId = agrNode->getNet()->getId();
179 if (agrNetId < vicNetId)
180 continue; // avoid duplicate grounding
181 if (agrNetId == vicNetId) {
182 getImpl()->getLogger()->warn(
183 utl::ODB,
184 24,
185 "cc seg {} has both capNodes {} {} from the same net {} . "
186 "ignored by groundCC .",
187 cc->getId(),
188 getId(),
189 agrNode->getId(),
190 agrNetId);
191 continue;
192 }
193 grounded = true;
194 for (uint ii = 0; ii < cornerCnt; ii++) {
195 deltaC = cc->getCapacitance(ii) * gndFactor;
196 addCapacitance(deltaC, ii);
197 agrNode->addCapacitance(deltaC, ii);
198 }
199 }
200 return grounded;
201 }
202
adjustCC(uint adjOrder,float adjFactor,std::vector<dbCCSeg * > & adjustedCC,std::vector<dbNet * > & halonets)203 void dbCapNode::adjustCC(uint adjOrder,
204 float adjFactor,
205 std::vector<dbCCSeg*>& adjustedCC,
206 std::vector<dbNet*>& halonets)
207 {
208 dbSet<dbCCSeg> ccSegs = getCCSegs();
209 dbSet<dbCCSeg>::iterator ccitr;
210 dbNet* agrNet;
211 uint cid;
212 for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
213 dbCCSeg* cc = *ccitr;
214 if (cc->isMarked())
215 continue;
216 agrNet = cc->getTheOtherCapn(this, cid)->getNet();
217 if (agrNet->getCcAdjustFactor() > 0
218 && agrNet->getCcAdjustOrder() < adjOrder)
219 continue;
220 adjustedCC.push_back(cc);
221 cc->setMark(true);
222 cc->adjustCapacitance(adjFactor);
223 if (!agrNet->isMark_1ed()) {
224 agrNet->setMark_1(true);
225 halonets.push_back(agrNet);
226 }
227 }
228 }
229
adjustCapacitance(float factor,uint corner)230 void dbCapNode::adjustCapacitance(float factor, uint corner)
231 {
232 _dbCapNode* seg = (_dbCapNode*) this;
233 _dbBlock* block = (_dbBlock*) seg->getOwner();
234 uint cornerCnt = block->_corners_per_block;
235
236 ZASSERT(seg->_flags._foreign > 0);
237 ZASSERT(corner < cornerCnt);
238 float& value
239 = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
240 float prev_value = value;
241 value *= factor;
242
243 if (block->_journal) {
244 debugPrint(getImpl()->getLogger(),
245 utl::ODB,
246 "DB_ECO",
247 1,
248 "ECO: dbCapNode {}, adjustCapacitance {}, corner {}",
249 seg->getId(),
250 factor,
251 corner);
252 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
253 block->_journal->pushParam(dbCapNodeObj);
254 block->_journal->pushParam(seg->getId());
255 block->_journal->pushParam(_dbCapNode::CAPACITANCE);
256 block->_journal->pushParam(prev_value);
257 block->_journal->pushParam(value);
258 block->_journal->pushParam(0);
259 block->_journal->endAction();
260 }
261 }
262
adjustCapacitance(float factor)263 void dbCapNode::adjustCapacitance(float factor)
264 {
265 _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
266 uint cornerCnt = block->_corners_per_block;
267 uint corner;
268 for (corner = 0; corner < cornerCnt; corner++)
269 adjustCapacitance(factor, corner);
270 }
271
getCapacitance(uint corner)272 double dbCapNode::getCapacitance(uint corner)
273 {
274 _dbCapNode* seg = (_dbCapNode*) this;
275 _dbBlock* block = (_dbBlock*) seg->getOwner();
276 uint cornerCnt = block->_corners_per_block;
277
278 if (seg->_flags._foreign > 0) {
279 ZASSERT(corner < cornerCnt);
280 return (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
281 } else {
282 return 0.0;
283 }
284 }
285
getGndCap(double * gndcap,double * totalcap)286 void dbCapNode::getGndCap(double* gndcap, double* totalcap)
287 {
288 _dbCapNode* seg = (_dbCapNode*) this;
289 if (seg->_flags._foreign == 0)
290 return;
291 _dbBlock* block = (_dbBlock*) seg->getOwner();
292 uint cornerCnt = block->_corners_per_block;
293 double gcap;
294 for (uint ii = 0; ii < cornerCnt; ii++) {
295 gcap = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
296 if (gndcap)
297 gndcap[ii] = gcap;
298 if (totalcap)
299 totalcap[ii] = gcap;
300 }
301 }
302
addGndCap(double * gndcap,double * totalcap)303 void dbCapNode::addGndCap(double* gndcap, double* totalcap)
304 {
305 _dbCapNode* seg = (_dbCapNode*) this;
306 if (seg->_flags._foreign == 0)
307 return;
308 _dbBlock* block = (_dbBlock*) seg->getOwner();
309 uint cornerCnt = block->_corners_per_block;
310 double gcap;
311 for (uint ii = 0; ii < cornerCnt; ii++) {
312 gcap = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
313 if (gndcap)
314 gndcap[ii] += gcap;
315 if (totalcap)
316 totalcap[ii] += gcap;
317 }
318 }
319
accAllCcCap(double * totalcap,double MillerMult)320 void dbCapNode::accAllCcCap(double* totalcap, double MillerMult)
321 {
322 if (totalcap == NULL || MillerMult == 0)
323 return;
324 dbSet<dbCCSeg> ccSegs = getCCSegs();
325 dbSet<dbCCSeg>::iterator ccitr;
326 for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
327 double ccmult = MillerMult;
328 dbCCSeg* cc = *ccitr;
329 #ifdef TMG_SI
330 if (MillerMult < 0)
331 ccmult = getExtCCmult(cc->getTheOtherCapn(this, cid)->getNet());
332 #endif
333 cc->accAllCcCap(totalcap, ccmult);
334 }
335 }
336
getGndTotalCap(double * gndcap,double * totalcap,double MillerMult)337 void dbCapNode::getGndTotalCap(double* gndcap,
338 double* totalcap,
339 double MillerMult)
340 {
341 getGndCap(gndcap, totalcap);
342 accAllCcCap(totalcap, MillerMult);
343 }
344
addGndTotalCap(double * gndcap,double * totalcap,double MillerMult)345 void dbCapNode::addGndTotalCap(double* gndcap,
346 double* totalcap,
347 double MillerMult)
348 {
349 addGndCap(gndcap, totalcap);
350 accAllCcCap(totalcap, MillerMult);
351 }
352
getCapTable(double * cap)353 void dbCapNode::getCapTable(double* cap)
354 {
355 _dbCapNode* seg = (_dbCapNode*) this;
356 _dbBlock* block = (_dbBlock*) seg->getOwner();
357 uint cornerCnt = block->_corners_per_block;
358
359 for (uint ii = 0; ii < cornerCnt; ii++)
360 cap[ii] = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
361 }
362
addCapnCapacitance(dbCapNode * other)363 void dbCapNode::addCapnCapacitance(dbCapNode* other)
364 {
365 _dbCapNode* seg = (_dbCapNode*) this;
366 _dbCapNode* oseg = (_dbCapNode*) other;
367 _dbBlock* block = (_dbBlock*) seg->getOwner();
368 uint cornerCnt = block->_corners_per_block;
369 for (uint corner = 0; corner < cornerCnt; corner++) {
370 float& value
371 = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
372 float& ovalue
373 = (*block->_c_val_tbl)[(oseg->getOID() - 1) * cornerCnt + 1 + corner];
374 value += ovalue;
375 }
376
377 if (block->_journal) {
378 debugPrint(getImpl()->getLogger(),
379 utl::ODB,
380 "DB_ECO",
381 1,
382 "ECO: dbCapNode {}, other dbCapNode {}, addCapnCapacitance",
383 seg->getId(),
384 oseg->getId());
385 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
386 block->_journal->pushParam(dbCapNodeObj);
387 block->_journal->pushParam(seg->getId());
388 block->_journal->pushParam(_dbCapNode::ADDCAPNCAPACITANCE);
389 block->_journal->pushParam(oseg->getId());
390 block->_journal->endAction();
391 }
392 }
393
setCapacitance(double cap,int corner)394 void dbCapNode::setCapacitance(double cap, int corner)
395 {
396 _dbCapNode* seg = (_dbCapNode*) this;
397 _dbBlock* block = (_dbBlock*) seg->getOwner();
398 uint cornerCnt = block->_corners_per_block;
399 ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
400 float& value
401 = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
402 float prev_value = value;
403 value = (float) cap;
404
405 if (block->_journal) {
406 debugPrint(getImpl()->getLogger(),
407 utl::ODB,
408 "DB_ECO",
409 1,
410 "ECO: setCapacitance, corner {}, seg {}, prev: {}, new: {}",
411 corner,
412 seg->getId(),
413 prev_value,
414 value);
415 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
416 block->_journal->pushParam(dbCapNodeObj);
417 block->_journal->pushParam(seg->getId());
418 block->_journal->pushParam(_dbCapNode::CAPACITANCE);
419 block->_journal->pushParam(prev_value);
420 block->_journal->pushParam(value);
421 block->_journal->pushParam(corner);
422 block->_journal->endAction();
423 }
424 }
425
addCapacitance(double cap,int corner)426 void dbCapNode::addCapacitance(double cap, int corner)
427 {
428 _dbCapNode* seg = (_dbCapNode*) this;
429 _dbBlock* block = (_dbBlock*) seg->getOwner();
430 uint cornerCnt = block->_corners_per_block;
431 ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
432 float& value
433 = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
434 float prev_value = value;
435 value += (float) cap;
436
437 if (block->_journal) {
438 debugPrint(getImpl()->getLogger(),
439 utl::ODB,
440 "DB_ECO",
441 1,
442 "ECO: AddCapacitance, corner {}, seg {}, prev: {}, new: {}",
443 corner,
444 seg->getId(),
445 prev_value,
446 value);
447 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
448 block->_journal->pushParam(dbCapNodeObj);
449 block->_journal->pushParam(seg->getId());
450 block->_journal->pushParam(_dbCapNode::CAPACITANCE);
451 block->_journal->pushParam(prev_value);
452 block->_journal->pushParam(value);
453 block->_journal->pushParam(corner);
454 block->_journal->endAction();
455 }
456 }
457
isSelect()458 bool dbCapNode::isSelect()
459 {
460 _dbCapNode* seg = (_dbCapNode*) this;
461 return seg->_flags._select > 0 ? true : false;
462 }
isForeign()463 bool dbCapNode::isForeign()
464 {
465 _dbCapNode* seg = (_dbCapNode*) this;
466 return seg->_flags._foreign > 0 ? true : false;
467 }
isInternal()468 bool dbCapNode::isInternal()
469 {
470 _dbCapNode* seg = (_dbCapNode*) this;
471 return seg->_flags._internal > 0 ? true : false;
472 }
isTreeNode()473 bool dbCapNode::isTreeNode()
474 {
475 _dbCapNode* seg = (_dbCapNode*) this;
476 uint flags = seg->_flags._branch + seg->_flags._iterm + seg->_flags._bterm;
477 return flags > 0 ? true : false;
478 }
isBranch()479 bool dbCapNode::isBranch()
480 {
481 _dbCapNode* seg = (_dbCapNode*) this;
482 return seg->_flags._branch > 0 ? true : false;
483 }
isDangling()484 bool dbCapNode::isDangling()
485 {
486 return getChildrenCnt() <= 1 && !isTreeNode();
487 }
488
getITerm(dbBlock * mblock)489 dbITerm* dbCapNode::getITerm(dbBlock* mblock)
490 {
491 _dbCapNode* seg = (_dbCapNode*) this;
492 dbBlock* block = mblock ? mblock : (dbBlock*) seg->getOwner();
493 if (!seg->_flags._iterm)
494 return NULL;
495 return dbITerm::getITerm(block, seg->_node_num);
496 }
getBTerm(dbBlock * mblock)497 dbBTerm* dbCapNode::getBTerm(dbBlock* mblock)
498 {
499 _dbCapNode* seg = (_dbCapNode*) this;
500 dbBlock* block = mblock ? mblock : (dbBlock*) seg->getOwner();
501 if (!seg->_flags._bterm)
502 return NULL;
503 return dbBTerm::getBTerm(block, seg->_node_num);
504 }
isSourceTerm(dbBlock * mblock)505 bool dbCapNode::isSourceTerm(dbBlock* mblock)
506 {
507 _dbCapNode* seg = (_dbCapNode*) this;
508 dbBlock* block = mblock ? mblock : (dbBlock*) seg->getOwner();
509 dbIoType iotype;
510 if (seg->_flags._iterm) {
511 dbITerm* iterm = dbITerm::getITerm(block, seg->_node_num);
512 iotype = iterm->getIoType();
513 if (iterm->getIoType() == dbIoType::OUTPUT)
514 return true;
515 else
516 return false;
517 } else if (seg->_flags._bterm) {
518 dbBTerm* bterm = dbBTerm::getBTerm(block, seg->_node_num);
519 iotype = bterm->getIoType();
520 if (bterm->getIoType() == dbIoType::INPUT)
521 return true;
522 else
523 return false;
524 }
525 return false;
526 }
isInoutTerm(dbBlock * mblock)527 bool dbCapNode::isInoutTerm(dbBlock* mblock)
528 {
529 _dbCapNode* seg = (_dbCapNode*) this;
530 dbBlock* block = mblock ? mblock : (dbBlock*) seg->getOwner();
531 if (seg->_flags._iterm) {
532 dbITerm* iterm = dbITerm::getITerm(block, seg->_node_num);
533 if (iterm->getIoType() == dbIoType::INOUT)
534 return true;
535 else
536 return false;
537 } else if (seg->_flags._bterm) {
538 dbBTerm* bterm = dbBTerm::getBTerm(block, seg->_node_num);
539 if (bterm->getIoType() == dbIoType::INOUT)
540 return true;
541 else
542 return false;
543 }
544 return false;
545 }
isITerm()546 bool dbCapNode::isITerm()
547 {
548 _dbCapNode* seg = (_dbCapNode*) this;
549 return seg->_flags._iterm > 0 ? true : false;
550 }
isName()551 bool dbCapNode::isName()
552 {
553 _dbCapNode* seg = (_dbCapNode*) this;
554 return seg->_flags._name > 0 ? true : false;
555 }
isBTerm()556 bool dbCapNode::isBTerm()
557 {
558 _dbCapNode* seg = (_dbCapNode*) this;
559 return seg->_flags._bterm > 0 ? true : false;
560 }
561
resetBTermFlag()562 void dbCapNode::resetBTermFlag()
563 {
564 _dbCapNode* seg = (_dbCapNode*) this;
565 _dbBlock* block = (_dbBlock*) seg->getOwner();
566 uint prev_flags = flagsToUInt(seg);
567 seg->_flags._bterm = 0;
568
569 if (block->_journal) {
570 debugPrint(getImpl()->getLogger(),
571 utl::ODB,
572 "DB_ECO",
573 1,
574 "ECO: resetBTermFlag, id: {}",
575 getId());
576 block->_journal->updateField(
577 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
578 }
579 }
resetITermFlag()580 void dbCapNode::resetITermFlag()
581 {
582 _dbCapNode* seg = (_dbCapNode*) this;
583 _dbBlock* block = (_dbBlock*) seg->getOwner();
584 uint prev_flags = flagsToUInt(seg);
585 seg->_flags._iterm = 0;
586
587 if (block->_journal) {
588 debugPrint(getImpl()->getLogger(),
589 utl::ODB,
590 "DB_ECO",
591 1,
592 "ECO: resetITermFlag, id: {}",
593 getId());
594 block->_journal->updateField(
595 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
596 }
597 }
resetNameFlag()598 void dbCapNode::resetNameFlag()
599 {
600 _dbCapNode* seg = (_dbCapNode*) this;
601 _dbBlock* block = (_dbBlock*) seg->getOwner();
602 uint prev_flags = flagsToUInt(seg);
603 seg->_flags._name = 0;
604
605 if (block->_journal) {
606 debugPrint(getImpl()->getLogger(),
607 utl::ODB,
608 "DB_ECO",
609 1,
610 "ECO: resetInternalFlag, id: {}",
611 getId());
612 block->_journal->updateField(
613 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
614 }
615 }
resetInternalFlag()616 void dbCapNode::resetInternalFlag()
617 {
618 _dbCapNode* seg = (_dbCapNode*) this;
619 _dbBlock* block = (_dbBlock*) seg->getOwner();
620 uint prev_flags = flagsToUInt(seg);
621 seg->_flags._internal = 0;
622
623 if (block->_journal) {
624 debugPrint(getImpl()->getLogger(),
625 utl::ODB,
626 "DB_ECO",
627 1,
628 "ECO: resetInternalFlag, id: {}",
629 getId());
630 block->_journal->updateField(
631 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
632 }
633 }
resetBranchFlag()634 void dbCapNode::resetBranchFlag()
635 {
636 _dbCapNode* seg = (_dbCapNode*) this;
637 _dbBlock* block = (_dbBlock*) seg->getOwner();
638 uint prev_flags = flagsToUInt(seg);
639 seg->_flags._branch = 0;
640
641 if (block->_journal) {
642 debugPrint(getImpl()->getLogger(),
643 utl::ODB,
644 "DB_ECO",
645 1,
646 "ECO: resetBranchFlag, id: {}",
647 getId());
648 block->_journal->updateField(
649 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
650 }
651 }
resetForeignFlag()652 void dbCapNode::resetForeignFlag()
653 {
654 _dbCapNode* seg = (_dbCapNode*) this;
655 _dbBlock* block = (_dbBlock*) seg->getOwner();
656 uint prev_flags = flagsToUInt(seg);
657 seg->_flags._foreign = 0;
658
659 if (block->_journal) {
660 debugPrint(getImpl()->getLogger(),
661 utl::ODB,
662 "DB_ECO",
663 1,
664 "ECO: resetForeignFlag, id: {}",
665 getId());
666 block->_journal->updateField(
667 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
668 }
669 }
setBTermFlag()670 void dbCapNode::setBTermFlag()
671 {
672 _dbCapNode* seg = (_dbCapNode*) this;
673 _dbBlock* block = (_dbBlock*) seg->getOwner();
674 uint prev_flags = flagsToUInt(seg);
675 seg->_flags._bterm = 1;
676
677 if (block->_journal) {
678 debugPrint(getImpl()->getLogger(),
679 utl::ODB,
680 "DB_ECO",
681 1,
682 "ECO: setBTermFlag, id: {}",
683 getId());
684 block->_journal->updateField(
685 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
686 }
687 }
setITermFlag()688 void dbCapNode::setITermFlag()
689 {
690 _dbCapNode* seg = (_dbCapNode*) this;
691 _dbBlock* block = (_dbBlock*) seg->getOwner();
692 uint prev_flags = flagsToUInt(seg);
693 seg->_flags._iterm = 1;
694
695 if (block->_journal) {
696 debugPrint(getImpl()->getLogger(),
697 utl::ODB,
698 "DB_ECO",
699 1,
700 "ECO: setITermFlag, id: {}",
701 getId());
702 block->_journal->updateField(
703 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
704 }
705 }
incrChildrenCnt()706 uint dbCapNode::incrChildrenCnt()
707 {
708 _dbCapNode* seg = (_dbCapNode*) this;
709 _dbBlock* block = (_dbBlock*) seg->getOwner();
710 uint prev_flags = flagsToUInt(seg);
711 seg->_flags._childrenCnt++;
712
713 if (block->_journal) {
714 debugPrint(getImpl()->getLogger(),
715 utl::ODB,
716 "DB_ECO",
717 1,
718 "ECO: incrChildrenCnt, id: {}",
719 getId());
720 block->_journal->updateField(
721 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
722 }
723 return seg->_flags._childrenCnt;
724 }
getChildrenCnt()725 uint dbCapNode::getChildrenCnt()
726 {
727 _dbCapNode* seg = (_dbCapNode*) this;
728 return seg->_flags._childrenCnt;
729 }
setChildrenCnt(uint cnt)730 void dbCapNode::setChildrenCnt(uint cnt)
731 {
732 _dbCapNode* seg = (_dbCapNode*) this;
733 seg->_flags._childrenCnt = cnt;
734 }
setBranchFlag()735 void dbCapNode::setBranchFlag()
736 {
737 _dbCapNode* seg = (_dbCapNode*) this;
738 _dbBlock* block = (_dbBlock*) seg->getOwner();
739 uint prev_flags = flagsToUInt(seg);
740 seg->_flags._branch = 1;
741
742 if (block->_journal) {
743 debugPrint(getImpl()->getLogger(),
744 utl::ODB,
745 "DB_ECO",
746 1,
747 "ECO: setBranchFlag, id: {}",
748 getId());
749 block->_journal->updateField(
750 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
751 }
752 }
setNameFlag()753 void dbCapNode::setNameFlag()
754 {
755 _dbCapNode* seg = (_dbCapNode*) this;
756 _dbBlock* block = (_dbBlock*) seg->getOwner();
757 uint prev_flags = flagsToUInt(seg);
758 seg->_flags._name = 1;
759
760 if (block->_journal) {
761 debugPrint(getImpl()->getLogger(),
762 utl::ODB,
763 "DB_ECO",
764 1,
765 "ECO: setInternalFlag, id: {}",
766 getId());
767 block->_journal->updateField(
768 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
769 }
770 }
setInternalFlag()771 void dbCapNode::setInternalFlag()
772 {
773 _dbCapNode* seg = (_dbCapNode*) this;
774 _dbBlock* block = (_dbBlock*) seg->getOwner();
775 uint prev_flags = flagsToUInt(seg);
776 seg->_flags._internal = 1;
777
778 if (block->_journal) {
779 debugPrint(getImpl()->getLogger(),
780 utl::ODB,
781 "DB_ECO",
782 1,
783 "ECO: setInternalFlag, id: {}",
784 getId());
785 block->_journal->updateField(
786 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
787 }
788 }
setForeignFlag()789 void dbCapNode::setForeignFlag()
790 {
791 _dbCapNode* seg = (_dbCapNode*) this;
792 _dbBlock* block = (_dbBlock*) seg->getOwner();
793 uint prev_flags = flagsToUInt(seg);
794 seg->_flags._foreign = 1;
795
796 if (block->_journal) {
797 debugPrint(getImpl()->getLogger(),
798 utl::ODB,
799 "DB_ECO",
800 1,
801 "ECO: setForeignFlag, id: {}",
802 getId());
803 block->_journal->updateField(
804 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
805 }
806 }
setSelect(bool val)807 void dbCapNode::setSelect(bool val)
808 {
809 _dbCapNode* seg = (_dbCapNode*) this;
810 //_dbBlock * block = (_dbBlock *) getOwner();
811 // uint prev_flags = flagsToUInt(seg);
812 seg->_flags._select = val ? 1 : 0;
813
814 #ifdef FULL_ECO
815 if (block->_journal) {
816 debugPrint(getImpl()->getLogger(),
817 utl::ODB,
818 "DB_ECO",
819 1,
820 "ECO: setSelect to {}, id: {}",
821 val,
822 getId());
823 block->_journal->updateField(
824 this, _dbCapNode::FLAGS, prev_flags, flagsToUInt(seg));
825 }
826 #endif
827 }
setNode(uint node)828 void dbCapNode::setNode(uint node)
829 {
830 _dbCapNode* seg = (_dbCapNode*) this;
831 _dbBlock* block = (_dbBlock*) seg->getOwner();
832 uint prev_node = seg->_node_num;
833 seg->_node_num = node;
834
835 if (block->_journal) {
836 debugPrint(getImpl()->getLogger(),
837 utl::ODB,
838 "DB_ECO",
839 1,
840 "ECO: setNode, id: {}, prev_node: {}, new node: {}",
841 getId(),
842 prev_node,
843 node);
844 block->_journal->updateField(this, _dbCapNode::NODE_NUM, prev_node, node);
845 }
846 }
getNode()847 uint dbCapNode::getNode()
848 {
849 _dbCapNode* seg = (_dbCapNode*) this;
850 return seg->_node_num;
851 }
852
getShapeId()853 uint dbCapNode::getShapeId()
854 {
855 _dbCapNode* seg = (_dbCapNode*) this;
856 dbBlock* block = (dbBlock*) seg->getOwner();
857 if (seg->_flags._internal > 0)
858 return seg->_node_num;
859 else if (seg->_flags._iterm > 0) {
860 dbITerm* iterm = dbITerm::getITerm(block, seg->_node_num);
861 if (!iterm->getNet() || !iterm->getNet()->getWire())
862 return 0;
863 return iterm->getNet()->getWire()->getTermJid(iterm->getId());
864 } else {
865 dbBTerm* bterm = dbBTerm::getBTerm(block, seg->_node_num);
866 if (!bterm->getNet() || !bterm->getNet()->getWire())
867 return 0;
868 return bterm->getNet()->getWire()->getTermJid(-bterm->getId());
869 }
870 }
871
setSortIndex(uint idx)872 void dbCapNode::setSortIndex(uint idx)
873 {
874 _dbCapNode* seg = (_dbCapNode*) this;
875 //_dbBlock * block = (_dbBlock *) getOwner();
876 seg->_flags._sort_index = idx;
877 }
878
getSortIndex()879 uint dbCapNode::getSortIndex()
880 {
881 _dbCapNode* seg = (_dbCapNode*) this;
882 //_dbBlock * block = (_dbBlock *) getOwner();
883 return seg->_flags._sort_index;
884 }
885
886 // void
887 // dbCapNode::setCoordY(int y)
888 //{
889 // _dbCapNode * seg = (_dbCapNode *) this;
890 // seg->_ycoord = y;
891 //}
892 //
893 // void
894 // dbCapNode::getCoordY(int & y)
895 //{
896 // _dbCapNode * seg = (_dbCapNode *) this;
897 // y = seg->_ycoord;
898 //}
899
getTermCoords(int & x,int & y,dbBlock * mblock)900 bool dbCapNode::getTermCoords(int& x, int& y, dbBlock* mblock)
901 {
902 _dbCapNode* seg = (_dbCapNode*) this;
903 dbBlock* block = mblock ? mblock : (dbBlock*) seg->getOwner();
904 if (seg->_flags._iterm > 0) {
905 dbITerm* iterm = dbITerm::getITerm(block, seg->_node_num);
906 return (iterm->getAvgXY(&x, &y));
907 } else if (seg->_flags._bterm > 0) {
908 dbBTerm* bterm = dbBTerm::getBTerm(block, seg->_node_num);
909 return (bterm->getFirstPinLocation(x, y));
910 } else
911 return false;
912 return true;
913 }
914
getCCSegs()915 dbSet<dbCCSeg> dbCapNode::getCCSegs()
916 {
917 _dbCapNode* seg = (_dbCapNode*) this;
918 _dbBlock* block = (_dbBlock*) seg->getOwner();
919 return dbSet<dbCCSeg>(seg, block->_cc_seg_itr);
920 }
921
setNext(uint nextid)922 void dbCapNode::setNext(uint nextid)
923 {
924 _dbCapNode* seg = (_dbCapNode*) this;
925 _dbBlock* block = (_dbBlock*) seg->getOwner();
926 uint prev_next = seg->_next;
927 seg->_next = nextid;
928
929 if (block->_journal) {
930 debugPrint(getImpl()->getLogger(),
931 utl::ODB,
932 "DB_ECO",
933 1,
934 "ECO: capNode setNext, id: {}, prev_next: {}, new next: {}",
935 getId(),
936 prev_next,
937 nextid);
938 block->_journal->updateField(this, _dbCapNode::SETNEXT, prev_next, nextid);
939 }
940 }
setNet(uint netid)941 void dbCapNode::setNet(uint netid)
942 {
943 _dbCapNode* seg = (_dbCapNode*) this;
944 _dbBlock* block = (_dbBlock*) seg->getOwner();
945 uint prev_net = seg->_net;
946 seg->_net = netid;
947
948 if (block->_journal) {
949 debugPrint(getImpl()->getLogger(),
950 utl::ODB,
951 "DB_ECO",
952 1,
953 "ECO: setNet, id: {}, prev_net: {}, new net: {}",
954 getId(),
955 prev_net,
956 netid);
957 block->_journal->updateField(this, _dbCapNode::SETNET, prev_net, netid);
958 }
959 }
960 /*
961 * This routine exposes the schema... Use an iterator!
962
963 dbCapNode *
964 dbCapNode::getNext(dbBlock *block_)
965 {
966 _dbCapNode * seg = (_dbCapNode *) this;
967 if (seg->_next==0)
968 return NULL;
969
970 _dbBlock * block = (_dbBlock *) block_;
971 return (dbCapNode *) block->_cap_node_tbl->getPtr( seg->_next );
972 }
973 */
974
create(dbNet * net_,uint node,bool foreign)975 dbCapNode* dbCapNode::create(dbNet* net_, uint node, bool foreign)
976 {
977 _dbNet* net = (_dbNet*) net_;
978 _dbBlock* block = (_dbBlock*) net->getOwner();
979 uint cornerCnt = block->_corners_per_block;
980 _dbCapNode* seg = block->_cap_node_tbl->create();
981
982 if (block->_journal) {
983 debugPrint(block->getImpl()->getLogger(),
984 utl::ODB,
985 "DB_ECO",
986 1,
987 "ECO: dbCapNode::create, net id: {}, node: {}, foreign: {}",
988 net->getId(),
989 node,
990 foreign);
991 block->_journal->beginAction(dbJournal::CREATE_OBJECT);
992 block->_journal->pushParam(dbCapNodeObj);
993 block->_journal->pushParam(net->getId());
994 block->_journal->pushParam(node);
995 block->_journal->pushParam(foreign);
996 block->_journal->endAction();
997 }
998
999 seg->_node_num = node;
1000 // seg->_flags._cnt = block->_num_corners;
1001 seg->_flags._select = 0;
1002 seg->_flags._sort_index = 0;
1003
1004 if (foreign) {
1005 seg->_flags._foreign = 1;
1006 if (block->_maxCapNodeId >= seg->getOID()) {
1007 for (uint ii = 0; ii < cornerCnt; ii++)
1008 (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii] = 0.0;
1009 } else {
1010 block->_maxCapNodeId = seg->getOID();
1011 uint capIdx = block->_c_val_tbl->getIdx(cornerCnt, (float) 0.0);
1012 ZASSERT((seg->getOID() - 1) * cornerCnt + 1 == capIdx);
1013 }
1014 }
1015 seg->_net = net->getOID();
1016 seg->_next = net->_cap_nodes;
1017 net->_cap_nodes = seg->getOID();
1018
1019 return (dbCapNode*) seg;
1020 }
addToNet()1021 void dbCapNode::addToNet()
1022 {
1023 _dbCapNode* seg = (_dbCapNode*) this;
1024 _dbBlock* block = (_dbBlock*) seg->getOwner();
1025 _dbNet* net = (_dbNet*) dbNet::getNet((dbBlock*) block, seg->_net);
1026
1027 seg->_next = net->_cap_nodes;
1028 net->_cap_nodes = seg->getOID();
1029 }
1030
destroy(dbCapNode * seg_,bool destroyCC)1031 void dbCapNode::destroy(dbCapNode* seg_, bool destroyCC)
1032 {
1033 _dbCapNode* seg = (_dbCapNode*) seg_;
1034 _dbBlock* block = (_dbBlock*) seg->getOwner();
1035 _dbNet* net = (_dbNet*) seg_->getNet();
1036
1037 for (uint sid = seg->_cc_segs; destroyCC && sid; sid = seg->_cc_segs) {
1038 _dbCCSeg* s = block->_cc_seg_tbl->getPtr(sid);
1039 dbCCSeg::destroy((dbCCSeg*) s);
1040 }
1041
1042 // unlink the cap-node from the net cap-node list
1043 dbId<_dbCapNode> c = net->_cap_nodes;
1044 _dbCapNode* p = NULL;
1045
1046 while (c != 0) {
1047 _dbCapNode* s = block->_cap_node_tbl->getPtr(c);
1048
1049 if (s == seg) {
1050 if (p == NULL)
1051 net->_cap_nodes = s->_next;
1052 else
1053 p->_next = s->_next;
1054 break;
1055 }
1056 p = s;
1057 c = s->_next;
1058 }
1059
1060 if (block->_journal) {
1061 debugPrint(net->getImpl()->getLogger(),
1062 utl::ODB,
1063 "DB_ECO",
1064 1,
1065 "ECO: dbCapNode::destroy, seg id: {}, net id: {}",
1066 seg->getId(),
1067 net->getId());
1068 block->_journal->beginAction(dbJournal::DELETE_OBJECT);
1069 block->_journal->pushParam(dbCapNodeObj);
1070 block->_journal->pushParam(seg->getId());
1071 block->_journal->endAction();
1072 }
1073
1074 dbProperty::destroyProperties(seg);
1075 block->_cap_node_tbl->destroy(seg);
1076 }
1077
destroy(dbSet<dbCapNode>::iterator & itr)1078 dbSet<dbCapNode>::iterator dbCapNode::destroy(dbSet<dbCapNode>::iterator& itr)
1079 {
1080 dbCapNode* bt = *itr;
1081 dbSet<dbCapNode>::iterator next = ++itr;
1082 destroy(bt);
1083 return next;
1084 }
getNet()1085 dbNet* dbCapNode::getNet()
1086 {
1087 _dbCapNode* seg = (_dbCapNode*) this;
1088 _dbBlock* block = (_dbBlock*) seg->getOwner();
1089 return dbNet::getNet((dbBlock*) block, seg->_net);
1090 }
1091
printCC()1092 void dbCapNode::printCC()
1093 {
1094 _dbCapNode* node = (_dbCapNode*) this;
1095 dbBlock* block = (dbBlock*) node->getOwner();
1096 uint ccn = node->_cc_segs;
1097 if (ccn == 0)
1098 return;
1099 dbCCSeg* ccs = dbCCSeg::getCCSeg(block, ccn);
1100 getImpl()->getLogger()->info(utl::ODB, 25, " capn {}", getId());
1101 ccs->printCapnCC(getId());
1102 }
1103
checkCC()1104 bool dbCapNode::checkCC()
1105 {
1106 _dbCapNode* node = (_dbCapNode*) this;
1107 dbBlock* block = (dbBlock*) node->getOwner();
1108 uint ccn = node->_cc_segs;
1109 if (ccn == 0)
1110 return true;
1111 dbCCSeg* ccs = dbCCSeg::getCCSeg(block, ccn);
1112 uint rc = ccs->checkCapnCC(getId());
1113 return rc;
1114 }
1115
getCapNode(dbBlock * block_,uint dbid_)1116 dbCapNode* dbCapNode::getCapNode(dbBlock* block_, uint dbid_)
1117 {
1118 _dbBlock* block = (_dbBlock*) block_;
1119 return (dbCapNode*) block->_cap_node_tbl->getPtr(dbid_);
1120 }
1121 } // namespace odb
1122