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