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 "dbFlatten.h"
34
35 #include "db.h"
36 #include "dbCapNode.h"
37 #include "dbInst.h"
38 #include "dbNet.h"
39 #include "dbObstruction.h"
40 #include "dbSWire.h"
41 #include "dbShape.h"
42 #include "dbTransform.h"
43 #include "dbWire.h"
44 #include "dbWireOpcode.h"
45 #include "utl/Logger.h"
46
47 namespace odb {
48
dbFlatten()49 dbFlatten::dbFlatten()
50 : _do_not_copy_power_wires(true),
51 _copy_shields(true),
52 _create_boundary_regions(false),
53 _create_bterm_map(false),
54 _copy_parasitics(false),
55 _hier_d(0),
56 _next_bterm_map_id(0)
57 {
58 }
59
~dbFlatten()60 dbFlatten::~dbFlatten()
61 {
62 }
63
flatten(dbBlock * block,int level)64 bool dbFlatten::flatten(dbBlock* block, int level)
65 {
66 _hier_d = block->getHierarchyDelimeter();
67 _next_bterm_map_id = 0;
68 dbProperty* bterm_map = NULL;
69
70 if (_create_bterm_map) {
71 dbProperty* p = dbProperty::find(block, "_ADS_BTERM_MAP");
72
73 if (p != NULL)
74 dbProperty::destroy(p);
75
76 std::string name = block->getName();
77 bterm_map = dbStringProperty::create(block, "_ADS_BTERM_MAP", name.c_str());
78 }
79
80 bool error = false;
81 dbSet<dbInst> insts = block->getInsts();
82 dbSet<dbInst>::iterator itr;
83
84 for (itr = insts.begin(); itr != insts.end(); ++itr) {
85 dbInst* inst = *itr;
86 dbBlock* child = inst->getChild();
87
88 if (child)
89 if (!flatten(block, child, level, bterm_map))
90 error = true;
91 }
92
93 for (itr = insts.begin(); itr != insts.end();) {
94 dbInst* inst = *itr;
95 dbBlock* child = inst->getChild();
96
97 if (child) {
98 inst->unbindBlock();
99 dbBlock::destroy(child);
100 itr = dbInst::destroy(itr);
101 } else
102 ++itr;
103 }
104
105 return !error;
106 }
107
108 /* // flatten = flatten child block into parent
109 //
110 // ..........o Parent (inst/block)
111 // . / \
112 // . / \
113 // . / ... \
114 // . /
115 // . o Child (inst/block)
116 // . / \
117 // . / \
118 // . / ... \
119 // ./
120 // o Grandchild (inst)
121 // */
flatten(dbBlock * parent,dbBlock * child,int level,dbProperty * bterm_map)122 bool dbFlatten::flatten(dbBlock* parent,
123 dbBlock* child,
124 int level,
125 dbProperty* bterm_map)
126 {
127 bool error = false;
128
129 if (level == 0)
130 return true;
131
132 if (bterm_map) {
133 std::string name = child->getName();
134 std::string propName("_ADS_BTERM_MAP");
135 propName += "_";
136 propName += name.c_str();
137 bterm_map
138 = dbStringProperty::create(bterm_map, propName.c_str(), name.c_str());
139 }
140
141 // Descend hierarchy and flatten
142 dbSet<dbInst> insts = child->getInsts();
143 dbSet<dbInst>::iterator itr;
144
145 for (itr = insts.begin(); itr != insts.end(); ++itr) {
146 dbInst* inst = *itr;
147 dbBlock* grandchild = inst->getChild();
148
149 if (grandchild)
150 flatten(child, grandchild, level - 1, bterm_map);
151 }
152
153 child->getParentInst()->getTransform(_transform);
154
155 ////////////////////////////
156 // Copy child data to parent
157 ////////////////////////////
158
159 _net_map.clear();
160 _via_map.clear();
161 _inst_map.clear();
162 _layer_rule_map.clear();
163 _reg_map.clear();
164
165 ////////////////////////////
166 // Copy vias
167 ////////////////////////////
168 dbVia::copy(parent, child);
169 dbSet<dbVia> vias = child->getVias();
170 dbSet<dbVia>::iterator vitr;
171 for (vitr = vias.begin(); vitr != vias.end(); ++vitr) {
172 dbVia* v = *vitr;
173 std::string name = v->getName();
174 _via_map[v] = parent->findVia(name.c_str());
175 }
176
177 ////////////////////////////
178 // Copy non-default_rules
179 ////////////////////////////
180 dbSet<dbTechNonDefaultRule> ndrules = child->getNonDefaultRules();
181 dbSet<dbTechNonDefaultRule>::iterator nditr;
182 for (nditr = ndrules.begin(); nditr != ndrules.end(); ++nditr) {
183 dbTechNonDefaultRule* rule = *nditr;
184 copyNonDefaultRule(parent, child->getParentInst(), rule);
185 }
186
187 ////////////////////////////
188 // Copy nets
189 ////////////////////////////
190 dbSet<dbNet> nets = child->getNets();
191 dbSet<dbNet>::iterator nitr;
192
193 for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
194 dbNet* src = *nitr;
195 dbNet* dst = copyNet(parent, src);
196
197 if (dst == NULL)
198 error = true;
199
200 _net_map[src] = dst;
201 }
202
203 ////////////////////////////
204 // Copy instances
205 ////////////////////////////
206 for (itr = insts.begin(); itr != insts.end();) {
207 dbInst* inst = *itr;
208 dbBlock* grandchild = inst->getChild();
209
210 if (grandchild) {
211 inst->unbindBlock();
212 dbBlock::destroy(grandchild);
213 itr = dbInst::destroy(itr);
214 } else {
215 if (!copyInst(parent, child->getParentInst(), inst))
216 error = true;
217
218 ++itr;
219 }
220 }
221
222 ////////////////////////////
223 // Copy the wires seperately
224 ////////////////////////////
225 for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
226 dbNet* src = *nitr;
227 dbNet* dst = _net_map[src];
228
229 if (dst)
230 copyNetWires(dst, src, level, bterm_map);
231 }
232
233 ////////////////////////////
234 // Copy obstructions
235 ////////////////////////////
236 dbSet<dbObstruction> obstructions = child->getObstructions();
237 dbSet<dbObstruction>::iterator oitr;
238
239 for (oitr = obstructions.begin(); oitr != obstructions.end(); ++oitr) {
240 dbObstruction* o = *oitr;
241 copyObstruction(parent, o);
242 }
243
244 ////////////////////////////
245 // Copy blocakges
246 ////////////////////////////
247 dbSet<dbBlockage> blocakges = child->getBlockages();
248 dbSet<dbBlockage>::iterator bitr;
249
250 for (bitr = blocakges.begin(); bitr != blocakges.end(); ++bitr) {
251 dbBlockage* b = *bitr;
252 copyBlockage(parent, b);
253 }
254
255 ////////////////////////////
256 // Copy regions
257 ////////////////////////////
258 dbSet<dbRegion> regions = child->getRegions();
259 dbSet<dbRegion>::iterator rgitr;
260
261 for (rgitr = regions.begin(); rgitr != regions.end(); ++rgitr) {
262 dbRegion* rg = *rgitr;
263 if (rg->getParent() == NULL)
264 copyRegion(parent, child->getParentInst(), NULL, rg);
265 }
266
267 if (_create_boundary_regions) {
268 std::string name = child->getParentInst()->getName();
269 name += _hier_d;
270 name += "ADS_BLOCK_REGION";
271 dbRegion* block_region = dbRegion::create(parent, name.c_str());
272 Rect bndry;
273 child->getDieArea(bndry);
274 _transform.apply(bndry);
275 dbBox::create(
276 block_region, bndry.xMin(), bndry.yMin(), bndry.xMax(), bndry.yMax());
277
278 for (rgitr = regions.begin(); rgitr != regions.end(); ++rgitr) {
279 dbRegion* rg = *rgitr;
280
281 if (rg->getParent() == NULL)
282 block_region->addChild(_reg_map[rg]);
283 }
284
285 for (itr = insts.begin(); itr != insts.end(); ++itr) {
286 dbInst* inst = *itr;
287
288 if (inst->getRegion() == NULL)
289 block_region->addInst(_inst_map[inst]);
290 }
291 }
292
293 _net_map.clear();
294 _via_map.clear();
295 _inst_map.clear();
296 _layer_rule_map.clear();
297 _reg_map.clear();
298 _node_map.clear();
299 return !error;
300 }
301
302 /*
303 // copyInst - This method copies the Grandchild from the Child to the Parent
304 node
305 //
306 // ..........o Parent (inst/block)
307 // . / \
308 // . / \
309 // . / ... \
310 // . /
311 // . o Child (inst/block)
312 // . / \
313 // . / \
314 // . / ... \
315 // ./
316 // o Grandchild (inst)
317 //
318 */
copyInst(dbBlock * parent,dbInst * child,dbInst * grandchild)319 bool dbFlatten::copyInst(dbBlock* parent, dbInst* child, dbInst* grandchild)
320 {
321 std::string name = child->getName();
322 name += _hier_d;
323 name += grandchild->getName();
324
325 dbInst* inst = dbInst::create(parent, grandchild->getMaster(), name.c_str());
326 _inst_map[grandchild] = inst;
327
328 // Copy placement
329 dbTransform gt;
330 grandchild->getTransform(gt);
331 gt.concat(_transform);
332 inst->setTransform(gt);
333 inst->setPlacementStatus(child->getPlacementStatus());
334
335 // Copy connections
336 dbSet<dbITerm> iterms = grandchild->getITerms();
337 dbSet<dbITerm>::iterator itr;
338
339 for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
340 dbITerm* child_iterm = *itr;
341 dbNet* child_net = child_iterm->getNet();
342
343 if (child_net != NULL) {
344 dbNet* parent_net = _net_map[child_net];
345
346 if (parent_net == NULL)
347 continue; // error
348
349 dbITerm* parent_iterm = inst->getITerm(child_iterm->getMTerm());
350 dbITerm::connect(parent_iterm, parent_net);
351 }
352 }
353
354 // Copy misc. attributes
355 copyAttrs(inst, child);
356 return true;
357 }
358
copyNet(dbBlock * parent_block,dbNet * child_net)359 dbNet* dbFlatten::copyNet(dbBlock* parent_block, dbNet* child_net)
360 {
361 dbSet<dbBTerm> bterms = child_net->getBTerms();
362
363 if (!bterms.empty()) {
364 // external net, find a parent
365 dbSet<dbBTerm>::iterator itr;
366
367 for (itr = bterms.begin(); itr != bterms.end(); ++itr) {
368 dbBTerm* bterm = *itr;
369 dbITerm* iterm = bterm->getITerm();
370 dbNet* net = iterm->getNet();
371
372 if (net)
373 return net;
374 }
375
376 // None of the iterms were connected to a net in the parent-inst.
377 // Create a new net?
378 // TODO: Does this case need special consideration...
379 }
380
381 // internal net, export up hierarchy
382 dbInst* inst = child_net->getBlock()->getParentInst();
383 std::string name = inst->getName();
384 name += _hier_d;
385 name += child_net->getName();
386 dbNet* net = dbNet::create(parent_block, name.c_str());
387
388 if (net == NULL) {
389 // TODO:
390 parent_block->getImpl()->getLogger()->warn(
391 utl::ODB, 281, "Failed to create net {}", name);
392 return NULL;
393 }
394
395 // copy attrs
396 copyAttrs(net, child_net);
397 return net;
398 }
399
printShapes(FILE * fp,dbWire * wire,bool skip_rcSegs)400 void dbFlatten::printShapes(FILE* fp, dbWire* wire, bool skip_rcSegs)
401 {
402 dbWireShapeItr shapes;
403 dbShape s;
404
405 for (shapes.begin(wire); shapes.next(s);) {
406 uint sid = shapes.getShapeId();
407 Rect r;
408 s.getBox(r);
409 fprintf(fp,
410 "J%d -- %d %d %d %d\n",
411 sid,
412 r.xMin(),
413 r.yMin(),
414 r.xMax(),
415 r.yMax());
416 }
417 if (skip_rcSegs)
418 return;
419 fprintf(fp, "\ncapNOdes\n");
420 dbSet<dbCapNode> nodeSet = wire->getNet()->getCapNodes();
421 dbSet<dbCapNode>::iterator rc_itr;
422 for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
423 dbCapNode* node = *rc_itr;
424
425 uint node_num = node->getNode();
426 uint sid = node->getShapeId();
427 fprintf(fp, "cap%d node%d J%d\n", node->getId(), node_num, sid);
428 }
429 dbBlock* block = wire->getNet()->getBlock();
430 dbSet<dbRSeg> rSet = wire->getNet()->getRSegs();
431 dbSet<dbRSeg>::iterator rcitr;
432
433 fprintf(fp, "\nRSEGS\n");
434 for (rcitr = rSet.begin(); rcitr != rSet.end(); ++rcitr) {
435 dbRSeg* rc = *rcitr;
436 dbCapNode* capNode = dbCapNode::getCapNode(block, rc->getTargetNode());
437
438 uint shapeId = rc->getShapeId();
439 dbCapNode* srcNode = rc->getSourceCapNode();
440
441 fprintf(fp, "%d J%d rc%d ", srcNode->getNode(), shapeId, rc->getId());
442
443 // if (!_foreign && shapeId==0)
444 if (shapeId == 0) {
445 fprintf(fp, "\n");
446 continue;
447 }
448
449 dbShape s;
450 wire->getShape(shapeId, s);
451 if (s.isVia())
452 continue;
453
454 Rect r;
455 s.getBox(r);
456
457 fprintf(fp, "-- %d %d %d %d --", r.xMin(), r.yMin(), r.xMax(), r.yMax());
458
459 if (capNode->isITerm() || capNode->isBTerm()) {
460 fprintf(fp, "B%d I%d -- ", capNode->isBTerm(), capNode->isITerm());
461 // continue;
462 }
463
464 int rsegId;
465 wire->getProperty(shapeId, rsegId);
466
467 fprintf(fp,
468 " prop%d tgt%d node%d\n",
469 rsegId,
470 rc->getTargetNode(),
471 capNode->getId());
472 }
473 }
setOldShapeIds(dbWire * wire)474 void dbFlatten::setOldShapeIds(dbWire* wire)
475 {
476 dbWireShapeItr shapes;
477 dbShape s;
478
479 for (shapes.begin(wire); shapes.next(s);) {
480 uint sid = shapes.getShapeId();
481 dbShape s;
482 wire->getShape(sid, s);
483 if (s.isVia())
484 continue;
485 wire->setProperty(sid, -sid);
486 }
487 }
mapOld2newIds(dbWire * wire,FILE * fp)488 void dbFlatten::mapOld2newIds(dbWire* wire, FILE* fp)
489 {
490 if (fp != NULL)
491 fprintf(fp, "\nmapOld2newIds\n");
492 dbWireShapeItr shapes;
493 dbShape s;
494
495 for (shapes.begin(wire); shapes.next(s);) {
496 uint sid = shapes.getShapeId();
497 dbShape s;
498 wire->getShape(sid, s);
499 if (s.isVia())
500 continue;
501 int n;
502 wire->getProperty(sid, n);
503 if (n >= 0)
504 continue;
505 _shape_rc_map[-n] = sid;
506 if (fp != NULL)
507 fprintf(fp, "old shapeId %d to new %d\n", -n, sid);
508 }
509 }
setShapeProperties(dbWire * wire)510 void dbFlatten::setShapeProperties(dbWire* wire)
511 {
512 dbBlock* block = wire->getNet()->getBlock();
513 dbSet<dbRSeg> rSet = wire->getNet()->getRSegs();
514 dbSet<dbRSeg>::iterator rcitr;
515 for (rcitr = rSet.begin(); rcitr != rSet.end(); ++rcitr) {
516 dbRSeg* rc = *rcitr;
517 dbCapNode* capNode = dbCapNode::getCapNode(block, rc->getTargetNode());
518 if (capNode->isITerm() || capNode->isBTerm())
519 continue;
520
521 uint shapeId = rc->getShapeId();
522
523 // if (!_foreign && shapeId==0)
524 if (shapeId == 0)
525 continue;
526
527 wire->setProperty(shapeId, -rc->getId());
528 }
529 }
530
debugNetWires(FILE * fp,dbNet * dst,dbNet * src,const char * msg)531 FILE* dbFlatten::debugNetWires(FILE* fp,
532 dbNet* dst,
533 dbNet* src,
534 const char* msg)
535 {
536 if (fp == NULL) {
537 char buf[32];
538 sprintf(buf, "%d", dst->getId());
539 fp = fopen(buf, "w");
540
541 if (fp == NULL) {
542 src->getImpl()->getLogger()->error(
543 utl::ODB, 26, "Cannot Open file {} to write", buf);
544 return nullptr;
545 }
546 }
547 fprintf(fp, "%s -------------------------------\n", msg);
548
549 if (src != NULL) {
550 fprintf(
551 fp, "Rsegs for SRC : %s --------------------\n", src->getConstName());
552 printRSegs(fp, src);
553 fprintf(fp, "\tsrc Wire -- net %s\n\n", src->getConstName());
554 if (src->getWire() != NULL) {
555 src->getWire()->printWire(fp, 0, 0);
556 printShapes(fp, src->getWire());
557 }
558 }
559 if (dst != NULL) {
560 fprintf(
561 fp, "Rsegs for DST : %s --------------------\n", dst->getConstName());
562 printRSegs(fp, dst);
563 fprintf(fp, "\n\tdst Wire -- net %s\n\n", dst->getConstName());
564 if (dst->getWire() != NULL) {
565 dst->getWire()->printWire(fp, 0, 0);
566 printShapes(fp, dst->getWire());
567 }
568 }
569 return fp;
570 }
copyNetWires(dbNet * dst,dbNet * src,int level,dbProperty * bterm_map)571 void dbFlatten::copyNetWires(dbNet* dst,
572 dbNet* src,
573 int level,
574 dbProperty* bterm_map)
575 {
576 FILE* fp = NULL;
577 if (isDebug("FLATTEN", "R"))
578 fp = debugNetWires(NULL, dst, src, "Before CopyWires");
579
580 copyWires(dst, src, level, bterm_map, _copy_parasitics);
581 copySWires(dst, src);
582
583 if (fp != NULL) {
584 debugNetWires(fp, dst, NULL, "After CopyWires");
585 fclose(fp);
586 }
587 }
588
copyAttrs(dbInst * dst_,dbInst * src_)589 void dbFlatten::copyAttrs(dbInst* dst_, dbInst* src_)
590 {
591 _dbInst* dst = (_dbInst*) dst_;
592 _dbInst* src = (_dbInst*) src_;
593
594 dst->_flags._user_flag_1 = src->_flags._user_flag_1;
595 dst->_flags._user_flag_2 = src->_flags._user_flag_2;
596 dst->_flags._user_flag_3 = src->_flags._user_flag_3;
597 dst->_flags._size_only = src->_flags._size_only;
598 dst->_flags._dont_touch = src->_flags._dont_touch;
599 dst->_flags._dont_size = src->_flags._dont_size;
600 dst->_flags._source = src->_flags._source;
601 dst->_weight = src->_weight;
602 }
603
copyAttrs(dbNet * dst_,dbNet * src_)604 void dbFlatten::copyAttrs(dbNet* dst_, dbNet* src_)
605 {
606 _dbNet* dst = (_dbNet*) dst_;
607 _dbNet* src = (_dbNet*) src_;
608
609 dst->_flags._sig_type = src->_flags._sig_type;
610 dst->_flags._wire_type = src->_flags._wire_type;
611 dst->_flags._special = src->_flags._special;
612 dst->_flags._wild_connect = src->_flags._wild_connect;
613 dst->_flags._wire_ordered = src->_flags._wire_ordered;
614 dst->_flags._buffered = src->_flags._buffered;
615 dst->_flags._disconnected = src->_flags._disconnected;
616 dst->_flags._spef = src->_flags._spef;
617 dst->_flags._select = src->_flags._select;
618 dst->_flags._mark = src->_flags._mark;
619 dst->_flags._mark_1 = src->_flags._mark_1;
620 dst->_flags._wire_altered = src->_flags._wire_altered;
621 dst->_flags._extracted = src->_flags._extracted;
622 dst->_flags._rc_graph = src->_flags._rc_graph;
623 dst->_flags._reduced = src->_flags._reduced;
624 dst->_flags._set_io = src->_flags._set_io;
625 dst->_flags._io = src->_flags._io;
626 dst->_flags._dont_touch = src->_flags._dont_touch;
627 dst->_flags._size_only = src->_flags._size_only;
628 dst->_flags._fixed_bump = src->_flags._fixed_bump;
629 dst->_flags._source = src->_flags._source;
630 dst->_flags._rc_disconnected = src->_flags._rc_disconnected;
631 dst->_weight = src->_weight;
632 dst->_xtalk = src->_xtalk;
633 dst->_non_default_rule = src->_non_default_rule;
634 }
635
copyWires(dbNet * dst_,dbNet * src_,int level,dbProperty * bterm_map,bool copyParasitics)636 void dbFlatten::copyWires(dbNet* dst_,
637 dbNet* src_,
638 int level,
639 dbProperty* bterm_map,
640 bool copyParasitics)
641 {
642 //_dbNet * dst = (_dbNet *) dst_;
643 _dbNet* src = (_dbNet*) src_;
644
645 if (src->_wire) {
646 _dbWire* src_wire = (_dbWire*) src_->getWire();
647
648 if (canCopyWire((dbWire*) src_wire, src->_flags._sig_type)) {
649 if (copyParasitics)
650 setOldShapeIds(src_->getWire());
651
652 if (dst_->getWire()) {
653 dbVector<unsigned char> opcodes;
654 dbVector<int> data;
655 opcodes.reserve(src_wire->_opcodes.size());
656 opcodes = src_wire->_opcodes;
657 data.reserve(src_wire->_data.size());
658 data = src_wire->_data;
659 fixWire(opcodes, data, src_->getBlock(), level, bterm_map);
660 appendWire(opcodes, data, dst_->getWire());
661 } else {
662 _dbWire* dst_wire = (_dbWire*) dbWire::create(dst_);
663 dst_wire->_opcodes.reserve(src_wire->_opcodes.size());
664 dst_wire->_opcodes = src_wire->_opcodes;
665 dst_wire->_data.reserve(src_wire->_data.size());
666 dst_wire->_data = src_wire->_data;
667 fixWire(dst_wire->_opcodes,
668 dst_wire->_data,
669 src_->getBlock(),
670 level,
671 bterm_map);
672 }
673 if (copyParasitics) {
674 dbSet<dbRSeg> rSet = dst_->getRSegs();
675 rSet.reverse();
676
677 rSet = dst_->getRSegs();
678 rSet.reverse();
679 }
680 }
681 }
682
683 if (src->_global_wire) {
684 _dbWire* src_wire = (_dbWire*) src_->getGlobalWire();
685
686 if (canCopyWire((dbWire*) src_wire, src->_flags._sig_type)) {
687 if (dst_->getGlobalWire()) {
688 dbVector<unsigned char> opcodes;
689 dbVector<int> data;
690 opcodes.reserve(src_wire->_opcodes.size());
691 opcodes = src_wire->_opcodes;
692 data.reserve(src_wire->_data.size());
693 data = src_wire->_data;
694 fixWire(opcodes, data, src_->getBlock(), level, bterm_map);
695 appendWire(opcodes, data, dst_->getGlobalWire());
696 } else {
697 _dbWire* dst_wire = (_dbWire*) dbWire::create(dst_, true);
698 dst_wire->_opcodes.reserve(src_wire->_opcodes.size());
699 dst_wire->_opcodes = src_wire->_opcodes;
700 dst_wire->_data.reserve(src_wire->_data.size());
701 dst_wire->_data = src_wire->_data;
702 fixWire(dst_wire->_opcodes,
703 dst_wire->_data,
704 src_->getBlock(),
705 level,
706 bterm_map);
707 }
708 }
709 }
710 }
711
fixWire(dbVector<unsigned char> & opcodes,dbVector<int> & data,dbBlock * src,int level,dbProperty * bterm_map)712 void dbFlatten::fixWire(dbVector<unsigned char>& opcodes,
713 dbVector<int>& data,
714 dbBlock* src,
715 int level,
716 dbProperty* bterm_map)
717 {
718 uint i;
719 uint n = opcodes.size();
720 uint point_cnt = 0;
721 int curX = 0;
722 int curY = 0;
723 std::vector<Point> jct_points;
724 jct_points.resize(opcodes.size());
725
726 for (i = 0; i < n; ++i) {
727 unsigned char opcode = opcodes[i] & WOP_OPCODE_MASK;
728
729 switch (opcode) {
730 case WOP_PATH:
731 case WOP_SHORT:
732 case WOP_VWIRE: {
733 point_cnt = 0;
734 break;
735 }
736
737 case WOP_JUNCTION: {
738 Point p = jct_points[data[i]];
739 curX = p.x();
740 curY = p.y();
741 point_cnt = 0;
742 break;
743 }
744
745 case WOP_X: {
746 curX = data[i];
747
748 if (point_cnt != 0) {
749 Point p(curX, curY);
750 jct_points[i] = p;
751 _transform.apply(p);
752 data[i] = p.x();
753 } else {
754 curY = data[++i];
755 Point p(curX, curY);
756 jct_points[i - 1] = p;
757 jct_points[i] = p;
758 _transform.apply(p);
759 data[i - 1] = p.x();
760 data[i] = p.y();
761 }
762
763 point_cnt++;
764 break;
765 }
766
767 case WOP_Y: {
768 point_cnt++;
769 curY = data[i];
770 Point p(curX, curY);
771 jct_points[i] = p;
772 _transform.apply(p);
773 data[i] = p.y();
774 break;
775 }
776
777 case WOP_COLINEAR: {
778 point_cnt++;
779 jct_points[i] = Point(curX, curY);
780 break;
781 }
782
783 case WOP_VIA: {
784 uint vid = data[i];
785 dbVia* src_via = dbVia::getVia(src, vid);
786 dbVia* dst_via = _via_map[src_via];
787 data[i] = dst_via->getImpl()->getOID();
788 break;
789 }
790
791 case WOP_ITERM: {
792 dbITerm* src_iterm = dbITerm::getITerm(src, data[i]);
793 /*notice(0, "WOP_ITERM: src_iterm= %d I%d/%s %s\n",
794 src_iterm->getId(), src_iterm->getInst()->getId(),
795 src_iterm->getMTerm()->getConstName(),
796 src_iterm->getInst()->getConstName());
797 */
798
799 // Check for hierarchical iterm, if iterm's block will be flattened then
800 // discard this iterm
801 if (src_iterm->getBTerm()) {
802 // notice(0, "------------------------------> WOP_ITERM:\n");
803 if (level > 1) {
804 opcodes[i] = WOP_NOP;
805 data[i] = 0;
806 break;
807 }
808 }
809
810 dbInst* src_inst = src_iterm->getInst();
811 dbInst* dst_inst = _inst_map[src_inst];
812 assert(dst_inst);
813 dbMTerm* mterm = src_iterm->getMTerm();
814 dbITerm* dst_iterm = dst_inst->getITerm(mterm);
815 data[i] = dst_iterm->getImpl()->getOID();
816 break;
817 }
818
819 case WOP_BTERM: {
820 assert(bterm_map == NULL);
821 opcodes[i] = WOP_NOP;
822 data[i] = 0;
823 break;
824 }
825
826 case WOP_RULE: {
827 if (opcodes[i] & WOP_BLOCK_RULE) {
828 dbTechLayerRule* rule
829 = dbTechLayerRule::getTechLayerRule(src, data[i]);
830 data[i] = _layer_rule_map[rule]->getImpl()->getOID();
831 }
832 }
833 }
834 }
835 }
836
appendWire(dbVector<unsigned char> & opcodes,dbVector<int> & data,dbWire * dst_)837 void dbFlatten::appendWire(dbVector<unsigned char>& opcodes,
838 dbVector<int>& data,
839 dbWire* dst_)
840 {
841 _dbWire* dst = (_dbWire*) dst_;
842
843 uint sz = dst->_opcodes.size();
844 dst->_opcodes.insert(dst->_opcodes.end(), opcodes.begin(), opcodes.end());
845 dst->_data.insert(dst->_data.end(), data.begin(), data.end());
846
847 // Fix up the junction-ids
848 int i;
849 int n = dst->_opcodes.size();
850
851 for (i = sz; i < n; ++i) {
852 unsigned char opcode = dst->_opcodes[i] & WOP_OPCODE_MASK;
853 if ((opcode == WOP_SHORT) || (opcode == WOP_JUNCTION)
854 || (opcode == WOP_VWIRE))
855 dst->_data[i] += sz;
856 }
857 }
858
copySWires(dbNet * dst,dbNet * src)859 void dbFlatten::copySWires(dbNet* dst, dbNet* src)
860 {
861 dbSet<dbSWire> swires = src->getSWires();
862 dbSet<dbSWire>::iterator itr;
863
864 for (itr = swires.begin(); itr != swires.end(); ++itr) {
865 dbSWire* src_wire = *itr;
866
867 if (canCopySWire(src_wire, src->getSigType()))
868 copySWire(dst, src, src_wire);
869 }
870 }
871
copySWire(dbNet * dst,dbNet * src,dbSWire * src_swire)872 void dbFlatten::copySWire(dbNet* dst, dbNet* src, dbSWire* src_swire)
873 {
874 dbSWire* dst_swire
875 = dbSWire::create(dst, src->getWireType(), src_swire->getShield());
876
877 dbSet<dbSBox> wires = src_swire->getWires();
878
879 dbSet<dbSBox>::iterator itr;
880
881 for (itr = wires.begin(); itr != wires.end(); ++itr) {
882 dbSBox* w = *itr;
883
884 if (!w->isVia()) {
885 Rect r;
886 w->getBox(r);
887 _transform.apply(r);
888 dbSBox::create(dst_swire,
889 w->getTechLayer(),
890 r.xMin(),
891 r.yMin(),
892 r.xMax(),
893 r.yMax(),
894 w->getWireShapeType());
895 } else {
896 int x, y;
897 w->getViaXY(x, y);
898 Point p(x, y);
899 _transform.apply(p);
900
901 if (w->getTechVia())
902 dbSBox::create(
903 dst_swire, (dbTechVia*) w, p.x(), p.y(), w->getWireShapeType());
904 else {
905 dbVia* v = _via_map[(dbVia*) w];
906 dbSBox::create(dst_swire, v, p.x(), p.y(), w->getWireShapeType());
907 }
908 }
909 }
910 }
911
canCopyWire(dbWire *,dbSigType::Value sig_type)912 bool dbFlatten::canCopyWire(dbWire* /* unused: wire_ */,
913 dbSigType::Value sig_type)
914 {
915 //_dbWire * wire = (_dbWire *) wire_;
916
917 if (_do_not_copy_power_wires) {
918 if (sig_type == dbSigType::POWER || sig_type == dbSigType::GROUND)
919 return false;
920 }
921
922 return true;
923 }
924
canCopySWire(dbSWire * wire_,dbSigType::Value sig_type)925 bool dbFlatten::canCopySWire(dbSWire* wire_, dbSigType::Value sig_type)
926 {
927 _dbSWire* wire = (_dbSWire*) wire_;
928
929 if (_do_not_copy_power_wires) {
930 if (wire->_flags._wire_type == dbWireType::SHIELD && _copy_shields)
931 return true;
932
933 if (sig_type == dbSigType::POWER || sig_type == dbSigType::GROUND)
934 return false;
935 }
936
937 return true;
938 }
939
copyObstruction(dbBlock * dst_block,dbObstruction * src_)940 void dbFlatten::copyObstruction(dbBlock* dst_block, dbObstruction* src_)
941 {
942 _dbObstruction* src = (_dbObstruction*) src_;
943
944 dbBox* box = src_->getBBox();
945 Rect r;
946 box->getBox(r);
947 _transform.apply(r);
948
949 _dbObstruction* dst
950 = (_dbObstruction*) dbObstruction::create(dst_block,
951 box->getTechLayer(),
952 r.xMin(),
953 r.yMin(),
954 r.xMax(),
955 r.yMax(),
956 _inst_map[src_->getInstance()]);
957 dst->_flags = src->_flags;
958 dst->_min_spacing = src->_min_spacing;
959 dst->_effective_width = src->_effective_width;
960 }
961
copyBlockage(dbBlock * dst_block,dbBlockage * src)962 void dbFlatten::copyBlockage(dbBlock* dst_block, dbBlockage* src)
963 {
964 dbBox* box = src->getBBox();
965 Rect r;
966 box->getBox(r);
967 _transform.apply(r);
968
969 // dbBlockage * dst = dbBlockage::create( dst_block,
970 dbBlockage::create(dst_block,
971 r.xMin(),
972 r.yMin(),
973 r.xMax(),
974 r.yMax(),
975 _inst_map[src->getInstance()]);
976 }
977
978 //
979 // Copy "src" region of the child_inst to parent_block.
980 //
copyRegion(dbBlock * parent_block,dbInst * child_inst,dbRegion * parent_region,dbRegion * src)981 void dbFlatten::copyRegion(dbBlock* parent_block,
982 dbInst* child_inst,
983 dbRegion* parent_region,
984 dbRegion* src)
985 {
986 std::string name = child_inst->getName();
987 name += _hier_d;
988 name += src->getName();
989
990 dbRegion* dst;
991
992 if (parent_region)
993 dst = dbRegion::create(parent_region, name.c_str());
994 else
995 dst = dbRegion::create(parent_block, name.c_str());
996
997 if (dst == NULL) {
998 // TODO:
999 parent_block->getImpl()->getLogger()->warn(
1000 utl::ODB, 272, "Failed to create region {}", name);
1001 return;
1002 }
1003
1004 _reg_map[src] = dst;
1005 dst->setRegionType(src->getRegionType());
1006 dst->setInvalid(src->isInvalid());
1007
1008 dbSet<dbBox> boxes = src->getBoundaries();
1009 dbSet<dbBox>::iterator bitr = boxes.begin();
1010
1011 for (; bitr != boxes.end(); ++bitr) {
1012 dbBox* box = *bitr;
1013 Rect r;
1014 box->getBox(r);
1015 _transform.apply(r);
1016 dbBox::create(dst, r.xMin(), r.yMin(), r.xMax(), r.yMax());
1017 }
1018
1019 dbSet<dbInst> insts = src->getRegionInsts();
1020 dbSet<dbInst>::iterator iitr = insts.begin();
1021
1022 for (; iitr != insts.end(); ++iitr) {
1023 dbInst* inst = *iitr;
1024 dst->addInst(_inst_map[inst]);
1025 }
1026
1027 dbSet<dbRegion> children = src->getChildren();
1028 dbSet<dbRegion>::iterator citr = children.begin();
1029
1030 for (; citr != children.end(); ++citr) {
1031 dbRegion* child = *citr;
1032 copyRegion(parent_block, child_inst, dst, child);
1033 }
1034 }
1035
copyNonDefaultRule(dbBlock * parent,dbInst * child_inst,dbTechNonDefaultRule * src_rule)1036 dbTechNonDefaultRule* dbFlatten::copyNonDefaultRule(
1037 dbBlock* parent,
1038 dbInst* child_inst,
1039 dbTechNonDefaultRule* src_rule)
1040 {
1041 std::string name = child_inst->getName();
1042 name += _hier_d;
1043 name += src_rule->getName();
1044
1045 dbTechNonDefaultRule* dst_rule
1046 = dbTechNonDefaultRule::create(parent, name.c_str());
1047
1048 if (dst_rule == NULL)
1049 return NULL;
1050
1051 dst_rule->setHardSpacing(src_rule->getHardSpacing());
1052
1053 std::vector<dbTechVia*> vias;
1054 src_rule->getUseVias(vias);
1055
1056 std::vector<dbTechVia*>::iterator vitr;
1057
1058 for (vitr = vias.begin(); vitr != vias.end(); ++vitr)
1059 dst_rule->addUseVia(*vitr);
1060
1061 std::vector<dbTechViaGenerateRule*> rules;
1062 src_rule->getUseViaRules(rules);
1063
1064 std::vector<dbTechViaGenerateRule*>::iterator ritr;
1065
1066 for (ritr = rules.begin(); ritr != rules.end(); ++ritr)
1067 dst_rule->addUseViaRule(*ritr);
1068
1069 dbTech* tech = parent->getDb()->getTech();
1070 dbSet<dbTechLayer> layers = tech->getLayers();
1071 dbSet<dbTechLayer>::iterator layitr;
1072
1073 for (layitr = layers.begin(); layitr != layers.end(); ++layitr) {
1074 dbTechLayer* layer = *layitr;
1075 int count;
1076
1077 if (src_rule->getMinCuts(layer, count))
1078 dst_rule->setMinCuts(layer, count);
1079 }
1080
1081 std::vector<dbTechLayerRule*> layer_rules;
1082 src_rule->getLayerRules(layer_rules);
1083
1084 std::vector<dbTechLayerRule*>::iterator layer_rules_itr;
1085
1086 for (layer_rules_itr = layer_rules.begin();
1087 layer_rules_itr != layer_rules.end();
1088 ++layer_rules_itr) {
1089 dbTechLayerRule* src_lay_rule = *layer_rules_itr;
1090 dbTechLayerRule* dst_lay_rule
1091 = dbTechLayerRule::create(src_rule, src_lay_rule->getLayer());
1092 _layer_rule_map[src_lay_rule] = dst_lay_rule;
1093
1094 dst_lay_rule->setWidth(src_lay_rule->getWidth());
1095 dst_lay_rule->setSpacing(src_lay_rule->getSpacing());
1096 dst_lay_rule->setWireExtension(src_lay_rule->getWireExtension());
1097 }
1098
1099 return dst_rule;
1100 }
createParentCapNode(dbCapNode * node,dbNet * dstNet)1101 bool dbFlatten::createParentCapNode(dbCapNode* node, dbNet* dstNet)
1102 {
1103 bool foreign = false;
1104
1105 debugPrint(node->getImpl()->getLogger(),
1106 utl::ODB,
1107 "FLATTEN",
1108 3,
1109 "Cap {} num {}",
1110 node->getId(),
1111 node->getNode());
1112
1113 dbCapNode* cap = NULL;
1114 if (!node->isBTerm()) { //
1115 cap = dbCapNode::create(dstNet, 0, foreign);
1116 _node_map[node->getId()] = cap->getId();
1117 }
1118 if (node->isInternal()) { //
1119 cap->setInternalFlag();
1120 uint nodeNum = _shape_rc_map[node->getNode()];
1121 cap->setNode(nodeNum);
1122 debugPrint(node->getImpl()->getLogger(),
1123 utl::ODB,
1124 "FLATTEN",
1125 3,
1126 "\t--> {} {}",
1127 cap->getId(),
1128 cap->getNode());
1129 } else if (node->isITerm()) { //
1130 dbITerm* src_iterm = node->getITerm();
1131 dbInst* src_inst = src_iterm->getInst();
1132
1133 dbInst* dst_inst = _inst_map[src_inst];
1134 assert(dst_inst);
1135 dbMTerm* mterm = src_iterm->getMTerm();
1136 dbITerm* dst_iterm = dst_inst->getITerm(mterm);
1137 cap->setNode(dst_iterm->getId());
1138 cap->setITermFlag();
1139 debugPrint(node->getImpl()->getLogger(),
1140 utl::ODB,
1141 "FLATTEN",
1142 3,
1143 "\t--> {} {}",
1144 cap->getId(),
1145 cap->getNode());
1146 } else if (node->isBTerm()) { //
1147
1148 dbBTerm* bterm = node->getBTerm();
1149 dbITerm* iterm = bterm->getITerm();
1150 uint parentId = adjustParentNode2(dstNet, iterm->getId());
1151 _node_map[node->getId()] = parentId;
1152
1153 debugPrint(node->getImpl()->getLogger(),
1154 utl::ODB,
1155 "FLATTEN",
1156 3,
1157 "\t\tG BTerm {} --> {} <-- {} ==> {} {}",
1158 node->getId(),
1159 bterm->getConstName(),
1160 iterm->getId(),
1161 _node_map[node->getId()],
1162 parentId);
1163 }
1164 return true;
1165 }
adjustParentNode2(dbNet * dstNet,uint srcTermId)1166 uint dbFlatten::adjustParentNode2(dbNet* dstNet, uint srcTermId)
1167 {
1168 dbSet<dbCapNode> capNodes = dstNet->getCapNodes();
1169 dbSet<dbCapNode>::iterator cap_node_itr = capNodes.begin();
1170 for (; cap_node_itr != capNodes.end(); ++cap_node_itr) {
1171 dbCapNode* node = *cap_node_itr;
1172 if (!node->isITerm())
1173 continue;
1174
1175 uint nodeNum = node->getNode();
1176 dbITerm* iterm = node->getITerm();
1177 if (iterm->getId() != srcTermId)
1178 continue;
1179
1180 uint jid = node->getShapeId();
1181 debugPrint(node->getImpl()->getLogger(),
1182 utl::ODB,
1183 "FLATTEN",
1184 3,
1185 "\tadjustParentNode {} J{} N{} srcTermId={}",
1186 node->getId(),
1187 jid,
1188 nodeNum,
1189 srcTermId);
1190
1191 node->resetITermFlag();
1192 node->setInternalFlag();
1193
1194 node->setNode(jid);
1195
1196 return node->getId();
1197 }
1198 return 0;
1199 }
checkNode(dbCapNode * src,uint srcTermId)1200 dbCapNode* dbFlatten::checkNode(dbCapNode* src, uint srcTermId)
1201 {
1202 if (src == NULL)
1203 return NULL;
1204 if (!src->isITerm())
1205 return NULL;
1206
1207 debugPrint(src->getImpl()->getLogger(),
1208 utl::ODB,
1209 "FLATTEN",
1210 3,
1211 "\tcheckNode node={} i{} rcTermId={}",
1212 src->getId(),
1213 src->getITerm()->getId(),
1214 srcTermId);
1215
1216 if (src->getITerm()->getId() == srcTermId)
1217 return src;
1218
1219 return NULL;
1220 }
adjustParentNode(dbNet * dstNet,uint srcTermId)1221 uint dbFlatten::adjustParentNode(dbNet* dstNet, uint srcTermId)
1222 {
1223 dbSet<dbRSeg> rsegs = dstNet->getRSegs();
1224 dbSet<dbRSeg>::iterator rseg_itr = rsegs.begin();
1225 for (; rseg_itr != rsegs.end(); ++rseg_itr) {
1226 dbRSeg* rseg = *rseg_itr;
1227
1228 uint jid = rseg->getShapeId();
1229 debugPrint(dstNet->getImpl()->getLogger(),
1230 utl::ODB,
1231 "FLATTEN",
1232 3,
1233 "\tadjustParentNode J{} rseg{} {} {} srcTermId={}",
1234 jid,
1235 rseg->getId(),
1236 rseg->getSourceNode(),
1237 rseg->getTargetNode(),
1238 srcTermId);
1239 if ((rseg->getSourceNode() > 0) && (rseg->getTargetNode() > 0))
1240 continue;
1241 dbCapNode* src = rseg->getSourceCapNode();
1242 dbCapNode* tgt = rseg->getTargetCapNode();
1243
1244 dbCapNode* node = checkNode(src, srcTermId);
1245 if (node == NULL) {
1246 node = checkNode(tgt, srcTermId);
1247 if (node == NULL)
1248 continue;
1249 }
1250
1251 // uint jid= rseg->getShapeId();
1252
1253 debugPrint(dstNet->getImpl()->getLogger(),
1254 utl::ODB,
1255 "FLATTEN",
1256 3,
1257 "\tadjustParentNode rseg{} J{} {} {} srcTermId={}",
1258 rseg->getId(),
1259 jid,
1260 src->getId(),
1261 tgt->getId(),
1262 srcTermId);
1263
1264 node->resetITermFlag();
1265 node->setInternalFlag();
1266
1267 node->setNode(jid);
1268
1269 return node->getId();
1270 }
1271 return 0;
1272 }
1273
createTop1stRseg(dbNet *,dbNet * dst)1274 void dbFlatten::createTop1stRseg(dbNet* /* unused: src */, dbNet* dst)
1275 {
1276 if (dst->getWire() != NULL)
1277 return;
1278
1279 dbCapNode* cap = dbCapNode::create(dst, 0, /*_foreign*/ false);
1280 // cap->setNode(iterm->getId());
1281 cap->setInternalFlag();
1282 dbRSeg* rc = dbRSeg::create(dst, 0, 0, 0, true);
1283 rc->setTargetNode(cap->getId());
1284 }
1285
createCapNodes(dbNet * src,dbNet * dst,bool noDstWires)1286 uint dbFlatten::createCapNodes(dbNet* src, dbNet* dst, bool noDstWires)
1287 {
1288 _shape_rc_map.clear();
1289 mapOld2newIds(dst->getWire(), NULL);
1290
1291 if (noDstWires)
1292 createTop1stRseg(src, dst);
1293
1294 // uint maxCap= dst->maxInternalCapNum()+1;
1295
1296 debugPrint(src->getImpl()->getLogger(),
1297 utl::ODB,
1298 "FLATTEN",
1299 3,
1300 "\tCapNodes: {} {}",
1301 src->getConstName(),
1302 dst->getConstName());
1303
1304 uint gCnt = 0;
1305 dbSet<dbCapNode> capNodes = src->getCapNodes();
1306 dbSet<dbCapNode>::iterator cap_node_itr = capNodes.begin();
1307 for (; cap_node_itr != capNodes.end(); ++cap_node_itr) {
1308 dbCapNode* node = *cap_node_itr;
1309
1310 gCnt += createParentCapNode(node, dst);
1311 }
1312 return gCnt;
1313 }
1314
setCorrectRsegIds(dbNet * dst)1315 uint dbFlatten::setCorrectRsegIds(dbNet* dst)
1316 {
1317 dbWire* wire = dst->getWire();
1318
1319 dbSet<dbRSeg> rsegs = dst->getRSegs();
1320
1321 uint rCnt = 0;
1322 dbSet<dbRSeg>::iterator rseg_itr = rsegs.begin();
1323 for (; rseg_itr != rsegs.end(); ++rseg_itr) {
1324 dbRSeg* rseg = *rseg_itr;
1325
1326 uint sid = rseg->getShapeId();
1327 if (sid == 0) {
1328 dst->getImpl()->getLogger()->warn(utl::ODB,
1329 27,
1330 "rsegId {} has zero shape : {}",
1331 rseg->getId(),
1332 dst->getConstName());
1333 continue;
1334 }
1335 if (!rseg->getTargetCapNode()->isInternal())
1336 continue;
1337
1338 int rsegId;
1339 wire->getProperty(sid, rsegId);
1340 if (rsegId > 0)
1341 continue;
1342 rCnt++;
1343 // notice(0, "old %d new %d\n", rsegId, rseg->getId());
1344 wire->setProperty(sid, rseg->getId());
1345 }
1346 return rCnt;
1347 }
createRSegs(dbNet * src,dbNet * dst)1348 uint dbFlatten::createRSegs(dbNet* src, dbNet* dst)
1349 {
1350 debugPrint(src->getImpl()->getLogger(),
1351 utl::ODB,
1352 "FLATTEN",
1353 18,
1354 "\tRSegs: {} {}",
1355 src->getConstName(),
1356 dst->getConstName());
1357
1358 dbBlock* block = dst->getBlock();
1359 // extMain::printRSegs(parentNet);
1360
1361 dbSet<dbRSeg> rsegs = src->getRSegs();
1362
1363 uint rCnt = 0;
1364 dbSet<dbRSeg>::iterator rseg_itr = rsegs.begin();
1365 for (; rseg_itr != rsegs.end(); ++rseg_itr) {
1366 dbRSeg* rseg = *rseg_itr;
1367
1368 // int x, y;
1369 // TODO rseg->getCoords(x, y);
1370 // TODO uint pathDir= rseg->pathLowToHigh() ? 0 : 1;
1371 dbRSeg* rc = dbRSeg::create(dst, 0, 0, 0, true);
1372
1373 uint tgtId = rseg->getTargetNode();
1374 uint srcId = rseg->getSourceNode();
1375
1376 rc->setSourceNode(_node_map[srcId]);
1377 rc->setTargetNode(_node_map[tgtId]);
1378
1379 for (int corner = 0; corner < block->getCornerCount(); corner++) {
1380 double res = rseg->getResistance(corner);
1381 double cap = rseg->getCapacitance(corner);
1382
1383 rc->setResistance(res, corner);
1384 rc->setCapacitance(cap, corner);
1385 debugPrint(src->getImpl()->getLogger(),
1386 utl::ODB,
1387 "FLATTEN",
1388 18,
1389 "\t\tsrc:{}->{} - tgt:{}->{} - {} {}",
1390 srcId,
1391 _node_map[srcId],
1392 tgtId,
1393 _node_map[tgtId],
1394 res,
1395 cap);
1396 }
1397 rCnt++;
1398 }
1399 setCorrectRsegIds(dst);
1400 return rCnt;
1401 }
printRSegs(FILE * fp,dbNet * net)1402 uint dbFlatten::printRSegs(FILE* fp, dbNet* net)
1403 {
1404 if (fp == NULL)
1405 net->getImpl()->getLogger()->info(
1406 utl::ODB, 28, "\t\t\tprintRSegs: {}", net->getConstName());
1407 else
1408 fprintf(fp, "\t\t\tprintRSegs: %s\n", net->getConstName());
1409
1410 dbSet<dbRSeg> rsegs = net->getRSegs();
1411
1412 uint rCnt = 0;
1413 dbSet<dbRSeg>::iterator rseg_itr = rsegs.begin();
1414 for (; rseg_itr != rsegs.end(); ++rseg_itr) {
1415 dbRSeg* rseg = *rseg_itr;
1416
1417 if (fp == NULL)
1418 net->getImpl()->getLogger()->info(utl::ODB,
1419 29,
1420 "\t\t\t\t\trsegId: {} J{} -- ",
1421 rseg->getId(),
1422 rseg->getShapeId());
1423 else
1424 fprintf(fp,
1425 "\t\t\t\t\trsegId: %d J%d -- ",
1426 rseg->getId(),
1427 rseg->getShapeId());
1428
1429 dbCapNode* src = rseg->getSourceCapNode();
1430 if (fp == NULL) {
1431 if (src == NULL)
1432 net->getImpl()->getLogger()->info(utl::ODB, 30, " 0 --");
1433 else
1434 net->getImpl()->getLogger()->info(utl::ODB,
1435 31,
1436 " {} I{} B{} -- ",
1437 src->getNode(),
1438 src->isITerm(),
1439 src->isBTerm());
1440 } else {
1441 if (src == NULL)
1442 fprintf(fp, " 0 --");
1443 else
1444 fprintf(fp,
1445 " %d I%d B%d -- ",
1446 src->getNode(),
1447 src->isITerm(),
1448 src->isBTerm());
1449 }
1450 dbCapNode* tgt = rseg->getTargetCapNode();
1451 if (fp == NULL) {
1452 if (tgt == NULL)
1453 net->getImpl()->getLogger()->info(utl::ODB, 32, " 0");
1454 else
1455 net->getImpl()->getLogger()->info(utl::ODB,
1456 33,
1457 " {} I{} B{}",
1458 tgt->getNode(),
1459 tgt->isITerm(),
1460 tgt->isBTerm());
1461
1462 } else {
1463 if (tgt == NULL)
1464 fprintf(fp, " 0\n");
1465 else
1466 fprintf(fp,
1467 " %d I%d B%d\n",
1468 tgt->getNode(),
1469 tgt->isITerm(),
1470 tgt->isBTerm());
1471 }
1472 rCnt++;
1473 }
1474 return rCnt;
1475 }
1476 } // namespace odb
1477