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