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