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 <stdio.h>
34 
35 #include "dbLogger.h"
36 #include "wire.h"
37 
38 //#define SINGLE_WIRE
39 
Ath__box()40 Ath__box::Ath__box()
41 {
42   set(0, 0, 0, 0);
43 }
getXlo(int bound)44 int Ath__box::getXlo(int bound)
45 {
46   if (_xlo < bound)
47     return bound;
48   else
49     return _xlo;
50 }
getYlo(int bound)51 int Ath__box::getYlo(int bound)
52 {
53   if (_ylo < bound)
54     return bound;
55   else
56     return _ylo;
57 }
getXhi(int bound)58 int Ath__box::getXhi(int bound)
59 {
60   if (_xhi > bound)
61     return bound;
62   else
63     return _xhi;
64 }
getYhi(int bound)65 int Ath__box::getYhi(int bound)
66 {
67   if (_yhi > bound)
68     return bound;
69   else
70     return _yhi;
71 }
getDir()72 uint Ath__box::getDir()
73 {
74   uint dx = getDX();
75   uint dy = getDY();
76 
77   return (dx < dy) ? 0 : 1;
78 }
getWidth(uint * dir)79 uint Ath__box::getWidth(uint* dir)
80 {
81   uint dx = getDX();
82   uint dy = getDY();
83   *dir = 1;       // horizontal
84   if (dx < dy) {  // vertical
85     *dir = 0;
86     return dx;
87   } else {
88     return dy;
89   }
90 }
91 
Ath__box(int x1,int y1,int x2,int y2,uint units)92 Ath__box::Ath__box(int x1, int y1, int x2, int y2, uint units)
93 {
94   set(x1, y1, x2, y2, units);
95 }
set(int x1,int y1,int x2,int y2,uint units)96 void Ath__box::set(int x1, int y1, int x2, int y2, uint units)
97 {
98   _xlo = x1 * units;
99   _ylo = y1 * units;
100   _xhi = x2 * units;
101   _yhi = y2 * units;
102   _valid = 1;
103   _id = 0;
104 }
getOwner()105 uint Ath__box::getOwner()
106 {
107   return 0;
108 }
getDX()109 uint Ath__box::getDX()
110 {
111   return _xhi - _xlo;
112 }
getDY()113 uint Ath__box::getDY()
114 {
115   return _yhi - _ylo;
116 }
getLength()117 uint Ath__box::getLength()
118 {
119   uint dx = _xhi - _xlo;
120   uint dy = _yhi - _ylo;
121   if (dx < dy)
122     return dy;
123   else
124     return dx;
125 }
invalidateBox()126 void Ath__box::invalidateBox()
127 {
128   _valid = 0;
129 }
set(Ath__box * bb)130 void Ath__box::set(Ath__box* bb)
131 {
132   _xlo = bb->_xlo;
133   _ylo = bb->_ylo;
134   _xhi = bb->_xhi;
135   _yhi = bb->_yhi;
136 }
137 
outside(int x1,int y1,int x2,int y2)138 bool Ath__box::outside(int x1, int y1, int x2, int y2)
139 {
140   if (_valid == 0)
141     return false;
142 
143   if (x1 >= _xhi)
144     return true;
145   if (y1 >= _yhi)
146     return true;
147 
148   if (x2 <= _xlo)
149     return true;
150   if (y2 <= _ylo)
151     return true;
152 
153   return false;
154 }
155 
set(int x1,int y1,int x2,int y2,uint l,int dir)156 void Ath__searchBox::set(int x1, int y1, int x2, int y2, uint l, int dir)
157 {
158   _ll[0] = x1;
159   _ll[1] = y1;
160   _ur[0] = x2;
161   _ur[1] = y2;
162   _level = l;
163   setDir(dir);
164   _ownId = 0;
165   _otherId = 0;
166   _type = 0;
167 }
Ath__searchBox()168 Ath__searchBox::Ath__searchBox()
169 {
170 }
Ath__searchBox(Ath__box * bb,uint l,int dir)171 Ath__searchBox::Ath__searchBox(Ath__box* bb, uint l, int dir)
172 {
173   set(bb->_xlo, bb->_ylo, bb->_xhi, bb->_yhi, l, dir);
174 }
Ath__searchBox(Ath__searchBox * bb,uint l,int dir)175 Ath__searchBox::Ath__searchBox(Ath__searchBox* bb, uint l, int dir)
176 {
177   set(bb->_ll[0], bb->_ll[1], bb->_ur[0], bb->_ur[1], l, dir);
178 }
Ath__searchBox(int x1,int y1,int x2,int y2,uint l,int dir)179 Ath__searchBox::Ath__searchBox(int x1, int y1, int x2, int y2, uint l, int dir)
180 {
181   set(x1, y1, x2, y2, l, dir);
182 }
setMidPointSearch()183 void Ath__searchBox::setMidPointSearch()
184 {
185   for (uint i = 0; i < 2; i++) {
186     _ll[i] = (_ll[i] + _ur[i]) / 2;
187     _ur[i] = _ll[i] + 1;
188   }
189 }
190 
setLo(uint d,int xy)191 void Ath__searchBox::setLo(uint d, int xy)
192 {
193   _ll[d] = xy;
194 }
setHi(uint d,int xy)195 void Ath__searchBox::setHi(uint d, int xy)
196 {
197   _ur[d] = xy;
198 }
loXY(uint d)199 int Ath__searchBox::loXY(uint d)
200 {
201   return _ll[d];
202 }
hiXY(uint d)203 int Ath__searchBox::hiXY(uint d)
204 {
205   return _ur[d];
206 }
loXY(uint d,int loBound)207 int Ath__searchBox::loXY(uint d, int loBound)
208 {
209   if (_ll[d] < loBound)
210     return loBound;
211   else
212     return _ll[d];
213 }
hiXY(uint d,int hiBound)214 int Ath__searchBox::hiXY(uint d, int hiBound)
215 {
216   if (_ur[d] > hiBound)
217     return hiBound;
218   else
219     return _ur[d];
220 }
getDir()221 uint Ath__searchBox::getDir()
222 {
223   return _dir;
224 }
getLevel()225 uint Ath__searchBox::getLevel()
226 {
227   return _level;
228 }
getOwnerId()229 uint Ath__searchBox::getOwnerId()
230 {
231   return _ownId;
232 }
getOtherId()233 uint Ath__searchBox::getOtherId()
234 {
235   return _otherId;
236 }
getType()237 uint Ath__searchBox::getType()
238 {
239   return _type;
240 }
setOwnerId(uint v,uint other)241 void Ath__searchBox::setOwnerId(uint v, uint other)
242 {
243   _ownId = v;
244   _otherId = other;
245 }
setType(uint v)246 void Ath__searchBox::setType(uint v)
247 {
248   _type = v;
249 }
setDir(int dir)250 void Ath__searchBox::setDir(int dir)
251 {
252   if (dir >= 0) {
253     _dir = dir;
254   } else {
255     _dir = 1;  // horizontal
256     int dx = _ur[0] - _ll[0];
257     if (dx < _ur[1] - _ll[1])
258       _dir = 0;  // vertical
259   }
260 }
getLength()261 uint Ath__searchBox::getLength()
262 {
263   if (_dir > 0)
264     return _ur[0] - _ll[0];
265   else
266     return _ur[1] - _ll[1];
267 }
setLevel(uint v)268 void Ath__searchBox::setLevel(uint v)
269 {
270   _level = v;
271 }
272 
reset()273 void Ath__wire::reset()
274 {
275   _boxId = 0;
276   _srcId = 0;
277   _otherId = 0;
278   _track = NULL;
279   _next = NULL;
280 
281   _xy = 0;  // offset from track start
282   _len = 0;
283 
284   _base = 0;
285   _width = 0;
286   _flags = 0;  // ownership
287                // 0=wire, 1=obs, 2=pin, 3=power
288   _dir = 0;
289   _ext = 0;
290   _ouLen = 0;
291 }
isTilePin()292 bool Ath__wire::isTilePin()
293 {
294   if (_flags == 1)
295     return true;
296   else
297     return false;
298 }
isTileBus()299 bool Ath__wire::isTileBus()
300 {
301   if (_flags == 2)
302     return true;
303   else
304     return false;
305 }
isPower()306 bool Ath__wire::isPower()
307 {
308   uint power_wire_id = 11;  // see db/dbSearch.cpp
309   if (_flags == power_wire_id)
310     return true;
311   else
312     return false;
313 }
isVia()314 bool Ath__wire::isVia()
315 {
316   uint via_wire_id = 5;  // see db/dbSearch.cpp
317   if (_flags == via_wire_id)
318     return true;
319   else
320     return false;
321 }
setOtherId(uint id)322 void Ath__wire::setOtherId(uint id)
323 {
324   _otherId = id;
325 }
getRsegId()326 int Ath__wire::getRsegId()
327 {
328   int wBoxId = _boxId;
329   if (!(_otherId > 0))
330     return wBoxId;
331 
332   if (isVia()) {
333     wBoxId = getShapeProperty(_otherId);
334   } else {
335     getNet()->getWire()->getProperty((int) _otherId, wBoxId);
336   }
337   return wBoxId;
338 }
getShapeProperty(int id)339 int Ath__wire::getShapeProperty(int id)
340 {
341   dbNet* net = getNet();
342   if (net == NULL)
343     return 0;
344   char buff[64];
345   sprintf(buff, "%d", id);
346   char const* pchar = strdup(buff);
347   dbIntProperty* p = dbIntProperty::find(net, pchar);
348   if (p == NULL)
349     return 0;
350   int rcid = p->getValue();
351   return rcid;
352 }
getNet()353 dbNet* Ath__wire::getNet()
354 {
355   Ath__gridTable* gtb = _track->getGrid()->getGridTable();
356   dbBlock* block = gtb->getBlock();
357   if (_otherId == 0)
358     return (dbSBox::getSBox(block, _boxId)->getSWire()->getNet());
359   if (gtb->usingDbSdb())
360     return dbNet::getNet(block, _boxId);
361   else
362     return (dbRSeg::getRSeg(block, _boxId)->getNet());
363 }
getBoxId()364 uint Ath__wire::getBoxId()
365 {
366   return _boxId;
367 }
getOtherId()368 uint Ath__wire::getOtherId()
369 {
370   return _otherId;
371 }
getSrcId()372 uint Ath__wire::getSrcId()
373 {
374   return _srcId;
375 }
set(uint dir,int * ll,int * ur)376 void Ath__wire::set(uint dir, int* ll, int* ur)
377 {
378   _boxId = 0;
379   _srcId = 0;
380   _track = NULL;
381   _next = NULL;
382 
383   _dir = dir;
384   uint d = (_dir > 0) ? 0 : 1;
385 
386   int xy1 = ll[d];
387   int xy2 = ur[d];
388 
389   int yx1 = ll[dir];
390   int yx2 = ur[dir];
391 
392   _xy = xy1;  // offset from track start
393   _len = xy2 - xy1;
394 
395   _base = yx1;  // small dimension
396   _width = yx2 - yx1;
397   // OpenRCX
398   _visited = 0;
399   _ouLen = 0;
400 }
getTargetWire()401 Ath__wire* Ath__track::getTargetWire()
402 {
403   return _targetWire;
404 }
initTargetWire(int noPowerWire)405 void Ath__track::initTargetWire(int noPowerWire)
406 {
407   _targetWire = NULL;
408   for (_targetMarker = 0; _targetMarker < _markerCnt; _targetMarker++) {
409     if (_marker[_targetMarker] == NULL)
410       continue;
411     _targetWire = _marker[_targetMarker];
412     while (_targetWire && noPowerWire && _targetWire->isPower())
413       _targetWire = _targetWire->_next;
414     if (_targetWire)
415       break;
416   }
417 }
nextTargetWire(int noPowerWire)418 Ath__wire* Ath__track::nextTargetWire(int noPowerWire)
419 {
420   if (_targetWire) {
421     _targetWire = _targetWire->_next;
422     while (_targetWire && noPowerWire && _targetWire->isPower())
423       _targetWire = _targetWire->_next;
424     if (!_targetWire)
425       _targetMarker++;
426   }
427   if (_targetWire)
428     return _targetWire;
429   for (; _targetMarker < _markerCnt; _targetMarker++) {
430     if (_marker[_targetMarker] == NULL)
431       continue;
432     _targetWire = _marker[_targetMarker];
433     while (_targetWire && noPowerWire && _targetWire->isPower())
434       _targetWire = _targetWire->_next;
435     if (_targetWire)
436       break;
437   }
438   return _targetWire;
439 }
440 
wireOverlap(Ath__wire * w,int * len1,int * len2,int * len3)441 int Ath__wire::wireOverlap(Ath__wire* w, int* len1, int* len2, int* len3)
442 {
443   // _xy, _len : reference rect
444 
445   int X1 = _xy;
446   int DX = _len;
447   int x1 = w->_xy;
448   int dx = w->_len;
449 
450   //	fprintf(stdout, "%d %d   %d %d  : ", X1, DX,   x1, dx);
451 
452   int dx1 = X1 - x1;
453   //*len1= dx1;
454   if (dx1 >= 0)  // on left side
455   {
456     int dlen = dx - dx1;
457     if (dlen <= 0)
458       return 1;
459 
460     *len1 = 0;
461     int DX2 = dlen - DX;
462 
463     if (DX2 <= 0) {
464       *len2 = dlen;
465       *len3 = -DX2;
466     } else {
467       *len2 = DX;
468       //*len3= DX2;
469       *len3 = 0;
470     }
471   } else {
472     *len1 = -dx1;
473 
474     if (dx1 + DX <= 0)  // outside right side
475       return 2;
476 
477     int DX2 = (x1 + dx) - (X1 + DX);
478     if (DX2 > 0) {
479       *len2 = DX + dx1;  // dx1 is negative
480       *len3 = 0;
481     } else {
482       *len2 = dx;
483       *len3 = -DX2;
484     }
485   }
486   return 0;
487 }
getCoords(int * x1,int * y1,int * x2,int * y2,uint * dir)488 void Ath__wire::getCoords(int* x1, int* y1, int* x2, int* y2, uint* dir)
489 {
490   if (_dir > 0)  // horizontal
491   {
492     *x1 = _xy;
493     *y1 = _base;
494     *x2 = _xy + _len;
495     *y2 = _base + _width;
496   } else {
497     *y1 = _xy;
498     *x1 = _base;
499     *y2 = _xy + _len;
500     *x2 = _base + _width;
501   }
502   *dir = _dir;
503 }
getCoords(Ath__searchBox * box)504 void Ath__wire::getCoords(Ath__searchBox* box)
505 {
506   uint level = _track->getGrid()->getLevel();
507   if (_dir > 0)  // horizontal
508   {
509     box->set(_xy, _base, _xy + _len, _base + _width, level, _dir);
510   } else {
511     box->set(_base, _xy, _base + _width, _xy + _len, level, _dir);
512   }
513   box->setType(_flags);
514 }
515 
getNextSubTrack(Ath__track * subt,bool tohi)516 Ath__track* Ath__track::getNextSubTrack(Ath__track* subt, bool tohi)
517 {
518   if (!subt)
519     return tohi ? this : this->getLowTrack();
520   if (tohi)
521     return subt->getHiTrack()->_lowest ? NULL : subt->getHiTrack();
522   else
523     return subt->_lowest ? NULL : subt->getLowTrack();
524 }
525 
setHiTrack(Ath__track * hitrack)526 void Ath__track::setHiTrack(Ath__track* hitrack)
527 {
528   _hiTrack = hitrack;
529 }
setLowTrack(Ath__track * lowtrack)530 void Ath__track::setLowTrack(Ath__track* lowtrack)
531 {
532   _lowTrack = lowtrack;
533 }
getHiTrack()534 Ath__track* Ath__track::getHiTrack()
535 {
536   return _hiTrack;
537 }
getLowTrack()538 Ath__track* Ath__track::getLowTrack()
539 {
540   return _lowTrack;
541 }
542 
set(Ath__grid * g,int x,int y,uint n,uint width,uint markerLen,uint markerCnt,int base)543 void Ath__track::set(Ath__grid* g,
544                      int x,
545                      int y,
546                      uint n,
547                      uint width,
548                      uint markerLen,
549                      uint markerCnt,
550                      int base)
551 {
552   _grid = g;
553   _x = x;
554   _y = y;
555   _num = n;
556   _width = width;
557 
558   if (markerCnt <= 4) {
559     _markerCnt = markerCnt;
560     _marker = new Ath__wire*[4];
561     _eMarker = new Ath__wire*[4];
562   } else {
563     _markerCnt = markerCnt;
564     _marker = new Ath__wire*[_markerCnt];
565     _eMarker = new Ath__wire*[_markerCnt];
566   }
567   for (uint ii = 0; ii < _markerCnt; ii++) {
568     _marker[ii] = NULL;
569     _eMarker[ii] = NULL;
570   }
571 
572   _blocked = 1;
573   _ordered = false;
574 
575   _hiTrack = this;
576   _lowTrack = this;
577   _lowest = 0;
578   _base = base;
579 }
freeWires(AthPool<Ath__wire> * pool)580 void Ath__track::freeWires(AthPool<Ath__wire>* pool)
581 {
582   for (uint ii = 0; ii < _markerCnt; ii++) {
583     Ath__wire* w = _marker[ii];
584     while (w != NULL) {
585       Ath__wire* a = w->getNext();
586 
587       pool->free(w);
588       w = a;
589     }
590   }
591 }
dealloc(AthPool<Ath__wire> * pool)592 void Ath__track::dealloc(AthPool<Ath__wire>* pool)
593 {
594   freeWires(pool);
595   delete[] _marker;
596   delete[] _eMarker;
597 }
598 
getAbsTrackNum(int xy)599 uint Ath__grid::getAbsTrackNum(int xy)
600 {
601   int dist = xy - _base;
602 
603   assert(dist >= 0);
604 
605   uint n = dist / _pitch;
606 
607   assert(n < _trackCnt);
608 
609   return n;
610 }
getMinMaxTrackNum(int xy)611 uint Ath__grid::getMinMaxTrackNum(int xy)
612 {
613   int dist = xy - _base;
614 
615   if (dist < 0)
616     return 0;
617 
618   uint n = dist / _pitch;
619 
620   if (n >= _trackCnt)
621     return _trackCnt - 1;
622 
623   return n;
624 }
625 
initContextTracks()626 void Ath__grid::initContextTracks()
627 {
628   setSearchDomain(1);
629   Ath__track *track, *btrack;
630   uint ii;
631   bool noPowerTarget = _gridtable->noPowerTarget() > 0 ? true : false;
632   for (ii = _searchLowTrack; ii <= _searchHiTrack; ii++) {
633     btrack = _trackTable[ii];
634     if (btrack == NULL)
635       continue;
636     track = NULL;
637     bool tohi = true;
638     while ((track = btrack->getNextSubTrack(track, tohi)) != nullptr)
639       track->initTargetWire(noPowerTarget);
640   }
641 }
642 
initContextGrids()643 void Ath__grid::initContextGrids()
644 {
645   uint sdepth = _gridtable->contextDepth();
646   if (sdepth == 0)
647     return;
648   uint ii = _dir ? 0 : 1;
649   uint jj;
650   for (jj = 1; jj <= sdepth && (jj + _level) < _gridtable->getColCnt(); jj++)
651     _gridtable->getGrid(ii, jj + _level)->initContextTracks();
652   for (jj = 1; jj <= sdepth && (_level - jj) > 0; jj++)
653     _gridtable->getGrid(ii, _level - jj)->initContextTracks();
654 }
655 
setSearchDomain(uint domainAdjust)656 void Ath__grid::setSearchDomain(uint domainAdjust)
657 {
658   if (_gridtable->allNet()) {
659     _searchLowTrack = 0;
660     _searchHiTrack = _trackCnt - 1;
661     _searchLowMarker = 0;
662     _searchHiMarker = _markerCnt - 1;
663     return;
664   }
665   Ath__box* searchBox = _gridtable->maxSearchBox();
666   int lo = _dir ? searchBox->_ylo : searchBox->_xlo;
667   int hi = _dir ? searchBox->_yhi : searchBox->_xhi;
668   int ltrack = (int) getMinMaxTrackNum(lo) - (int) domainAdjust;
669   _searchLowTrack = ltrack < 0 ? 0 : ltrack;
670   _searchHiTrack = getMinMaxTrackNum(hi) + domainAdjust;
671   if (_searchHiTrack >= _trackCnt)
672     _searchHiTrack = _trackCnt - 1;
673   int mlo = _dir ? searchBox->_xlo : searchBox->_ylo;
674   int mhi = _dir ? searchBox->_xhi : searchBox->_yhi;
675   _searchLowMarker = getBucketNum(mlo);
676   _searchHiMarker = getBucketNum(mhi);
677 }
678 
addTrack(uint ii,uint markerCnt,int base)679 Ath__track* Ath__grid::addTrack(uint ii, uint markerCnt, int base)
680 {
681   Ath__track* track = _trackPoolPtr->alloc();
682   track->set(this, _start, _end, ii, _width, _markerLen, markerCnt, base);
683   return track;
684 }
addTrack(uint ii,uint markerCnt)685 Ath__track* Ath__grid::addTrack(uint ii, uint markerCnt)
686 {
687   int trackBase = _base + _pitch * ii;
688   addTrack(ii, markerCnt, trackBase);
689   return NULL;
690 }
getTrackPtr(uint ii,uint markerCnt,int base)691 Ath__track* Ath__grid::getTrackPtr(uint ii, uint markerCnt, int base)
692 {
693   if (ii >= _trackCnt)
694     return NULL;
695 
696   if (_blockedTrackTable[ii] > 0)
697     return NULL;
698 
699   Ath__track* ntrack;
700   Ath__track* ttrack = _trackTable[ii];
701   while (ttrack) {
702     if (ttrack->getBase() == base)
703       break;
704     ntrack = ttrack->getHiTrack();
705     ttrack = ntrack == _trackTable[ii] ? NULL : ntrack;
706   }
707   if (ttrack)
708     return ttrack;
709   ttrack = addTrack(ii, markerCnt, base);
710   if (_trackTable[ii] == NULL) {
711     _trackTable[ii] = ttrack;
712     ttrack->setLowest(1);
713     return ttrack;
714   }
715   _subTrackCnt[ii]++;
716   ntrack = _trackTable[ii];
717   while (1) {
718     if (ntrack->getBase() > base)
719       break;
720     ntrack = ntrack->getHiTrack();
721     if (ntrack == _trackTable[ii])
722       break;
723   }
724   ntrack->getLowTrack()->setHiTrack(ttrack);
725   ttrack->setHiTrack(ntrack);
726   ttrack->setLowTrack(ntrack->getLowTrack());
727   ntrack->setLowTrack(ttrack);
728   if (base < _trackTable[ii]->getBase()) {
729     _trackTable[ii]->setLowest(0);
730     ttrack->setLowest(1);
731     _trackTable[ii] = ttrack;
732   }
733   return ttrack;
734 }
getTrackPtr(uint ii,uint markerCnt)735 Ath__track* Ath__grid::getTrackPtr(uint ii, uint markerCnt)
736 {
737   int trackBase = _base + _pitch * ii;
738   return getTrackPtr(ii, markerCnt, trackBase);
739 }
place(Ath__wire * w,int markIndex1,int markIndex2)740 bool Ath__track::place(Ath__wire* w, int markIndex1, int markIndex2)
741 {
742   assert(markIndex1 >= 0);
743   assert(markIndex2 >= 0);
744 
745   for (int ii = markIndex1 + 1; ii <= markIndex2; ii++)
746     _marker[ii] = w;
747 
748   if (_marker[markIndex1] == NULL) {
749     _marker[markIndex1] = w;
750     return true;
751   }
752 
753   Ath__wire* a = _marker[markIndex1];
754   if (w->_xy < a->_xy) {
755     if (w->_xy + w->_len >= a->_xy) {
756       fprintf(stdout, "overlap %d %d \n", w->_xy, a->_xy);
757       return false;
758     }
759     w->setNext(a);
760     _marker[markIndex1] = w;
761     return true;
762   }
763 
764   Ath__wire* e = _marker[markIndex1];
765   for (; e != NULL; e = e->_next) {
766     if (w->_xy < e->_xy) {
767       continue;
768     }
769     if (w->_xy + w->_len >= a->_xy) {
770       fprintf(stdout, "overlap %d %d \n", w->_xy, a->_xy);
771       return false;
772     }
773     w->setNext(e);
774     break;
775   }
776   return false;
777 }
search(int xy1,int xy2,uint & cnt,Ath__array1D<uint> * idTable)778 void Ath__wire::search(int xy1, int xy2, uint& cnt, Ath__array1D<uint>* idTable)
779 {
780   Ath__wire* e = this;
781   for (; e != NULL; e = e->_next) {
782     if (xy2 <= e->_xy)
783       break;
784 
785     if ((xy1 <= e->_xy) && (xy2 >= e->_xy)) {
786       idTable->add(e->_boxId);
787       cnt++;
788     } else if ((e->_xy <= xy1) && (e->_xy + e->_len >= xy1)) {
789       idTable->add(e->_boxId);
790       cnt++;
791     }
792   }
793 }
search1(int xy1,int xy2,uint & cnt,Ath__array1D<uint> * idTable)794 void Ath__wire::search1(int xy1,
795                         int xy2,
796                         uint& cnt,
797                         Ath__array1D<uint>* idTable)
798 {
799   Ath__wire* e = this;
800   for (; e != NULL; e = e->_next) {
801     if (xy2 <= e->_xy)
802       break;
803 
804     if ((xy1 <= e->_xy) && (xy2 >= e->_xy)) {
805       idTable->add(e->_id);
806       cnt++;
807     } else if ((e->_xy <= xy1) && (e->_xy + e->_len >= xy1)) {
808       idTable->add(e->_id);
809       cnt++;
810     }
811   }
812 }
search(int xy1,int xy2,uint markIndex1,uint markIndex2,Ath__array1D<uint> * idTable)813 uint Ath__track::search(int xy1,
814                         int xy2,
815                         uint markIndex1,
816                         uint markIndex2,
817                         Ath__array1D<uint>* idTable)
818 {
819   uint cnt = 0;
820   if (_eMarker[markIndex1])
821     _eMarker[markIndex1]->search(xy1, xy2, cnt, idTable);
822   for (uint ii = markIndex1; ii <= markIndex2; ii++) {
823     if (_marker[ii] == NULL)
824       continue;
825     _marker[ii]->search(xy1, xy2, cnt, idTable);
826   }
827   return cnt;
828 }
resetExtFlag(uint markerCnt)829 void Ath__track::resetExtFlag(uint markerCnt)
830 {
831   for (uint ii = 0; ii < markerCnt; ii++) {
832     Ath__wire* e = _marker[ii];
833     for (; e != NULL; e = e->_next) {
834       e->_ext = 0;
835     }
836   }
837 }
getAllWires(Ath__array1D<Ath__wire * > * boxTable,uint markerCnt)838 uint Ath__track::getAllWires(Ath__array1D<Ath__wire*>* boxTable, uint markerCnt)
839 {
840   for (uint ii = 0; ii < markerCnt; ii++) {
841     Ath__wire* e = _marker[ii];
842     for (; e != NULL; e = e->_next) {
843       if (e->_ext > 0)
844         continue;
845 
846       e->_ext = 1;
847       boxTable->add(e);
848     }
849   }
850   resetExtFlag(markerCnt);
851   return boxTable->getCnt();
852 }
search1(int xy1,int xy2,uint markIndex1,uint markIndex2,Ath__array1D<uint> * idTable)853 uint Ath__track::search1(int xy1,
854                          int xy2,
855                          uint markIndex1,
856                          uint markIndex2,
857                          Ath__array1D<uint>* idTable)
858 {
859   if (!_ordered) {
860     markIndex1 = 0;
861   }
862 
863   uint cnt = 0;
864   if (_eMarker[markIndex1])
865     _eMarker[markIndex1]->search1(xy1, xy2, cnt, idTable);
866   for (uint ii = markIndex1; ii <= markIndex2; ii++) {
867     if (_marker[ii] == NULL)
868       continue;
869     _marker[ii]->search1(xy1, xy2, cnt, idTable);
870   }
871   return cnt;
872 }
setExtrusionMarker(int markerCnt,int start,uint markerLen)873 uint Ath__track::setExtrusionMarker(int markerCnt, int start, uint markerLen)
874 {
875   _ordered = true;
876 
877   int jj;
878   int cnt = 0;
879   int ii;
880   for (ii = 0; ii < markerCnt; ii++)
881     _eMarker[ii] = NULL;
882   for (ii = 0; ii < markerCnt - 1; ii++) {
883     for (Ath__wire* e = _marker[ii]; e != NULL; e = e->_next) {
884       int tailMark = (e->_xy + e->_len - start) / markerLen;
885       if (tailMark == ii)
886         continue;
887       if (tailMark > markerCnt - 1)
888         tailMark = markerCnt - 1;
889       for (jj = ii + 1; jj <= tailMark; jj++) {
890         _eMarker[jj] = e;
891         if (_marker[jj]) {
892           jj++;
893           break;
894         }
895       }
896       ii = jj - 2;
897       cnt++;
898       break;
899     }
900   }
901   return cnt;
902 }
placeTrail(Ath__wire * w,uint m1,uint m2)903 bool Ath__track::placeTrail(Ath__wire* w, uint m1, uint m2)
904 {
905   for (uint ii = m1 + 1; ii <= m2; ii++) {
906     if (_marker[ii] == NULL) {
907       _marker[ii] = w;
908       continue;
909     }
910     if (w->_xy <= _marker[ii]->_xy) {
911       w->setNext(_marker[ii]);
912       _marker[ii] = w;
913     } else {
914       w->setNext(_marker[ii]->_next);
915       _marker[ii]->setNext(w);
916     }
917   }
918   return true;
919 }
checkAndplacerOnMarker(Ath__wire * w,int markIndex)920 bool Ath__track::checkAndplacerOnMarker(Ath__wire* w, int markIndex)
921 {
922   if (_marker[markIndex] == NULL) {
923     _marker[markIndex] = w;
924     return true;
925   }
926   return false;
927 }
checkMarker(int markIndex)928 bool Ath__track::checkMarker(int markIndex)
929 {
930   if (_marker[markIndex] == NULL) {
931     return true;
932   }
933   return false;
934 }
checkAndplace(Ath__wire * w,int markIndex1)935 bool Ath__track::checkAndplace(Ath__wire* w, int markIndex1)
936 {
937   if (_marker[markIndex1] == NULL) {
938     _marker[markIndex1] = w;
939     return true;
940   }
941 
942   Ath__wire* a = _marker[markIndex1];
943   if (w->_xy <= a->_xy) {
944     if (w->_xy + w->_len > a->_xy)
945       return false;
946 
947     w->setNext(a);
948     _marker[markIndex1] = w;
949 
950     return true;
951   }
952   Ath__wire* prev = _marker[markIndex1];
953   Ath__wire* e = _marker[markIndex1];
954   for (; e != NULL; e = e->_next) {
955     if (w->_xy <= e->_xy) {
956       if (w->_xy + w->_len > e->_xy)
957         return false;
958 
959       w->setNext(e);
960       prev->setNext(w);
961       return true;
962     }
963     prev = e;
964   }
965 
966   if (prev->_xy + prev->_len > w->_xy)
967     return false;
968   prev->setNext(w);
969   return true;
970 }
insertWire(Ath__wire * w,int mark1,int mark2)971 void Ath__track::insertWire(Ath__wire* w, int mark1, int mark2)
972 {
973   w->_track = this;
974   for (int ii = mark1; ii < mark2; ii++) {
975     _marker[ii] = w;
976   }
977   if (mark2 > mark1) {
978     w->setNext(_marker[mark2]);
979     _marker[mark2] = w;
980   }
981 }
982 
place2(Ath__wire * w,int mark1,int mark2)983 bool Ath__track::place2(Ath__wire* w, int mark1, int mark2)
984 {
985   assert(mark1 >= 0);
986 
987   w->_next = NULL;
988   if (_marker[mark1] == NULL) {
989     insertWire(w, mark1, mark2);
990     return true;
991   }
992   bool status = true;
993 
994   Ath__wire* a = _marker[mark1];
995   if (w->_xy <= a->_xy) {
996     w->setNext(a);
997     _marker[mark1] = w;
998 
999     w->_track = this;
1000 
1001     return true;
1002   }
1003   Ath__wire* prev = _marker[mark1];
1004   Ath__wire* e = _marker[mark1];
1005   for (; e != NULL; e = e->_next) {
1006     if (w->_xy <= e->_xy) {
1007       w->setNext(e);
1008       prev->setNext(w);
1009 
1010       w->_track = this;
1011       return true;
1012     }
1013     prev = e;
1014   }
1015   if (e == NULL) {  // at the end of the list
1016     prev->setNext(w);
1017     insertWire(w, mark1, mark2);
1018     return true;
1019   }
1020 
1021   if (!status)
1022     fprintf(stdout, "OVERLAP placement\n");
1023 
1024   return status;
1025 }
1026 int SdbPlaceWireNoTouchCheckForOverlap = 0;
linkWire(Ath__wire * & w1,Ath__wire * & w2)1027 void Ath__track::linkWire(Ath__wire*& w1, Ath__wire*& w2)
1028 {
1029   Ath__overlapAdjust adj
1030       = (Ath__overlapAdjust) _grid->getGridTable()->getOverlapAdjust();
1031   int nend, oend, tend;
1032   nend = w1->_xy + w1->_len;
1033   oend = w2->_xy + w2->_len;
1034   tend = nend > oend ? nend : oend;
1035   if (adj == Z_noAdjust || nend <= w2->_xy)
1036     w1->setNext(w2);
1037   else if (w1->_base != w2->_base || w1->_width != w2->_width) {
1038     if (!_grid->getGridTable()->getOverlapTouchCheck()
1039         || w1->_base > w2->_base + w2->_width
1040         || w2->_base > w1->_base + w1->_width)
1041       w1->setNext(w2);
1042     else {  // only good for adj == Z_endAdjust
1043       if (w1->_base < w2->_base) {  // w1 is wider?
1044         w2->_xy = nend;
1045         w1->setNext(w2);
1046         if (nend >= oend)
1047           w2->_len = 0;
1048         else
1049           w2->_len = oend - nend;
1050       } else {  // todo: nend > oend
1051         w1->setNext(w2);
1052         w1->_len = w2->_xy - w1->_xy;
1053       }
1054     }
1055   } else if (adj == Z_merge) {
1056     w1->_len = tend - w1->_xy;
1057     w1->setNext(w2->_next);
1058     w2 = w1;
1059   } else {  // adj == Z_endAdjust
1060     w2->_xy = nend;
1061     w1->setNext(w2);
1062     if (nend >= oend)
1063       w2->_len = 0;
1064     else
1065       w2->_len = oend - nend;
1066   }
1067 }
1068 
place(Ath__wire * w,int markIndex1)1069 bool Ath__track::place(Ath__wire* w, int markIndex1)
1070 {
1071   assert(markIndex1 >= 0);
1072 
1073   w->_track = this;
1074 
1075   if (_marker[markIndex1] == NULL) {
1076     _marker[markIndex1] = w;
1077     return true;
1078   }
1079   Ath__overlapAdjust adj
1080       = (Ath__overlapAdjust) _grid->getGridTable()->getOverlapAdjust();
1081   bool status = true;
1082 
1083   Ath__wire* a = _marker[markIndex1];
1084   if (w->_xy <= a->_xy) {
1085     if (adj != Z_noAdjust && w->_xy + w->_len > a->_xy + a->_len
1086         && w->_base <= a->_base
1087         && w->_base + w->_width >= a->_base + a->_width) {  // a inside w
1088       w->_next = _marker[markIndex1]->_next;
1089       _marker[markIndex1] = w;
1090       return true;
1091     }
1092     linkWire(w, a);
1093     _marker[markIndex1] = w;
1094 
1095     return true;
1096   }
1097   Ath__wire* prev = _marker[markIndex1];
1098   Ath__wire* e = _marker[markIndex1];
1099   for (; e != NULL; e = e->_next) {
1100     if (w->_xy <= e->_xy) {
1101       if (adj != Z_noAdjust && w->_xy + w->_len >= e->_xy + e->_len
1102           && w->_base <= e->_base
1103           && w->_base + w->_width >= e->_base + e->_width) {  // e inside w
1104         prev->_next = w;
1105         w->_next = e->_next;
1106         return true;
1107       }
1108       linkWire(prev, w);
1109       linkWire(w, e);
1110       return true;
1111     } else if (adj != Z_noAdjust && w->_xy + w->_len <= e->_xy + e->_len
1112                && e->_base <= w->_base
1113                && e->_base + e->_width >= w->_base + w->_width) {  // w inside e
1114       return true;
1115     }
1116     prev = e;
1117   }
1118   if (e == NULL) {
1119     linkWire(prev, w);
1120   }
1121 
1122   if (!status)
1123     fprintf(stdout, "OVERLAP placement\n");
1124 
1125   return status;
1126 }
getNextWire(Ath__wire * wire)1127 Ath__wire* Ath__track::getNextWire(Ath__wire* wire)
1128 {
1129   Ath__wire* nwire;
1130   if (!wire) {
1131     _searchMarkerIndex = _grid->searchLowMarker();
1132     nwire = _marker[_searchMarkerIndex];
1133   } else
1134     nwire = wire->_next;
1135   if (nwire)
1136     return nwire;
1137   for (_searchMarkerIndex++; _searchMarkerIndex <= _grid->searchHiMarker();
1138        _searchMarkerIndex++) {
1139     nwire = _marker[_searchMarkerIndex];
1140     if (nwire)
1141       return nwire;
1142   }
1143   return NULL;
1144 }
1145 
getWire_Linear(uint markerCnt,uint id)1146 Ath__wire* Ath__track::getWire_Linear(uint markerCnt, uint id)
1147 {
1148   for (uint ii = 0; ii < markerCnt; ii++) {
1149     Ath__wire* e = _marker[ii];
1150     for (; e != NULL; e = e->_next) {
1151       if (e->_id == id)
1152         return e;
1153     }
1154   }
1155   return NULL;
1156 }
adjustOverlapMakerEnd(uint markerCnt,int start,uint markerLen)1157 void Ath__track::adjustOverlapMakerEnd(uint markerCnt,
1158                                        int start,
1159                                        uint markerLen)
1160 {
1161   _ordered = true;
1162 
1163   Ath__wire* e;
1164   uint tailMark;
1165   uint jj;
1166   for (uint ii = 0; ii < markerCnt - 1; ii++) {
1167     if ((e = _marker[ii]) == NULL)
1168       continue;
1169     for (; e->_next != NULL; e = e->_next) {
1170       ;
1171     }
1172     tailMark = (e->_xy + e->_len - start) / markerLen;
1173     if (tailMark == ii)
1174       continue;
1175     if (tailMark > markerCnt - 1)
1176       tailMark = markerCnt - 1;
1177     for (jj = ii + 1; jj <= tailMark; jj++) {
1178       _eMarker[jj] = e;
1179       if (_marker[jj]) {
1180         jj++;
1181         break;
1182       }
1183     }
1184     jj--;
1185     if (_marker[jj] != NULL && e->_xy + e->_len > _marker[jj]->_xy)
1186       e->_len = _marker[jj]->_xy - e->_xy;
1187     ii = jj - 1;
1188   }
1189 }
adjustOverlapMakerEnd(uint markerCnt)1190 void Ath__track::adjustOverlapMakerEnd(uint markerCnt)
1191 {
1192   Ath__wire* e;
1193   uint jj;
1194   for (uint ii = 0; ii < markerCnt - 1; ii++) {
1195     if ((e = _marker[ii]) == NULL)
1196       continue;
1197     for (; e->_next != NULL; e = e->_next) {
1198       ;
1199     }
1200     for (jj = ii + 1; jj < markerCnt && _marker[jj] == NULL; jj++) {
1201       ;
1202     }
1203     if (jj == markerCnt)
1204       continue;
1205     if (e->_xy + e->_len > _marker[jj]->_xy)
1206       e->_len = _marker[jj]->_xy - e->_xy;
1207     ii = jj - 1;
1208   }
1209 }
adjustMetalFill()1210 void Ath__track::adjustMetalFill()
1211 {
1212   uint wsrcId;
1213   int wstart, wend;
1214   Ath__wire* wire = getNextWire(NULL);
1215   Ath__wire* gwire = NULL;
1216   Ath__wire* nwire = NULL;
1217   Ath__wire* nnwire = NULL;
1218   Ath__wire* pnwire = NULL;
1219   Ath__wire* prevwire = NULL;
1220   for (; wire; prevwire = wire, wire = nwire) {
1221     nwire = getNextWire(wire);
1222     if (!nwire || wire->_xy + wire->_len <= nwire->_xy)
1223       continue;
1224     if (wire->_base != nwire->_base || wire->_width != nwire->_width) {
1225       _grid->getGridTable()->incrNotAlignedOverlap(wire, nwire);
1226       continue;
1227     }
1228     if (wire->isPower() == nwire->isPower()) {
1229       if (!wire->isPower()) {
1230         _grid->getGridTable()->incrSignalOverlap();
1231       } else {
1232         _grid->getGridTable()->incrPowerOverlap();
1233         if (wire->_xy >= nwire->_xy)
1234           continue;  // bp
1235         wire->_len = nwire->_xy - wire->_xy;
1236       }
1237       continue;
1238     }
1239     if (!wire->isPower())
1240     // signal wire extends into power wire
1241     {
1242       _grid->getGridTable()->incrSignalToPowerOverlap();
1243       if (wire->_xy + wire->_len >= nwire->_xy + nwire->_len) {
1244         if (wire->_next == nwire)
1245           wire->_next = nwire->_next;
1246         else {
1247           assert(wire->_next == NULL);
1248           assert(_marker[_searchMarkerIndex] == nwire);
1249           _marker[_searchMarkerIndex] = nwire->_next;
1250         }
1251         _grid->getWirePoolPtr()->free(nwire);
1252         nwire = getNextWire(wire);
1253       } else
1254         nwire->_xy = wire->_xy + wire->_len;
1255       continue;
1256     }
1257     // power wire extends into signal wire
1258     _grid->getGridTable()->incrPowerToSignallOverlap();
1259     if (wire->_xy + wire->_len
1260         <= nwire->_xy
1261                + nwire->_len) {     // power wire does not end after signal wire
1262       if (wire->_xy >= nwire->_xy)  // can be > by prvious adjustment
1263       {
1264         if (_marker[_searchMarkerIndex] == wire)
1265           _marker[_searchMarkerIndex] = nwire;
1266         else {
1267           assert(prevwire->_next == wire);
1268           prevwire->_next = nwire;
1269         }
1270         _grid->getWirePoolPtr()->free(wire);
1271         wire = prevwire;
1272       } else {
1273         wire->_len = nwire->_xy - wire->_xy;
1274       }
1275       continue;
1276     } else {  // power wire ends after signal wire
1277       wstart = nwire->_xy + nwire->_len;
1278       wend = wire->_xy + wire->_len;
1279       wsrcId = wire->_srcId;
1280       if (wire->_xy >= nwire->_xy)  // can be > by prvious adjustment
1281       {
1282         if (_marker[_searchMarkerIndex] == wire)
1283           _marker[_searchMarkerIndex] = nwire;
1284         else
1285           prevwire->_next = nwire;
1286         _grid->getWirePoolPtr()->free(wire);
1287         wire = prevwire;
1288       } else {
1289         wire->_len = nwire->_xy - wire->_xy;
1290       }
1291       if (wsrcId != 0)
1292         continue;
1293       pnwire = nwire;
1294       for (nnwire = getNextWire(nwire); nnwire;
1295            pnwire = nnwire, nnwire = getNextWire(nnwire)) {
1296         if (wend <= nnwire->_xy) {
1297           gwire
1298               = wire->makeWire(_grid->getWirePoolPtr(), wstart, wend - wstart);
1299           _grid->placeWire(gwire);
1300           wire = gwire;
1301           nwire = nnwire;
1302           break;
1303         }
1304         if (nwire->_base != nnwire->_base || nwire->_width != nnwire->_width) {
1305           _grid->getGridTable()->incrNotAlignedOverlap(nwire, nnwire);
1306           // notice(0,"Overlapped but not aligned wires!\n");
1307         }
1308         if (nnwire->isPower()) {
1309           // notice (0, "Overlapped power wire\n");
1310           _grid->getGridTable()->incrPowerOverlap();
1311         }
1312         gwire = NULL;
1313         if (wstart < nnwire->_xy) {
1314           gwire = wire->makeWire(
1315               _grid->getWirePoolPtr(), wstart, nnwire->_xy - wstart);
1316           _grid->placeWire(gwire);
1317         }
1318         wstart = nnwire->_xy + nnwire->_len;
1319         if (wend <= wstart) {
1320           wire = gwire ? gwire : pnwire;
1321           nwire = nnwire;
1322           break;
1323         }
1324       }
1325       if (nnwire == NULL)
1326         break;
1327     }  // end of power wire extends into signal wire
1328   }
1329 }
isAscendingOrdered(uint markerCnt,uint * wCnt)1330 bool Ath__track::isAscendingOrdered(uint markerCnt, uint* wCnt)
1331 {
1332   uint cnt = 0;
1333   for (uint ii = 0; ii < markerCnt; ii++) {
1334     Ath__wire* e = _marker[ii];
1335     for (; e != NULL; e = e->_next) {
1336       Ath__wire* w = e->_next;
1337       cnt++;
1338 
1339       if (w == NULL)
1340         break;
1341 
1342       if (w->_xy < e->_xy) {
1343         *wCnt = cnt;
1344         return false;
1345       }
1346     }
1347   }
1348   *wCnt += cnt;
1349   return true;
1350 }
overlapCheck(Ath__wire * w,int markIndex1,int)1351 bool Ath__track::overlapCheck(Ath__wire* w,
1352                               int markIndex1,
1353                               int /* unused: markIndex2 */)
1354 {
1355   assert(markIndex1 >= 0);
1356 
1357   Ath__wire* e = _marker[markIndex1];
1358   for (; e != NULL; e = e->_next) {
1359     if (w->_xy + w->_len >= e->_xy) {
1360       return true;
1361     }
1362   }
1363   return false;
1364 }
makeTrackTable(uint width,uint pitch,uint space)1365 void Ath__grid::makeTrackTable(uint width, uint pitch, uint space)
1366 {
1367   if (width > 0)
1368     _width = width;
1369 
1370   if (space > 0)
1371     _pitch = _width + space;
1372   else if (pitch > 0)
1373     _pitch = pitch;
1374 
1375   _markerLen = ((_end - _start) / _width) / _markerCnt;
1376 
1377   _trackCnt = _max;  // for LINUX assert
1378   _trackCnt = getAbsTrackNum(_max) + 1;
1379   _subTrackCnt = (uint*) calloc(sizeof(uint), _trackCnt);
1380   _trackTable = new Ath__track*[_trackCnt];
1381   _blockedTrackTable = new uint[_trackCnt];
1382 
1383   for (uint ii = 0; ii < _trackCnt; ii++) {
1384     _trackTable[ii] = NULL;
1385     _blockedTrackTable[ii] = 0;
1386   }
1387 }
1388 
setBoundaries(uint dir,int xlo,int ylo,int xhi,int yhi)1389 void Ath__grid::setBoundaries(uint dir, int xlo, int ylo, int xhi, int yhi)
1390 {
1391   _lo[0] = xlo;
1392   _lo[1] = ylo;
1393   _hi[0] = xhi;
1394   _hi[1] = yhi;
1395 
1396   _dir = dir;
1397   if (_dir == 0) {  // vertical
1398     _base = xlo;
1399     _max = xhi;
1400     _start = ylo;
1401     _end = yhi;
1402   } else {
1403     _base = ylo;
1404     _max = yhi;
1405     _start = xlo;
1406     _end = xhi;
1407   }
1408 }
Ath__grid(Ath__gridTable * gt,AthPool<Ath__track> * trackPool,AthPool<Ath__wire> * wirePool,uint level,uint num,uint markerCnt)1409 Ath__grid::Ath__grid(Ath__gridTable* gt,
1410                      AthPool<Ath__track>* trackPool,
1411                      AthPool<Ath__wire>* wirePool,
1412                      uint level,
1413                      uint num,
1414                      uint markerCnt)
1415 {
1416   _gridtable = gt;
1417   _trackPoolPtr = trackPool;
1418   _wirePoolPtr = wirePool;
1419   _markerCnt = markerCnt;
1420   _level = level;
1421   _layer = num;
1422   _schema = 0;
1423 }
1424 
setTracks(uint dir,uint width,uint pitch,int xlo,int ylo,int xhi,int yhi,uint markerLen)1425 void Ath__grid::setTracks(uint dir,
1426                           uint width,
1427                           uint pitch,
1428                           int xlo,
1429                           int ylo,
1430                           int xhi,
1431                           int yhi,
1432                           uint markerLen)
1433 {
1434   setBoundaries(dir, xlo, ylo, xhi, yhi);
1435   makeTrackTable(width, pitch);
1436 
1437   if (markerLen > 0) {
1438     _markerLen = markerLen;
1439     _markerCnt = ((_end - _start) / _width) / markerLen;
1440     if (_markerCnt == 0)
1441       _markerCnt = 1;
1442   }
1443 }
setSchema(uint v)1444 void Ath__grid::setSchema(uint v)
1445 {
1446   _schema = v;
1447 }
Ath__grid(Ath__gridTable * gt,AthPool<Ath__track> * trackPool,AthPool<Ath__wire> * wirePool,Ath__box * bb,uint level,uint dir,uint num,uint width,uint pitch,uint markerCnt)1448 Ath__grid::Ath__grid(Ath__gridTable* gt,
1449                      AthPool<Ath__track>* trackPool,
1450                      AthPool<Ath__wire>* wirePool,
1451                      Ath__box* bb,
1452                      uint level,
1453                      uint dir,
1454                      uint num,
1455                      uint width,
1456                      uint pitch,
1457                      uint markerCnt)
1458 {
1459   _gridtable = gt;
1460   _trackPoolPtr = trackPool;
1461   _wirePoolPtr = wirePool;
1462   _markerCnt = markerCnt;
1463 
1464   _level = level;
1465   _layer = num;
1466 
1467   setBoundaries(dir, bb->_xlo, bb->_ylo, bb->_xhi, bb->_yhi);
1468   makeTrackTable(width, pitch);
1469   _schema = 0;
1470 }
getBbox(Ath__searchBox * bb)1471 void Ath__grid::getBbox(Ath__searchBox* bb)
1472 {
1473   if (_dir == 0)  // vertical
1474     bb->set(_base, _start, _max, _end, _level, _dir);
1475   else
1476     bb->set(_start, _base, _end, _max, _level, _dir);
1477 }
getBbox(Ath__box * bb)1478 void Ath__grid::getBbox(Ath__box* bb)
1479 {
1480   if (_dir == 0) {  // vertical
1481     bb->_xlo = _base;
1482     bb->_xhi = _max;
1483     bb->_ylo = _start;
1484     bb->_yhi = _end;
1485   } else {
1486     bb->_ylo = _base;
1487     bb->_yhi = _max;
1488     bb->_xlo = _start;
1489     bb->_xhi = _end;
1490   }
1491 }
1492 
freeTracksAndTables()1493 void Ath__grid::freeTracksAndTables()
1494 {
1495   delete[] _trackTable;
1496   delete[] _blockedTrackTable;
1497 }
~Ath__grid()1498 Ath__grid::~Ath__grid()
1499 {
1500   freeTracksAndTables();
1501 }
getLevel()1502 uint Ath__grid::getLevel()
1503 {
1504   return _level;
1505 }
getDir()1506 uint Ath__grid::getDir()
1507 {
1508   return _dir;
1509 }
getTrackHeight(uint track)1510 int Ath__grid::getTrackHeight(uint track)
1511 {
1512   return _base + track * _pitch;
1513 }
getGrid()1514 Ath__grid* Ath__track::getGrid()
1515 {
1516   return _grid;
1517 }
removeMarkedNetWires()1518 uint Ath__track::removeMarkedNetWires()
1519 {
1520   uint cnt = 0;
1521   Ath__wire *wire, *pwire, *nwire;
1522   for (uint jj = 0; jj < _markerCnt; jj++) {
1523     pwire = NULL;
1524     wire = _marker[jj];
1525     _marker[jj] = NULL;
1526     for (; wire != NULL; wire = nwire) {
1527       nwire = wire->_next;
1528       uint kk = 0;
1529       if (wire->isPower() || !wire->getNet()->isMarked()) {
1530         if (wire->isPower() || wire->getNet()->getWire() != NULL) {
1531           pwire = wire;
1532           if (_marker[jj] == NULL)
1533             _marker[jj] = wire;
1534           continue;
1535         } else
1536           kk = 0;  // bp
1537       }
1538       if (pwire)
1539         pwire->_next = nwire;
1540       for (kk = jj + 1; kk < _markerCnt; kk++) {
1541         if (_eMarker[kk] == wire)
1542           _eMarker[kk] = nwire;
1543       }
1544       _grid->getWirePoolPtr()->free(wire);
1545       cnt++;
1546     }
1547   }
1548   return cnt;
1549 }
defaultWireType()1550 uint Ath__grid::defaultWireType()
1551 {
1552   return _wireType;
1553 }
setDefaultWireType(uint v)1554 void Ath__grid::setDefaultWireType(uint v)
1555 {
1556   _wireType = v;  // TODO-OPTIMIZE : can it be 32-bit?
1557 }
getBoxes(uint trackIndex,Ath__array1D<uint> * table)1558 uint Ath__grid::getBoxes(uint trackIndex, Ath__array1D<uint>* table)
1559 {
1560   Ath__track* tr = _trackTable[trackIndex];
1561   if (tr == NULL)
1562     return 0;
1563   if (_blockedTrackTable[trackIndex] > 0)
1564     return 0;
1565 
1566   for (uint k = 0; k < tr->_markerCnt; k++) {
1567     if (tr->_marker[k] == NULL)
1568       continue;
1569     for (Ath__wire* w = tr->_marker[k]; w != NULL; w = w->_next) {
1570       table->add(w->_boxId);
1571     }
1572   }
1573   return table->getCnt();
1574 }
getBoxes(Ath__array1D<uint> * table)1575 void Ath__grid::getBoxes(Ath__array1D<uint>* table)
1576 {
1577   for (uint ii = 0; ii < _trackCnt; ii++) {
1578     Ath__track* tr = _trackTable[ii];
1579     if (tr == NULL)
1580       continue;
1581     if (_blockedTrackTable[ii] > 0)
1582       continue;
1583 
1584     for (Ath__wire* w = tr->_marker[0]; w != NULL; w = w->_next) {
1585       table->add(w->_boxId);
1586     }
1587   }
1588 }
1589 
addOnTrack(uint track,Ath__wire * w,uint mark1,uint mark2)1590 bool Ath__grid::addOnTrack(uint track, Ath__wire* w, uint mark1, uint mark2)
1591 {
1592   if (_blockedTrackTable[track] > 0)
1593     return false;
1594 
1595   Ath__track* tr = NULL;
1596   if (_trackTable[track] == NULL) {
1597     tr = addTrack(track, _markerCnt);
1598     _trackTable[track] = tr;
1599     if (tr->place(w, mark1, mark2)) {
1600       w->_track = tr;
1601       return true;
1602     } else
1603       return false;
1604   }
1605   if (!_trackTable[track]->overlapCheck(w, mark1, mark2)) {
1606     tr = _trackTable[track];
1607     if (tr->place(w, mark1, mark2)) {
1608       w->_track = tr;
1609       return true;
1610     } else
1611       return false;
1612   }
1613   return false;
1614 }
placeWire(uint initTrack,Ath__wire * w,uint mark1,uint mark2,int sortedOrder,int * height)1615 uint Ath__grid::placeWire(uint initTrack,
1616                           Ath__wire* w,
1617                           uint mark1,
1618                           uint mark2,
1619                           int sortedOrder,
1620                           int* height)
1621 {
1622   uint check = 20;
1623   uint track = initTrack;
1624 
1625   uint nextTrack = track;
1626 
1627   bool status = false;
1628   if (sortedOrder > 0) {
1629     for (; (track < _trackCnt) && (track < initTrack + check); track++) {
1630       status = addOnTrack(track, w, mark1, mark2);
1631       if (status)
1632         break;
1633     }
1634     nextTrack = track + 1;
1635   } else {
1636     for (; (!status) && (track > 0) && (track > initTrack - check); track--) {
1637       status = addOnTrack(track, w, mark1, mark2);
1638       if (status)
1639         break;
1640     }
1641     nextTrack = track - 1;
1642   }
1643   if (!status) {
1644     fprintf(stdout, "Cannot place at track# %d\n", initTrack);
1645     *height = getTrackHeight(initTrack);
1646     return initTrack;
1647   }
1648   *height = getTrackHeight(track);
1649   return nextTrack;
1650 }
addWireList(Ath__box * list)1651 uint Ath__grid::addWireList(Ath__box* list)
1652 {
1653   uint cnt = 0;
1654   for (Ath__box* e = list; e != NULL; e = e->_next) {
1655     if (e->_layer != _level)
1656       continue;
1657     if (e->getDir() != _dir)
1658       continue;
1659 
1660     uint initTrack = getTrackNum(e);
1661     int height;
1662 
1663     addWire(initTrack, e, 1, &height);
1664     cnt++;
1665   }
1666   return cnt;
1667 }
addWire(uint initTrack,Ath__box * box,int sortedOrder,int * height)1668 uint Ath__grid::addWire(uint initTrack,
1669                         Ath__box* box,
1670                         int sortedOrder,
1671                         int* height)
1672 {
1673   uint id, markIndex1, markIndex2;
1674   Ath__wire* w = makeWire(box, &id, &markIndex1, &markIndex2, 0);
1675 
1676   return placeWire(initTrack, w, markIndex1, markIndex2, sortedOrder, height);
1677 }
getTrackPtr(int xy)1678 Ath__track* Ath__grid::getTrackPtr(int xy)
1679 {
1680   uint trackNum = getMinMaxTrackNum(xy);
1681 
1682   return getTrackPtr(trackNum, _markerCnt);
1683 }
getTrackPtr(int * ll)1684 Ath__track* Ath__grid::getTrackPtr(int* ll)
1685 {
1686   uint trackNum = getMinMaxTrackNum(ll[_dir]);
1687 
1688   return getTrackPtr(trackNum, _markerCnt);
1689 }
placeBox(uint id,int x1,int y1,int x2,int y2)1690 uint Ath__grid::placeBox(uint id, int x1, int y1, int x2, int y2)
1691 {
1692   int ll[2] = {x1, y1};
1693   int ur[2] = {x2, y2};
1694 
1695   uint d = (_dir > 0) ? 0 : 1;
1696 
1697   int xy1 = ll[d];
1698 
1699   uint m1 = getBucketNum(xy1);
1700   int width = ur[_dir] - ll[_dir];
1701 
1702   uint trackNum1 = getMinMaxTrackNum(ll[_dir]);
1703   uint trackNum2 = trackNum1;
1704   if (width > _pitch)
1705     trackNum2 = getMinMaxTrackNum(ur[_dir]);
1706 
1707   for (uint ii = trackNum1; ii <= trackNum2; ii++) {
1708     Ath__wire* w = makeWire(_dir, ll, ur, id, 0);
1709 
1710     Ath__track* track = getTrackPtr(ii, _markerCnt);
1711 
1712     if (track->place(w, m1)) {
1713       w->_track = track;
1714     } else {
1715       fprintf(stdout, "OVERLAP placement\n");
1716     }
1717   }
1718 
1719   return trackNum1;
1720 }
setXY(int xy1,uint len)1721 void Ath__wire::setXY(int xy1, uint len)
1722 {
1723   _xy = xy1;  // offset from track start??
1724   _len = len;
1725 }
makeCoupleWire(AthPool<Ath__wire> * wirePool,int targetHighTracks,Ath__wire * w2,int xy1,uint len,uint)1726 Ath__wire* Ath__wire::makeCoupleWire(AthPool<Ath__wire>* wirePool,
1727                                      int targetHighTracks,
1728                                      Ath__wire* w2,
1729                                      int xy1,
1730                                      uint len,
1731                                      uint /* unused: wtype */)
1732 {
1733   int dist;
1734   if (targetHighTracks)
1735     dist = w2->_base - (_base + _width);
1736   else
1737     dist = _base - (w2->_base + w2->_width);
1738   if (dist <= 0)
1739     return NULL;
1740 
1741   Ath__wire* w = getPoolWire(wirePool);
1742   w->_srcId = 0;
1743 
1744   w->reset();
1745 
1746   w->_xy = xy1;  // offset from track start??
1747   w->_len = len;
1748 
1749   w->_width = dist;
1750   w->_boxId = _id;
1751   w->_otherId = w2->_id;
1752   w->_flags = _flags;
1753   w->_dir = _dir;
1754   if (targetHighTracks)
1755     w->_base = _base + _width;  // small dimension
1756   else
1757     w->_base = w2->_base + w2->_width;
1758   return w;
1759 }
getPoolWire(AthPool<Ath__wire> * wirePool)1760 Ath__wire* Ath__wire::getPoolWire(AthPool<Ath__wire>* wirePool)
1761 {
1762   uint n;
1763   uint getRecycleFlag = 0;
1764   Ath__wire* w = wirePool->alloc(&getRecycleFlag, &n);
1765   if (getRecycleFlag == 0)
1766     w->_id = n;
1767   return w;
1768 }
makeWire(AthPool<Ath__wire> * wirePool,int xy1,uint len)1769 Ath__wire* Ath__wire::makeWire(AthPool<Ath__wire>* wirePool, int xy1, uint len)
1770 {
1771   Ath__wire* w = getPoolWire(wirePool);
1772 
1773   w->_srcId = 0;
1774 
1775   w->reset();
1776 
1777   w->_xy = xy1;  // offset from track start
1778   w->_len = len;
1779 
1780   w->_base = _base;  // small dimension
1781   w->_width = _width;
1782 
1783   w->_boxId = _boxId;
1784   w->_otherId = _otherId;
1785 
1786   w->_flags = _flags;
1787   w->_dir = _dir;
1788 
1789   return w;
1790 }
getPoolWire()1791 Ath__wire* Ath__grid::getPoolWire()
1792 {
1793   uint n;
1794   uint getRecycleFlag = 0;
1795   Ath__wire* w = _wirePoolPtr->alloc(&getRecycleFlag, &n);
1796   if (getRecycleFlag == 0)
1797     w->_id = n;
1798   return w;
1799 }
makeWire(Ath__wire * v,uint type)1800 Ath__wire* Ath__grid::makeWire(Ath__wire* v, uint type)
1801 {
1802   Ath__wire* w = getPoolWire();
1803   w->_srcId = 0;
1804 
1805   w->reset();
1806 
1807   w->_xy = v->_xy;  // offset from track start
1808   w->_len = v->_len;
1809 
1810   w->_base = v->_base;  // small dimension
1811   w->_width = v->_width;
1812 
1813   w->_boxId = v->_boxId;
1814   w->_otherId = v->_otherId;
1815 
1816   w->_flags = type;
1817 
1818   w->_dir = v->_dir;
1819 
1820   return w;
1821 }
1822 
placeWire(Ath__searchBox * bb)1823 uint Ath__grid::placeWire(Ath__searchBox* bb)
1824 {
1825   uint d = !_dir;
1826 
1827   int xy1 = bb->loXY(d);
1828 
1829   int ll[2] = {bb->loXY(0), bb->loXY(1)};
1830   int ur[2] = {bb->hiXY(0), bb->hiXY(1)};
1831 
1832   uint m1 = getBucketNum(xy1);
1833 
1834 #ifdef SINGLE_WIRE
1835   uint width = bb->hiXY(_dir) - bb->loXY(_dir);
1836   uint trackNum1 = getMinMaxTrackNum((bb->loXY(_dir) + bb->loXY(_dir)) / 2);
1837   uint trackNum2 = trackNum1;
1838   if (width > _pitch)
1839     trackNum2 = getMinMaxTrackNum(bb->hiXY(_dir));
1840     // ** wire base is not always at track base
1841 #else
1842   uint trackNum1 = getMinMaxTrackNum(bb->loXY(_dir));
1843   uint trackNum2 = getMinMaxTrackNum(bb->hiXY(_dir));
1844 #endif
1845 
1846   uint wireType = bb->getType();
1847 
1848   Ath__wire* w
1849       = makeWire(_dir, ll, ur, bb->getOwnerId(), bb->getOtherId(), wireType);
1850   Ath__track* track;
1851   int TTTsubt = 1;
1852   if (TTTsubt)
1853     track = getTrackPtr(trackNum1, _markerCnt, w->_base);
1854   else
1855     track = getTrackPtr(trackNum1, _markerCnt);
1856   // track->place2(w, m1, m2);
1857   track->place(w, m1);
1858   uint wCnt = 1;
1859   for (uint ii = trackNum1 + 1; ii <= trackNum2; ii++) {
1860     Ath__wire* w1 = makeWire(w, wireType);
1861     w1->_srcId = w->_id;
1862     w1->_srcWire = w;
1863     _gridtable->incrMultiTrackWireCnt(w->isPower());
1864     Ath__track* track = getTrackPtr(ii, _markerCnt);
1865     track->place(w1, m1);
1866     wCnt++;
1867   }
1868 
1869   return trackNum1;
1870 }
placeWire(Ath__wire * w)1871 uint Ath__grid::placeWire(Ath__wire* w)
1872 {
1873   uint m1 = getBucketNum(w->_xy);
1874 
1875   uint trackNum1 = getMinMaxTrackNum(w->_base);
1876   uint trackNum2 = getMinMaxTrackNum(w->_base + w->_width);
1877 
1878   Ath__track* track = getTrackPtr(trackNum1, _markerCnt);
1879   track->place(w, m1);
1880 
1881   for (uint ii = trackNum1 + 1; ii <= trackNum2; ii++) {
1882     Ath__wire* w1 = makeWire(w, w->_flags);
1883     w1->_srcId = w->_id;
1884     _gridtable->incrMultiTrackWireCnt(w->isPower());
1885     Ath__track* track = getTrackPtr(ii, _markerCnt);
1886     track->place(w1, m1);
1887   }
1888 
1889   return trackNum1;
1890 }
placeBox(dbBox * box,uint wtype,uint id)1891 uint Ath__grid::placeBox(dbBox* box, uint wtype, uint id)
1892 {
1893   int ll[2] = {box->xMin(), box->yMin()};
1894   int ur[2] = {box->xMax(), box->yMax()};
1895 
1896   uint d = (_dir > 0) ? 0 : 1;
1897 
1898   int xy1 = ll[d];
1899 
1900   uint m1 = getBucketNum(xy1);
1901 
1902   int width = ur[_dir] - ll[_dir];
1903 
1904   uint trackNum1 = getMinMaxTrackNum(ll[_dir]);
1905   uint trackNum2 = trackNum1;
1906   if (width > _pitch)
1907     trackNum2 = getMinMaxTrackNum(ur[_dir]);
1908 
1909   if (id == 0)
1910     id = box->getId();
1911   Ath__wire* w = makeWire(_dir, ll, ur, id, 0, wtype);
1912   Ath__track* track = getTrackPtr(trackNum1, _markerCnt);
1913   track->place(w, m1);
1914 
1915   for (uint ii = trackNum1 + 1; ii <= trackNum2; ii++) {
1916     Ath__wire* w1 = makeWire(w);
1917     w1->_srcId = w->_id;
1918     _gridtable->incrMultiTrackWireCnt(w->isPower());
1919     Ath__track* track = getTrackPtr(ii, _markerCnt);
1920     track->place(w1, m1);
1921   }
1922   return trackNum1;
1923 }
setExtrusionMarker()1924 uint Ath__grid::setExtrusionMarker()
1925 {
1926   Ath__track *track, *tstr;
1927   uint cnt = 0;
1928   for (uint ii = 0; ii < _trackCnt; ii++) {
1929     track = _trackTable[ii];
1930     if (track == NULL)
1931       continue;
1932     tstr = NULL;
1933     bool tohi = true;
1934     while ((tstr = track->getNextSubTrack(tstr, tohi)) != nullptr)
1935       cnt += tstr->setExtrusionMarker(_markerCnt, _start, _markerLen);
1936   }
1937   return cnt;
1938 }
placeBox(Ath__box * box)1939 uint Ath__grid::placeBox(Ath__box* box)
1940 {
1941   int ll[2] = {box->_xlo, box->_ylo};
1942   int ur[2] = {box->_xhi, box->_yhi};
1943 
1944   uint markIndex1;
1945   Ath__wire* w = makeWire(ll, ur, box->getOwner(), &markIndex1);
1946 
1947   Ath__track* track = getTrackPtr(ll);
1948 
1949   if (!track->place(w, markIndex1))
1950     fprintf(stdout, "OVERLAP placement\n");
1951   else
1952     w->_track = track;
1953 
1954   return track->_num;
1955 }
getWirePtr(uint wireId)1956 Ath__wire* Ath__grid::getWirePtr(uint wireId)
1957 {
1958   return _wirePoolPtr->get(wireId);
1959 }
getBoxIds(Ath__array1D<uint> * wireIdTable,Ath__array1D<uint> * idtable)1960 void Ath__grid::getBoxIds(Ath__array1D<uint>* wireIdTable,
1961                           Ath__array1D<uint>* idtable)
1962 {
1963   // remove duplicate entries
1964 
1965   for (uint ii = 0; ii < wireIdTable->getCnt(); ii++) {
1966     uint wid = wireIdTable->get(ii);
1967     Ath__wire* w = getWirePtr(wid);
1968 
1969     uint boxId = w->_boxId;
1970     if (w->_srcId > 0) {
1971       w = getWirePtr(w->_srcId);
1972       boxId = w->_boxId;
1973     }
1974     if (w->_ext > 0)
1975       continue;
1976 
1977     w->_ext = 1;
1978     idtable->add(boxId);
1979   }
1980 
1981   for (uint jj = 0; jj < wireIdTable->getCnt(); jj++) {
1982     Ath__wire* w = getWirePtr(wireIdTable->get(jj));
1983     w->_ext = 0;
1984 
1985     if (w->_srcId > 0) {
1986       w = getWirePtr(w->_srcId);
1987       w->_ext = 0;
1988     }
1989   }
1990 }
getWireIds(Ath__array1D<uint> * wireIdTable,Ath__array1D<uint> * idtable)1991 void Ath__grid::getWireIds(Ath__array1D<uint>* wireIdTable,
1992                            Ath__array1D<uint>* idtable)
1993 {
1994   // remove duplicate entries
1995 
1996   for (uint ii = 0; ii < wireIdTable->getCnt(); ii++) {
1997     uint wid = wireIdTable->get(ii);
1998     Ath__wire* w = getWirePtr(wid);
1999 
2000     if (w->_srcId > 0) {
2001       w = getWirePtr(w->_srcId);
2002       wid = w->_id;
2003     }
2004     if (w->_ext > 0)
2005       continue;
2006 
2007     w->_ext = 1;
2008     idtable->add(wid);
2009   }
2010 
2011   for (uint jj = 0; jj < wireIdTable->getCnt(); jj++) {
2012     Ath__wire* w = getWirePtr(wireIdTable->get(jj));
2013     w->_ext = 0;
2014     if (w->_srcId > 0) {
2015       w = getWirePtr(w->_srcId);
2016       w->_ext = 0;
2017     }
2018   }
2019 }
search(Ath__searchBox * bb,Ath__array1D<uint> * idtable,bool wireIdFlag)2020 uint Ath__grid::search(Ath__searchBox* bb,
2021                        Ath__array1D<uint>* idtable,
2022                        bool wireIdFlag)
2023 {
2024   Ath__array1D<uint> wireIdTable(16000);
2025 
2026   // uint d= (_dir>0) ? 0 : 1;
2027   uint d = !_dir;
2028 
2029   uint loTrackNum = getTrackNum1(bb->loXY(_dir));
2030   if (loTrackNum > 0)
2031     loTrackNum--;
2032 
2033   uint hiTrackNum = getTrackNum1(bb->hiXY(_dir));
2034 
2035   int loXY = bb->loXY(d);
2036   int hiXY = bb->hiXY(d);
2037   uint loMarker = getBucketNum(loXY);
2038   uint hiMarker = getBucketNum(hiXY);
2039 
2040   Ath__track* tstrack;
2041   uint cnt = 0;
2042   for (uint ii = loTrackNum; ii <= hiTrackNum; ii++) {
2043     Ath__track* track = _trackTable[ii];
2044     if (track == NULL)
2045       continue;
2046 
2047     tstrack = NULL;
2048     bool tohi = true;
2049     while ((tstrack = track->getNextSubTrack(tstrack, tohi)) != nullptr) {
2050       if (_schema > 0)
2051         cnt += tstrack->search1(loXY, hiXY, loMarker, hiMarker, &wireIdTable);
2052       else
2053         cnt += tstrack->search(loXY, hiXY, loMarker, hiMarker, idtable);
2054     }
2055   }
2056   if (wireIdFlag)
2057     getWireIds(&wireIdTable, idtable);
2058   else
2059     getBoxIds(&wireIdTable, idtable);
2060 
2061   return idtable->getCnt();
2062 }
search(Ath__searchBox * bb,uint * gxy,Ath__array1D<uint> * idtable,Ath__grid * g)2063 uint Ath__grid::search(Ath__searchBox* bb,
2064                        uint* gxy,
2065                        Ath__array1D<uint>* idtable,
2066                        Ath__grid* g)
2067 {
2068   Ath__array1D<uint> wireIdTable(1024);
2069 
2070   AthPool<Ath__wire>* wirePool = _wirePoolPtr;
2071   if (g != NULL)
2072     wirePool = g->getWirePoolPtr();
2073 
2074   uint d = !_dir;
2075 
2076   uint loTrackNum = getTrackNum1(bb->loXY(_dir));
2077   if (loTrackNum > 0)
2078     loTrackNum--;
2079 
2080   uint hiTrackNum = getTrackNum1(bb->hiXY(_dir));
2081 
2082   int loXY = bb->loXY(d);
2083   int hiXY = bb->hiXY(d);
2084   uint loMarker = getBucketNum(loXY);
2085   uint hiMarker = getBucketNum(hiXY);
2086 
2087   uint cnt = 0;
2088   for (uint ii = loTrackNum; ii <= hiTrackNum; ii++) {
2089     Ath__track* track = _trackTable[ii];
2090     if (track == NULL)
2091       continue;
2092 
2093     wireIdTable.resetCnt();
2094     uint cnt1 = track->search1(loXY, hiXY, loMarker, hiMarker, &wireIdTable);
2095     if (cnt1 <= 0)
2096       continue;
2097 
2098     cnt += cnt1;
2099 
2100     Ath__wire* w0 = _wirePoolPtr->get(wireIdTable.get(0));
2101     Ath__wire* w1 = w0->makeWire(wirePool, w0->_xy, w0->_len);
2102 
2103     if (g != NULL)
2104       g->placeWire(w1);
2105     idtable->add(w1->_id);
2106 
2107     for (uint jj = 1; jj < cnt1; jj++) {
2108       Ath__wire* w = _wirePoolPtr->get(wireIdTable.get(jj));
2109 
2110       uint dist = w->_xy - (w1->_xy + w1->_len);
2111       if (dist <= gxy[d]) {
2112         w1->setXY(w1->_xy, w->_xy + w->_len - w1->_xy);
2113       } else  // start new
2114       {
2115         w1 = w0->makeWire(wirePool, w->_xy, w->_len);
2116 
2117         if (g != NULL)
2118           g->placeWire(w1);
2119         idtable->add(w1->_id);
2120       }
2121     }
2122   }
2123 
2124   return idtable->getCnt();
2125 }
getBuses(Ath__array1D<Ath__box * > * boxTable,uint width)2126 void Ath__grid::getBuses(Ath__array1D<Ath__box*>* boxTable, uint width)
2127 {
2128   Ath__array1D<Ath__wire*> wireTable(32);
2129 
2130   for (uint ii = 0; ii < _trackCnt; ii++) {
2131     if (_blockedTrackTable[ii] > 0)
2132       continue;
2133 
2134     Ath__track* track = _trackTable[ii];
2135     if (track == NULL)
2136       continue;
2137 
2138     if (!(_schema > 0))
2139       continue;
2140 
2141     uint height = _base + ii * _pitch;
2142 
2143     wireTable.resetCnt();
2144     track->getAllWires(&wireTable, _markerCnt);
2145 
2146     for (uint jj = 0; jj < wireTable.getCnt(); jj++) {
2147       Ath__wire* e = wireTable.get(jj);
2148       if (!e->isTileBus())
2149         continue;
2150 
2151       Ath__box* bb = new Ath__box();
2152       if (_dir > 0)
2153         bb->set(e->_xy, height, e->_xy + e->_len, height + width);
2154       else
2155         bb->set(height, e->_xy, height + width, e->_xy + e->_len);
2156 
2157       bb->_layer = _level;
2158 
2159       boxTable->add(bb);
2160     }
2161   }
2162 }
getWire_Linear(uint id)2163 Ath__wire* Ath__grid::getWire_Linear(uint id)
2164 {
2165   for (uint ii = 0; ii < _trackCnt; ii++) {
2166     Ath__track* tr = _trackTable[ii];
2167     if (tr == NULL)
2168       continue;
2169 
2170     Ath__wire* w = tr->getWire_Linear(_markerCnt, id);
2171     if (w != NULL)
2172       return w;
2173   }
2174   return NULL;
2175 }
adjustOverlapMakerEnd()2176 void Ath__grid::adjustOverlapMakerEnd()
2177 {
2178   int TTTnewAdj = 1;
2179   Ath__track *track, *tstr;
2180   for (uint ii = 0; ii < _trackCnt; ii++) {
2181     track = _trackTable[ii];
2182     if (track == NULL)
2183       continue;
2184     tstr = NULL;
2185     bool tohi = true;
2186     while ((tstr = track->getNextSubTrack(tstr, tohi)) != nullptr)
2187       if (TTTnewAdj)
2188         tstr->adjustOverlapMakerEnd(_markerCnt, _start, _markerLen);
2189       else
2190         tstr->adjustOverlapMakerEnd(_markerCnt);
2191   }
2192 }
adjustMetalFill()2193 void Ath__grid::adjustMetalFill()
2194 {
2195   Ath__track *track, *tstr;
2196   _searchLowMarker = 0;
2197   _searchHiMarker = _markerCnt - 1;
2198   for (int ii = _trackCnt - 1; ii >= 0; ii--) {
2199     track = _trackTable[ii];
2200     if (track == NULL)
2201       continue;
2202     tstr = NULL;
2203     bool tohi = false;
2204     while ((tstr = track->getNextSubTrack(tstr, tohi)) != nullptr)
2205       tstr->adjustMetalFill();
2206   }
2207 }
isOrdered(bool,uint * cnt)2208 bool Ath__grid::isOrdered(bool /* unused: ascending */, uint* cnt)
2209 {
2210   bool ordered = true;
2211   for (uint ii = 0; ii < _trackCnt; ii++) {
2212     Ath__track* tr = _trackTable[ii];
2213     if (tr == NULL)
2214       continue;
2215 
2216     if (!tr->isAscendingOrdered(_markerCnt, cnt)) {
2217       fprintf(stdout, "Track #%d is not ordered\n", ii);
2218       ordered = false;
2219     }
2220   }
2221   return ordered;
2222 }
getBucketNum(int xy)2223 uint Ath__grid::getBucketNum(int xy)
2224 {
2225   int offset = xy - _start;
2226   if (offset < 0) {
2227     return 0;
2228   }
2229   uint b = offset / _markerLen;
2230   if (b == 0)
2231     return 0;
2232 
2233   if (b >= _markerCnt) {
2234     return _markerCnt - 1;
2235   }
2236   return b;
2237 }
getWidth()2238 uint Ath__grid::getWidth()
2239 {
2240   return _width;
2241 }
2242 
getXYbyWidth(int xy,uint * mark)2243 int Ath__grid::getXYbyWidth(int xy, uint* mark)
2244 {
2245   int offset = xy - _start;
2246   if (offset < 0) {
2247     *mark = 0;
2248     return 0;
2249   }
2250   uint a = offset / _width;
2251   int b = a / _markerLen;
2252   if (b > 3) {
2253     *mark = 3;
2254   } else {
2255     *mark = b;
2256   }
2257   return a;
2258 }
getTrackNum1(int xy)2259 uint Ath__grid::getTrackNum1(int xy)
2260 {
2261   int a = xy - _base;
2262 
2263   // if (a<0)
2264   if (xy < _base)
2265     return 0;
2266 
2267   uint b = a / _pitch;
2268   if (b >= _trackCnt)
2269     return _trackCnt - 1;
2270   else
2271     return b;
2272 }
getTrackNum(int * ll,uint d,uint * marker)2273 uint Ath__grid::getTrackNum(int* ll, uint d, uint* marker)
2274 {
2275   *marker = getBucketNum(ll[d]);
2276 
2277   int a = ll[_dir] - _base;
2278 
2279   if (a < 0)
2280     return 0;
2281 
2282   uint b = a / _pitch;
2283   if (b >= _trackCnt)
2284     return _trackCnt - 1;
2285   else
2286     return b;
2287 }
getTrackNum(Ath__box * box)2288 uint Ath__grid::getTrackNum(Ath__box* box)
2289 {
2290   int ll[2] = {box->_xlo, box->_ylo};
2291 
2292   int a = ll[_dir] - _base;
2293 
2294   if (a < 0)
2295     return 0;
2296   else
2297     return a / _pitch;
2298 }
makeWire(uint dir,int * ll,int * ur,uint id1,uint id2,uint type)2299 Ath__wire* Ath__grid::makeWire(uint dir,
2300                                int* ll,
2301                                int* ur,
2302                                uint id1,
2303                                uint id2,
2304                                uint type)
2305 {
2306   Ath__wire* w = getPoolWire();
2307   w->_srcId = 0;
2308   w->_srcWire = NULL;
2309 
2310   w->reset();
2311   w->set(dir, ll, ur);
2312   w->_boxId = id1;
2313   w->_otherId = id2;
2314 
2315   w->_flags = type;
2316 
2317   return w;
2318 }
makeWire(int * ll,int * ur,uint id,uint * m1)2319 Ath__wire* Ath__grid::makeWire(int* ll, int* ur, uint id, uint* m1)
2320 {
2321   uint d = (_dir > 0) ? 0 : 1;
2322 
2323   int xy1 = ll[d];
2324   // int xy2= ur[d];
2325   *m1 = getBucketNum(xy1);
2326 
2327   Ath__wire* w = getPoolWire();
2328   w->_srcId = 0;
2329   w->_otherId = 0;
2330 
2331   w->reset();
2332   w->set(_dir, ll, ur);
2333   w->_boxId = id;
2334 
2335   return w;
2336 }
makeWire(Ath__box * box,uint * id,uint * m1,uint * m2,uint)2337 Ath__wire* Ath__grid::makeWire(Ath__box* box,
2338                                uint* id,
2339                                uint* m1,
2340                                uint* m2,
2341                                uint /* unused: fullTrack */)
2342 {
2343   int ll[2] = {box->_xlo, box->_ylo};
2344   int ur[2] = {box->_xhi, box->_yhi};
2345 
2346   *m1 = 0;
2347   *m2 = 3;
2348   Ath__wire* w = getPoolWire();
2349   w->_otherId = 0;
2350 
2351   *id = w->_id;
2352   w->reset();
2353   w->set(_dir, ll, ur);
2354   w->_boxId = box->_id;
2355   w->_srcId = 0;
2356   return w;
2357 }
2358 
getFirstTrack(uint divider)2359 uint Ath__grid::getFirstTrack(uint divider)
2360 {
2361   int xy = _base + (_max - _base) / divider;
2362 
2363   return getAbsTrackNum(xy);
2364 }
getClosestTrackCoord(int xy)2365 int Ath__grid::getClosestTrackCoord(int xy)
2366 {
2367   int track1 = getAbsTrackNum(xy);
2368   int ii;
2369   for (ii = track1 - 1; ii < (int) _trackCnt; ii++) {
2370     if (_trackTable[ii] != NULL)
2371       break;
2372   }
2373   int h1 = _max;
2374   if (ii < (int) _trackCnt)
2375     h1 = getTrackHeight(ii);
2376 
2377   for (ii = track1 + 1; ii >= 0; ii--) {
2378     if (_trackTable[ii] != NULL)
2379       break;
2380   }
2381   int h2 = _base;
2382   if (ii > 0)
2383     h2 = getTrackHeight(ii);
2384 
2385   if (xy - h2 < h1 - xy)
2386     return h2 + _width / 2;
2387   else
2388     return h1 + _width / 2;
2389 }
findEmptyTrack(int ll[2],int ur[2])2390 int Ath__grid::findEmptyTrack(int ll[2], int ur[2])
2391 {
2392   uint track1 = getAbsTrackNum(ll[_dir]);
2393   uint track2 = getAbsTrackNum(ur[_dir]);
2394   uint cnt = 0;
2395   for (uint ii = track1; ii <= track2; ii++) {
2396     if (_trackTable[ii] == NULL) {
2397       cnt++;
2398       continue;
2399     }
2400     Ath__wire w;
2401     w.reset();
2402 
2403     int xy1 = (ll[_dir % 1] - _start) / _width;
2404     int xy2 = (ur[_dir % 1] - _start) / _width;
2405 
2406     w.set(_dir, ll, ur);
2407 
2408     int markIndex1 = xy1 / _markerLen;
2409     int markIndex2 = xy2 / _markerLen;
2410 
2411     if (_trackTable[ii]->overlapCheck(&w, markIndex1, markIndex2))
2412       continue;
2413     cnt++;
2414   }
2415   if (cnt == track2 - track1 + 1)
2416     return track1;
2417 
2418   return -1;
2419 }
2420 
Ath__intersect(int X1,int DX,int x1,int dx,int * ix1,int * ix2)2421 bool Ath__intersect(int X1, int DX, int x1, int dx, int* ix1, int* ix2)
2422 {
2423   *ix1 = X1;
2424   *ix2 = X1 + DX;
2425 
2426   int dx1 = X1 - x1;
2427   if (dx1 >= 0) {  // on left side
2428     int dlen = dx - dx1;
2429     if (dlen <= 0)
2430       return false;
2431 
2432     if (dlen < DX)
2433       *ix2 = x1 + dx;
2434   } else {
2435     *ix1 = x1;
2436     if (dx1 + DX <= 0)  // outside right side
2437       return false;
2438 
2439     if (*ix2 > x1 + dx)
2440       *ix2 = x1 + dx;
2441   }
2442   return true;
2443 }
Ath__gridTile(uint levelCnt,int x1,int y1,int x2,int y2,AthPool<Ath__track> * trackPoolPtr,AthPool<Ath__wire> * wirePoolPtr)2444 Ath__gridTile::Ath__gridTile(uint levelCnt,
2445                              int x1,
2446                              int y1,
2447                              int x2,
2448                              int y2,
2449                              AthPool<Ath__track>* trackPoolPtr,
2450                              AthPool<Ath__wire>* wirePoolPtr)
2451 {
2452   assert(levelCnt > 0);
2453   _levelCnt = levelCnt;
2454 
2455   _bb.reset(x1, y1, x2, y2);
2456 
2457   _gTable = new Ath__grid*[levelCnt];
2458   for (uint ii = 0; ii < levelCnt; ii++)
2459     _gTable[ii] = NULL;
2460 
2461   _poolFlag = true;
2462   if (trackPoolPtr != NULL) {
2463     _trackPool = trackPoolPtr;
2464     _wirePool = wirePoolPtr;
2465     _poolFlag = false;
2466   } else {
2467     _trackPool = new AthPool<Ath__track>(false, 512);
2468     _wirePool = new AthPool<Ath__wire>(false, 512);
2469   }
2470 }
~Ath__gridTile()2471 Ath__gridTile::~Ath__gridTile()
2472 {
2473   for (uint ii = 1; ii < _levelCnt; ii++) {
2474     if (_gTable[ii] != NULL)
2475       delete _gTable[ii];
2476   }
2477   delete[] _gTable;
2478 
2479   if (_poolFlag) {
2480     delete _trackPool;
2481     delete _wirePool;
2482   }
2483 }
getGrid(uint level)2484 Ath__grid* Ath__gridTile::getGrid(uint level)
2485 {
2486   return _gTable[level];
2487 }
addGrid(Ath__grid * g)2488 void Ath__gridTile::addGrid(Ath__grid* g)
2489 {
2490   Ath__searchBox sbb;
2491   g->getBbox(&sbb);
2492 
2493   uint level = sbb.getLevel();
2494   assert(level < _levelCnt);
2495   _gTable[level] = g;
2496 }
addGrid(Ath__box * bb,uint level,uint dir,uint layerNum,uint width,uint pitch)2497 Ath__grid* Ath__gridTile::addGrid(Ath__box* bb,
2498                                   uint level,
2499                                   uint dir,
2500                                   uint layerNum,
2501                                   uint width,
2502                                   uint pitch)
2503 {
2504   assert(level < _levelCnt);
2505   _gTable[level] = new Ath__grid(
2506       NULL, _trackPool, _wirePool, bb, level, dir, layerNum, width, pitch);
2507 
2508   return _gTable[level];
2509 }
2510 
getBuses(Ath__array1D<Ath__box * > * boxTable,dbTech * tech)2511 void Ath__gridTile::getBuses(Ath__array1D<Ath__box*>* boxTable, dbTech* tech)
2512 {
2513   for (uint level = 1; level < _levelCnt; level++) {
2514     uint width = tech->findRoutingLayer(level)->getWidth();
2515 
2516     _gTable[level]->getBuses(boxTable, width);
2517   }
2518 }
2519 
getBounds(int * x1,int * y1,int * x2,int * y2)2520 void Ath__gridTile::getBounds(int* x1, int* y1, int* x2, int* y2)
2521 {
2522   *x1 = _bb.xMin();
2523   *y1 = _bb.yMin();
2524   *x2 = _bb.xMax();
2525   *y2 = _bb.yMax();
2526 }
2527 
init1(uint memChunk,uint rowSize,uint colSize,uint dx,uint dy)2528 void Ath__gridTable::init1(uint memChunk,
2529                            uint rowSize,
2530                            uint colSize,
2531                            uint dx,
2532                            uint dy)
2533 {
2534   _trackPool = new AthPool<Ath__track>(false, memChunk);
2535   _wirePool = new AthPool<Ath__wire>(false, memChunk * 1000);
2536 
2537   _wirePool->alloc();  // so all wire ids>0
2538 
2539   _rowSize = rowSize;
2540   _colSize = colSize;
2541   _rowCnt = dy / rowSize + 1;
2542   _colCnt = dx / colSize + 1;
2543 
2544   _wireCnt = 0;
2545   resetMaxArea();
2546 }
2547 
Ath__gridTable(Ath__box * bb,uint rowSize,uint colSize,uint layer,uint dir,uint width,uint pitch)2548 Ath__gridTable::Ath__gridTable(Ath__box* bb,
2549                                uint rowSize,
2550                                uint colSize,
2551                                uint layer,
2552                                uint dir,
2553                                uint width,
2554                                uint pitch)
2555 {
2556   init1(1024, rowSize, colSize, bb->getDX(), bb->getDY());
2557   _bbox.set(bb);
2558   _schema = 0;
2559   _overlapTouchCheck = 1;
2560   _noPowerSource = 0;
2561   _noPowerTarget = 0;
2562   _CCshorts = 0;
2563   _CCtargetHighTracks = 1;
2564   _targetTrackReversed = false;
2565   _ccContextDepth = 0;
2566   _ccContextArray = NULL;
2567   _allNet = true;
2568   _useDbSdb = true;
2569   _overlapAdjust = Z_noAdjust;
2570   _powerMultiTrackWire = 0;
2571   _signalMultiTrackWire = 0;
2572   _bandWire = NULL;
2573 
2574   _gridTable = new Ath__grid**[_rowCnt];
2575   int y1 = bb->_ylo;
2576   for (uint ii = 0; ii < _rowCnt; ii++) {
2577     _gridTable[ii] = new Ath__grid*[_colCnt];
2578 
2579     int y2 = y1 + rowSize;
2580     int x1 = bb->_xlo;
2581     for (uint jj = 0; jj < _colCnt; jj++) {
2582       int x2 = x1 + colSize;
2583       uint num = ii * 1000 + jj;
2584 
2585       Ath__box box;
2586       box.set(x1, y1, x2, y2);
2587       _gridTable[ii][jj] = new Ath__grid(
2588           this, _trackPool, _wirePool, &box, layer, dir, num, width, pitch, 32);
2589 
2590       x1 = x2;
2591     }
2592     y1 = y2;
2593   }
2594 }
Ath__gridTable(dbBox * bb,uint rowSize,uint colSize,uint layer,uint dir,uint width,uint pitch,uint minWidth)2595 Ath__gridTable::Ath__gridTable(dbBox* bb,
2596                                uint rowSize,
2597                                uint colSize,
2598                                uint layer,
2599                                uint dir,
2600                                uint width,
2601                                uint pitch,
2602                                uint minWidth)
2603 {
2604   init1(1024, rowSize, colSize, bb->getDX(), bb->getDY());
2605   bb->getBox(_rectBB);
2606   _schema = 1;
2607   _overlapTouchCheck = 1;
2608   _noPowerSource = 0;
2609   _noPowerTarget = 0;
2610   _CCshorts = 0;
2611   _CCtargetHighTracks = 1;
2612   _targetTrackReversed = false;
2613   _ccContextDepth = 0;
2614   _ccContextArray = NULL;
2615   _allNet = true;
2616   _useDbSdb = true;
2617   _overlapAdjust = Z_noAdjust;
2618   _powerMultiTrackWire = 0;
2619   _signalMultiTrackWire = 0;
2620   _bandWire = NULL;
2621 
2622   uint maxCellNumPerMarker = 16;
2623   uint markerCnt = (bb->getDX() / minWidth) / maxCellNumPerMarker;
2624 
2625   _gridTable = new Ath__grid**[_rowCnt];
2626   int y1 = bb->yMin();
2627   for (uint ii = 0; ii < _rowCnt; ii++) {
2628     _gridTable[ii] = new Ath__grid*[_colCnt];
2629 
2630     int y2 = y1 + rowSize;
2631     int x1 = bb->xMin();
2632     for (uint jj = 0; jj < _colCnt; jj++) {
2633       int x2 = x1 + colSize;
2634       uint num = ii * 1000 + jj;
2635       // Rect rectBB(x1, y1, x2, y2);
2636       _gridTable[ii][jj]
2637           = new Ath__grid(this, _trackPool, _wirePool, layer, num, markerCnt);
2638 
2639       _gridTable[ii][jj]->setTracks(dir, width, pitch, x1, y1, x2, y2);
2640       _gridTable[ii][jj]->setSchema(_schema);
2641       x1 = x2;
2642     }
2643     y1 = y2;
2644   }
2645 }
releaseWire(uint wireId)2646 void Ath__gridTable::releaseWire(uint wireId)
2647 {
2648   Ath__wire* w = _wirePool->get(wireId);
2649   _wirePool->free(w);
2650 }
getWirePtr(uint id)2651 Ath__wire* Ath__gridTable::getWirePtr(uint id)
2652 {
2653   return _wirePool->get(id);
2654 }
getRowCnt()2655 uint Ath__gridTable::getRowCnt()
2656 {
2657   return _rowCnt;
2658 }
getColCnt()2659 uint Ath__gridTable::getColCnt()
2660 {
2661   return _colCnt;
2662 }
dumpTrackCounts(FILE * fp)2663 void Ath__gridTable::dumpTrackCounts(FILE* fp)
2664 {
2665   fprintf(fp, "Multiple_track_power_wires : %d\n", _powerMultiTrackWire);
2666   fprintf(fp, "Multiple_track_signal_wires : %d\n", _signalMultiTrackWire);
2667   fprintf(fp,
2668           "layer  dir   alloc    live offbase  expand  tsubtn   toptk  stn\n");
2669   Ath__grid* tgrid;
2670   uint topBigTrack = 0;
2671   uint topSubtNum;
2672   uint totalSubtNum;
2673   uint expTrackNum;
2674   int trn;
2675   uint offbase;
2676   uint liveCnt;
2677   uint talloc = 0;
2678   uint tlive = 0;
2679   uint toffbase = 0;
2680   uint texpand = 0;
2681   uint ttsubtn = 0;
2682   for (uint layer = 1; layer < _colCnt; layer++) {
2683     for (uint dir = 0; dir < _rowCnt; dir++) {
2684       topBigTrack = 0;
2685       topSubtNum = 0;
2686       totalSubtNum = 0;
2687       expTrackNum = 0;
2688       offbase = 0;
2689       liveCnt = 0;
2690       tgrid = _gridTable[dir][layer];
2691       for (trn = 0; trn < (int) tgrid->_trackCnt; trn++) {
2692         if (tgrid->_trackTable[trn] == NULL)
2693           continue;
2694         liveCnt++;
2695         if (tgrid->_base + tgrid->_pitch * trn
2696             != tgrid->_trackTable[trn]->_base)
2697           offbase++;
2698         if (tgrid->_subTrackCnt[trn] == 0)
2699           continue;
2700         expTrackNum++;
2701         totalSubtNum += tgrid->_subTrackCnt[trn];
2702         if (tgrid->_subTrackCnt[trn] > topSubtNum) {
2703           topSubtNum = tgrid->_subTrackCnt[trn];
2704           topBigTrack = trn;
2705         }
2706       }
2707       fprintf(fp,
2708               "%5d%5d%8d%8d%8d%8d%8d%8d%5d\n",
2709               layer,
2710               dir,
2711               tgrid->_trackCnt,
2712               liveCnt,
2713               offbase,
2714               expTrackNum,
2715               totalSubtNum,
2716               topBigTrack,
2717               topSubtNum);
2718       talloc += tgrid->_trackCnt;
2719       tlive += liveCnt;
2720       toffbase += offbase;
2721       texpand += expTrackNum;
2722       ttsubtn += totalSubtNum;
2723     }
2724   }
2725   fprintf(fp,
2726           "---------------------------------------------------------------\n");
2727   fprintf(fp,
2728           "          %8d%8d%8d%8d%8d\n",
2729           talloc,
2730           tlive,
2731           toffbase,
2732           texpand,
2733           ttsubtn);
2734 }
Ath__gridTable(Rect * bb,uint rowCnt,uint colCnt,uint *,uint * pitch,uint *,int * X1,int * Y1)2735 Ath__gridTable::Ath__gridTable(Rect* bb,
2736                                uint rowCnt,
2737                                uint colCnt,
2738                                uint* /* unused: width */,
2739                                uint* pitch,
2740                                uint* /* unused: spacing */,
2741                                int* X1,
2742                                int* Y1)
2743 {
2744   // for net wires
2745   init1(1024, bb->dy(), bb->dx(), bb->dx(), bb->dy());
2746   _rectBB.reset(bb->xMin(), bb->yMin(), bb->xMax(), bb->yMax());
2747   _rowCnt = rowCnt;
2748   _colCnt = colCnt;
2749   _schema = 1;
2750   _overlapTouchCheck = 1;
2751   _noPowerSource = 0;
2752   _noPowerTarget = 0;
2753   _CCshorts = 0;
2754   _CCtargetHighTracks = 1;
2755   _targetTrackReversed = false;
2756   _ccContextDepth = 0;
2757   _ccContextArray = NULL;
2758   _allNet = true;
2759   _useDbSdb = true;
2760   _overlapAdjust = Z_noAdjust;
2761   _powerMultiTrackWire = 0;
2762   _signalMultiTrackWire = 0;
2763   _bandWire = NULL;
2764 
2765   uint markerLen = 500000;  // EXT-DEFAULT
2766 
2767   // int x1= bb->xMin();
2768   // int y1= bb->yMin();
2769   int x1, y1;
2770   int x2 = bb->xMax();
2771   int y2 = bb->yMax();
2772 
2773   _gridTable = new Ath__grid**[_rowCnt];
2774   for (uint ii = 0; ii < _rowCnt; ii++) {
2775     _gridTable[ii] = new Ath__grid*[_colCnt];
2776     _gridTable[ii][0] = NULL;
2777 
2778     for (uint jj = 1; jj < _colCnt; jj++) {
2779       uint num = ii * 1000 + jj;
2780 
2781       _gridTable[ii][jj]
2782           = new Ath__grid(this, _trackPool, _wirePool, jj, num, 10);
2783       x1 = X1 ? X1[jj] : bb->xMin();
2784       y1 = Y1 ? Y1[jj] : bb->yMin();
2785       _gridTable[ii][jj]->setTracks(
2786           ii, 1, pitch[jj], x1, y1, x2, y2, markerLen);
2787       _gridTable[ii][jj]->setSchema(_schema);
2788     }
2789   }
2790 }
2791 
Ath__gridTable(Rect * bb,uint layer,uint dir,uint width,uint pitch,uint minWidth)2792 Ath__gridTable::Ath__gridTable(Rect* bb,
2793                                uint layer,
2794                                uint dir,
2795                                uint width,
2796                                uint pitch,
2797                                uint minWidth)
2798 {
2799   init1(1024, bb->dy(), bb->dx(), bb->dx(), bb->dy());
2800   _colCnt = 1;
2801   _rowCnt = 1;
2802   _rectBB.reset(bb->xMin(), bb->yMin(), bb->xMax(), bb->yMax());
2803   _schema = 1;
2804   _overlapTouchCheck = 1;
2805   _noPowerSource = 0;
2806   _noPowerTarget = 0;
2807   _CCshorts = 0;
2808   _CCtargetHighTracks = 1;
2809   _targetTrackReversed = false;
2810   _ccContextDepth = 0;
2811   _ccContextArray = NULL;
2812   _allNet = true;
2813   _useDbSdb = true;
2814   _overlapAdjust = Z_noAdjust;
2815   _powerMultiTrackWire = 0;
2816   _signalMultiTrackWire = 0;
2817   _bandWire = NULL;
2818 
2819   uint maxCellNumPerMarker = 16;
2820   uint markerCnt = (bb->dx() / minWidth) / maxCellNumPerMarker;
2821   if (markerCnt == 0)
2822     markerCnt = 1;
2823 
2824   Ath__grid* g
2825       = new Ath__grid(this, _trackPool, _wirePool, layer, 1, markerCnt);
2826 
2827   g->setTracks(
2828       dir, width, pitch, bb->xMin(), bb->yMin(), bb->xMax(), bb->yMax());
2829   g->setSchema(_schema);
2830 
2831   _gridTable = new Ath__grid**[1];
2832   _gridTable[0] = new Ath__grid*[1];
2833 
2834   _gridTable[0][0] = g;
2835 }
~Ath__gridTable()2836 Ath__gridTable::~Ath__gridTable()
2837 {
2838   delete _trackPool;
2839   delete _wirePool;
2840 
2841   for (uint ii = 0; ii < _rowCnt; ii++) {
2842     for (uint jj = 0; jj < _rowCnt; jj++) {
2843       delete _gridTable[ii][jj];
2844     }
2845     delete[] _gridTable[ii];
2846   }
2847   delete[] _gridTable;
2848 }
xMin()2849 int Ath__gridTable::xMin()
2850 {
2851   if (_schema > 0)
2852     return _rectBB.xMin();
2853   else
2854     return _bbox._xlo;
2855 }
xMax()2856 int Ath__gridTable::xMax()
2857 {
2858   if (_schema > 0)
2859     return _rectBB.xMax();
2860   else
2861     return _bbox._xhi;
2862 }
yMin()2863 int Ath__gridTable::yMin()
2864 {
2865   if (_schema > 0)
2866     return _rectBB.yMin();
2867   else
2868     return _bbox._ylo;
2869 }
yMax()2870 int Ath__gridTable::yMax()
2871 {
2872   if (_schema > 0)
2873     return _rectBB.yMax();
2874   else
2875     return _bbox._yhi;
2876 }
getRowNum(int y)2877 uint Ath__gridTable::getRowNum(int y)
2878 {
2879   int dy = y - yMin();
2880   if (dy < 0)
2881     return 0;
2882   return dy / _rowSize;
2883 }
getColNum(int x)2884 uint Ath__gridTable::getColNum(int x)
2885 {
2886   int dx = x - xMin();
2887   if (dx < 0)
2888     return 0;
2889 
2890   return dx / _colSize;
2891 }
search(Ath__searchBox * bb,uint row,uint col,Ath__array1D<uint> * idTable,bool wireIdFlag)2892 uint Ath__gridTable::search(Ath__searchBox* bb,
2893                             uint row,
2894                             uint col,
2895                             Ath__array1D<uint>* idTable,
2896                             bool wireIdFlag)
2897 {
2898   return _gridTable[row][col]->search(bb, idTable, wireIdFlag);
2899 }
search(Ath__searchBox * bb,uint * gxy,uint row,uint col,Ath__array1D<uint> * idtable,Ath__grid * g)2900 uint Ath__gridTable::search(Ath__searchBox* bb,
2901                             uint* gxy,
2902                             uint row,
2903                             uint col,
2904                             Ath__array1D<uint>* idtable,
2905                             Ath__grid* g)
2906 {
2907   return _gridTable[row][col]->search(bb, gxy, idtable, g);
2908 }
search(Ath__searchBox * bb,Ath__array1D<uint> * idTable)2909 uint Ath__gridTable::search(Ath__searchBox* bb, Ath__array1D<uint>* idTable)
2910 {
2911   uint row1 = getRowNum(bb->loXY(1));
2912   if (row1 > 0)
2913     row1--;
2914 
2915   uint row2 = getRowNum(bb->hiXY(1));
2916 
2917   uint col1 = getColNum(bb->loXY(0));
2918   if (col1 > 0)
2919     col1--;
2920 
2921   uint col2 = getColNum(bb->hiXY(0));
2922 
2923   for (uint ii = row1; ii < _rowCnt && ii <= row2; ii++) {
2924     for (uint jj = col1; jj < _colCnt && jj <= col2; jj++) {
2925       _gridTable[ii][jj]->search(bb, idTable);
2926     }
2927   }
2928   return 0;
2929 }
getRowCol(int x1,int y1,uint * row,uint * col)2930 bool Ath__gridTable::getRowCol(int x1, int y1, uint* row, uint* col)
2931 {
2932   *row = getRowNum(y1);
2933   if (*row >= _rowCnt) {
2934     fprintf(stderr, "Y=%d Out of Row Range %d\n", y1, _rowCnt);
2935     return false;
2936   }
2937   *col = getColNum(x1);
2938   if (*col >= _colCnt) {
2939     fprintf(stderr, "X=%d Out of Col Range %d\n", x1, _colCnt);
2940     return false;
2941   }
2942   return true;
2943 }
setExtrusionMarker(uint startRow,uint startCol)2944 uint Ath__gridTable::setExtrusionMarker(uint startRow, uint startCol)
2945 {
2946   uint cnt = 0;
2947   for (uint ii = startRow; ii < _rowCnt; ii++) {
2948     for (uint jj = startCol; jj < _colCnt; jj++) {
2949       cnt += _gridTable[ii][jj]->setExtrusionMarker();
2950     }
2951   }
2952   return cnt;
2953 }
getWirePoolPtr()2954 AthPool<Ath__wire>* Ath__grid::getWirePoolPtr()
2955 {
2956   return _wirePoolPtr;
2957 }
2958 
removeMarkedNetWires()2959 uint Ath__grid::removeMarkedNetWires()
2960 {
2961   uint cnt = 0;
2962   for (uint ii = 0; ii < _trackCnt; ii++) {
2963     Ath__track* btrack = _trackTable[ii];
2964     if (btrack == NULL)
2965       continue;
2966 
2967     Ath__track* track = NULL;
2968     bool tohi = true;
2969     while ((track = btrack->getNextSubTrack(track, tohi)) != nullptr)
2970       cnt += track->removeMarkedNetWires();
2971   }
2972   return cnt;
2973 }
2974 
getGrid(uint row,uint col)2975 Ath__grid* Ath__gridTable::getGrid(uint row, uint col)
2976 {
2977   return _gridTable[row][col];
2978 }
addBox(uint row,uint col,dbBox * bb)2979 bool Ath__gridTable::addBox(uint row, uint col, dbBox* bb)
2980 {
2981   Ath__grid* g = _gridTable[row][col];
2982 
2983   g->placeBox(bb, 0, 0);
2984 
2985   return true;
2986 }
addBox(dbBox * bb,uint wtype,uint id)2987 Ath__wire* Ath__gridTable::addBox(dbBox* bb, uint wtype, uint id)
2988 {
2989   uint row = 0;
2990   uint col = 0;
2991   Ath__grid* g = _gridTable[row][col];
2992 
2993   g->placeBox(bb, wtype, id);
2994 
2995   return NULL;
2996 }
addBox(Ath__box * bb)2997 Ath__wire* Ath__gridTable::addBox(Ath__box* bb)
2998 {
2999   uint row;
3000   uint col;
3001   if (!getRowCol(bb->_xlo, bb->_ylo, &row, &col))
3002     return NULL;
3003 
3004   Ath__grid* g = _gridTable[row][col];
3005   g->placeBox(bb);
3006 
3007   return NULL;
3008 }
getWire_Linear(uint instId)3009 Ath__wire* Ath__gridTable::getWire_Linear(uint instId)
3010 {
3011   // bool ordered= true;
3012 
3013   // uint cnt= 0;
3014   for (uint ii = 0; ii < _rowCnt; ii++) {
3015     for (uint jj = 0; jj < _colCnt; jj++) {
3016       Ath__wire* w = _gridTable[ii][jj]->getWire_Linear(instId);
3017       if (w != NULL)
3018         return w;
3019     }
3020   }
3021   return NULL;
3022 }
adjustOverlapMakerEnd()3023 void Ath__gridTable::adjustOverlapMakerEnd()
3024 {
3025   if (_overlapAdjust != Z_endAdjust)
3026     return;
3027   for (uint ii = 0; ii < _rowCnt; ii++) {
3028     for (uint jj = 0; jj < _colCnt; jj++) {
3029       if (_gridTable[ii][jj])
3030         _gridTable[ii][jj]->adjustOverlapMakerEnd();
3031     }
3032   }
3033 }
adjustMetalFill()3034 void Ath__gridTable::adjustMetalFill()
3035 {
3036   _signalPowerNotAlignedOverlap = 0;
3037   _powerNotAlignedOverlap = 0;
3038   _signalNotAlignedOverlap = 0;
3039   _signalOverlap = 0;
3040   _powerOverlap = 0;
3041   _signalPowerOverlap = 0;
3042   _powerSignalOverlap = 0;
3043   for (uint ii = 0; ii < _rowCnt; ii++) {
3044     for (uint jj = 0; jj < _colCnt; jj++) {
3045       if (_gridTable[ii][jj])
3046         _gridTable[ii][jj]->adjustMetalFill();
3047     }
3048   }
3049   if (_signalPowerNotAlignedOverlap)
3050     notice(0,
3051            "%d not aligned power-signal overlaps\n",
3052            _signalPowerNotAlignedOverlap);
3053   if (_powerNotAlignedOverlap)
3054     notice(0, "%d not aligned power overlaps\n", _powerNotAlignedOverlap);
3055   if (_signalNotAlignedOverlap)
3056     notice(0, "%d not aligned signal overlaps\n", _signalNotAlignedOverlap);
3057   if (_powerSignalOverlap)
3058     notice(0, "%d power-signal overlaps\n", _powerSignalOverlap);
3059   if (_signalPowerOverlap)
3060     notice(0, "%d signal-power overlaps\n", _signalPowerOverlap);
3061   if (_powerOverlap)
3062     notice(0, "%d power overlaps\n", _powerOverlap);
3063   if (_signalOverlap)
3064     notice(0, "%d signal overlaps\n", _signalOverlap);
3065   setExtrusionMarker(0, 1);
3066 }
incrNotAlignedOverlap(Ath__wire * w1,Ath__wire * w2)3067 void Ath__gridTable::incrNotAlignedOverlap(Ath__wire* w1, Ath__wire* w2)
3068 {
3069   if (w1->isPower() != w2->isPower())
3070     _signalPowerNotAlignedOverlap++;
3071   else if (w1->isPower())
3072     _powerNotAlignedOverlap++;
3073   else
3074     _signalNotAlignedOverlap++;
3075 }
incrSignalOverlap()3076 void Ath__gridTable::incrSignalOverlap()
3077 {
3078   _signalOverlap++;
3079 }
incrPowerOverlap()3080 void Ath__gridTable::incrPowerOverlap()
3081 {
3082   _powerOverlap++;
3083 }
incrSignalToPowerOverlap()3084 void Ath__gridTable::incrSignalToPowerOverlap()
3085 {
3086   _signalPowerOverlap++;
3087 }
incrPowerToSignallOverlap()3088 void Ath__gridTable::incrPowerToSignallOverlap()
3089 {
3090   _powerSignalOverlap++;
3091 }
incrMultiTrackWireCnt(bool isPower)3092 void Ath__gridTable::incrMultiTrackWireCnt(bool isPower)
3093 {
3094   if (isPower)
3095     _powerMultiTrackWire++;
3096   else
3097     _signalMultiTrackWire++;
3098 }
isOrdered(bool)3099 bool Ath__gridTable::isOrdered(bool /* unused: ascending */)
3100 {
3101   bool ordered = true;
3102 
3103   uint cnt = 0;
3104   for (uint ii = 0; ii < _rowCnt; ii++) {
3105     for (uint jj = 0; jj < _colCnt; jj++) {
3106       uint cnt1 = 0;
3107       if (!_gridTable[ii][jj]->isOrdered(true, &cnt1)) {
3108         ordered = false;
3109         fprintf(stdout,
3110                 "NOT ordered grid [%d][%d] -- has %d wires\n",
3111                 ii,
3112                 jj,
3113                 cnt1);
3114       } else {
3115         fprintf(
3116             stdout, "Ordered grid [%d][%d] -- has %d wires\n", ii, jj, cnt1);
3117       }
3118       cnt += cnt1;
3119     }
3120   }
3121   return ordered;
3122 }
3123 
removeMarkedNetWires()3124 void Ath__gridTable::removeMarkedNetWires()
3125 {
3126   uint cnt = 0;
3127   for (uint jj = 1; jj < _colCnt; jj++) {
3128     for (int ii = _rowCnt - 1; ii >= 0; ii--) {
3129       Ath__grid* netGrid = _gridTable[ii][jj];
3130       cnt += netGrid->removeMarkedNetWires();
3131     }
3132   }
3133   fprintf(stdout, "remove %d sdb wires.\n", cnt);
3134 }
3135 
setExtControl(dbBlock * block,bool useDbSdb,uint adj,uint npsrc,uint nptgt,uint ccUp,bool allNet,uint contextDepth,Ath__array1D<int> ** contextArray,uint * contextLength,Ath__array1D<SEQ * > *** dgContextArray,uint * dgContextDepth,uint * dgContextPlanes,uint * dgContextTracks,uint * dgContextBaseLvl,int * dgContextLowLvl,int * dgContextHiLvl,uint * dgContextBaseTrack,int * dgContextLowTrack,int * dgContextHiTrack,int ** dgContextTrackBase,AthPool<SEQ> * seqPool)3136 void Ath__gridTable::setExtControl(dbBlock* block,
3137                                    bool useDbSdb,
3138                                    uint adj,
3139                                    uint npsrc,
3140                                    uint nptgt,
3141                                    uint ccUp,
3142                                    bool allNet,
3143                                    uint contextDepth,
3144                                    Ath__array1D<int>** contextArray,
3145                                    uint* contextLength,
3146                                    Ath__array1D<SEQ*>*** dgContextArray,
3147                                    uint* dgContextDepth,
3148                                    uint* dgContextPlanes,
3149                                    uint* dgContextTracks,
3150                                    uint* dgContextBaseLvl,
3151                                    int* dgContextLowLvl,
3152                                    int* dgContextHiLvl,
3153                                    uint* dgContextBaseTrack,
3154                                    int* dgContextLowTrack,
3155                                    int* dgContextHiTrack,
3156                                    int** dgContextTrackBase,
3157                                    AthPool<SEQ>* seqPool)
3158 {
3159   _block = block;
3160   _useDbSdb = useDbSdb;
3161   _overlapAdjust = adj;
3162   _noPowerSource = npsrc;
3163   _noPowerTarget = nptgt;
3164   _CCtargetHighTracks = ccUp;
3165   if (ccUp == 2)
3166     _CCtargetHighMarkedNet = 1;
3167   else
3168     _CCtargetHighMarkedNet = 0;
3169   _targetTrackReversed = false;
3170   _ccContextDepth = contextDepth;
3171   _ccContextArray = contextArray;
3172   _ccContextLength = contextLength;
3173   _allNet = allNet;
3174   _dgContextArray = dgContextArray;
3175   _dgContextDepth = dgContextDepth;
3176   _dgContextPlanes = dgContextPlanes;
3177   _dgContextTracks = dgContextTracks;
3178   _dgContextBaseLvl = dgContextBaseLvl;
3179   _dgContextLowLvl = dgContextLowLvl;
3180   _dgContextHiLvl = dgContextHiLvl;
3181   _dgContextBaseTrack = dgContextBaseTrack;
3182   _dgContextLowTrack = dgContextLowTrack;
3183   _dgContextHiTrack = dgContextHiTrack;
3184   _dgContextTrackBase = dgContextTrackBase;
3185   _seqPool = seqPool;
3186 }
reverseTargetTrack()3187 void Ath__gridTable::reverseTargetTrack()
3188 {
3189   _CCtargetHighTracks = _CCtargetHighTracks == 2 ? 0 : 2;
3190   _targetTrackReversed = _targetTrackReversed ? false : true;
3191 }
3192 
setMaxArea(int x1,int y1,int x2,int y2)3193 void Ath__gridTable::setMaxArea(int x1, int y1, int x2, int y2)
3194 {
3195   _maxSearchBox.set(x1, y1, x2, y2, 1);
3196   _setMaxArea = true;
3197 }
resetMaxArea()3198 void Ath__gridTable::resetMaxArea()
3199 {
3200   _setMaxArea = false;
3201   _maxSearchBox.invalidateBox();
3202 }
getBox(uint wid,int * x1,int * y1,int * x2,int * y2,uint * level,uint * id1,uint * id2,uint * wtype)3203 void Ath__gridTable::getBox(uint wid,
3204                             int* x1,
3205                             int* y1,
3206                             int* x2,
3207                             int* y2,
3208                             uint* level,
3209                             uint* id1,
3210                             uint* id2,
3211                             uint* wtype)
3212 {
3213   Ath__wire* w = getWirePtr(wid);
3214 
3215   *id1 = w->_boxId;
3216   *id2 = w->_otherId;
3217   *wtype = w->_flags;
3218   *level = w->_track->getGrid()->getLevel();
3219   uint dir;
3220   w->getCoords(x1, y1, x2, y2, &dir);
3221 }
addBox(int x1,int y1,int x2,int y2,uint level,uint id1,uint id2,uint wireType)3222 uint Ath__gridTable::addBox(int x1,
3223                             int y1,
3224                             int x2,
3225                             int y2,
3226                             uint level,
3227                             uint id1,
3228                             uint id2,
3229                             uint wireType)
3230 {
3231   Ath__searchBox bb(x1, y1, x2, y2, level);
3232   bb.setOwnerId(id1, id2);
3233   bb.setType(wireType);
3234 
3235   uint dir = bb.getDir();
3236   uint trackNum = getGrid(dir, level)->placeWire(&bb);
3237   _wireCnt++;
3238   return trackNum;
3239 }
getWireCnt()3240 uint Ath__gridTable::getWireCnt()
3241 {
3242   return _wireCnt;
3243 }
search(int x1,int y1,int x2,int y2,uint row,uint col,Ath__array1D<uint> * idTable,bool)3244 uint Ath__gridTable::search(int x1,
3245                             int y1,
3246                             int x2,
3247                             int y2,
3248                             uint row,
3249                             uint col,
3250                             Ath__array1D<uint>* idTable,
3251                             bool /* unused: wireIdFlag */)
3252 {
3253   Ath__searchBox bb(x1, y1, x2, y2, col, row);
3254 
3255   return search(&bb, row, col, idTable, true);  // single grid
3256 }
getCoords(Ath__searchBox * bb,uint wireId)3257 void Ath__gridTable::getCoords(Ath__searchBox* bb, uint wireId)
3258 {
3259   Ath__wire* w = getWirePtr(wireId);
3260   w->getCoords(bb);
3261 }
getCCdist(uint wid,uint * width,uint * len,uint * id1,uint * id2)3262 void Ath__gridTable::getCCdist(uint wid,
3263                                uint* width,
3264                                uint* len,
3265                                uint* id1,
3266                                uint* id2)
3267 {
3268   Ath__wire* w = getWirePtr(wid);
3269 
3270   *width = w->_width;
3271   *len = w->_len;
3272   *id1 = w->_boxId;
3273   *id2 = w->_otherId;
3274 }
getIds(uint wid,uint * id1,uint * id2,uint * wtype)3275 void Ath__gridTable::getIds(uint wid, uint* id1, uint* id2, uint* wtype)
3276 {
3277   Ath__wire* w = getWirePtr(wid);
3278 
3279   *wtype = w->_flags;
3280   *id1 = w->_boxId;
3281   *id2 = w->_otherId;
3282 }
3283