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 "dbSearch.h"
34
35 #include "db.h"
36 #include "dbBlock.h"
37 #include "dbDatabase.h"
38 #include "dbNet.h"
39 #include "dbTable.h"
40 #include "dbTable.hpp"
41 #include "dbTypes.h"
42
43 //#define NEW_TRACKS
44
45 #include "dbShape.h"
46 namespace odb {
47
dbBlockSearch(dbBlock * blk,dbTech * tech)48 dbBlockSearch::dbBlockSearch(dbBlock* blk, dbTech* tech)
49 {
50 _block = blk;
51 _tech = tech;
52 _blockId = blk->getId();
53
54 _signalNetSdb = NULL;
55 _netSdb = NULL;
56 _netViaSdb = NULL;
57 _instSdb = NULL;
58 _trackSdb = NULL;
59
60 initMenuIds();
61
62 _skipCutBoxes = false;
63 }
~dbBlockSearch()64 dbBlockSearch::~dbBlockSearch()
65 {
66 if (_signalNetSdb != NULL)
67 delete _signalNetSdb;
68 if (_netSdb != NULL)
69 delete _netSdb;
70 if (_instSdb != NULL)
71 delete _instSdb;
72 if (_netViaSdb != NULL)
73 delete _netViaSdb;
74 if (_trackSdb != NULL)
75 delete _trackSdb;
76 }
77
initMenuIds()78 void dbBlockSearch::initMenuIds()
79 {
80 _blockMenuId = 0;
81
82 _block_bb_id = 1; // ids are required by SDB in the absence of GUI
83 _block_pin_id = 2;
84 _block_obs_id = 3;
85 _block_track_id = 4;
86
87 _instMenuId = 0;
88
89 _inst_bb_id = 5;
90 _inst_pin_id = 6;
91 _inst_obs_id = 7;
92
93 _signalMenuId = 0;
94
95 _signal_wire_id = 9;
96 _signal_via_id = 10;
97
98 _powerMenuId = 0;
99
100 _power_wire_id = 11;
101 _power_via_id = 12;
102 }
getBbox(int * x1,int * y1,int * x2,int * y2)103 uint dbBlockSearch::getBbox(int* x1, int* y1, int* x2, int* y2)
104 {
105 Rect rect;
106 _block->getDieArea(rect);
107 *x1 = rect.xMin();
108 *y1 = rect.yMin();
109 *x2 = rect.xMax();
110 *y2 = rect.yMax();
111 return _block->getId();
112 }
setViaCutsFlag(bool skipViaCuts)113 void dbBlockSearch::setViaCutsFlag(bool skipViaCuts)
114 {
115 _skipCutBoxes = skipViaCuts;
116 }
makeSearchDB(bool nets,bool insts,ZContext & context)117 void dbBlockSearch::makeSearchDB(bool nets, bool insts, ZContext& context)
118 {
119 //_dbBlock * block = (_dbBlock *) this;
120 if (insts) {
121 if (adsNewComponent(context, ZCID(Sdb), _instSdb) != Z_OK) {
122 assert(0);
123 }
124 makeInstSearchDb();
125 }
126 if (nets) {
127 if (!_netSdb)
128 makeNetSdb(context);
129 if (!_netViaSdb)
130 makeNetViaSdb(context);
131 #ifndef NEW_TRACKS
132 if (!_trackSdb)
133 makeTrackSdb(context);
134 #endif
135 }
136 }
137 #ifndef NEW_TRACKS
makeTrackSdb(ZContext & context)138 void dbBlockSearch::makeTrackSdb(ZContext& context)
139 {
140 if (adsNewComponent(context, ZCID(Sdb), _trackSdb) != Z_OK) {
141 assert(0);
142 }
143 Rect r;
144 _trackSdb->initSearchForNets(_tech, _block);
145 _block->getDieArea(r);
146 _trackSdb->setMaxArea(r.xMin(), r.yMin(), r.xMax(), r.yMax());
147 makeTrackSearchDb();
148 }
149 #endif
makeNetSdb(ZContext & context)150 void dbBlockSearch::makeNetSdb(ZContext& context)
151 {
152 if (adsNewComponent(context, ZCID(Sdb), _netSdb) != Z_OK) {
153 assert(0);
154 }
155 Rect r;
156 _netSdb->initSearchForNets(_tech, _block);
157 _block->getDieArea(r);
158 _netSdb->setMaxArea(r.xMin(), r.yMin(), r.xMax(), r.yMax());
159 _netSdb->addPowerNets(_block, _power_wire_id, true);
160 _netSdb->addSignalNets(_block, _signal_wire_id, true);
161
162 // if ( adsNewComponent( context, ZCID(Sdb), _trackSdb ) != Z_OK )
163 // {
164 // assert(0);
165 // }
166 // _trackSdb->initSearchForNets(_tech, _block);
167 // _trackSdb->setMaxArea(r.xMin(), r.yMin(), r.xMax(), r.yMax());
168 //
169 // makeTrackSearchDb();
170 }
makeNetViaSdb(ZContext & context)171 void dbBlockSearch::makeNetViaSdb(ZContext& context)
172 {
173 //_dbBlock * block = (_dbBlock *) this;
174 if (adsNewComponent(context, ZCID(Sdb), _netViaSdb) != Z_OK) {
175 assert(0);
176 }
177 _netViaSdb->initSearchForNets(_tech, _block);
178 _netViaSdb->addPowerNets(_block, _power_via_id, false);
179 // _netViaSdb->addSignalNets(_block, _signal_via_id, false);
180 }
181
makeSignalNetSdb(ZContext & context)182 void dbBlockSearch::makeSignalNetSdb(ZContext& context)
183 {
184 if (adsNewComponent(context, ZCID(Sdb), _signalNetSdb) != Z_OK) {
185 assert(0);
186 }
187 Rect r;
188 _signalNetSdb->initSearchForNets(_tech, _block);
189 _block->getDieArea(r);
190 _signalNetSdb->setMaxArea(r.xMin(), r.yMin(), r.xMax(), r.yMax());
191 _signalNetSdb->addSignalNets(_block, _signal_wire_id, _signal_via_id);
192 }
getSignalNetSdb(ZContext & context)193 ZPtr<ISdb> dbBlockSearch::getSignalNetSdb(ZContext& context)
194 {
195 if (!_signalNetSdb)
196 makeSignalNetSdb(context);
197 return _signalNetSdb;
198 }
getSignalNetSdb()199 ZPtr<ISdb> dbBlockSearch::getSignalNetSdb()
200 {
201 return _signalNetSdb;
202 }
resetSignalNetSdb()203 void dbBlockSearch::resetSignalNetSdb()
204 {
205 _signalNetSdb = NULL;
206 }
getNetSdb(ZContext & context)207 ZPtr<ISdb> dbBlockSearch::getNetSdb(ZContext& context)
208 {
209 if (!_netSdb)
210 makeNetSdb(context);
211 return _netSdb;
212 }
getNetSdb()213 ZPtr<ISdb> dbBlockSearch::getNetSdb()
214 {
215 return _netSdb;
216 }
resetNetSdb()217 void dbBlockSearch::resetNetSdb()
218 {
219 _netSdb = NULL;
220 }
makeInstSearchDb()221 uint dbBlockSearch::makeInstSearchDb()
222 {
223 uint maxInt = 2100000000;
224 uint minWidth = maxInt;
225 uint minHeight = maxInt;
226
227 dbSet<dbInst> insts = _block->getInsts();
228
229 // dbBox *maxBox= _block->getBBox();
230 Rect maxRect;
231 _block->getDieArea(maxRect);
232
233 maxRect.reset(maxInt, maxInt, -maxInt, -maxInt);
234 // maxBox->getBox(maxRect);
235
236 dbSet<dbInst>::iterator inst_itr;
237 uint instCnt = 0;
238 for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
239 dbInst* inst = *inst_itr;
240
241 if (inst->getMaster()->getType() == dbMasterType::CORE_FEEDTHRU)
242 continue;
243 if (inst->getMaster()->getMTermCount() <= 0)
244 continue;
245
246 dbBox* bb = inst->getBBox();
247
248 minWidth = MIN(minWidth, bb->getDX());
249 minHeight = MIN(minHeight, bb->getDY());
250
251 Rect r;
252 bb->getBox(r);
253 maxRect.merge(r);
254 instCnt++;
255 }
256
257 //_dbBlock * block = (_dbBlock *) this;
258
259 if (instCnt == 0)
260 return 0;
261
262 // TODO uint rowSize= 100 * minHeight;
263 // TODO uint colSize= 100 * minWidth;
264
265 _instSdb->setupForBoxes(maxRect, minHeight, minWidth);
266
267 for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
268 dbInst* inst = *inst_itr;
269 /*
270 if (inst->getMaster()->getMTermCount()<=0)
271 continue;
272 */
273
274 dbBox* ibox = inst->getBBox();
275
276 // _inst->addBox(x1, y1, x2, y2,
277 // level, rc->getId(), pshape.junction_id, _dbSignalId);
278
279 _instSdb->addBox(ibox, _inst_bb_id, inst->getId());
280 }
281
282 uint start = 0;
283 uint end = 0;
284 // uint adjustedMarkerCnt= _instSdb->setExtrusionMarker(start, end);
285 _instSdb->setExtrusionMarker(start, end);
286 return instCnt;
287 }
288 #ifndef NEW_TRACKS
makeTrackSearchDb()289 uint dbBlockSearch::makeTrackSearchDb()
290 {
291 Rect maxRect;
292 _block->getDieArea(maxRect);
293
294 dbSet<dbTechLayer> layers = _tech->getLayers();
295 dbSet<dbTechLayer>::iterator itr;
296
297 uint cnt = 0;
298
299 dbSet<dbTechLayer>::iterator litr;
300 dbTechLayer* layer;
301 for (litr = layers.begin(); litr != layers.end(); ++litr) {
302 layer = *litr;
303 if (layer->getType() != dbTechLayerType::ROUTING)
304 continue;
305
306 dbTrackGrid* g = _block->findTrackGrid(layer);
307 if (g == NULL)
308 continue;
309
310 uint level = layer->getRoutingLevel();
311
312 int lo[2] = {maxRect.xMin(), maxRect.yMin()};
313 int hi[2] = {maxRect.xMax(), maxRect.yMax()};
314
315 cnt += addTracks(g, 1, level, lo, hi);
316
317 lo[0] = maxRect.xMin();
318 lo[1] = maxRect.yMin();
319 hi[0] = maxRect.xMax();
320 hi[1] = maxRect.yMax();
321
322 cnt += addTracks(g, 0, level, lo, hi);
323 }
324 return cnt;
325 }
326 #endif
327 #ifndef NEW_TRACKS
addTracks(dbTrackGrid * g,uint dir,uint level,int lo[2],int hi[2])328 uint dbBlockSearch::addTracks(dbTrackGrid* g,
329 uint dir,
330 uint level,
331 int lo[2],
332 int hi[2])
333 {
334 std::vector<int> trackXY(32000);
335
336 if (dir > 0) // horizontla
337 g->getGridY(trackXY);
338 else
339 g->getGridX(trackXY);
340
341 uint cnt = 0;
342 for (uint ii = 0; ii < trackXY.size(); ii++) {
343 int xy = trackXY[ii];
344 lo[dir] = xy;
345 hi[dir] = xy + 1;
346 cnt++;
347
348 Ath__searchBox bb;
349 bb.set(lo[0], lo[1], hi[0], hi[1], level, -1);
350 bb.setOwnerId(xy, 0);
351
352 _trackSdb->addBox(
353 lo[0], lo[1], hi[0], hi[1], level, g->getId(), ii, _block_track_id);
354
355 cnt++;
356 }
357 return cnt;
358 }
359 #endif
360
getViaLevel(dbSBox * s)361 uint dbBlockSearch::getViaLevel(dbSBox* s)
362 {
363 dbTechVia* via = s->getTechVia();
364 if (via != NULL) {
365 return via->getTopLayer()->getRoutingLevel();
366 /*
367 dbTechLayer * getTopLayer();
368 dbTechLayer * getBottomLayer();
369 */
370 } else {
371 dbVia* via = s->getBlockVia();
372 return via->getTopLayer()->getRoutingLevel();
373 }
374 }
getViaLevel(dbShape * s)375 uint dbBlockSearch::getViaLevel(dbShape* s)
376 {
377 dbTechVia* via = s->getTechVia();
378 if (via != NULL) {
379 return via->getTopLayer()->getRoutingLevel();
380 /*
381 dbTechLayer * getTopLayer();
382 dbTechLayer * getBottomLayer();
383 */
384 } else {
385 dbVia* via = s->getVia();
386 return via->getTopLayer()->getRoutingLevel();
387 }
388 }
389
getBlockObs(bool ignoreFlags)390 uint dbBlockSearch::getBlockObs(bool ignoreFlags)
391 {
392 if (!ignoreFlags && !_dcr->getSubMenuFlag(_blockMenuId, _block_obs_id))
393 return 0;
394
395 dbSet<dbObstruction> obstructions = _block->getObstructions();
396 dbSet<dbBlockage> blockages = _block->getBlockages();
397
398 int bcnt = obstructions.size() + blockages.size();
399
400 if (bcnt == 0)
401 return 0;
402
403 uint cnt = 0;
404 dbSet<dbObstruction>::iterator obs_itr;
405
406 for (obs_itr = obstructions.begin(); obs_itr != obstructions.end();
407 ++obs_itr) {
408 dbObstruction* obs = *obs_itr;
409
410 // dbInst * inst = obs->getInstance();
411 // if ( obs->isSlotObstruction() )
412 // if ( obs->isFillObstruction() )
413 // if ( obs->isPushedDown() )
414
415 dbBox* s = obs->getBBox();
416 uint level = s->getTechLayer()->getRoutingLevel();
417 cnt += _dcr->addBox(s->getId(),
418 _block_obs_id,
419 _blockMenuId,
420 level,
421 s->xMin(),
422 s->yMin(),
423 s->xMax(),
424 s->yMax(),
425 0);
426 }
427
428 dbSet<dbBlockage>::iterator blockage_itr;
429
430 for (blockage_itr = blockages.begin(); blockage_itr != blockages.end();
431 ++blockage_itr) {
432 dbBlockage* obs = *blockage_itr;
433
434 // dbInst * inst = obs->getInstance();
435 // if ( obs->isSlotObstruction() )
436 // if ( obs->isFillObstruction() )
437 // if ( obs->isPushedDown() )
438
439 dbBox* s = obs->getBBox();
440 uint level = 0;
441 if (s->getTechLayer() != NULL)
442 level = s->getTechLayer()->getRoutingLevel();
443
444 cnt += _dcr->addBox(s->getId(),
445 _block_obs_id,
446 _blockMenuId,
447 level,
448 s->xMin(),
449 s->yMin(),
450 s->xMax(),
451 s->yMax(),
452 0);
453 }
454
455 return cnt;
456 }
457
addInstBox(dbInst * inst)458 uint dbBlockSearch::addInstBox(dbInst* inst)
459 {
460 dbBox* s = inst->getBBox();
461
462 return _dcr->addBox(inst->getId(),
463 _inst_bb_id,
464 _instMenuId,
465 0,
466 s->xMin(),
467 s->yMin(),
468 s->xMax(),
469 s->yMax(),
470 0);
471 }
addBoxes(dbBTerm * bterm)472 uint dbBlockSearch::addBoxes(dbBTerm* bterm)
473 {
474 uint cnt = 0;
475 dbSet<dbBPin> bpins = bterm->getBPins();
476 dbSet<dbBPin>::iterator itr;
477
478 // TWG: Added bpins
479 for (itr = bpins.begin(); itr != bpins.end(); ++itr) {
480 dbBPin* bpin = *itr;
481
482 for (dbBox* box : bpin->getBoxes()) {
483 cnt += _dcr->addBox(box->getId(),
484 _block_pin_id,
485 _blockMenuId,
486 box->getTechLayer()->getRoutingLevel(),
487 box->xMin(),
488 box->yMin(),
489 box->xMax(),
490 box->yMax(),
491 0);
492 }
493 }
494
495 return cnt;
496 }
addBtermBoxes(dbSet<dbBTerm> & bterms,bool ignoreFlag)497 uint dbBlockSearch::addBtermBoxes(dbSet<dbBTerm>& bterms, bool ignoreFlag)
498 {
499 if (!(ignoreFlag || _dcr->getSubMenuFlag(_blockMenuId, _block_pin_id)))
500 return 0;
501
502 uint cnt = 0;
503 dbSet<dbBTerm>::iterator itr;
504 for (itr = bterms.begin(); itr != bterms.end(); ++itr) {
505 dbBTerm* bterm = *itr;
506
507 cnt += addBoxes(bterm);
508 }
509 return cnt;
510 }
getFirstShape(dbITerm * iterm,bool viaFlag,int & x1,int & y1,int & x2,int & y2)511 uint dbBlockSearch::getFirstShape(dbITerm* iterm,
512 bool viaFlag,
513 int& x1,
514 int& y1,
515 int& x2,
516 int& y2)
517 {
518 // dbInst *inst= iterm->getInst();
519 // uint cnt= 0;
520
521 dbITermShapeItr term_shapes;
522
523 dbShape s;
524 for (term_shapes.begin(iterm); term_shapes.next(s);) {
525 if (s.isVia()) {
526 if (viaFlag)
527 continue;
528 } else {
529 x1 = s.xMin();
530 y1 = s.yMin();
531 x2 = s.xMax();
532 y2 = s.yMax();
533 return s.getTechLayer()->getRoutingLevel();
534 break;
535 }
536 }
537 return 0;
538 }
getItermShapesWithViaShapes(dbITerm * iterm)539 uint dbBlockSearch::getItermShapesWithViaShapes(dbITerm* iterm)
540 {
541 const char* tcut = "tcut";
542 const char* bcut = "bcut";
543
544 // dbInst *inst= iterm->getInst();
545 uint cnt = 0;
546 uint itermId = iterm->getId();
547
548 dbITermShapeItr term_shapes(true);
549
550 uint shapeId = 0;
551
552 dbShape s;
553 for (term_shapes.begin(iterm); term_shapes.next(s);) {
554 if (s.isViaBox()) {
555 int x1 = s.xMin();
556 int y1 = s.yMin();
557 int x2 = s.xMax();
558 int y2 = s.yMax();
559
560 if (s.getTechLayer()->getType() != dbTechLayerType::CUT) {
561 uint level = s.getTechLayer()->getRoutingLevel();
562
563 cnt += _dcr->addBox(
564 itermId, _inst_pin_id, _instMenuId, level, x1, y1, x2, y2, shapeId);
565 } else {
566 dbTechVia* via = s.getTechVia();
567 uint topLevel = via->getTopLayer()->getRoutingLevel();
568 uint botLevel = via->getBottomLayer()->getRoutingLevel();
569
570 cnt += _dcr->addBox(itermId,
571 _inst_pin_id,
572 _instMenuId,
573 topLevel,
574 x1,
575 y1,
576 x2,
577 y2,
578 shapeId,
579 tcut);
580 cnt += _dcr->addBox(itermId,
581 _inst_pin_id,
582 _instMenuId,
583 botLevel,
584 x1,
585 y1,
586 x2,
587 y2,
588 shapeId,
589 bcut);
590 }
591 } else {
592 cnt += _dcr->addBox(iterm->getId(),
593 _inst_pin_id,
594 _instMenuId,
595 s.getTechLayer()->getRoutingLevel(),
596 s.xMin(),
597 s.yMin(),
598 s.xMax(),
599 s.yMax(),
600 0);
601 }
602 }
603 return cnt;
604 }
getItermShapesNoVias(dbITerm * iterm)605 uint dbBlockSearch::getItermShapesNoVias(dbITerm* iterm)
606 {
607 // dbInst *inst= iterm->getInst();
608 uint cnt = 0;
609 // uint itermId= iterm->getId();
610
611 dbITermShapeItr term_shapes;
612
613 dbShape s;
614 for (term_shapes.begin(iterm); term_shapes.next(s);) {
615 if (s.isVia()) {
616 continue;
617 } else {
618 cnt += _dcr->addBox(iterm->getId(),
619 _inst_pin_id,
620 _instMenuId,
621 s.getTechLayer()->getRoutingLevel(),
622 s.xMin(),
623 s.yMin(),
624 s.xMax(),
625 s.yMax(),
626 0);
627 }
628 }
629 return cnt;
630 }
getItermShapes(dbInst * inst,bool viaFlag)631 uint dbBlockSearch::getItermShapes(dbInst* inst, bool viaFlag)
632 {
633 uint cnt = 0;
634 dbSet<dbITerm> iterms = inst->getITerms();
635
636 dbSet<dbITerm>::iterator iterm_itr;
637
638 for (iterm_itr = iterms.begin(); iterm_itr != iterms.end(); ++iterm_itr) {
639 dbITerm* iterm = *iterm_itr;
640 if (viaFlag)
641 cnt += getItermShapesWithViaShapes(iterm);
642 else
643 cnt += getItermShapesNoVias(iterm);
644 }
645 return cnt;
646 }
647
getFirstInstObsShape(dbInst * inst,bool viaFlag,int & x1,int & y1,int & x2,int & y2)648 uint dbBlockSearch::getFirstInstObsShape(dbInst* inst,
649 bool viaFlag,
650 int& x1,
651 int& y1,
652 int& x2,
653 int& y2)
654 {
655 // uint cnt= 0;
656
657 dbInstShapeItr obs_shapes;
658
659 dbShape s;
660 for (obs_shapes.begin(inst, dbInstShapeItr::OBSTRUCTIONS);
661 obs_shapes.next(s);) {
662 if (s.isVia()) {
663 if (viaFlag)
664 continue;
665 } else {
666 x1 = s.xMin();
667 y1 = s.yMin();
668 x2 = s.xMax();
669 y2 = s.yMax();
670
671 return s.getTechLayer()->getRoutingLevel();
672 }
673 }
674 return 0;
675 }
getInstObs(dbInst * inst,bool viaFlag)676 uint dbBlockSearch::getInstObs(dbInst* inst, bool viaFlag)
677 {
678 uint cnt = 0;
679
680 dbInstShapeItr obs_shapes;
681
682 dbShape s;
683 for (obs_shapes.begin(inst, dbInstShapeItr::OBSTRUCTIONS);
684 obs_shapes.next(s);) {
685 if (s.isVia()) {
686 if (viaFlag)
687 continue;
688 } else {
689 cnt += _dcr->addBox(inst->getId(),
690 _inst_obs_id,
691 _instMenuId,
692 s.getTechLayer()->getRoutingLevel(),
693 s.xMin(),
694 s.yMin(),
695 s.xMax(),
696 s.yMax(),
697 0);
698 }
699 }
700 return cnt;
701 }
addInstShapes(dbInst * inst,bool vias,bool pinFlag,bool obsFlag)702 uint dbBlockSearch::addInstShapes(dbInst* inst,
703 bool vias,
704 bool pinFlag,
705 bool obsFlag)
706 {
707 uint cnt = 0;
708 if (pinFlag) {
709 cnt += getItermShapes(inst, false);
710 if (vias)
711 cnt += getItermShapes(inst, true);
712 }
713 if (obsFlag) {
714 cnt += getInstObs(inst, false);
715 if (vias)
716 cnt += getInstObs(inst, true);
717 }
718 return cnt;
719 }
720
getInstBoxes(int x1,int y1,int x2,int y2,std::vector<dbInst * > & result)721 uint dbBlockSearch::getInstBoxes(int x1,
722 int y1,
723 int x2,
724 int y2,
725 std::vector<dbInst*>& result)
726 {
727 _instSdb->searchBoxIds(x1, y1, x2, y2);
728
729 uint cnt = 0;
730 _instSdb->startIterator();
731 uint wireId = 0;
732 while ((wireId = _instSdb->getNextWireId()) > 0) {
733 uint dbBoxId;
734 uint id2;
735 uint wtype;
736 _instSdb->getIds(wireId, &dbBoxId, &id2, &wtype);
737 dbInst* inst = dbInst::getInst(_block, dbBoxId);
738
739 result.push_back(inst);
740 cnt++;
741 }
742 return cnt;
743 }
744
getInstBoxes(bool)745 void dbBlockSearch::getInstBoxes(bool /* unused: ignoreFlag */)
746 {
747 if (_instSdb == NULL)
748 return;
749
750 if (!_dcr->getSubMenuFlag(_instMenuId, _inst_bb_id))
751 return;
752
753 int x1, y1, x2, y2;
754 _dcr->getBbox(&x1, &y1, &x2, &y2);
755
756 _instSdb->searchBoxIds(x1, y1, x2, y2);
757 _instSdb->makeGuiBoxes(
758 _dcr, _instMenuId, _inst_bb_id, false); // use coords from Sdb
759
760 /* Can get box ids and use DB box coords
761
762 while (uint boxId= zui->getNextId()) {
763 dbBox *bb= dbBox::getBox(_block, boxId);
764 zui->addBox(bb, Ath_box__bbox, 0);
765 }
766 */
767 }
getInstShapes(bool vias,bool pins,bool obs)768 void dbBlockSearch::getInstShapes(bool vias, bool pins, bool obs)
769 {
770 if (_instSdb == NULL)
771 return;
772
773 bool obsFlag = obs || _dcr->getSubMenuFlag(_instMenuId, _inst_obs_id);
774 bool pinFlag = pins || _dcr->getSubMenuFlag(_instMenuId, _inst_pin_id);
775
776 if (!(obsFlag || pinFlag))
777 return;
778
779 uint cnt = 0;
780
781 int x1, y1, x2, y2;
782 _dcr->getBbox(&x1, &y1, &x2, &y2);
783
784 _instSdb->searchBoxIds(x1, y1, x2, y2);
785
786 _instSdb->startIterator();
787 uint wireId = 0;
788 while ((wireId = _instSdb->getNextWireId()) > 0) {
789 /*
790 int x1, y1, x2, y2;
791 uint level, id1, id2, wtype;
792 _instSdb->getBox(wireId, &x1, &y1, &x2, &y2, &level, &id1, &id2, &wtype);
793 */
794 uint dbBoxId;
795 uint id2;
796 uint wtype;
797 _instSdb->getIds(wireId, &dbBoxId, &id2, &wtype);
798 dbInst* inst = dbInst::getInst(_block, dbBoxId);
799
800 /* DKF 07/05/05 dbBox *bb= dbBox::getBox(_block, dbBoxId);
801 dbInst *inst= (dbInst *) bb->getBoxOwner();
802 */
803 cnt += addInstShapes(inst, vias, pinFlag, obsFlag);
804 }
805 }
806 /*
807 void dbBlockSearch::white(Ath__zui *zui, Ath__hierType hier, bool ignoreFlag)
808 {
809 if (!ignoreFlag && !zui->getDbFlag("inst/white"))
810 return;
811
812 if (_dbInstSearch==NULL)
813 return;
814
815 Ath__searchBox bb(zui->getBbox(), 0, 0);
816 zui->getIdTable()->resetCnt();
817 _dbInstSearch->white(&bb, 0, 0, zui->getIdTable(), false); //single grid
818
819 while (uint id= zui->getNextId())
820 {
821 Ath__wire *w= _dbInstSearch->getWirePtr(id);
822
823 Ath__searchBox bb;
824 w->getCoords(&bb);
825 bb.setLevel(5);
826
827 zui->addBox(&bb, Ath_hier__block, Ath_box__white, id);
828
829 _dbInstSearch->releaseWire(id);
830 }
831 }
832 void dbBlockSearch::getWireIds(Ath__array1D<uint> *wireIdTable,
833 Ath__array1D<uint> *idtable)
834 {
835 // remove duplicate entries
836
837 for (uint ii= 0; ii<wireIdTable->getCnt(); ii++)
838 {
839 uint wid= wireIdTable->get(ii);
840 Ath__wire *w= _dbNetWireSearch->getWirePtr(wid);
841
842 uint srcId= w->getSrcId();
843 if (srcId>0) {
844 w= _dbNetWireSearch->getWirePtr(srcId);
845 }
846 if (w->_ext>0)
847 continue;
848
849 w->_ext= 1;
850 idtable->add(w->_id);
851 }
852
853 for (uint jj= 0; jj<wireIdTable->getCnt(); jj++)
854 {
855 Ath__wire *w= _dbNetWireSearch->getWirePtr( wireIdTable->get(jj)
856 );
857
858 w->_ext= 0;
859 }
860 }
861 uint dbBlockSearch::getDbBoxId(uint wid, uint wireType)
862 {
863 Ath__wire *w= _dbNetWireSearch->getWirePtr(wid);
864 if (w->_flags!=wireType)
865 return 0;
866
867 return w->getBoxId();
868 }
869 */
getShapeLevel(dbSBox * s,bool wireVia)870 int dbBlockSearch::getShapeLevel(dbSBox* s, bool wireVia)
871 {
872 if (s->isVia()) {
873 if (wireVia) // request for wire
874 return -1;
875
876 return getViaLevel(s);
877 } else {
878 if (!wireVia) // request for via
879 return -1;
880
881 return s->getTechLayer()->getRoutingLevel();
882 }
883 }
getShapeLevel(dbShape * s,bool wireVia)884 int dbBlockSearch::getShapeLevel(dbShape* s, bool wireVia)
885 {
886 if (s->isVia()) {
887 if (wireVia) // request for wire
888 return -1;
889
890 return getViaLevel(s);
891 } else {
892 if (!wireVia) // request for via
893 return -1;
894
895 return s->getTechLayer()->getRoutingLevel();
896 }
897 }
getNet(uint wireId,uint shapeId)898 dbNet* dbBlockSearch::getNet(uint wireId, uint shapeId)
899 {
900 // wireVia=true, wire
901 if (shapeId > 0) {
902 dbShape s;
903 dbWire* w = dbWire::getWire(_block, wireId);
904 w->getShape(shapeId, s);
905
906 return w->getNet();
907 } else {
908 dbSBox* s = dbSBox::getSBox(_block, wireId);
909
910 dbSWire* sw = (dbSWire*) s->getBoxOwner();
911 return sw->getNet();
912 }
913 }
addSBox(uint menuId,uint subMenuId,bool wireVia,uint wireId)914 uint dbBlockSearch::addSBox(uint menuId,
915 uint subMenuId,
916 bool wireVia,
917 uint wireId)
918 {
919 dbSBox* s = dbSBox::getSBox(_block, wireId);
920
921 int level = getShapeLevel(s, wireVia);
922 if (level < 0)
923 return 0;
924
925 dbSWire* sw = (dbSWire*) s->getBoxOwner();
926 dbNet* net = sw->getNet();
927
928 return _dcr->addBox(net->getId(),
929 subMenuId,
930 menuId,
931 level,
932 s->xMin(),
933 s->yMin(),
934 s->xMax(),
935 s->yMax(),
936 0);
937 }
addWireCoords(dbShape & s,uint menuId,uint subMenuId,uint netId,uint shapeId)938 uint dbBlockSearch::addWireCoords(dbShape& s,
939 uint menuId,
940 uint subMenuId,
941 uint netId,
942 uint shapeId)
943 {
944 int level = s.getTechLayer()->getRoutingLevel();
945
946 int x1 = s.xMin();
947 int y1 = s.yMin();
948 int x2 = s.xMax();
949 int y2 = s.yMax();
950
951 return _dcr->addBox(netId, subMenuId, menuId, level, x1, y1, x2, y2, shapeId);
952 }
addViaCoords(dbShape & viaShape,uint menuId,uint subMenuId,uint netId,uint shapeId)953 uint dbBlockSearch::addViaCoords(dbShape& viaShape,
954 uint menuId,
955 uint subMenuId,
956 uint netId,
957 uint shapeId)
958 {
959 std::vector<dbShape> shapes;
960 dbShape::getViaBoxes(viaShape, shapes);
961
962 // dbTechVia *via= viaShape.getTechVia();
963
964 return addViaBoxes(viaShape, menuId, subMenuId, netId, shapeId);
965 }
966
addWireViaCoords(uint menuId,uint subMenuId,bool wireVia,uint wireId,uint shapeId)967 uint dbBlockSearch::addWireViaCoords(uint menuId,
968 uint subMenuId,
969 bool wireVia,
970 uint wireId,
971 uint shapeId)
972 {
973 // wireVia=true, wire
974 if (shapeId > 0) {
975 dbShape s;
976 dbWire* w = dbWire::getWire(_block, wireId);
977 w->getShape(shapeId, s);
978
979 dbNet* net = w->getNet();
980
981 if (s.isVia()) {
982 if (!wireVia)
983 return addViaBoxes(s, menuId, subMenuId, net->getId(), shapeId);
984 // return addViaCoords(s, menuId, subMenuId, net->getId(), shapeId);
985 else
986 return 0;
987 }
988
989 int level = getShapeLevel(&s, wireVia);
990
991 int x1 = s.xMin();
992 int y1 = s.yMin();
993 int x2 = s.xMax();
994 int y2 = s.yMax();
995 uint flag = _dcr->addBox(
996 net->getId(), subMenuId, menuId, level, x1, y1, x2, y2, shapeId);
997
998 return flag;
999 } else {
1000 dbSBox* s = dbSBox::getSBox(_block, wireId);
1001
1002 int level = getShapeLevel(s, wireVia);
1003 if (level < 0)
1004 return 0;
1005
1006 dbSWire* sw = (dbSWire*) s->getBoxOwner();
1007 dbNet* net = sw->getNet();
1008
1009 return _dcr->addBox(net->getId(),
1010 subMenuId,
1011 menuId,
1012 level,
1013 s->xMin(),
1014 s->yMin(),
1015 s->xMax(),
1016 s->yMax(),
1017 0);
1018 }
1019 }
addViaBoxes(dbShape & sVia,uint menuId,uint subMenuId,uint id,uint shapeId)1020 uint dbBlockSearch::addViaBoxes(dbShape& sVia,
1021 uint menuId,
1022 uint subMenuId,
1023 uint id,
1024 uint shapeId)
1025 {
1026 uint cnt = 0;
1027
1028 const char* tcut = "tcut";
1029 const char* bcut = "bcut";
1030
1031 std::vector<dbShape> shapes;
1032 dbShape::getViaBoxes(sVia, shapes);
1033 uint topLevel = 0;
1034 uint botLevel = getViaLevels(sVia, topLevel);
1035
1036 // uint topLevel= via->getTopLayer()->getRoutingLevel();
1037 // uint botLevel= via->getBottomLayer()->getRoutingLevel();
1038
1039 std::vector<dbShape>::iterator shape_itr;
1040
1041 for (shape_itr = shapes.begin(); shape_itr != shapes.end(); ++shape_itr) {
1042 dbShape s = *shape_itr;
1043
1044 if (s.getTechLayer()->getType() == dbTechLayerType::CUT)
1045 continue;
1046
1047 int x1 = s.xMin();
1048 int y1 = s.yMin();
1049 int x2 = s.xMax();
1050 int y2 = s.yMax();
1051
1052 uint level = s.getTechLayer()->getRoutingLevel();
1053
1054 cnt += _dcr->addBox(id, subMenuId, menuId, level, x1, y1, x2, y2, shapeId);
1055 }
1056 notice(0, "_skipCutBoxes=%d\n", _skipCutBoxes);
1057 if (_skipCutBoxes)
1058 return cnt;
1059 for (shape_itr = shapes.begin(); shape_itr != shapes.end(); ++shape_itr) {
1060 dbShape s = *shape_itr;
1061
1062 if (s.getTechLayer()->getType() != dbTechLayerType::CUT)
1063 continue;
1064
1065 int x1 = s.xMin();
1066 int y1 = s.yMin();
1067 int x2 = s.xMax();
1068 int y2 = s.yMax();
1069
1070 cnt += _dcr->addBox(
1071 id, subMenuId, menuId, topLevel, x1, y1, x2, y2, shapeId, tcut);
1072 cnt += _dcr->addBox(
1073 id, subMenuId, menuId, botLevel, x1, y1, x2, y2, shapeId, bcut);
1074 }
1075 return cnt;
1076 }
addViaBoxes(dbBox * viaBox,uint menuId,uint subMenuId,uint netId,uint shapeId)1077 uint dbBlockSearch::addViaBoxes(dbBox* viaBox,
1078 uint menuId,
1079 uint subMenuId,
1080 uint netId,
1081 uint shapeId)
1082 {
1083 uint cnt = 0;
1084
1085 const char* tcut = "tcut";
1086 const char* bcut = "bcut";
1087
1088 uint topLevel = 0;
1089 uint botLevel = getViaLevels(viaBox, topLevel);
1090
1091 std::vector<dbShape> shapes;
1092 viaBox->getViaBoxes(shapes);
1093
1094 std::vector<dbShape>::iterator shape_itr;
1095
1096 for (shape_itr = shapes.begin(); shape_itr != shapes.end(); ++shape_itr) {
1097 dbShape s = *shape_itr;
1098
1099 if (s.getTechLayer()->getType() == dbTechLayerType::CUT)
1100 continue;
1101
1102 int x1 = s.xMin();
1103 int y1 = s.yMin();
1104 int x2 = s.xMax();
1105 int y2 = s.yMax();
1106
1107 uint level = s.getTechLayer()->getRoutingLevel();
1108
1109 cnt += _dcr->addBox(
1110 netId, subMenuId, menuId, level, x1, y1, x2, y2, shapeId);
1111 }
1112 notice(0, "_skipCutBoxes=%d\n", _skipCutBoxes);
1113 if (_skipCutBoxes)
1114 return cnt;
1115
1116 for (shape_itr = shapes.begin(); shape_itr != shapes.end(); ++shape_itr) {
1117 dbShape s = *shape_itr;
1118
1119 if (s.getTechLayer()->getType() != dbTechLayerType::CUT)
1120 continue;
1121
1122 int x1 = s.xMin();
1123 int y1 = s.yMin();
1124 int x2 = s.xMax();
1125 int y2 = s.yMax();
1126
1127 cnt += _dcr->addBox(
1128 netId, subMenuId, menuId, topLevel, x1, y1, x2, y2, shapeId, tcut);
1129 cnt += _dcr->addBox(
1130 netId, subMenuId, menuId, botLevel, x1, y1, x2, y2, shapeId, bcut);
1131 }
1132 return cnt;
1133 }
getViaLevels(dbBox * s,uint & top)1134 uint dbBlockSearch::getViaLevels(dbBox* s, uint& top)
1135 {
1136 dbTechVia* via = s->getTechVia();
1137 if (via != NULL) {
1138 uint topLevel = via->getTopLayer()->getRoutingLevel();
1139 uint botLevel = via->getBottomLayer()->getRoutingLevel();
1140 top = topLevel;
1141
1142 return botLevel;
1143 } else {
1144 top = 0;
1145 dbVia* via = s->getBlockVia();
1146 if (via == NULL) // should be error????
1147 return 0;
1148 uint topLevel = via->getTopLayer()->getRoutingLevel();
1149 uint botLevel = via->getBottomLayer()->getRoutingLevel();
1150 top = topLevel;
1151
1152 return botLevel;
1153 }
1154 }
getViaLevels(dbShape & s,uint & top)1155 uint dbBlockSearch::getViaLevels(dbShape& s, uint& top)
1156 {
1157 dbTechVia* via = s.getTechVia();
1158 if (via != NULL) {
1159 uint topLevel = via->getTopLayer()->getRoutingLevel();
1160 uint botLevel = via->getBottomLayer()->getRoutingLevel();
1161 top = topLevel;
1162
1163 return botLevel;
1164 } else {
1165 top = 0;
1166 dbVia* via = s.getVia();
1167 if (via == NULL) // should be error????
1168 return 0;
1169 uint topLevel = via->getTopLayer()->getRoutingLevel();
1170 uint botLevel = via->getBottomLayer()->getRoutingLevel();
1171 top = topLevel;
1172
1173 return botLevel;
1174 }
1175 }
addViaCoordsFromWire(uint menuId,uint subMenuId,uint netId,uint shapeId)1176 uint dbBlockSearch::addViaCoordsFromWire(uint menuId,
1177 uint subMenuId,
1178 uint netId,
1179 uint shapeId)
1180 {
1181 /* TODO
1182 uint labelCnt= 2;
1183 strcpy(_labelName[0], "R=");
1184 strcpy(_labelName[1], "C=");
1185 */
1186 uint cnt = 0;
1187
1188 if (shapeId > 0) { // signal via
1189 dbNet* net = dbNet::getNet(_block, netId);
1190 dbWire* w = net->getWire();
1191
1192 dbShape viaShape1;
1193 if (w->getPrevVia(shapeId, viaShape1)) {
1194 cnt = addViaBoxes(viaShape1, menuId, subMenuId, net->getId(), shapeId);
1195 }
1196 dbShape viaShape2;
1197 if (w->getNextVia(shapeId, viaShape2)) {
1198 cnt = addViaBoxes(viaShape2, menuId, subMenuId, net->getId(), shapeId);
1199 }
1200 } else { // power via
1201 uint sboxId = netId;
1202
1203 dbBox* viaBox
1204 = (dbBox*) dbSBox::getSBox(_block, sboxId); // netId is box id
1205 if (!viaBox->isVia())
1206 return 0;
1207
1208 cnt = addViaBoxes(viaBox, menuId, subMenuId, sboxId, 0);
1209 }
1210 return cnt;
1211 }
1212
getViasFromWires(ZPtr<ISdb> sdb,uint menuId,uint subMenuId,uint wireMenuId,dbNet * targetNet,bool excludeFlag)1213 uint dbBlockSearch::getViasFromWires(ZPtr<ISdb> sdb,
1214 uint menuId,
1215 uint subMenuId,
1216 uint wireMenuId,
1217 dbNet* targetNet,
1218 bool excludeFlag)
1219 {
1220 uint cnt = 0;
1221 sdb->startIterator();
1222 uint wid = 0;
1223 while ((wid = sdb->getNextWireId()) > 0) {
1224 uint netId, shapeId;
1225 uint wtype;
1226 sdb->getIds(wid, &netId, &shapeId, &wtype);
1227
1228 if (wireMenuId != wtype) // TO_TEST
1229 continue;
1230
1231 dbNet* net = NULL;
1232 if (shapeId == 0) {
1233 dbSBox* b = dbSBox::getSBox(_block, netId);
1234 net = (dbNet*) b->getBoxOwner();
1235 } else {
1236 net = dbNet::getNet(_block, netId);
1237 }
1238 if (targetNet == NULL) {
1239 cnt += addViaCoordsFromWire(menuId, subMenuId, netId, shapeId);
1240 continue;
1241 }
1242 if (excludeFlag && (net == targetNet))
1243 continue;
1244 if (!excludeFlag && (net != targetNet))
1245 continue;
1246
1247 cnt += addViaCoordsFromWire(menuId, subMenuId, netId, shapeId);
1248 }
1249 return cnt;
1250 }
getTrackXY(int boxXY,int org,int count,int step)1251 int dbBlockSearch::getTrackXY(int boxXY, int org, int count, int step)
1252 {
1253 int startTrackNum = (boxXY - org) / step;
1254 if (startTrackNum > count)
1255 startTrackNum = count;
1256 if (startTrackNum <= 0)
1257 startTrackNum = 0;
1258
1259 int xy = org + startTrackNum * step;
1260
1261 return xy;
1262 }
getTracks(dbTrackGrid * g,int org,int count,int step,int * bb_ll,int * bb_ur,uint level,uint dir)1263 uint dbBlockSearch::getTracks(dbTrackGrid* g,
1264 int org,
1265 int count,
1266 int step,
1267 int* bb_ll,
1268 int* bb_ur,
1269 uint level,
1270 uint dir)
1271 {
1272 uint cnt = 0;
1273
1274 int ll[2] = {bb_ll[0], bb_ll[1]};
1275 int ur[2] = {bb_ur[0], bb_ur[1]};
1276
1277 int XY1 = getTrackXY(bb_ll[dir], org, count, step);
1278 int XY2 = getTrackXY(bb_ur[dir], org, count, step);
1279
1280 for (int xy = XY1; xy <= XY2; xy += step) {
1281 ll[dir] = xy;
1282 ur[dir] = xy + 4;
1283
1284 cnt += _dcr->addBox(g->getId(),
1285 _block_track_id,
1286 _blockMenuId,
1287 level,
1288 ll[0],
1289 ll[1],
1290 ur[0],
1291 ur[1],
1292 dir + 1);
1293 }
1294 return cnt;
1295 }
1296 #ifdef NEW_TRACKS
getTracks(bool ignoreLayers)1297 uint dbBlockSearch::getTracks(bool ignoreLayers)
1298 {
1299 if (!_dcr->getSubMenuFlag(_blockMenuId, _block_track_id))
1300 return 0;
1301
1302 Rect die;
1303 _block->getDieArea(die);
1304
1305 int x1, y1, x2, y2;
1306 _dcr->getBbox(&x1, &y1, &x2, &y2);
1307
1308 x1 = MAX(x1, die.xMin());
1309 y1 = MAX(y1, die.yMin());
1310 x2 = MIN(x2, die.xMax());
1311 y2 = MIN(y2, die.yMax());
1312
1313 int bb_ll[2] = {x1, y1};
1314 int bb_ur[2] = {x2, y2};
1315
1316 bool* excludeTable = _dcr->getExcludeLayerTable();
1317
1318 dbSet<dbTrackGrid> grids = _block->getTrackGrids();
1319 dbSet<dbTrackGrid>::iterator itr;
1320
1321 uint cnt = 0;
1322 for (itr = grids.begin(); itr != grids.end(); ++itr) {
1323 dbTrackGrid* grid = *itr;
1324 dbTechLayer* layer = grid->getTechLayer();
1325 uint level = layer->getRoutingLevel();
1326 if (excludeTable[level])
1327 continue;
1328
1329 int i;
1330 for (i = 0; i < grid->getNumGridPatternsX(); ++i) {
1331 int orgX, count, step;
1332 grid->getGridPatternX(i, orgX, count, step);
1333
1334 cnt += getTracks(grid, orgX, count, step, bb_ll, bb_ur, level, 0);
1335 }
1336
1337 for (i = 0; i < grid->getNumGridPatternsY(); ++i) {
1338 int orgY, count, step;
1339 grid->getGridPatternY(i, orgY, count, step);
1340
1341 cnt += getTracks(grid, orgY, count, step, bb_ll, bb_ur, level, 1);
1342 }
1343 }
1344 return cnt;
1345 }
1346 #else
getTracks(bool)1347 uint dbBlockSearch::getTracks(bool /* unused: ignoreLayers */)
1348 {
1349 if (_trackSdb == NULL)
1350 return 0;
1351
1352 if (!_dcr->getSubMenuFlag(_blockMenuId, _block_track_id))
1353 return 0;
1354
1355 int x1, y1, x2, y2;
1356 _dcr->getBbox(&x1, &y1, &x2, &y2);
1357
1358 bool* exludeTable = _dcr->getExcludeLayerTable();
1359 _trackSdb->searchWireIds(x1, y1, x2, y2, false, exludeTable);
1360
1361 return _trackSdb->makeGuiBoxes(
1362 _dcr, _blockMenuId, _block_track_id, false, 0); // use coords from Sdb
1363 }
1364 #endif
getPowerWireVias(ZPtr<ISdb> sdb,dbNet * targetNet,bool vias,std::vector<dbBox * > & viaTable)1365 uint dbBlockSearch::getPowerWireVias(ZPtr<ISdb> sdb,
1366 dbNet* targetNet,
1367 bool vias,
1368 std::vector<dbBox*>& viaTable)
1369 {
1370 sdb->startIterator();
1371 uint wid = 0;
1372 while ((wid = sdb->getNextWireId()) > 0) {
1373 uint netId, shapeId;
1374 uint wtype;
1375 sdb->getIds(wid, &netId, &shapeId, &wtype);
1376
1377 dbNet* net = NULL;
1378 if (shapeId > 0)
1379 continue;
1380
1381 uint sboxId = netId;
1382 dbSBox* s = (dbSBox*) dbSBox::getSBox(_block, sboxId); // netId is box id
1383
1384 if (vias && !s->isVia())
1385 continue;
1386 if (!vias && s->isVia())
1387 continue;
1388
1389 net = s->getSWire()->getNet();
1390 if ((targetNet != NULL) && (net != targetNet))
1391 continue;
1392
1393 viaTable.push_back(s);
1394 }
1395 return viaTable.size();
1396 }
getPowerWires(int x1,int y1,int x2,int y2,int layer,dbNet * targetNet,std::vector<dbBox * > & viaTable)1397 uint dbBlockSearch::getPowerWires(int x1,
1398 int y1,
1399 int x2,
1400 int y2,
1401 int layer,
1402 dbNet* targetNet,
1403 std::vector<dbBox*>& viaTable)
1404 {
1405 if (_netSdb == NULL)
1406 return 0;
1407
1408 bool exludeTable[16];
1409 for (uint i = 0; i < 16; i++)
1410 exludeTable[i] = true;
1411
1412 exludeTable[layer] = false;
1413 uint cnt = 0;
1414
1415 _netSdb->searchWireIds(x1, y1, x2, y2, false, exludeTable);
1416 cnt = getPowerWireVias(_netSdb, targetNet, false, viaTable);
1417 return cnt;
1418 }
getPowerWiresAndVias(int x1,int y1,int x2,int y2,int layer,dbNet * targetNet,bool power_wires,std::vector<dbBox * > & viaTable)1419 uint dbBlockSearch::getPowerWiresAndVias(int x1,
1420 int y1,
1421 int x2,
1422 int y2,
1423 int layer,
1424 dbNet* targetNet,
1425 bool power_wires,
1426 std::vector<dbBox*>& viaTable)
1427 {
1428 if ((_netSdb == NULL) || (_netViaSdb == NULL))
1429 return 0;
1430
1431 bool exludeTable[16];
1432 for (uint i = 0; i < 16; i++)
1433 exludeTable[i] = true;
1434
1435 exludeTable[layer] = false;
1436 uint cnt = 0;
1437
1438 if (power_wires) {
1439 _netSdb->searchWireIds(x1, y1, x2, y2, false, exludeTable);
1440 cnt = getPowerWireVias(_netSdb, targetNet, false, viaTable);
1441 } else {
1442 _netViaSdb->searchWireIds(x1, y1, x2, y2, true, exludeTable);
1443 cnt = getPowerWireVias(_netViaSdb, targetNet, true, viaTable);
1444 }
1445 return cnt;
1446 }
getWiresAndVias_all(dbNet * targetNet,bool ignoreFlag)1447 uint dbBlockSearch::getWiresAndVias_all(dbNet* targetNet, bool ignoreFlag)
1448 {
1449 if (_netSdb == NULL)
1450 return 0;
1451
1452 bool signal_wires = _dcr->getSubMenuFlag(_signalMenuId, _signal_wire_id);
1453 bool signal_vias = _dcr->getSubMenuFlag(_signalMenuId, _signal_via_id);
1454 bool power_wires = _dcr->getSubMenuFlag(_powerMenuId, _power_wire_id);
1455 bool power_vias = _dcr->getSubMenuFlag(_powerMenuId, _power_via_id);
1456
1457 if ((!ignoreFlag)
1458 && (!(signal_wires || signal_vias || power_wires || power_vias)))
1459
1460 return 0;
1461
1462 uint excludeNetId = 0;
1463 if (targetNet != NULL)
1464 excludeNetId = targetNet->getId();
1465
1466 uint cnt = 0;
1467
1468 int x1, y1, x2, y2;
1469 _dcr->getBbox(&x1, &y1, &x2, &y2);
1470
1471 bool* exludeTable = NULL;
1472 if (!signal_vias) // get all layers
1473 exludeTable = _dcr->getExcludeLayerTable();
1474
1475 // _netSdb->searchWireIds(x1, y1, x2, y2, true, exludeTable);
1476 _netSdb->searchWireIds(x1, y1, x2, y2, false, exludeTable);
1477
1478 if (power_wires)
1479 _netSdb->makeGuiBoxes(_dcr,
1480 _powerMenuId,
1481 _power_wire_id,
1482 false,
1483 excludeNetId); // use coords from Sdb
1484
1485 if (power_vias) {
1486 _netViaSdb->searchWireIds(x1, y1, x2, y2, true, exludeTable);
1487 getViasFromWires(
1488 _netViaSdb, _powerMenuId, _power_via_id, _power_via_id, NULL, false);
1489 //_netViaSdb->makeGuiBoxes(_dcr, _powerMenuId, _power_via_id, false,
1490 // excludeNetId); // use coords from Sdb
1491 }
1492
1493 if (signal_wires)
1494 _netSdb->makeGuiBoxes(_dcr,
1495 _signalMenuId,
1496 _signal_wire_id,
1497 false,
1498 excludeNetId); // use coords from Sdb
1499
1500 if (signal_vias)
1501 getViasFromWires(
1502 _netSdb, _signalMenuId, _signal_via_id, _signal_wire_id, NULL, false);
1503 //_netViaSdb->makeGuiBoxes(_dcr, _signalMenuId, _signal_via_id, false,
1504 // excludeNetId); // use coords from Sdb
1505
1506 return cnt;
1507 }
getWiresClipped(dbNet * targetNet,uint halo,bool ignoreFlag)1508 uint dbBlockSearch::getWiresClipped(dbNet* targetNet,
1509 uint halo,
1510 bool ignoreFlag)
1511 {
1512 if (_netSdb == NULL)
1513 return 0;
1514
1515 bool signal_wires = _dcr->getSubMenuFlag(_signalMenuId, _signal_wire_id);
1516 bool power_wires = _dcr->getSubMenuFlag(_powerMenuId, _power_wire_id);
1517
1518 if ((!ignoreFlag) && (!(signal_wires || power_wires)))
1519 return 0;
1520
1521 uint excludeNetId = 0;
1522 if (targetNet != NULL)
1523 excludeNetId = targetNet->getId();
1524
1525 int x1, y1, x2, y2;
1526 _dcr->getBbox(&x1, &y1, &x2, &y2);
1527 bool* exludeTable = _dcr->getExcludeLayerTable();
1528 uint cnt = 0;
1529
1530 dbWire* wire = targetNet->getWire();
1531
1532 if (wire == NULL)
1533 return 0;
1534
1535 dbWireShapeItr shapes;
1536 dbShape s;
1537 for (shapes.begin(wire); shapes.next(s);) {
1538 // uint level= 0;
1539
1540 // int shapeId= shapes.getShapeId();
1541
1542 if (s.isVia())
1543 continue;
1544 // level= s.getTechLayer()->getRoutingLevel();
1545
1546 int sx1 = s.xMin() - halo;
1547 int sy1 = s.yMin() - halo;
1548 int sx2 = s.xMax() + halo;
1549 int sy2 = s.yMax() + halo;
1550
1551 if (_dcr->clipBox(sx1, sy1, sx2, sy2)) {
1552 _netSdb->searchWireIds(sx1, sy1, sx2, sy2, true, exludeTable);
1553
1554 _dcr->setSearchBox(sx1, sy1, sx2, sy2);
1555
1556 if (power_wires)
1557 _netSdb->makeGuiBoxes(_dcr,
1558 _powerMenuId,
1559 _power_wire_id,
1560 false,
1561 excludeNetId); // use coords from Sdb
1562 if (signal_wires)
1563 _netSdb->makeGuiBoxes(_dcr,
1564 _signalMenuId,
1565 _signal_wire_id,
1566 false,
1567 excludeNetId); // use coords from Sdb
1568 }
1569 _dcr->setSearchBox(x1, y1, x2, y2);
1570 }
1571 return cnt;
1572 }
1573 /*
1574 uint dbBlockSearch::getTileBuses(Ath__zui *zui)
1575 {
1576 if (_quad==NULL)
1577 return 0;
1578
1579 uint cnt= 0;
1580 if (zui->getDbFlag("tile/tnet/bus"))
1581 cnt += _quad->getTileBuses_1(zui);
1582
1583 return cnt;
1584 }
1585 uint dbBlockSearch::getTilePins(Ath__zui *zui)
1586 {
1587 if (_quad==NULL)
1588 return 0;
1589
1590 uint cnt= 0;
1591 if (zui->getDbFlag("tile/tnet/pin"))
1592 cnt += _quad->getTilePins_1(zui);
1593
1594 return cnt;
1595 }
1596 */
addArrow(int x1,int y1,int x2,int y2,int labelCnt,char ** label,double * val)1597 uint dbBlockSearch::addArrow(int x1,
1598 int y1,
1599 int x2,
1600 int y2,
1601 int labelCnt,
1602 char** label,
1603 double* val)
1604 {
1605 return _dcr->addArrow(true,
1606 _inst_bb_id,
1607 _instMenuId,
1608 0,
1609 labelCnt,
1610 label,
1611 val,
1612 x1,
1613 y1,
1614 x2,
1615 y2,
1616 0);
1617 }
addArrow(dbInst * inst1,dbInst * inst2,int labelCnt,char ** label,double * val)1618 uint dbBlockSearch::addArrow(dbInst* inst1,
1619 dbInst* inst2,
1620 int labelCnt,
1621 char** label,
1622 double* val)
1623 {
1624 dbBox* s1 = inst1->getBBox();
1625 dbBox* s2 = inst2->getBBox();
1626
1627 int x1 = (s1->xMin() + s1->xMax()) / 2;
1628 int y1 = (s1->yMin() + s1->yMax()) / 2;
1629 int x2 = (s2->xMin() + s2->xMax()) / 2;
1630 int y2 = (s2->yMin() + s2->yMax()) / 2;
1631
1632 // 3 inst rarrow 1900000 400000 0 5000 color 0 label {tarrow 1}
1633 /*
1634 uint Ath__zui::addArrow(bool right, uint boxType, uint hier, int layer,
1635 int labelCnt, char **label, double
1636 *val, int x1, int y1,int x2, int y2, uint boxFilter)
1637 */
1638
1639 return _dcr->addArrow(true,
1640 _inst_bb_id,
1641 _instMenuId,
1642 0,
1643 labelCnt,
1644 label,
1645 val,
1646 x1,
1647 y1,
1648 x2,
1649 y2,
1650 0);
1651 }
addFlightLines(dbInst * inst)1652 uint dbBlockSearch::addFlightLines(dbInst* inst)
1653 {
1654 int labelCnt = 0;
1655 char** label = new char*[3];
1656 for (uint ii = 0; ii < 3; ii++)
1657 label[ii] = new char[16];
1658
1659 double val[3];
1660
1661 uint cnt = 0;
1662 std::vector<dbInst*> connectivity;
1663 inst->getConnectivity(connectivity);
1664
1665 std::vector<dbInst*>::iterator inst_itr;
1666
1667 _dcr->setInstMarker();
1668 for (inst_itr = connectivity.begin(); inst_itr != connectivity.end();
1669 ++inst_itr) {
1670 dbInst* inst1 = *inst_itr;
1671
1672 labelCnt = 0;
1673
1674 val[labelCnt] = inst->getId();
1675 strcpy(label[labelCnt++], "instId1=");
1676
1677 val[labelCnt] = inst1->getId();
1678 strcpy(label[labelCnt++], "instId2=");
1679 cnt += addArrow(inst, inst1, labelCnt, label, val);
1680 }
1681 for (uint jj = 0; jj < 3; jj++)
1682 delete[] label[jj];
1683 delete[] label;
1684
1685 return cnt;
1686 }
addInstConnList(dbInst * inst,bool ignoreFlags)1687 void dbBlockSearch::addInstConnList(dbInst* inst, bool ignoreFlags)
1688 {
1689 bool instBoxes
1690 = ignoreFlags || _dcr->getSubMenuFlag(_instMenuId, _inst_bb_id);
1691 bool termShapes
1692 = ignoreFlags || _dcr->getSubMenuFlag(_instMenuId, _inst_pin_id);
1693 bool instObs = ignoreFlags || _dcr->getSubMenuFlag(_instMenuId, _inst_obs_id);
1694
1695 std::vector<dbInst*> connectivity;
1696 inst->getConnectivity(connectivity);
1697
1698 std::vector<dbInst*>::iterator inst_itr;
1699
1700 _dcr->setInstMarker();
1701 uint cnt = addInstBoxes(inst, instBoxes, termShapes, instObs, false);
1702
1703 for (inst_itr = connectivity.begin(); inst_itr != connectivity.end();
1704 ++inst_itr) {
1705 dbInst* inst1 = *inst_itr;
1706 cnt += addInstBoxes(inst1, instBoxes, termShapes, instObs, false);
1707 }
1708 }
1709
getWildCardName(const char * name,char * outName)1710 bool dbBlockSearch::getWildCardName(const char* name, char* outName)
1711 {
1712 uint wCnt = 0;
1713 uint kk = 0;
1714 for (uint ii = 0; name[ii] != '\0'; ii++) {
1715 if (name[ii] == '*') {
1716 wCnt++;
1717 continue;
1718 }
1719 outName[kk++] = name[ii];
1720 }
1721 outName[kk] = '\0';
1722 if (wCnt > 1)
1723 return false;
1724 else
1725 return true;
1726 }
1727
selectInst()1728 void dbBlockSearch::selectInst()
1729 {
1730 bool termShapes = false;
1731 bool instObs = false;
1732 bool vias = false;
1733
1734 uint instId = _dcr->getSubmenuObjId(NULL);
1735 dbInst* inst = NULL;
1736 dbSet<dbInst> insts = _block->getInsts();
1737
1738 if (instId > 0) {
1739 if (instId <= insts.sequential())
1740 inst = dbInst::getInst(_block, instId);
1741
1742 if (inst == NULL) {
1743 warning(0, "Cannot find instance in DB with id %d\n", instId);
1744 return;
1745 }
1746 addInstBoxes(inst, true, termShapes, instObs, vias);
1747 } else {
1748 char* inspectName = _dcr->getInspectName();
1749 if (strstr(inspectName, "*") == NULL) {
1750 inst = _block->findInst(inspectName);
1751 if (inst == NULL) {
1752 warning(0, "Cannot find instance in DB with name %s\n", inspectName);
1753 return;
1754 }
1755 addInstBoxes(inst, true, termShapes, instObs, vias);
1756 } else {
1757 char instSubName[1024];
1758 if (!getWildCardName(inspectName, instSubName))
1759 return;
1760
1761 dbSet<dbInst>::iterator inst_itr;
1762
1763 // uint instCnt= 0;
1764 for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
1765 dbInst* inst = *inst_itr;
1766
1767 if (inst->getMaster()->getMTermCount() <= 0)
1768 continue;
1769
1770 char instName[1024];
1771 strcpy(instName, inst->getName().c_str());
1772
1773 if (strstr(instName, instSubName) == NULL)
1774 continue;
1775
1776 addInstBoxes(inst, true, termShapes, instObs, vias);
1777 }
1778 }
1779 }
1780 }
selectIterm2Net(uint itermId)1781 void dbBlockSearch::selectIterm2Net(uint itermId)
1782 {
1783 dbITerm* iterm = NULL;
1784 dbSet<dbITerm> iterms = _block->getITerms();
1785
1786 if (itermId <= iterms.sequential())
1787 iterm = dbITerm::getITerm(_block, itermId);
1788 if (iterm == NULL) {
1789 warning(0, "Cannot find instance term in DB with id %d\n", itermId);
1790 return;
1791 }
1792
1793 getItermShapesWithViaShapes(iterm);
1794
1795 dbNet* net = iterm->getNet();
1796
1797 // add context markers
1798
1799 dbSigType type = net->getSigType();
1800 if ((type == dbSigType::POWER) || (type == dbSigType::GROUND))
1801 addNetSBoxesOnSearch(net, false);
1802 else
1803 getNetConnectivity(net, false, 0, false, false, false);
1804 }
1805
selectIterm()1806 uint dbBlockSearch::selectIterm()
1807 {
1808 uint itermId = _dcr->getSubmenuObjId(NULL);
1809
1810 uint netCnt = 0;
1811
1812 // dbNet *net= NULL;
1813 if (itermId > 0) {
1814 selectIterm2Net(itermId);
1815 netCnt++;
1816 }
1817 /*
1818 else {
1819 char *inspectName= _dcr->getInspectName();
1820 if (strstr(inspectName, "*")==NULL) {
1821 dbBTerm* bterm= _block->findBTerm(inspectName);
1822
1823 selectBterm2Net(bterm->getId());
1824 netCnt++;
1825 }
1826 else {
1827 char netSubName[1024];
1828 if (!getWildCardName(inspectName, netSubName))
1829 return 0;
1830
1831 dbSet<dbBTerm> bterms = _block->getBTerms();
1832 dbSet<dbBTerm>::iterator bterm_itr;
1833
1834 for( bterm_itr = bterms.begin(); bterm_itr != bterms.end();
1835 ++bterm_itr ) { dbBTerm *bterm = *bterm_itr;
1836
1837 char btermName[1024];
1838 strcpy(btermName, bterm->getName().c_str());
1839
1840 if (strstr(btermName, netSubName)==NULL)
1841 continue;
1842
1843 selectBterm2Net(bterm->getId());
1844
1845 netCnt++;
1846 }
1847 }
1848 }
1849 */
1850 return netCnt;
1851 }
1852
addNetSBoxesOnSearch(dbNet * net,bool skipVias)1853 void dbBlockSearch::addNetSBoxesOnSearch(dbNet* net, bool skipVias)
1854 {
1855 dbSet<dbSWire> swires = net->getSWires();
1856 dbSet<dbSWire>::iterator itr;
1857 for (itr = swires.begin(); itr != swires.end(); ++itr) {
1858 dbSWire* swire = *itr;
1859 dbSet<dbSBox> wires = swire->getWires();
1860 dbSet<dbSBox>::iterator box_itr;
1861
1862 for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
1863 dbSBox* s = *box_itr;
1864
1865 uint boxId = s->getId();
1866
1867 uint level = 0;
1868
1869 if (s->isVia()) {
1870 if (skipVias)
1871 continue;
1872
1873 level = getViaLevel(s);
1874 } else
1875 level = s->getTechLayer()->getRoutingLevel();
1876
1877 Ath__searchBox sbb;
1878 sbb.set(s->xMin(), s->yMin(), s->xMax(), s->yMax(), level, -1);
1879 sbb.setOwnerId(boxId, 0);
1880
1881 // uint dir= sbb.getDir();
1882
1883 // _dbNetWireSearch->getGrid(dir,
1884 // level)->placeWire(&sbb);
1885 }
1886 }
1887 }
getNetSBoxes(dbNet * net,bool skipVias)1888 uint dbBlockSearch::getNetSBoxes(dbNet* net, bool skipVias)
1889 {
1890 uint cnt = 0;
1891 dbSet<dbSWire> swires = net->getSWires();
1892 dbSet<dbSWire>::iterator itr;
1893 for (itr = swires.begin(); itr != swires.end(); ++itr) {
1894 dbSWire* swire = *itr;
1895 dbSet<dbSBox> wires = swire->getWires();
1896 dbSet<dbSBox>::iterator box_itr;
1897
1898 for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
1899 dbSBox* s = *box_itr;
1900
1901 uint sboxId = s->getId();
1902
1903 uint level = 0;
1904
1905 if (s->isVia()) {
1906 if (skipVias)
1907 continue;
1908
1909 dbBox* viaBox
1910 = (dbBox*) dbSBox::getSBox(_block, sboxId); // netId is box id
1911 if (!viaBox->isVia())
1912 return 0;
1913
1914 cnt += addViaBoxes(viaBox, _powerMenuId, _power_wire_id, sboxId, 0);
1915
1916 } else {
1917 level = s->getTechLayer()->getRoutingLevel();
1918
1919 cnt += _dcr->addBox(sboxId,
1920 _power_wire_id,
1921 _powerMenuId,
1922 level,
1923 s->xMin(),
1924 s->yMin(),
1925 s->xMax(),
1926 s->yMax(),
1927 0);
1928 }
1929 }
1930 }
1931 return cnt;
1932 }
addInstBoxes(dbInst * inst,bool instBoxes,bool termShapes,bool instObs,bool vias)1933 uint dbBlockSearch::addInstBoxes(dbInst* inst,
1934 bool instBoxes,
1935 bool termShapes,
1936 bool instObs,
1937 bool vias)
1938 {
1939 uint cnt = 0;
1940 _dcr->setInstMarker();
1941
1942 if (instBoxes)
1943 cnt += addInstBox(inst);
1944
1945 if (termShapes)
1946 cnt += getItermShapes(inst, vias);
1947
1948 if (instObs)
1949 cnt += getInstObs(inst, vias);
1950
1951 return cnt;
1952 }
addInstBoxes(dbNet * net,bool ignoreFlags)1953 uint dbBlockSearch::addInstBoxes(dbNet* net, bool ignoreFlags)
1954 {
1955 bool instBoxes
1956 = ignoreFlags || _dcr->getSubMenuFlag(_instMenuId, _inst_bb_id);
1957 bool termShapes
1958 = ignoreFlags || _dcr->getSubMenuFlag(_instMenuId, _inst_pin_id);
1959 bool instObs = ignoreFlags || _dcr->getSubMenuFlag(_instMenuId, _inst_obs_id);
1960
1961 if (!(instBoxes || instBoxes || termShapes))
1962 return 0;
1963
1964 dbSet<dbITerm> iterms = net->getITerms();
1965 dbSet<dbITerm>::iterator iterm_itr;
1966
1967 uint cnt = 0;
1968 for (iterm_itr = iterms.begin(); iterm_itr != iterms.end(); ++iterm_itr) {
1969 dbITerm* iterm = *iterm_itr;
1970
1971 if (termShapes)
1972 cnt += getItermShapesWithViaShapes(iterm);
1973
1974 dbInst* inst = iterm->getInst();
1975 // dbBox * bb = inst->getBBox();
1976
1977 if (instBoxes)
1978 cnt += addInstBox(inst);
1979
1980 if (instObs)
1981 cnt += getInstObs(inst, true);
1982 }
1983 return cnt;
1984 }
1985
addNetShapes(dbNet * net,bool viaWireFlag,uint menuId,uint subMenuId)1986 uint dbBlockSearch::addNetShapes(dbNet* net,
1987 bool viaWireFlag,
1988 uint menuId,
1989 uint subMenuId)
1990 {
1991 uint cnt = 0;
1992 dbWire* wire = net->getWire();
1993 if (wire == NULL)
1994 return 0;
1995
1996 // uint wireId= wire->getId();
1997 uint netId = net->getId();
1998
1999 dbWireShapeItr shapes;
2000 dbShape s;
2001
2002 for (shapes.begin(wire); shapes.next(s);) {
2003 if (s.isVia()) {
2004 if (viaWireFlag)
2005 continue;
2006
2007 cnt += addViaCoords(s, menuId, subMenuId, netId, shapes.getShapeId());
2008 } else if (viaWireFlag) {
2009 cnt += addWireCoords(s, menuId, subMenuId, netId, shapes.getShapeId());
2010 }
2011 }
2012
2013 return cnt;
2014 }
getNetBbox(dbNet * net,Rect & maxRect)2015 void dbBlockSearch::getNetBbox(dbNet* net, Rect& maxRect)
2016 {
2017 dbWire* wire = net->getWire();
2018 if (wire == NULL)
2019 return;
2020
2021 // uint wireId= wire->getId();
2022
2023 dbWireShapeItr shapes;
2024 dbShape s;
2025
2026 for (shapes.begin(wire); shapes.next(s);) {
2027 Rect r;
2028 s.getBox(r);
2029 maxRect.merge(r);
2030 }
2031 }
getNetFromDb(dbNet * net,bool,bool ignoreBB)2032 uint dbBlockSearch::getNetFromDb(dbNet* net,
2033 bool /* unused: ignoreZuiFlags */,
2034 bool ignoreBB)
2035 {
2036 uint cnt = 0;
2037
2038 if (ignoreBB || !_dcr->validSearchBbox()) {
2039 Rect maxBB;
2040 maxBB.reset(ath__maxInt, ath__maxInt, -ath__maxInt, -ath__maxInt);
2041 getNetBbox(net, maxBB);
2042
2043 uint dd = 1000;
2044 _dcr->setSearchBox(maxBB.xMin() - dd,
2045 maxBB.yMin() - dd,
2046 maxBB.xMax() + dd,
2047 maxBB.yMax() + dd);
2048
2049 cnt += addNetShapes(net, true, _signalMenuId, _signal_wire_id);
2050 cnt += addNetShapes(net, false, _signalMenuId, _signal_via_id);
2051
2052 _dcr->invalidateSearchBox();
2053 } else {
2054 cnt += addNetShapes(net, true, _signalMenuId, _signal_wire_id);
2055 cnt += addNetShapes(net, false, _signalMenuId, _signal_via_id);
2056 }
2057
2058 return cnt;
2059 }
2060 /*
2061 uint dbBlockSearch::getNetFromSearch(dbNet *net, bool ignoreZuiFlags, bool
2062 ignoreBB)
2063 {
2064 uint cnt= 0;
2065
2066 int x1, y1, x2, y2;
2067 _dcr->getBbox(&x1, &y1, &x2, &y2);
2068
2069 Ath__array1D<uint> wireIdTable(16000);
2070
2071 if (!ignoreBB && !_dcr->validSearchBbox())
2072 {
2073 Rect maxBB;
2074 maxBB.reset(ath__maxInt, ath__maxInt, -ath__maxInt,
2075 -ath__maxInt); getNetBbox(net, maxBB);
2076
2077 x1= maxBB.xMin();
2078 y1= maxBB.yMin();
2079 x2= maxBB.xMax();
2080 y2= maxBB.yMax();
2081
2082 uint dd= 1000;
2083 _dcr->setSearchBox(x1-dd, y1-dd, x2+dd, y2+dd);
2084 }
2085 else {
2086 _dcr->getBbox(&x1, &y1, &x2, &y2);
2087 }
2088
2089 bool *exludeTable= _dcr->getExcludeLayerTable();
2090 _netSdb->searchWireIds(x1, y1, x2, y2, true, exludeTable);
2091
2092 cnt += getWireVias(_signalMenuId, _signal_wire_id, true, net, false);
2093 cnt += getWireVias(_signalMenuId, _signal_via_id, false, net, false);
2094
2095 return cnt;
2096 }
2097 */
getNetWires(dbNet * net,bool contextFlag,uint clipMargin,bool ignoreZuiFlags,bool ignoreBB)2098 uint dbBlockSearch::getNetWires(dbNet* net,
2099 bool contextFlag,
2100 uint clipMargin,
2101 bool ignoreZuiFlags,
2102 bool ignoreBB)
2103 {
2104 if (net == NULL)
2105 return 0;
2106
2107 _dcr->setSignalMarker();
2108 uint cnt = getNetFromDb(net, ignoreZuiFlags, ignoreBB);
2109 _dcr->resetMarker();
2110
2111 _dcr->setContextMarker();
2112 if (contextFlag) {
2113 if (clipMargin > 0)
2114 cnt += getWiresClipped(net, 5000, false);
2115 else
2116 // cnt += getWiresAndVias_all(net, true);
2117 cnt += getWiresClipped(net, 0, false);
2118 }
2119
2120 return cnt;
2121 }
getNetConnectivity(dbNet * net,bool contextFlag,uint clipMargin,bool,bool ignoreZuiFlags,bool ignoreBB)2122 uint dbBlockSearch::getNetConnectivity(dbNet* net,
2123 bool contextFlag,
2124 uint clipMargin,
2125 bool /* unused: ignoreLayerFlags */,
2126 bool ignoreZuiFlags,
2127 bool ignoreBB)
2128 {
2129 if (net == NULL)
2130 return 0;
2131
2132 _dcr->setSignalMarker();
2133 uint cnt = getNetFromDb(net, ignoreZuiFlags, ignoreBB);
2134 _dcr->resetMarker();
2135
2136 _dcr->setInstMarker();
2137 cnt += addInstBoxes(net, ignoreZuiFlags);
2138
2139 dbSet<dbBTerm> bterms = net->getBTerms();
2140 cnt += addBtermBoxes(bterms, ignoreZuiFlags);
2141
2142 _dcr->setContextMarker();
2143 if (contextFlag) {
2144 if (clipMargin > 0)
2145 cnt += getWiresClipped(net, 5000, false);
2146 else
2147 cnt += getWiresAndVias_all(net, true);
2148
2149 dbSet<dbBTerm> blk_bterms = net->getBTerms();
2150 cnt += addBtermBoxes(blk_bterms, ignoreZuiFlags);
2151 }
2152
2153 return cnt;
2154 }
getConnectivityWires(dbInst * inst,bool ignoreZuiFlags)2155 uint dbBlockSearch::getConnectivityWires(dbInst* inst, bool ignoreZuiFlags)
2156 {
2157 _dcr->setSignalMarker();
2158
2159 dbSet<dbITerm> iterms = inst->getITerms();
2160 dbSet<dbITerm>::iterator iterm_itr;
2161
2162 uint cnt = 0;
2163 for (iterm_itr = iterms.begin(); iterm_itr != iterms.end(); ++iterm_itr) {
2164 dbITerm* iterm = *iterm_itr;
2165 dbNet* net = iterm->getNet();
2166 if (net == NULL)
2167 continue;
2168
2169 dbSigType type = net->getSigType();
2170 if ((type == dbSigType::POWER) || (type == dbSigType::GROUND))
2171 continue;
2172
2173 cnt += getNetFromDb(net, ignoreZuiFlags, true);
2174 }
2175 return cnt;
2176 }
2177
addNetSBoxes(dbNet * net,uint,bool skipVias)2178 void dbBlockSearch::addNetSBoxes(dbNet* net,
2179 uint /* unused: wtype */,
2180 bool skipVias)
2181 {
2182 dbSet<dbSWire> swires = net->getSWires();
2183 dbSet<dbSWire>::iterator itr;
2184
2185 for (itr = swires.begin(); itr != swires.end(); ++itr) {
2186 dbSWire* swire = *itr;
2187 dbSet<dbSBox> wires = swire->getWires();
2188 dbSet<dbSBox>::iterator box_itr;
2189
2190 for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
2191 dbSBox* s = *box_itr;
2192
2193 // uint level = 0;
2194
2195 if (s->isVia()) {
2196 if (skipVias)
2197 continue;
2198
2199 // level = getViaLevel(s);
2200 } else {
2201 // level = s->getTechLayer()->getRoutingLevel();
2202 }
2203 // _search->addBox(s->xMin(), s->yMin(), s->xMax(),
2204 // s->yMax(), level, s->getId(), 0, wtype);
2205 }
2206 }
2207 }
2208
2209 /*
2210 dbInst *dbBlockSearch::getDbInst(Ath__zui *zui)
2211 {
2212 uint id= zui->getInspNameId();
2213 dbInst* inst= NULL;
2214 if (id==0)
2215 {
2216 inst= _block->findInst(zui->getInspectName());
2217 if (inst==NULL)
2218 {
2219 fprintf(stdout, "Cannot find instance %s\n",
2220 zui->getInspectName());
2221 return NULL;
2222 }
2223 id= inst->getId();
2224 }
2225 else {
2226 inst= dbInst::getInst(_block, id);
2227 }
2228 return inst;
2229 }
2230 dbNet *dbBlockSearch::getDbNet(Ath__zui *zui)
2231 {
2232 uint id= zui->getInspNameId();
2233 dbNet *net= NULL;
2234 if (id==0)
2235 {
2236 net= _block->findNet(zui->getInspectName());
2237 if (net==NULL)
2238 {
2239 fprintf(stdout, "Cannot find net %s\n",
2240 zui->getInspectName());
2241 return NULL;
2242 }
2243 id= net->getId();
2244 }
2245 else {
2246 net= dbNet::getNet(_block, id);
2247 }
2248 return net;
2249 }
2250 dbBTerm *dbBlockSearch::getDbBTerm(Ath__zui *zui)
2251 {
2252 uint id= zui->getInspNameId();
2253 dbBTerm *bterm= NULL;
2254 if (id==0)
2255 {
2256 bterm= _block->findBTerm(zui->getInspectName());
2257 if (bterm==NULL)
2258 {
2259 fprintf(stdout, "Cannot find bterm %s\n",
2260 zui->getInspectName()); return NULL;
2261 }
2262 id= bterm->getId();
2263 }
2264 else {
2265 bterm= dbBTerm::getBTerm(_block, id);
2266 }
2267 return bterm;
2268 }
2269 */
getNetAndShape(dbShape & s,uint * shapeId,uint * level)2270 dbNet* dbBlockSearch::getNetAndShape(dbShape& s, uint* shapeId, uint* level)
2271 {
2272 uint netId = _dcr->getSubmenuObjId(shapeId);
2273 dbNet* net = dbNet::getNet(_block, netId);
2274
2275 dbWire* w = net->getWire();
2276 w->getShape(*shapeId, s);
2277
2278 *level = getShapeLevel(&s, true);
2279
2280 return net;
2281 }
getRSeg(dbNet * net,uint shapeId)2282 dbRSeg* dbBlockSearch::getRSeg(dbNet* net, uint shapeId)
2283 {
2284 int rsegId = 0;
2285
2286 dbWire* w = net->getWire();
2287
2288 dbRSeg* rseg = NULL;
2289 if (w->getProperty(shapeId, rsegId) && rsegId != 0)
2290 rseg = dbRSeg::getRSeg(_block, rsegId);
2291
2292 return rseg;
2293 }
2294
isSignalNet(dbNet * net)2295 bool dbBlockSearch::isSignalNet(dbNet* net)
2296 {
2297 dbSigType type = net->getSigType();
2298
2299 return ((type == dbSigType::POWER) || (type == dbSigType::GROUND)) ? false
2300 : true;
2301 }
selectNet()2302 uint dbBlockSearch::selectNet()
2303 {
2304 uint netId = _dcr->getSubmenuObjId(NULL);
2305
2306 uint netCnt = 0;
2307
2308 // bool contextFlag=false;
2309 // uint clipMargin= 0;
2310 // bool ignoreLayerFlags= true;
2311 bool ignoreZuiFlags = false;
2312 bool ignoreBB = false;
2313
2314 _dcr->setSignalMarker();
2315 dbNet* net = NULL;
2316 dbSet<dbNet> nets = _block->getNets();
2317
2318 if (netId > 0) {
2319 if (netId <= nets.sequential())
2320 net = dbNet::getNet(_block, netId);
2321 if (net == NULL) {
2322 warning(0, "Cannot find net in DB with id %d\n", netId);
2323 return 0;
2324 }
2325 if (isSignalNet(net))
2326 getNetFromDb(net, ignoreZuiFlags, ignoreBB);
2327 // getNetConnectivity(net, false, 0, true, false, true);
2328 // getNetConnectivity(net, contextFlag, clipMargin, ignoreLayerFlags,
2329 // ignoreZuiFlags, ignoreBB);
2330 else
2331 getNetSBoxes(net, false);
2332 netCnt++;
2333 } else {
2334 char* inspectName = _dcr->getInspectName();
2335 if (strstr(inspectName, "*") == NULL) {
2336 net = _block->findNet(inspectName);
2337 if (net == NULL) {
2338 warning(0, "Cannot find net in DB with name %s\n", inspectName);
2339 return 0;
2340 }
2341 if (isSignalNet(net))
2342 getNetFromDb(net, ignoreZuiFlags, ignoreBB);
2343 // getNetConnectivity(net, contextFlag, clipMargin, ignoreLayerFlags,
2344 // ignoreZuiFlags, ignoreBB);
2345 else
2346 getNetSBoxes(net, false);
2347
2348 netCnt++;
2349 } else {
2350 char netSubName[1024];
2351 if (!getWildCardName(inspectName, netSubName))
2352 return 0;
2353
2354 dbSet<dbNet>::iterator net_itr;
2355
2356 for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
2357 dbNet* net = *net_itr;
2358 /*
2359 dbSigType type= net->getSigType();
2360 if (!signal &&
2361 !((type==POWER)||(type==GROUND))) continue;
2362 */
2363
2364 char netName[1024];
2365 strcpy(netName, net->getName().c_str());
2366
2367 if (strstr(netName, netSubName) == NULL)
2368 continue;
2369
2370 if (isSignalNet(net))
2371 getNetFromDb(net, ignoreZuiFlags, ignoreBB);
2372 // getNetConnectivity(net, contextFlag, clipMargin, ignoreLayerFlags,
2373 // ignoreZuiFlags, ignoreBB);
2374 else
2375 getNetSBoxes(net, false);
2376
2377 netCnt++;
2378 }
2379 }
2380 }
2381 _dcr->resetMarker();
2382 return netCnt;
2383 }
2384
selectBterm2Net(uint btermId)2385 void dbBlockSearch::selectBterm2Net(uint btermId)
2386 {
2387 dbBTerm* bterm = NULL;
2388 dbSet<dbBTerm> bterms = _block->getBTerms();
2389
2390 if (btermId <= bterms.sequential())
2391 bterm = dbBTerm::getBTerm(_block, btermId);
2392 if (bterm == NULL) {
2393 warning(0, "Cannot find block term in DB with id %d\n", btermId);
2394 return;
2395 }
2396 dbNet* net = bterm->getNet();
2397
2398 dbSigType type = net->getSigType();
2399
2400 if ((type == dbSigType::POWER) || (type == dbSigType::GROUND))
2401 addNetSBoxesOnSearch(net, false);
2402 else
2403 getNetConnectivity(net, false, 0, false, false, false);
2404 }
2405
selectBterm()2406 uint dbBlockSearch::selectBterm()
2407 {
2408 uint btermId = _dcr->getSubmenuObjId(NULL);
2409
2410 uint netCnt = 0;
2411
2412 // dbNet *net= NULL;
2413 if (btermId > 0) {
2414 selectBterm2Net(btermId);
2415 netCnt++;
2416 } else {
2417 char* inspectName = _dcr->getInspectName();
2418 if (strstr(inspectName, "*") == NULL) {
2419 dbBTerm* bterm = _block->findBTerm(inspectName);
2420 if (bterm == NULL) {
2421 warning(0, "Cannot find block term in DB with name %s\n", inspectName);
2422 return 0;
2423 }
2424
2425 selectBterm2Net(bterm->getId());
2426 netCnt++;
2427 } else {
2428 char netSubName[1024];
2429 if (!getWildCardName(inspectName, netSubName))
2430 return 0;
2431
2432 dbSet<dbBTerm> bterms = _block->getBTerms();
2433 dbSet<dbBTerm>::iterator bterm_itr;
2434
2435 for (bterm_itr = bterms.begin(); bterm_itr != bterms.end(); ++bterm_itr) {
2436 dbBTerm* bterm = *bterm_itr;
2437
2438 char btermName[1024];
2439 strcpy(btermName, bterm->getName().c_str());
2440
2441 if (strstr(btermName, netSubName) == NULL)
2442 continue;
2443
2444 selectBterm2Net(bterm->getId());
2445
2446 netCnt++;
2447 }
2448 }
2449 }
2450 return netCnt;
2451 }
2452
2453 } // namespace odb
2454