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