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 "dbRSeg.h"
34 
35 #include "db.h"
36 #include "dbBlock.h"
37 #include "dbCapNode.h"
38 #include "dbCommon.h"
39 #include "dbDatabase.h"
40 #include "dbJournal.h"
41 #include "dbNet.h"
42 #include "dbShape.h"
43 #include "dbTable.h"
44 #include "dbTable.hpp"
45 #include "utl/Logger.h"
46 
47 namespace odb {
48 
49 template class dbTable<_dbRSeg>;
50 
operator ==(const _dbRSeg & rhs) const51 bool _dbRSeg::operator==(const _dbRSeg& rhs) const
52 {
53   if (_flags._path_dir != rhs._flags._path_dir)
54     return false;
55 
56   if (_flags._allocated_cap != rhs._flags._allocated_cap)
57     return false;
58 
59   if (_source != rhs._source)
60     return false;
61 
62   if (_target != rhs._target)
63     return false;
64 
65   if (_xcoord != rhs._xcoord)
66     return false;
67 
68   if (_ycoord != rhs._ycoord)
69     return false;
70 
71   if (_next != rhs._next)
72     return false;
73 
74   return true;
75 }
76 
differences(dbDiff & diff,const char * field,const _dbRSeg & rhs) const77 void _dbRSeg::differences(dbDiff& diff,
78                           const char* field,
79                           const _dbRSeg& rhs) const
80 {
81   DIFF_BEGIN
82   DIFF_FIELD(_flags._path_dir);
83   DIFF_FIELD(_flags._allocated_cap);
84   DIFF_FIELD(_source);
85   DIFF_FIELD(_target);
86   DIFF_FIELD(_xcoord);
87   DIFF_FIELD(_ycoord);
88   DIFF_FIELD(_next);
89   DIFF_END
90 }
91 
out(dbDiff & diff,char side,const char * field) const92 void _dbRSeg::out(dbDiff& diff, char side, const char* field) const
93 {
94   DIFF_OUT_BEGIN
95   DIFF_OUT_FIELD(_flags._path_dir);
96   DIFF_OUT_FIELD(_flags._allocated_cap);
97   DIFF_OUT_FIELD(_source);
98   DIFF_OUT_FIELD(_target);
99   DIFF_OUT_FIELD(_xcoord);
100   DIFF_OUT_FIELD(_ycoord);
101   DIFF_OUT_FIELD(_next);
102   DIFF_END
103 }
104 
105 ////////////////////////////////////////////////////////////////////
106 //
107 // dbRSeg - Methods
108 //
109 ////////////////////////////////////////////////////////////////////
110 
getResistance(int corner)111 double dbRSeg::getResistance(int corner)
112 {
113   _dbRSeg* seg = (_dbRSeg*) this;
114   _dbBlock* block = (_dbBlock*) seg->getOwner();
115   uint cornerCnt = block->_corners_per_block;
116 
117   ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
118   return (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
119 }
120 
getAllRes(double * res)121 void dbRSeg::getAllRes(double* res)
122 {
123   _dbRSeg* seg = (_dbRSeg*) this;
124   _dbBlock* block = (_dbBlock*) seg->getOwner();
125   uint cornerCnt = block->_corners_per_block;
126 
127   for (uint ii = 0; ii < cornerCnt; ii++)
128     res[ii] = (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
129 }
130 
addAllRes(double * res)131 void dbRSeg::addAllRes(double* res)
132 {
133   _dbRSeg* seg = (_dbRSeg*) this;
134   _dbBlock* block = (_dbBlock*) seg->getOwner();
135   uint cornerCnt = block->_corners_per_block;
136 
137   for (uint ii = 0; ii < cornerCnt; ii++)
138     res[ii] += (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
139 }
140 
updatedCap()141 bool dbRSeg::updatedCap()
142 {
143   _dbRSeg* seg = (_dbRSeg*) this;
144   return (seg->_flags._update_cap == 1 ? true : false);
145 }
allocatedCap()146 bool dbRSeg::allocatedCap()
147 {
148   _dbRSeg* seg = (_dbRSeg*) this;
149   return (seg->_flags._allocated_cap == 1 ? true : false);
150 }
151 
pathLowToHigh()152 bool dbRSeg::pathLowToHigh()
153 {
154   _dbRSeg* seg = (_dbRSeg*) this;
155   return (seg->_flags._path_dir == 0 ? true : false);
156 }
157 
addRSegCapacitance(dbRSeg * other)158 void dbRSeg::addRSegCapacitance(dbRSeg* other)
159 {
160   _dbRSeg* seg = (_dbRSeg*) this;
161   if (!seg->_flags._allocated_cap) {
162     getTargetCapNode()->addCapnCapacitance(other->getTargetCapNode());
163     return;
164   }
165   _dbRSeg* oseg = (_dbRSeg*) other;
166   _dbBlock* block = (_dbBlock*) seg->getOwner();
167   uint cornerCnt = ((dbBlock*) block)->getCornerCount();
168 
169   for (uint corner = 0; corner < cornerCnt; corner++) {
170     float& value
171         = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
172     float& ovalue
173         = (*block->_c_val_tbl)[(oseg->getOID() - 1) * cornerCnt + 1 + corner];
174     value += ovalue;
175   }
176 
177   if (block->_journal) {
178     debugPrint(getImpl()->getLogger(),
179                utl::ODB,
180                "DB_ECO",
181                1,
182                "ECO: dbRSeg {}, other dbRSeg {}, addRSegCapacitance",
183                seg->getId(),
184                oseg->getId());
185     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
186     block->_journal->pushParam(dbRSegObj);
187     block->_journal->pushParam(seg->getId());
188     block->_journal->pushParam(_dbRSeg::ADDRSEGCAPACITANCE);
189     block->_journal->pushParam(oseg->getId());
190     block->_journal->endAction();
191   }
192 }
193 
addRSegResistance(dbRSeg * other)194 void dbRSeg::addRSegResistance(dbRSeg* other)
195 {
196   _dbRSeg* seg = (_dbRSeg*) this;
197   _dbRSeg* oseg = (_dbRSeg*) other;
198   _dbBlock* block = (_dbBlock*) seg->getOwner();
199   uint cornerCnt = block->_corners_per_block;
200 
201   for (uint corner = 0; corner < cornerCnt; corner++) {
202     float& value
203         = (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
204     float& ovalue
205         = (*block->_r_val_tbl)[(oseg->getOID() - 1) * cornerCnt + 1 + corner];
206     value += ovalue;
207   }
208 
209   if (block->_journal) {
210     debugPrint(getImpl()->getLogger(),
211                utl::ODB,
212                "DB_ECO",
213                1,
214                "ECO: dbRSeg {}, other dbRSeg {}, addRSegResistance",
215                seg->getId(),
216                oseg->getId());
217     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
218     block->_journal->pushParam(dbRSegObj);
219     block->_journal->pushParam(seg->getId());
220     block->_journal->pushParam(_dbRSeg::ADDRSEGRESISTANCE);
221     block->_journal->pushParam(oseg->getId());
222     block->_journal->endAction();
223   }
224 }
225 
setResistance(double res,int corner)226 void dbRSeg::setResistance(double res, int corner)
227 {
228   _dbRSeg* seg = (_dbRSeg*) this;
229   _dbBlock* block = (_dbBlock*) seg->getOwner();
230   uint cornerCnt = block->_corners_per_block;
231   ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
232 
233   float& value
234       = (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
235   float prev_value = value;
236   value = (float) res;
237 
238   if (block->_journal) {
239     debugPrint(getImpl()->getLogger(),
240                utl::ODB,
241                "DB_ECO",
242                1,
243                "ECO: dbRSeg {}, setResistance {}, corner {}",
244                seg->getId(),
245                res,
246                corner);
247     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
248     block->_journal->pushParam(dbRSegObj);
249     block->_journal->pushParam(seg->getId());
250     block->_journal->pushParam(_dbRSeg::RESISTANCE);
251     block->_journal->pushParam(prev_value);
252     block->_journal->pushParam(value);
253     block->_journal->pushParam(corner);
254     block->_journal->endAction();
255   }
256 }
257 
adjustResistance(float factor,int corner)258 void dbRSeg::adjustResistance(float factor, int corner)
259 {
260   _dbRSeg* seg = (_dbRSeg*) this;
261   _dbBlock* block = (_dbBlock*) seg->getOwner();
262   uint cornerCnt = block->_corners_per_block;
263   ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
264 
265   float& value
266       = (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
267   float prev_value = value;
268   value *= factor;
269 
270   if (block->_journal) {
271     debugPrint(getImpl()->getLogger(),
272                utl::ODB,
273                "DB_ECO",
274                1,
275                "ECO: dbRSeg {}, adjustResistance {}, corner {}",
276                seg->getId(),
277                factor,
278                corner);
279     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
280     block->_journal->pushParam(dbRSegObj);
281     block->_journal->pushParam(seg->getId());
282     block->_journal->pushParam(_dbRSeg::RESISTANCE);
283     block->_journal->pushParam(prev_value);
284     block->_journal->pushParam(value);
285     block->_journal->pushParam(corner);
286     block->_journal->endAction();
287   }
288 }
289 
adjustResistance(float factor)290 void dbRSeg::adjustResistance(float factor)
291 {
292   _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
293   uint cornerCnt = block->_corners_per_block;
294   uint corner;
295   for (corner = 0; corner < cornerCnt; corner++)
296     adjustResistance(factor, corner);
297 }
298 
setCapacitance(double cap,int corner)299 void dbRSeg::setCapacitance(double cap, int corner)
300 {
301   _dbRSeg* seg = (_dbRSeg*) this;
302   _dbBlock* block = (_dbBlock*) seg->getOwner();
303   uint cornerCnt = block->_corners_per_block;
304 
305   if (!seg->_flags._allocated_cap) {
306     fprintf(stdout, "WARNING: cap value storage is not allocated\n");
307     return;
308   }
309   seg->_flags._update_cap = 1;
310   if (cap == 0.0)
311     seg->_flags._update_cap = 0;
312 
313   ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
314   float& value
315       = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
316   float prev_value = value;
317   value = (float) cap;
318 
319   if (block->_journal) {
320     debugPrint(getImpl()->getLogger(),
321                utl::ODB,
322                "DB_ECO",
323                1,
324                "ECO: dbRSeg {}, setCapacitance {}, corner {}",
325                seg->getId(),
326                cap,
327                corner);
328     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
329     block->_journal->pushParam(dbRSegObj);
330     block->_journal->pushParam(seg->getId());
331     block->_journal->pushParam(_dbRSeg::CAPACITANCE);
332     block->_journal->pushParam(prev_value);
333     block->_journal->pushParam(value);
334     block->_journal->pushParam(corner);
335     block->_journal->endAction();
336   }
337 }
338 
adjustSourceCapacitance(float factor,uint corner)339 void dbRSeg::adjustSourceCapacitance(float factor, uint corner)
340 {
341   _dbRSeg* seg = (_dbRSeg*) this;
342   _dbBlock* block = (_dbBlock*) seg->getOwner();
343 
344   if (seg->_flags._allocated_cap != 0)
345     return;
346   dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_source);
347   node->adjustCapacitance(factor, corner);
348 }
349 
adjustCapacitance(float factor,uint corner)350 void dbRSeg::adjustCapacitance(float factor, uint corner)
351 {
352   _dbRSeg* seg = (_dbRSeg*) this;
353   _dbBlock* block = (_dbBlock*) seg->getOwner();
354   uint cornerCnt = block->_corners_per_block;
355 
356   if (seg->_flags._allocated_cap == 0) {
357     _dbBlock* block = (_dbBlock*) seg->getOwner();
358     dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
359     node->adjustCapacitance(factor, corner);
360   } else {
361     float& value
362         = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
363     float prev_value = value;
364     value *= factor;
365 
366     if (block->_journal) {
367       debugPrint(getImpl()->getLogger(),
368                  utl::ODB,
369                  "DB_ECO",
370                  1,
371                  "ECO: dbRSeg {}, adjustCapacitance {}, corner {}",
372                  seg->getId(),
373                  value,
374                  0);
375       block->_journal->beginAction(dbJournal::UPDATE_FIELD);
376       block->_journal->pushParam(dbRSegObj);
377       block->_journal->pushParam(seg->getId());
378       block->_journal->pushParam(_dbRSeg::CAPACITANCE);
379       block->_journal->pushParam(prev_value);
380       block->_journal->pushParam(value);
381       block->_journal->pushParam(0);
382       block->_journal->endAction();
383     }
384   }
385 }
386 
adjustCapacitance(float factor)387 void dbRSeg::adjustCapacitance(float factor)
388 {
389   _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
390   uint cornerCnt = block->_corners_per_block;
391   uint corner;
392   for (corner = 0; corner < cornerCnt; corner++)
393     adjustCapacitance(factor, corner);
394 }
395 
getCapacitance(int corner)396 double dbRSeg::getCapacitance(int corner)
397 {
398   _dbRSeg* seg = (_dbRSeg*) this;
399   _dbBlock* block = (_dbBlock*) seg->getOwner();
400   uint cornerCnt = block->_corners_per_block;
401 
402   if (seg->_flags._allocated_cap == 0) {
403     _dbBlock* block = (_dbBlock*) seg->getOwner();
404     dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
405     return node->getCapacitance(corner);
406   } else {
407     ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
408     return (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
409   }
410 }
411 
getGndCap(double * gndcap,double * totalcap)412 void dbRSeg::getGndCap(double* gndcap, double* totalcap)
413 {
414   _dbRSeg* seg = (_dbRSeg*) this;
415   _dbBlock* block = (_dbBlock*) seg->getOwner();
416   uint cornerCnt = block->_corners_per_block;
417   double gcap;
418   if (seg->_flags._allocated_cap == 0) {
419     dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
420     node->getGndCap(gndcap, totalcap);
421   } else {
422     for (uint ii = 0; ii < cornerCnt; ii++) {
423       gcap = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
424       if (gndcap)
425         gndcap[ii] = gcap;
426       if (totalcap)
427         totalcap[ii] = gcap;
428     }
429   }
430 }
431 
addGndCap(double * gndcap,double * totalcap)432 void dbRSeg::addGndCap(double* gndcap, double* totalcap)
433 {
434   _dbRSeg* seg = (_dbRSeg*) this;
435   _dbBlock* block = (_dbBlock*) seg->getOwner();
436   uint cornerCnt = block->_corners_per_block;
437   double gcap;
438   if (seg->_flags._allocated_cap == 0) {
439     dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
440     node->addGndCap(gndcap, totalcap);
441   } else {
442     for (uint ii = 0; ii < cornerCnt; ii++) {
443       gcap = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
444       if (gndcap)
445         gndcap[ii] += gcap;
446       if (totalcap)
447         totalcap[ii] += gcap;
448     }
449   }
450 }
451 
getSourceCapacitance(int corner)452 double dbRSeg::getSourceCapacitance(int corner)
453 {
454   //_dbBlock * block = (_dbBlock *) getOwner();
455 
456   _dbRSeg* seg = (_dbRSeg*) this;
457 
458   if (seg->_flags._allocated_cap == 0) {
459     _dbBlock* block = (_dbBlock*) seg->getOwner();
460     dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_source);
461     return node->getCapacitance(corner);
462   } else {
463     return 0.0;
464   }
465 }
466 
getTargetCapNode()467 dbCapNode* dbRSeg::getTargetCapNode()
468 {
469   _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
470   uint target = getTargetNode();
471 
472   if (target == 0)
473     return NULL;
474 
475   _dbCapNode* n = block->_cap_node_tbl->getPtr(target);
476   return (dbCapNode*) n;
477 }
478 
getSourceCapNode()479 dbCapNode* dbRSeg::getSourceCapNode()
480 {
481   _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
482   uint source = getSourceNode();
483 
484   if (source == 0)
485     return NULL;
486 
487   _dbCapNode* n = block->_cap_node_tbl->getPtr(source);
488   return (dbCapNode*) n;
489 }
490 
getCapacitance(int corner,double MillerMult)491 double dbRSeg::getCapacitance(int corner, double MillerMult)
492 {
493   double cap = getCapacitance(corner);
494   double ccCap = 0.0;
495 
496   dbCapNode* targetCapNode = getTargetCapNode();
497 
498   if (targetCapNode == NULL)
499     return cap;
500 
501   dbSet<dbCCSeg> ccSegs = targetCapNode->getCCSegs();
502   dbSet<dbCCSeg>::iterator ccitr;
503   for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
504     dbCCSeg* cc = *ccitr;
505     ccCap += cc->getCapacitance(corner);
506   }
507 
508   cap += MillerMult * ccCap;
509   return cap;
510 }
511 
getGndTotalCap(double * gndcap,double * totalcap,double MillerMult)512 void dbRSeg::getGndTotalCap(double* gndcap, double* totalcap, double MillerMult)
513 {
514   getGndCap(gndcap, totalcap);
515   getTargetCapNode()->accAllCcCap(totalcap, MillerMult);
516 }
517 
addGndTotalCap(double * gndcap,double * totalcap,double MillerMult)518 void dbRSeg::addGndTotalCap(double* gndcap, double* totalcap, double MillerMult)
519 {
520   addGndCap(gndcap, totalcap);
521   getTargetCapNode()->accAllCcCap(totalcap, MillerMult);
522 }
523 
getCcSegs(std::vector<dbCCSeg * > & ccsegs)524 void dbRSeg::getCcSegs(std::vector<dbCCSeg*>& ccsegs)
525 {
526   ccsegs.clear();
527 
528   dbSet<dbCapNode> capNodes = getNet()->getCapNodes();
529   dbSet<dbCapNode>::iterator citr;
530 
531   uint target = getTargetNode();
532 
533   for (citr = capNodes.begin(); citr != capNodes.end(); ++citr) {
534     dbCapNode* n = *citr;
535     dbSet<dbCCSeg> ccSegs = n->getCCSegs();
536     dbSet<dbCCSeg>::iterator ccitr;
537 
538     if (n->getNode() == target) {
539       for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
540         dbCCSeg* cc = *ccitr;
541         ccsegs.push_back(cc);
542       }
543 
544       break;
545     }
546   }
547 }
548 
printCcSegs()549 void dbRSeg::printCcSegs()
550 {
551   std::vector<dbCCSeg*> ccsegs;
552   getCcSegs(ccsegs);
553   getImpl()->getLogger()->info(
554       utl::ODB, 54, "CC segs of RSeg {}-{}", getSourceNode(), getTargetNode());
555 #if 0
556     uint j;
557     dbCCSeg *seg;
558     for (j=0;j<ccsegs.size();j++)
559     {
560         seg = ccsegs[j];
561         getImpl()->getLogger()->info(utl::ODB, 55, "           CC{} : {}-{}", j, seg->getSourceNode(), seg->getTargetNode());
562     }
563 #endif
564 }
565 
printCC()566 void dbRSeg::printCC()
567 {
568   getImpl()->getLogger()->info(utl::ODB, 56, "rseg {}", getId());
569   getTargetCapNode()->printCC();
570 }
571 
checkCC()572 bool dbRSeg::checkCC()
573 {
574   bool rc = getTargetCapNode()->checkCC();
575   return rc;
576 }
577 
getCapTable(double * cap)578 void dbRSeg::getCapTable(double* cap)
579 {
580   _dbRSeg* seg = (_dbRSeg*) this;
581   _dbBlock* block = (_dbBlock*) seg->getOwner();
582   uint cornerCnt = block->_corners_per_block;
583 
584   if (seg->_flags._allocated_cap == 0) {
585     _dbBlock* block = (_dbBlock*) seg->getOwner();
586     dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
587     node->getCapTable(cap);
588   } else {
589     for (uint ii = 0; ii < cornerCnt; ii++)
590       cap[ii] = (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
591   }
592 }
593 
getSourceNode()594 uint dbRSeg::getSourceNode()
595 {
596   _dbRSeg* seg = (_dbRSeg*) this;
597   return seg->_source;
598 }
599 
setNext(uint rid)600 void dbRSeg::setNext(uint rid)
601 {
602   _dbRSeg* seg = (_dbRSeg*) this;
603   seg->_next = rid;
604 }
605 
setSourceNode(uint source_node)606 void dbRSeg::setSourceNode(uint source_node)
607 {
608   _dbRSeg* seg = (_dbRSeg*) this;
609   _dbBlock* block = (_dbBlock*) seg->getOwner();
610 
611   if (block->_journal) {
612     debugPrint(getImpl()->getLogger(),
613                utl::ODB,
614                "DB_ECO",
615                1,
616                "ECO: dbRSeg {}, setSourceNode {}",
617                seg->getId(),
618                source_node);
619     block->_journal->updateField(
620         this, _dbRSeg::SOURCE, seg->_source, source_node);
621   }
622 
623   seg->_source = source_node;
624 }
625 
setTargetNode(uint target_node)626 void dbRSeg::setTargetNode(uint target_node)
627 {
628   _dbRSeg* seg = (_dbRSeg*) this;
629   _dbBlock* block = (_dbBlock*) seg->getOwner();
630 
631   if (block->_journal) {
632     debugPrint(getImpl()->getLogger(),
633                utl::ODB,
634                "DB_ECO",
635                1,
636                "ECO: dbRSeg {}, setTargetNode {}",
637                seg->getId(),
638                target_node);
639     block->_journal->updateField(
640         this, _dbRSeg::TARGET, seg->_target, target_node);
641   }
642 
643   seg->_target = target_node;
644 }
645 
getTargetNode()646 uint dbRSeg::getTargetNode()
647 {
648   _dbRSeg* seg = (_dbRSeg*) this;
649   return seg->_target;
650 }
651 
getShapeId()652 uint dbRSeg::getShapeId()
653 {
654   _dbRSeg* seg = (_dbRSeg*) this;
655   dbBlock* block = (dbBlock*) seg->getOwner();
656   dbCapNode* node = dbCapNode::getCapNode(block, seg->_target);
657   return node->getShapeId();
658 }
659 
setCoords(int x,int y)660 void dbRSeg::setCoords(int x, int y)
661 {
662   _dbRSeg* seg = (_dbRSeg*) this;
663   int prev_x = seg->_xcoord;
664   int prev_y = seg->_ycoord;
665   seg->_xcoord = x;
666   seg->_ycoord = y;
667   _dbBlock* block = (_dbBlock*) seg->getOwner();
668   if (block->_journal) {
669     debugPrint(getImpl()->getLogger(),
670                utl::ODB,
671                "DB_ECO",
672                1,
673                "ECO: dbRSeg {}, setCoords {} {}",
674                seg->getId(),
675                x,
676                y);
677     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
678     block->_journal->pushParam(dbRSegObj);
679     block->_journal->pushParam(seg->getId());
680     block->_journal->pushParam(_dbRSeg::COORDINATES);
681     block->_journal->pushParam(prev_x);
682     block->_journal->pushParam(x);
683     block->_journal->pushParam(prev_y);
684     block->_journal->pushParam(y);
685     block->_journal->endAction();
686   }
687 }
688 
getCoords(int & x,int & y)689 void dbRSeg::getCoords(int& x, int& y)
690 {
691   _dbRSeg* seg = (_dbRSeg*) this;
692   // dbBlock * block = (dbBlock *) getOwner();
693   //    dbCapNode *node= dbCapNode::getCapNode(block, seg->_target);
694   //    if (node->getTermCoords(x, y))
695   //        return;
696   x = seg->_xcoord;
697   y = seg->_ycoord;
698   // node->getCoordY(y);
699 }
700 
getLengthWidth(uint & w)701 uint dbRSeg::getLengthWidth(uint& w)
702 {
703   dbShape s;
704   dbWire* wire = getNet()->getWire();
705   wire->getShape(getShapeId(), s);
706 
707   w = MIN(s.getDX(), s.getDY());
708 
709   return MAX(s.getDX(), s.getDY());
710 }
711 
getNet()712 dbNet* dbRSeg::getNet()
713 {
714   _dbRSeg* seg = (_dbRSeg*) this;
715   _dbBlock* block = (_dbBlock*) seg->getOwner();
716   dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
717   return node->getNet();
718 }
719 
updateShapeId(uint nsid)720 void dbRSeg::updateShapeId(uint nsid)
721 {
722   _dbRSeg* seg = (_dbRSeg*) this;
723   _dbBlock* block = (_dbBlock*) seg->getOwner();
724   dbCapNode* node = dbCapNode::getCapNode((dbBlock*) block, seg->_target);
725   if (node->isITerm() || node->isBTerm())
726     return;
727   node->setNode(nsid);
728 }
729 
create(dbNet * net_,int x,int y,uint path_dir,bool allocate_cap)730 dbRSeg* dbRSeg::create(dbNet* net_,
731                        int x,
732                        int y,
733                        uint path_dir,
734                        bool allocate_cap)
735 {
736   _dbNet* net = (_dbNet*) net_;
737   _dbBlock* block = (_dbBlock*) net->getOwner();
738   uint cornerCnt = block->_corners_per_block;
739 
740   if (block->_journal) {
741     debugPrint(net_->getImpl()->getLogger(),
742                utl::ODB,
743                "DB_ECO",
744                1,
745                "ECO: dbRSeg create 2, net id {}, x: {}, y: {}, path_dir: {}, "
746                "allocate_cap: {}",
747                net->getId(),
748                x,
749                y,
750                path_dir,
751                allocate_cap);
752     block->_journal->beginAction(dbJournal::CREATE_OBJECT);
753     block->_journal->pushParam(dbRSegObj);
754     block->_journal->pushParam(net->getId());
755     block->_journal->pushParam(x);
756     block->_journal->pushParam(y);
757     block->_journal->pushParam(path_dir);
758     block->_journal->pushParam(allocate_cap);
759     block->_journal->endAction();
760   }
761 
762   _dbRSeg* seg = block->_r_seg_tbl->create();
763   uint valueMem = 0;
764 
765   if (block->_maxRSegId >= seg->getOID())
766     valueMem = 1;
767   else
768     block->_maxRSegId = seg->getOID();
769 
770   seg->_xcoord = x;
771   seg->_ycoord = y;
772 
773   seg->_flags._path_dir = path_dir;
774   // seg->_flags._cnt = block->_num_corners;
775 
776   if (valueMem) {
777     for (uint ii = 0; ii < cornerCnt; ii++)
778       (*block->_r_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii] = 0.0;
779   } else {
780     uint resIdx = block->_r_val_tbl->getIdx(cornerCnt, (float) 0.0);
781     ZASSERT((seg->getOID() - 1) * cornerCnt + 1 == resIdx);
782   }
783 
784   // seg->_resIdx= block->_r_val_tbl->size();
785   // int i;
786   // for( i = 0; i < seg->_flags._cnt; ++i )
787   //{
788   // block->_r_val_tbl->push_back(0.0);
789   //}
790 
791   if (allocate_cap) {
792     seg->_flags._allocated_cap = 1;
793 
794     if (valueMem) {
795       for (uint ii = 0; ii < cornerCnt; ii++)
796         (*block->_c_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii] = 0.0;
797     } else {
798       uint capIdx = block->_c_val_tbl->getIdx(cornerCnt, (float) 0.0);
799       ZASSERT((seg->getOID() - 1) * cornerCnt + 1 == capIdx);
800     }
801 
802     // seg->_capIdx= block->_c_val_tbl->size();
803     // for( i = 0; i < seg->_flags._cnt; ++i )
804     //{
805     // block->_c_val_tbl->push_back(0.0);
806     //}
807   }
808 
809   /* OPT-MEM
810   //    seg->_res = (float *) malloc(sizeof(float)*seg->_flags._cnt);
811   //    ZALLOCATED(seg->_res);
812   //
813   //    int i;
814   //
815   //    for( i = 0; i < seg->_flags._cnt; ++i )
816   //    {
817   //        seg->_res[i] = 0.0;
818   //    }
819   //
820   //    seg->_cap= NULL;
821   //    if (allocate_cap)
822   //    {
823   //        seg->_flags._allocated_cap= 1;
824   //        seg->_cap = (float *) malloc( sizeof(float) * seg->_flags._cnt );
825   //        ZALLOCATED( seg->_cap );
826   //
827   //        int i;
828   //        for( i = 0; i < seg->_flags._cnt; ++i )
829   //        {
830   //            seg->_cap[i] = 0.0;
831   //        }
832   //    }
833   */
834   // seg->_net = net->getOID();
835   seg->_next = net->_r_segs;
836   net->_r_segs = seg->getOID();
837   return (dbRSeg*) seg;
838 }
addToNet()839 bool dbRSeg::addToNet()
840 {
841   dbCapNode* cap_node = getTargetCapNode();
842   if (cap_node == NULL) {
843     cap_node = getSourceCapNode();
844     if (cap_node == NULL) {
845       getImpl()->getLogger()->warn(
846           utl::ODB, 57, "Cannot find cap nodes for Rseg {}", this->getId());
847       return false;
848     }
849   }
850 
851   _dbCapNode* seg = (_dbCapNode*) cap_node;
852   _dbBlock* block = (_dbBlock*) seg->getOwner();
853   _dbNet* net = (_dbNet*) dbNet::getNet((dbBlock*) block, seg->_net);
854 
855   _dbRSeg* rseg = (_dbRSeg*) this;
856   rseg->_next = net->_r_segs;
857   net->_r_segs = rseg->getOID();
858 
859   return true;
860 }
861 
destroy(dbRSeg * seg_,dbNet * net_)862 void dbRSeg::destroy(dbRSeg* seg_, dbNet* net_)
863 {
864   _dbRSeg* seg = (_dbRSeg*) seg_;
865   _dbNet* net = (_dbNet*) net_;
866   _dbBlock* block = (_dbBlock*) seg->getOwner();
867 
868   if (block->_journal) {
869     debugPrint(net_->getImpl()->getLogger(),
870                utl::ODB,
871                "DB_ECO",
872                1,
873                "ECO: dbRSeg destroy seg {}, net {} ({})",
874                seg->getId(),
875                net->getId(),
876                block->_journal->size());
877     block->_journal->beginAction(dbJournal::DELETE_OBJECT);
878     block->_journal->pushParam(dbRSegObj);
879     block->_journal->pushParam(seg->getId());
880     block->_journal->pushParam(net->getId());
881     block->_journal->endAction();
882     debugPrint(net_->getImpl()->getLogger(),
883                utl::ODB,
884                "DB_ECO",
885                1,
886                "ECO: dbRSeg destroyed seg {}, net {} ({}) ({} {})",
887                seg->getId(),
888                net->getId(),
889                block->_journal->size(),
890                (void*) block,
891                (void*) block->_journal);
892   }
893 
894   dbId<_dbRSeg> c = net->_r_segs;
895   _dbRSeg* p = NULL;
896 
897   while (c != 0) {
898     _dbRSeg* s = block->_r_seg_tbl->getPtr(c);
899 
900     if (s == seg) {
901       if (p == NULL)
902         net->_r_segs = s->_next;
903       else
904         p->_next = s->_next;
905       break;
906     }
907     p = s;
908     c = s->_next;
909   }
910 
911   dbProperty::destroyProperties(seg);
912   block->_r_seg_tbl->destroy(seg);
913 }
914 
destroyS(dbRSeg * seg_)915 void dbRSeg::destroyS(dbRSeg* seg_)
916 {
917   _dbRSeg* seg = (_dbRSeg*) seg_;
918   _dbBlock* block = (_dbBlock*) seg->getOwner();
919 
920   if (block->_journal) {
921     debugPrint(seg_->getImpl()->getLogger(),
922                utl::ODB,
923                "DB_ECO",
924                1,
925                "ECO: dbRSeg simple destroy seg {}",
926                seg->getId());
927     block->_journal->beginAction(dbJournal::DELETE_OBJECT);
928     block->_journal->pushParam(dbRSegObj);
929     block->_journal->pushParam(seg->getId());
930     block->_journal->pushParam((uint) 0);
931     block->_journal->endAction();
932   }
933   dbProperty::destroyProperties(seg);
934   block->_r_seg_tbl->destroy(seg);
935 }
936 
destroy(dbRSeg * seg_)937 void dbRSeg::destroy(dbRSeg* seg_)
938 {
939   dbRSeg::destroy(seg_, seg_->getNet());
940 }
941 
destroy(dbSet<dbRSeg>::iterator & itr)942 dbSet<dbRSeg>::iterator dbRSeg::destroy(dbSet<dbRSeg>::iterator& itr)
943 {
944   dbRSeg* bt = *itr;
945   dbSet<dbRSeg>::iterator next = ++itr;
946   destroy(bt);
947   return next;
948 }
949 
getRSeg(dbBlock * block_,uint dbid_)950 dbRSeg* dbRSeg::getRSeg(dbBlock* block_, uint dbid_)
951 {
952   _dbBlock* block = (_dbBlock*) block_;
953   return (dbRSeg*) block->_r_seg_tbl->getPtr(dbid_);
954 }
955 
mergeRCs(std::vector<dbRSeg * > & mrsegs)956 void dbRSeg::mergeRCs(std::vector<dbRSeg*>& mrsegs)
957 {
958   uint rsegcnt = mrsegs.size();
959   dbRSeg* finalRSeg = mrsegs[rsegcnt - 1];
960   if (rsegcnt <= 1) {
961     // finalRSeg->setNext(0);
962     setNext(finalRSeg->getId());
963     // finalRSeg->setSourceNode(getTargetNode());
964     return;
965   }
966   std::vector<dbCCSeg*> mCcSegs;
967   std::vector<dbCapNode*> otherCapns;
968   mCcSegs.push_back(NULL);
969   otherCapns.push_back(NULL);
970   dbRSeg* rseg;
971   dbCapNode* tgtCapNode;
972   dbCapNode* ccCapNode;
973   dbCapNode* finalCapNode = finalRSeg->getTargetCapNode();
974   dbCCSeg *ccSeg, *tccSeg;
975   int ii;
976   uint cid;
977   for (ii = rsegcnt - 1; ii >= 0; ii--) {
978     rseg = mrsegs[ii];
979     tgtCapNode = rseg->getTargetCapNode();
980     dbSet<dbCCSeg> ccSegs = tgtCapNode->getCCSegs();
981     dbSet<dbCCSeg>::iterator ccitr;
982     for (ccitr = ccSegs.begin(); ccitr != ccSegs.end();) {
983       ccSeg = *ccitr;
984       ccitr++;
985       ccCapNode = ccSeg->getTheOtherCapn(tgtCapNode, cid);
986       uint ccidx = ccCapNode->getSortIndex();
987       if (ccidx == 0) {
988         if (tgtCapNode != finalCapNode)  // plug to finalCapNode
989           ccSeg->swapCapnode(tgtCapNode, finalCapNode);
990         mCcSegs.push_back(ccSeg);
991         otherCapns.push_back(ccCapNode);
992         ccCapNode->setSortIndex(mCcSegs.size() - 1);
993         continue;
994       } else {
995         tccSeg = mCcSegs[ccidx];
996         tccSeg->addCcCapacitance(ccSeg);
997         // if (tgtCapNode != finalCapNode)
998         // destroy ccSeg - unlink only ccCapNode
999         // else
1000         // destroy ccSeg
1001         dbCCSeg::destroy(ccSeg);
1002       }
1003     }
1004     if (tgtCapNode != finalCapNode) {
1005       finalRSeg->addRSegCapacitance(rseg);
1006       finalRSeg->addRSegResistance(rseg);
1007       // dbRSeg::destroy(rseg);
1008       // dbCapNode::destroy(tgtCapNode, false/*destroyCC*/);
1009     }
1010   }
1011   for (ii = 1; ii < (int) otherCapns.size(); ii++)
1012     otherCapns[ii]->setSortIndex(0);
1013   // finalRSeg->setNext(0);
1014   setNext(finalRSeg->getId());
1015   finalRSeg->setSourceNode(mrsegs[0]->getSourceNode());
1016   for (ii = rsegcnt - 2; ii >= 0; ii--) {
1017     rseg = mrsegs[ii];
1018     tgtCapNode = rseg->getTargetCapNode();
1019     dbRSeg::destroy(rseg);
1020     dbCapNode::destroy(tgtCapNode, false /*destroyCC*/);
1021   }
1022 }
1023 
1024 }  // namespace odb
1025