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 <wire.h>
34 
35 #include <map>
36 #include <vector>
37 
38 #include "dbUtil.h"
39 #include "rcx/extRCap.h"
40 #include "utl/Logger.h"
41 
42 //#define MAXINT 0x7FFFFFFF;
43 
44 //#define DEBUG_NET_ID 10
45 //#define TEST_SIGNAL_TABLE 1
46 //#define TEST_POWER_LEN 1
47 
48 namespace rcx {
49 
50 using utl::RCX;
51 
52 using odb::dbBlock;
53 using odb::dbBox;
54 using odb::dbBTerm;
55 using odb::dbCapNode;
56 using odb::dbCCSeg;
57 using odb::dbNet;
58 using odb::dbRSeg;
59 using odb::dbSet;
60 using odb::dbShape;
61 using odb::dbSigType;
62 using odb::dbTechLayer;
63 using odb::dbTechLayerDir;
64 using odb::dbTechLayerType;
65 using odb::dbWire;
66 using odb::dbWirePath;
67 using odb::dbWirePathItr;
68 using odb::dbWirePathShape;
69 using odb::gs;
70 using odb::Rect;
71 
getBucketNum(int base,int max,uint step,int xy)72 uint extMain::getBucketNum(int base, int max, uint step, int xy) {
73   if (xy >= max)
74     xy = max - 1;
75 
76   int delta = xy - base;
77   if (delta < 0)
78     return 0;
79 
80   uint n = delta / step;
81   return n;
82 }
openSearchFile(char * name)83 FILE* extMain::openSearchFile(char* name) {
84   _searchFP = fopen(name, "w");
85   return _searchFP;
86 }
closeSearchFile()87 void extMain::closeSearchFile() {
88   if (_searchFP != NULL)
89     fclose(_searchFP);
90 }
addNetOnTable(uint netId,uint dir,Rect * maxRect,uint * nm_step,int * bb_ll,int * bb_ur,Ath__array1D<uint> *** wireTable)91 uint extMain::addNetOnTable(uint netId, uint dir, Rect* maxRect, uint* nm_step,
92                             int* bb_ll, int* bb_ur,
93                             Ath__array1D<uint>*** wireTable) {
94   uint cnt = 0;
95   int ll[2] = {maxRect->xMin(), maxRect->yMin()};
96   int ur[2] = {maxRect->xMax(), maxRect->yMax()};
97 
98   uint lo_bound = getBucketNum(bb_ll[dir], bb_ur[dir], nm_step[dir], ll[dir]);
99   uint hi_bound = getBucketNum(bb_ll[dir], bb_ur[dir], nm_step[dir], ur[dir]);
100 
101   for (uint ii = lo_bound; ii <= hi_bound; ii++) {
102     if (wireTable[dir][ii] == NULL)
103       wireTable[dir][ii] = new Ath__array1D<uint>(8000);
104 
105     wireTable[dir][ii]->add(netId);
106     cnt++;
107   }
108   return cnt;
109 }
getNetBbox(dbNet * net,Rect & maxRect)110 uint extMain::getNetBbox(dbNet* net, Rect& maxRect) {
111   dbWire* wire = net->getWire();
112   if (wire == NULL)
113     return 0;
114 
115   maxRect.reset(MAX_INT, MAX_INT, MIN_INT, MIN_INT);
116   uint cnt = 0;
117   dbWireShapeItr shapes;
118   dbShape s;
119   for (shapes.begin(wire); shapes.next(s);) {
120     if (s.isVia())
121       continue;
122 
123     Rect r;
124     s.getBox(r);
125 
126     maxRect.merge(r);
127     cnt++;
128   }
129   return cnt;
130 }
getNetBbox(dbNet * net,Rect * maxRect[2])131 uint extMain::getNetBbox(dbNet* net, Rect* maxRect[2]) {
132   dbWire* wire = net->getWire();
133   if (wire == NULL)
134     return 0;
135 
136   maxRect[0]->reset(MAX_INT, MAX_INT, MIN_INT, MIN_INT);
137   maxRect[1]->reset(MAX_INT, MAX_INT, MIN_INT, MIN_INT);
138   uint cnt = 0;
139   dbWireShapeItr shapes;
140   dbShape s;
141   for (shapes.begin(wire); shapes.next(s);) {
142     if (s.isVia())
143       continue;
144 
145     Rect r;
146     s.getBox(r);
147 
148     //		maxRect.merge(r);
149     cnt++;
150   }
151   return cnt;
152 }
getNetShapes(dbNet * net,Rect ** maxRectSdb,Rect & maxRectGs,bool * hasSdbWires,bool & hasGsWires)153 void extMain::getNetShapes(dbNet* net, Rect** maxRectSdb, Rect& maxRectGs,
154                            bool* hasSdbWires, bool& hasGsWires) {
155   dbWire* wire = net->getWire();
156   if (wire == NULL)
157     return;
158 
159   dbWireShapeItr shapes;
160   dbShape s;
161   for (shapes.begin(wire); shapes.next(s);) {
162     if (s.isVia())
163       continue;
164 
165     Rect r;
166     s.getBox(r);
167 
168     uint dd = 0;  // vertical
169     if (r.dx() > r.dy())
170       dd = 1;  // horizontal
171 
172     maxRectSdb[dd]->merge(r);
173     hasSdbWires[dd] = true;
174 
175     maxRectGs.merge(r);
176     hasGsWires = true;
177   }
178 }
getNetSboxes(dbNet * net,Rect ** maxRectSdb,Rect & maxRectGs,bool * hasSdbWires,bool & hasGsWires)179 void extMain::getNetSboxes(dbNet* net, Rect** maxRectSdb, Rect& maxRectGs,
180                            bool* hasSdbWires, bool& hasGsWires) {
181   dbSet<dbSWire> swires = net->getSWires();
182   dbSet<dbSWire>::iterator itr;
183 
184   for (itr = swires.begin(); itr != swires.end(); ++itr) {
185     dbSWire* swire = *itr;
186     dbSet<dbSBox> wires = swire->getWires();
187     dbSet<dbSBox>::iterator box_itr;
188 
189     for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
190       dbSBox* s = *box_itr;
191 
192       if (s->isVia())
193         continue;
194 
195       Rect r;
196       s->getBox(r);
197 
198       uint dd = 0;  // vertical
199       if (r.dx() > r.dy())
200         dd = 1;  // horizontal
201 
202       maxRectSdb[dd]->merge(r);
203       hasSdbWires[dd] = true;
204 
205       maxRectGs.merge(r);
206       hasGsWires = true;
207     }
208   }
209 }
freeSignalTables(bool rlog,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> *** signalGsTable,uint * bucketCnt)210 void extMain::freeSignalTables(bool rlog, Ath__array1D<uint>*** sdbSignalTable,
211                                Ath__array1D<uint>*** signalGsTable,
212                                uint* bucketCnt) {
213   for (uint dd = 0; dd < 2; dd++) {
214     uint n = bucketCnt[dd];
215 
216     for (uint jj = 0; jj < n; jj++) {
217       if (sdbSignalTable[dd][jj] != NULL)
218         delete sdbSignalTable[dd][jj];
219 
220       if ((signalGsTable != NULL) && (signalGsTable[dd][jj] != NULL))
221         delete signalGsTable[dd][jj];
222     }
223     delete[] sdbSignalTable[dd];
224     if (signalGsTable != NULL)
225       delete[] signalGsTable[dd];
226   }
227 }
extWireBin(uint d,uint num,int base,AthPool<extWire> * wpool,uint allocChunk)228 extWireBin::extWireBin(uint d, uint num, int base, AthPool<extWire>* wpool,
229                        uint allocChunk) {
230   _dir = d;
231   _num = num;
232   _extWirePool = wpool;
233   _base = base;
234   _table = new Ath__array1D<extWire*>(allocChunk);
235 }
236 
addWire(uint netId,int sid,dbTechLayer * layer)237 int extWireBin::addWire(uint netId, int sid, dbTechLayer* layer) {
238   extWire* w = _extWirePool->alloc();
239   w->_layer = layer;
240   w->_netId = netId;
241   w->_shapeId = sid;
242   return _table->add(w);
243 }
addExtWires(Rect & r,extWireBin *** wireBinTable,uint netId,int shapeId,dbTechLayer * layer,uint * nm_step,int * bb_ll,int * bb_ur,AthPool<extWire> * wpool,bool cntxFlag)244 void extMain::addExtWires(Rect& r, extWireBin*** wireBinTable, uint netId,
245                           int shapeId, dbTechLayer* layer, uint* nm_step,
246                           int* bb_ll, int* bb_ur, AthPool<extWire>* wpool,
247                           bool cntxFlag) {
248   int ll[2] = {r.xMin(), r.yMin()};
249   int ur[2] = {r.xMax(), r.yMax()};
250 
251   uint dir = getDir(r.xMin(), r.yMin(), r.xMax(), r.yMax());
252 
253   if (!cntxFlag) {
254     uint binNum = getBucketNum(bb_ll[dir], bb_ur[dir], nm_step[dir], ll[dir]);
255     if (wireBinTable[dir][binNum] == NULL)
256       wireBinTable[dir][binNum] =
257           new extWireBin(dir, binNum, bb_ll[dir], wpool, 1024);
258 
259     wireBinTable[dir][binNum]->addWire(netId, shapeId, layer);
260   } else {
261     uint not_dir = !dir;
262     uint loBin = getBucketNum(bb_ll[not_dir], bb_ur[not_dir], nm_step[not_dir],
263                               ll[not_dir]);
264     uint hiBin = getBucketNum(bb_ll[not_dir], bb_ur[not_dir], nm_step[not_dir],
265                               ur[not_dir]);
266 
267     for (uint ii = loBin; ii <= hiBin; ii++) {
268       if (wireBinTable[not_dir][ii] == NULL)
269         wireBinTable[not_dir][ii] =
270             new extWireBin(dir, ii, bb_ll[not_dir], wpool, 1024);
271 
272       wireBinTable[not_dir][ii]->addWire(netId, shapeId, layer);
273     }
274   }
275 }
mkInstBins(uint binSize,int * bb_ll,int * bb_ur,uint * bucketCnt)276 Ath__array1D<uint>*** extMain::mkInstBins(uint binSize, int* bb_ll, int* bb_ur,
277                                           uint* bucketCnt) {
278   uint nm_step[2] = {binSize, binSize};
279   Ath__array1D<uint>*** instTable = new Ath__array1D<uint>** [2];
280 
281   for (uint dd = 0; dd < 2; dd++) {
282     bucketCnt[dd] = (bb_ur[dd] - bb_ll[dd]) / nm_step[dd] + 1;
283     uint n = bucketCnt[dd];
284 
285     instTable[dd] = new Ath__array1D<uint>* [n];
286     if (instTable[dd] == NULL) {
287       logger_->error(RCX, 466,
288                      "cannot allocate <Ath__array1D<extWireBin*>*[layerCnt]>");
289     }
290     for (uint jj = 0; jj < n; jj++) {
291       instTable[dd][jj] = NULL;
292     }
293   }
294   // uint cnt= 0;
295   dbSet<dbInst> insts = _block->getInsts();
296   dbSet<dbInst>::iterator inst_itr;
297 
298   for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
299     dbInst* inst = *inst_itr;
300     dbBox* bb = inst->getBBox();
301 
302     Rect r;
303     bb->getBox(r);
304 
305     for (uint dir = 0; dir < 2; dir++)
306       addNetOnTable(inst->getId(), dir, &r, nm_step, bb_ll, bb_ur, instTable);
307   }
308   return instTable;
309 }
310 
mkSignalBins(uint binSize,int * bb_ll,int * bb_ur,uint * bucketCnt,AthPool<extWire> * wpool,bool cntxFlag)311 extWireBin*** extMain::mkSignalBins(uint binSize, int* bb_ll, int* bb_ur,
312                                     uint* bucketCnt, AthPool<extWire>* wpool,
313                                     bool cntxFlag) {
314   uint nm_step[2] = {binSize, binSize};
315 
316   extWireBin*** sdbWireTable = new extWireBin** [2];
317   for (uint dd = 0; dd < 2; dd++) {
318     bucketCnt[dd] = (bb_ur[dd] - bb_ll[dd]) / nm_step[dd] + 1;
319     uint n = bucketCnt[dd];
320 
321     sdbWireTable[dd] = new extWireBin* [n];
322     if (sdbWireTable[dd] == NULL) {
323       logger_->error(RCX, 80,
324                      "cannot allocate <Ath__array1D<extWireBin*>*[layerCnt]>");
325     }
326     for (uint jj = 0; jj < n; jj++) {
327       sdbWireTable[dd][jj] = NULL;
328     }
329   }
330   // uint cnt= 0;
331   dbSet<dbNet> nets = _block->getNets();
332   dbSet<dbNet>::iterator net_itr;
333 
334   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
335     dbNet* net = *net_itr;
336 
337     uint netId = net->getId();
338 
339     if ((net->getSigType().isSupply())) {
340       dbSet<dbSWire> swires = net->getSWires();
341       dbSet<dbSWire>::iterator itr;
342 
343       for (itr = swires.begin(); itr != swires.end(); ++itr) {
344         dbSWire* swire = *itr;
345         dbSet<dbSBox> wires = swire->getWires();
346         dbSet<dbSBox>::iterator box_itr;
347 
348         for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
349           dbSBox* s = *box_itr;
350 
351           if (s->isVia())
352             continue;
353 
354           Rect r;
355           s->getBox(r);
356           addExtWires(r, sdbWireTable, netId, -s->getId(), s->getTechLayer(),
357                       nm_step, bb_ll, bb_ur, wpool, cntxFlag);
358         }
359       }
360 
361       continue;
362     }
363     dbWire* wire = net->getWire();
364     if (wire == NULL)
365       continue;
366 
367     dbWireShapeItr shapes;
368     dbShape s;
369     for (shapes.begin(wire); shapes.next(s);) {
370       if (s.isVia())
371         continue;
372 
373       Rect r;
374       s.getBox(r);
375       addExtWires(r, sdbWireTable, netId, shapes.getShapeId(), s.getTechLayer(),
376                   nm_step, bb_ll, bb_ur, wpool, cntxFlag);
377 
378       /*
379       int ll[2]= {s.xMin(), s.yMin()};
380       int ur[2]= {s.xMax(), s.yMax()};
381 
382       uint dir= getDir(s.xMin(), s.yMin(), s.xMax(), s.yMax());
383 
384       if (!cntxFlag)
385       {
386               uint binNum= getBucketNum(bb_ll[dir], bb_ur[dir], nm_step[dir],
387       ll[dir]); if (sdbWireTable[dir][binNum]==NULL) sdbWireTable[dir][binNum]=
388       new extWireBin(dir, binNum, bb_ll[dir], wpool, 1024);
389 
390               uint shapeId= shapes.getShapeId();
391               //uint l= s.getTechLayer()->getRoutingLevel();
392 
393               sdbWireTable[dir][binNum]->addWire(netId, shapeId,
394       s.getTechLayer());
395       }
396       else {
397               uint not_dir= !dir;
398               uint loBin= getBucketNum(bb_ll[not_dir], bb_ur[not_dir],
399       nm_step[not_dir], ll[not_dir]); uint hiBin= getBucketNum(bb_ll[not_dir],
400       bb_ur[not_dir], nm_step[not_dir], ur[not_dir]);
401 
402               for (uint ii= loBin; ii<=hiBin; ii++)
403               {
404                       if (sdbWireTable[not_dir][ii]==NULL)
405                               sdbWireTable[not_dir][ii]= new extWireBin(dir, ii,
406       bb_ll[not_dir], wpool, 1024);
407 
408                       uint shapeId= shapes.getShapeId();
409                       //uint l= s.getTechLayer()->getRoutingLevel();
410 
411                       sdbWireTable[not_dir][ii]->addWire(netId, shapeId,
412       s.getTechLayer());
413               }
414       }
415       */
416     }
417   }
418   return sdbWireTable;
419 }
mkSignalTables2(uint * nm_step,int * bb_ll,int * bb_ur,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> * sdbPowerTable,Ath__array1D<uint> *** instTable,uint * bucketCnt)420 uint extMain::mkSignalTables2(uint* nm_step, int* bb_ll, int* bb_ur,
421                               Ath__array1D<uint>*** sdbSignalTable,
422                               Ath__array1D<uint>* sdbPowerTable,
423                               Ath__array1D<uint>*** instTable,
424                               uint* bucketCnt) {
425   for (uint dd = 0; dd < 2; dd++) {
426     bucketCnt[dd] = (bb_ur[dd] - bb_ll[dd]) / nm_step[dd] + 2;
427     uint n = bucketCnt[dd];
428 
429     sdbSignalTable[dd] = new Ath__array1D<uint>* [n];
430     instTable[dd] = new Ath__array1D<uint>* [n];
431 
432     for (uint jj = 0; jj < n; jj++) {
433       sdbSignalTable[dd][jj] = NULL;
434       instTable[dd][jj] = NULL;
435     }
436   }
437   uint cnt = 0;
438   dbSet<dbNet> nets = _block->getNets();
439   dbSet<dbNet>::iterator net_itr;
440 
441   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
442     dbNet* net = *net_itr;
443 
444     if ((net->getSigType().isSupply())) {
445       sdbPowerTable->add(net->getId());
446       continue;
447     }
448 
449     Rect maxRect;
450     uint cnt1 = getNetBbox(net, maxRect);
451     if (cnt1 == 0)
452       continue;
453 
454     net->setSpef(false);
455 
456     for (uint dir = 0; dir < 2; dir++) {
457       addNetOnTable(net->getId(), dir, &maxRect, nm_step, bb_ll, bb_ur,
458                     sdbSignalTable);
459     }
460     cnt += cnt1;
461   }
462   if (_overCell) {
463     dbSet<dbInst> insts = _block->getInsts();
464     dbSet<dbInst>::iterator inst_itr;
465 
466     for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
467       dbInst* inst = *inst_itr;
468       dbBox* bb = inst->getBBox();
469 
470       Rect s;
471       bb->getBox(s);
472 
473       for (uint dir = 0; dir < 2; dir++)
474         addNetOnTable(inst->getId(), dir, &s, nm_step, bb_ll, bb_ur, instTable);
475 
476       inst->clearUserFlag1();
477     }
478   }
479   return cnt;
480 }
mkSignalTables(uint * nm_step,int * bb_ll,int * bb_ur,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> *** signalGsTable,Ath__array1D<uint> *** instTable,uint * bucketCnt)481 uint extMain::mkSignalTables(uint* nm_step, int* bb_ll, int* bb_ur,
482                              Ath__array1D<uint>*** sdbSignalTable,
483                              Ath__array1D<uint>*** signalGsTable,
484                              Ath__array1D<uint>*** instTable, uint* bucketCnt) {
485   for (uint dd = 0; dd < 2; dd++) {
486     bucketCnt[dd] = (bb_ur[dd] - bb_ll[dd]) / nm_step[dd] + 2;
487     uint n = bucketCnt[dd];
488 
489     sdbSignalTable[dd] = new Ath__array1D<uint>* [n];
490     signalGsTable[dd] = new Ath__array1D<uint>* [n];
491     instTable[dd] = new Ath__array1D<uint>* [n];
492 
493     for (uint jj = 0; jj < n; jj++) {
494       sdbSignalTable[dd][jj] = NULL;
495       signalGsTable[dd][jj] = NULL;
496       instTable[dd][jj] = NULL;
497     }
498     // bb_ur of chip has to be relace with one based on gs
499 
500     bb_ur[dd] = (bb_ur[dd] - bb_ll[dd]) / nm_step[dd];
501     bb_ur[dd] *= nm_step[dd];
502   }
503 
504   uint cnt = 0;
505   dbSet<dbNet> nets = _block->getNets();
506   dbSet<dbNet>::iterator net_itr;
507 
508   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
509     dbNet* net = *net_itr;
510 
511     Rect maxRectGs;
512     maxRectGs.reset(MAX_INT, MAX_INT, MIN_INT, MIN_INT);
513     bool hasGsWires = false;
514 
515     Rect a;
516     Rect b;
517     Rect* maxRectSdb[2] = {&a, &b};
518     maxRectSdb[0]->reset(MAX_INT, MAX_INT, MIN_INT, MIN_INT);
519     maxRectSdb[1]->reset(MAX_INT, MAX_INT, MIN_INT, MIN_INT);
520     bool hasSdbWires[2] = {false, false};
521 
522     if ((net->getSigType().isSupply()))
523       getNetSboxes(net, maxRectSdb, maxRectGs, hasSdbWires, hasGsWires);
524     else
525       getNetShapes(net, maxRectSdb, maxRectGs, hasSdbWires, hasGsWires);
526 
527     for (uint dir = 0; dir < 2; dir++) {
528       if (hasSdbWires[dir])
529         addNetOnTable(net->getId(), dir, maxRectSdb[dir], nm_step, bb_ll, bb_ur,
530                       sdbSignalTable);
531       if (hasGsWires)
532         addNetOnTable(net->getId(), dir, &maxRectGs, nm_step, bb_ll, bb_ur,
533                       signalGsTable);
534     }
535 
536     cnt++;
537   }
538   dbSet<dbInst> insts = _block->getInsts();
539   dbSet<dbInst>::iterator inst_itr;
540 
541   for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
542     dbInst* inst = *inst_itr;
543     dbBox* bb = inst->getBBox();
544 
545     Rect s;
546     bb->getBox(s);
547 
548     for (uint dir = 0; dir < 2; dir++)
549       addNetOnTable(inst->getId(), dir, &s, nm_step, bb_ll, bb_ur, instTable);
550   }
551   return cnt;
552 }
553 
matchDir(uint dir,Rect & r)554 bool extMain::matchDir(uint dir, Rect& r) {
555   uint dd = 0;  // vertical
556   if (r.dx() >= r.dy())
557     dd = 1;  // horizontal
558 
559   if (dir != dd)
560     return false;
561   else
562     return true;
563 }
isIncludedInsearch(Rect & r,uint dir,int * bb_ll,int * bb_ur)564 bool extMain::isIncludedInsearch(Rect& r, uint dir, int* bb_ll, int* bb_ur) {
565   if (!matchDir(dir, r))
566     return false;
567 
568   int ll[2] = {r.xMin(), r.yMin()};
569 
570   if (ll[dir] >= bb_ur[dir])
571     return false;
572 
573   if (ll[dir] < bb_ll[dir])
574     return false;
575 
576   return true;
577 }
isIncluded(Rect & r,uint dir,int * ll,int * ur)578 bool extMain::isIncluded(Rect& r, uint dir, int* ll, int* ur) {
579   uint dd = 0;  // vertical
580   if (r.dx() > r.dy())
581     dd = 1;  // horizontal
582 
583   if (dir != dd)
584     return false;
585 
586   int rLL[2] = {r.xMin(), r.yMin()};
587   int rUR[2] = {r.xMax(), r.yMax()};
588 
589   if ((rUR[dir] < ll[dir]) || (rLL[dir] > ur[dir]))
590     return false;
591 
592   return true;
593 }
GetDBcoords2(Rect & r)594 void extMain::GetDBcoords2(Rect& r) {
595   int x1 = r.xMin();
596   int x2 = r.xMax();
597   int y1 = r.yMin();
598   int y2 = r.yMax();
599   x1 = GetDBcoords2(x1);
600   x2 = GetDBcoords2(x2);
601   y1 = GetDBcoords2(y1);
602   y2 = GetDBcoords2(y2);
603   r.set_xlo(x1);
604   r.set_ylo(y1);
605   r.set_xhi(x2);
606   r.set_yhi(y2);
607 }
initSearchForNets(int * X1,int * Y1,uint * pitchTable,uint * widthTable,uint * dirTable,Rect & extRect,bool skipBaseCalc)608 uint extMain::initSearchForNets(int* X1, int* Y1, uint* pitchTable,
609                                 uint* widthTable, uint* dirTable, Rect& extRect,
610                                 bool skipBaseCalc) {
611   bool USE_DB_UNITS = false;
612   uint W[32];
613   uint S[32];
614 
615   dbSet<dbTechLayer> layers = _tech->getLayers();
616   dbSet<dbTechLayer>::iterator itr;
617   dbTrackGrid* tg = NULL;
618 
619   Rect maxRect;
620   if ((extRect.dx() > 0) && (extRect.dy() > 0)) {
621     maxRect = extRect;
622   } else {
623     _block->getDieArea(maxRect);
624     if (!((maxRect.dx() > 0) && (maxRect.dy() > 0)))
625       logger_->error(RCX, 81,
626                      "Die Area for the block has 0 size, or is undefined!");
627   }
628 
629   if (USE_DB_UNITS) {
630     GetDBcoords2(maxRect);
631     GetDBcoords2(extRect);
632   }
633 
634   std::vector<int> trackXY(32000);
635   uint n = 0;
636   for (itr = layers.begin(); itr != layers.end(); ++itr) {
637     dbTechLayer* layer = *itr;
638     dbTechLayerType type = layer->getType();
639 
640     if (type.getValue() != dbTechLayerType::ROUTING)
641       continue;
642 
643     n = layer->getRoutingLevel();
644     int w = GetDBcoords2(layer->getWidth());
645     widthTable[n] = layer->getWidth();
646 
647     if (USE_DB_UNITS)
648       widthTable[n] = w;
649 
650     W[n] = 1;
651     int s = GetDBcoords2(layer->getSpacing());
652     S[n] = layer->getSpacing();
653 
654     if (USE_DB_UNITS)
655       S[n] = s;
656 
657     int p = GetDBcoords2(layer->getPitch());
658     pitchTable[n] = layer->getPitch();
659 
660     if (USE_DB_UNITS)
661       pitchTable[n] = p;
662     if (pitchTable[n] <= 0)
663       logger_->error(RCX, 82, "Layer {}, routing level {}, has pitch {}!!",
664                      layer->getConstName(), n, pitchTable[n]);
665 
666     dirTable[n] = 0;
667     if (layer->getDirection() == dbTechLayerDir::HORIZONTAL)
668       dirTable[n] = 1;
669 
670     if (skipBaseCalc)
671       continue;
672 
673     tg = _block->findTrackGrid(layer);
674     if (tg) {
675       tg->getGridX(trackXY);
676       X1[n] = trackXY[0] - layer->getWidth() / 2;
677       tg->getGridY(trackXY);
678       Y1[n] = trackXY[0] - layer->getWidth() / 2;
679     } else {
680       X1[n] = maxRect.xMin();
681       Y1[n] = maxRect.yMin();
682     }
683   }
684   uint layerCnt = n + 1;
685 
686   _search = new Ath__gridTable(&maxRect, 2, layerCnt, W, pitchTable, S, X1, Y1);
687   _search->setBlock(_block);
688   return layerCnt;
689 }
690 
sBoxCounter(dbNet * net,uint & maxWidth)691 uint extMain::sBoxCounter(dbNet* net, uint& maxWidth) {
692   uint cnt = 0;
693   dbSet<dbSWire> swires = net->getSWires();
694   dbSet<dbSWire>::iterator itr;
695 
696   for (itr = swires.begin(); itr != swires.end(); ++itr) {
697     dbSWire* swire = *itr;
698     dbSet<dbSBox> wires = swire->getWires();
699     dbSet<dbSBox>::iterator box_itr;
700 
701     for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
702       dbSBox* s = *box_itr;
703       if (s->isVia())
704         continue;
705 
706       uint x = s->getDX();
707       uint y = s->getDY();
708       uint w = y;
709       if (w < x)
710         w = x;
711 
712       if (maxWidth > w)
713         maxWidth = w;
714 
715       cnt++;
716     }
717   }
718   return cnt;
719 }
powerWireCounter(uint & maxWidth)720 uint extMain::powerWireCounter(uint& maxWidth) {
721   uint cnt = 0;
722   dbSet<dbNet> nets = _block->getNets();
723   dbSet<dbNet>::iterator net_itr;
724 
725   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
726     dbNet* net = *net_itr;
727 
728     if (!((net->getSigType().isSupply())))
729       continue;
730 
731     cnt += sBoxCounter(net, maxWidth);
732   }
733   return cnt;
734 }
addMultipleRectsOnSearch(Rect & r,uint level,uint dir,uint id,uint shapeId,uint wtype)735 uint extMain::addMultipleRectsOnSearch(Rect& r, uint level, uint dir, uint id,
736                                        uint shapeId, uint wtype) {
737   if (_geoThickTable == NULL)
738     return _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level, id,
739                            shapeId, wtype);
740 
741   extGeoThickTable* thickTable = _geoThickTable[level];
742 
743   if (thickTable == NULL)
744     return _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level, id,
745                            shapeId, wtype);
746 
747   uint cnt = 0;
748 
749   int ll[2] = {r.xMin(), r.yMin()};
750   int ur[2] = {r.xMax(), r.yMax()};
751 
752   uint startSquare[2];
753   uint endSquare[2];
754 
755   extGeoVarTable* sq1 = thickTable->getSquare(r.xMin(), r.yMin(), startSquare);
756 
757   extGeoVarTable* sq2 = thickTable->getSquare(r.xMax(), r.yMax(), endSquare);
758 
759   if ((sq1 == NULL) || (sq2 == NULL))
760     return _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level, id,
761                            shapeId, wtype);
762 
763   dir = !dir;
764 
765   if (endSquare[dir] > startSquare[dir]) {
766     ur[dir] = thickTable->getUpperBound(dir, startSquare);
767     cnt +=
768         _search->addBox(ll[0], ll[1], ur[0], ur[1], level, id, shapeId, wtype);
769   } else {  // assume equal
770     return _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level, id,
771                            shapeId, wtype);
772   }
773 
774   uint sq[2] = {startSquare[0], startSquare[1]};
775   for (sq[dir]++; sq[dir] < endSquare[dir]; sq[dir]++) {
776     ll[dir] = ur[dir];  // prev bound
777     ur[dir] = thickTable->getUpperBound(dir, sq);
778 
779     cnt +=
780         _search->addBox(ll[0], ll[1], ur[0], ur[1], level, id, shapeId, wtype);
781 
782     // prevXY= thickTable->getUpperBound(dir, sq);
783   }
784   ll[dir] = ur[dir];
785 
786   cnt += _search->addBox(ll[0], ll[1], r.xMax(), r.yMax(), level, id, shapeId,
787                          wtype);
788 
789   if (cnt > 0)
790     return 1;
791   else
792     return 0;
793 }
794 
addNetSBoxes(dbNet * net,uint dir,int * bb_ll,int * bb_ur,uint wtype,dbCreateNetUtil * netUtil)795 uint extMain::addNetSBoxes(dbNet* net, uint dir, int* bb_ll, int* bb_ur,
796                            uint wtype, dbCreateNetUtil* netUtil) {
797   uint cnt = 0;
798   dbSet<dbSWire> swires = net->getSWires();
799   dbSet<dbSWire>::iterator itr;
800 
801   for (itr = swires.begin(); itr != swires.end(); ++itr) {
802     dbSWire* swire = *itr;
803     dbSet<dbSBox> wires = swire->getWires();
804     dbSet<dbSBox>::iterator box_itr;
805 
806     for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
807       dbSBox* s = *box_itr;
808       if (s->isVia())
809         continue;
810 
811       Rect r;
812       s->getBox(r);
813       if (isIncludedInsearch(r, dir, bb_ll, bb_ur)) {
814         uint level = s->getTechLayer()->getRoutingLevel();
815 
816         int trackNum = -1;
817         if (_geoThickTable != NULL) {
818           cnt += addMultipleRectsOnSearch(r, level, dir, s->getId(), 0, wtype);
819           continue;
820         }
821         if (netUtil != NULL) {
822           netUtil->createSpecialWire(NULL, r, s->getTechLayer(), s->getId());
823           // netUtil->createSpecialNetSingleWire(r, s->getTechLayer(), net,
824           // s->getId());
825         } else {
826           // int xmin= r.xMin();
827           trackNum = _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(),
828                                      level, s->getId(), 0, wtype);
829 
830           if (_searchFP != NULL) {
831             fprintf(_searchFP, "%d  %d %d  %d %d %d\n", level, r.xMin(),
832                     r.yMin(), r.xMax(), r.yMax(), trackNum);
833           }
834         }
835 
836         cnt++;
837       }
838     }
839   }
840   return cnt;
841 }
addNetSBoxes2(dbNet * net,uint dir,int * bb_ll,int * bb_ur,uint wtype,uint step)842 uint extMain::addNetSBoxes2(dbNet* net, uint dir, int* bb_ll, int* bb_ur,
843                             uint wtype, uint step) {
844   uint cnt = 0;
845   dbSet<dbSWire> swires = net->getSWires();
846   dbSet<dbSWire>::iterator itr;
847 
848   for (itr = swires.begin(); itr != swires.end(); ++itr) {
849     dbSWire* swire = *itr;
850     dbSet<dbSBox> wires = swire->getWires();
851     dbSet<dbSBox>::iterator box_itr;
852 
853     for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
854       dbSBox* s = *box_itr;
855       if (s->isVia())
856         continue;
857 
858       Rect r;
859       s->getBox(r);
860       if (isIncludedInsearch(r, dir, bb_ll, bb_ur)) {
861         uint level = s->getTechLayer()->getRoutingLevel();
862 
863         if (step > 0) {
864           uint len = r.dx();
865           if (len < r.dy())
866             len = r.dy();
867 
868           if (len <= step) {
869             _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level,
870                             s->getId(), 0, wtype);
871           } else {
872             if (r.dx() < r.dy()) {  // vertical
873               for (int y1 = r.yMin(); y1 < r.yMax();) {
874                 int y2 = y1 + step;
875                 if (y2 > r.yMax())
876                   y2 = r.yMax();
877 
878                 _search->addBox(r.xMin(), y1, r.xMax(), y2, level, s->getId(),
879                                 0, wtype);
880                 y1 = y2;
881               }
882             } else {  // horizontal
883               for (int x1 = r.xMin(); x1 < r.xMax();) {
884                 int x2 = x1 + step;
885                 if (x2 > r.xMax())
886                   x2 = r.xMax();
887 
888                 _search->addBox(x1, r.yMin(), x2, r.yMax(), level, s->getId(),
889                                 0, wtype);
890                 x1 = x2;
891               }
892             }
893           }
894         } else {
895           _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level,
896                           s->getId(), 0, wtype);
897         }
898 
899         cnt++;
900       }
901     }
902   }
903   return cnt;
904 }
signalWireCounter(uint & maxWidth)905 uint extMain::signalWireCounter(uint& maxWidth) {
906   uint cnt = 0;
907   dbSet<dbNet> nets = _block->getNets();
908   dbSet<dbNet>::iterator net_itr;
909 
910   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
911     dbNet* net = *net_itr;
912 
913     if ((net->getSigType().isSupply()))
914       continue;
915 
916     dbWire* wire = net->getWire();
917     if (wire == NULL)
918       continue;
919 
920     dbWireShapeItr shapes;
921     dbShape s;
922     for (shapes.begin(wire); shapes.next(s);) {
923       if (s.isVia())
924         continue;
925 
926       uint x = s.getDX();
927       uint y = s.getDY();
928       uint w = y;
929       if (w > x)
930         w = x;
931 
932       if (maxWidth < w)
933         maxWidth = w;
934     }
935 
936     uint wireCnt = 0;
937     uint viaCnt = 0;
938     net->getSignalWireCount(wireCnt, viaCnt);
939 
940     cnt += wireCnt;
941   }
942   return cnt;
943 }
addPowerNets(uint dir,int * bb_ll,int * bb_ur,uint wtype,dbCreateNetUtil * netUtil)944 uint extMain::addPowerNets(uint dir, int* bb_ll, int* bb_ur, uint wtype,
945                            dbCreateNetUtil* netUtil) {
946   uint cnt = 0;
947   dbSet<dbNet> nets = _block->getNets();
948   dbSet<dbNet>::iterator net_itr;
949 
950   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
951     dbNet* net = *net_itr;
952 
953     if (!((net->getSigType().isSupply())))
954       continue;
955 
956     cnt += addNetSBoxes(net, dir, bb_ll, bb_ur, wtype, netUtil);
957   }
958   return cnt;
959 }
960 
GetDBcoords1(int coord)961 double extMain::GetDBcoords1(int coord) {
962   int db_factor = _block->getDbUnitsPerMicron();
963   return 1.0 * coord / db_factor;
964 }
965 
GetDBcoords2(int coord)966 int extMain::GetDBcoords2(int coord) {
967   int db_factor = _block->getDbUnitsPerMicron();
968   double d = (1.0 * coord) / db_factor;
969   int n = (int)ceil(1000 * d);
970   return n;
971 }
972 
addNetShapesOnSearch(dbNet * net,uint dir,int * bb_ll,int * bb_ur,uint wtype,FILE * fp,dbCreateNetUtil * netUtil)973 uint extMain::addNetShapesOnSearch(dbNet* net, uint dir, int* bb_ll, int* bb_ur,
974                                    uint wtype, FILE* fp,
975                                    dbCreateNetUtil* netUtil) {
976   bool USE_DB_UNITS = false;
977 
978   dbWire* wire = net->getWire();
979 
980   if (wire == NULL)
981     return 0;
982 
983   if (netUtil != NULL)
984     netUtil->setCurrentNet(NULL);
985 
986   uint cnt = 0;
987   //	uint wireId= wire->getId();
988 
989   dbWireShapeItr shapes;
990   dbShape s;
991   for (shapes.begin(wire); shapes.next(s);) {
992     //		uint level= 0;
993 
994     int shapeId = shapes.getShapeId();
995 
996     if (s.isVia()) {
997       if (!_skip_via_wires)
998         addViaBoxes(s, net, shapeId, wtype);
999 
1000       continue;
1001     }
1002 
1003     Rect r;
1004     s.getBox(r);
1005     if (isIncludedInsearch(r, dir, bb_ll, bb_ur)) {
1006       uint level = s.getTechLayer()->getRoutingLevel();
1007 
1008       if (_geoThickTable != NULL) {
1009         cnt += addMultipleRectsOnSearch(r, level, dir, net->getId(), shapeId,
1010                                         wtype);
1011         continue;
1012       }
1013       if (netUtil != NULL) {
1014         netUtil->createNetSingleWire(r, level, net->getId(), shapeId);
1015       } else {
1016         int dx = r.xMax() - r.xMin();
1017         int dy = r.yMax() - r.yMin();
1018         int via_ext = 32;
1019 
1020         // int xmin= r.xMin();
1021         uint trackNum = 0;
1022         // if (net->getId()==2655) {
1023         if (trackNum > 0) {
1024           if (dy > dx) {
1025             trackNum = _search->addBox(r.xMin(), r.yMin() - via_ext, r.xMax(),
1026                                        r.yMax() + via_ext, level, net->getId(),
1027                                        shapeId, wtype);
1028           } else {
1029             trackNum = _search->addBox(r.xMin() - via_ext, r.yMin(),
1030                                        r.xMax() + via_ext, r.yMax(), level,
1031                                        net->getId(), shapeId, wtype);
1032           }
1033         } else {
1034           if (USE_DB_UNITS) {
1035             trackNum =
1036                 _search->addBox(GetDBcoords2(r.xMin()), GetDBcoords2(r.yMin()),
1037                                 GetDBcoords2(r.xMax()), GetDBcoords2(r.yMax()),
1038                                 level, net->getId(), shapeId, wtype);
1039           } else {
1040             trackNum = _search->addBox(r.xMin(), r.yMin(), r.xMax(), r.yMax(),
1041                                        level, net->getId(), shapeId, wtype);
1042             if (net->getId() == _debug_net_id) {
1043               debugPrint(
1044                   logger_, RCX, "debug_net", 1,
1045                   "\t[Search:W]"
1046                   "\tonSearch: tr={} L{}  DX={} DY={} {} {}  {} {} -- {:.3f} "
1047                   "{:.3f}  {:.3f} {:.3f} net {}",
1048                   trackNum, level, dx, dy, r.xMin(), r.yMin(), r.xMax(),
1049                   r.yMax(), GetDBcoords1(r.xMin()), GetDBcoords1(r.yMin()),
1050                   GetDBcoords1(r.xMax()), GetDBcoords1(r.yMax()), net->getId());
1051             }
1052           }
1053         }
1054 
1055         if (_searchFP != NULL) {
1056           fprintf(_searchFP, "%d  %d %d  %d %d %d\n", level, r.xMin(), r.yMin(),
1057                   r.xMax(), r.yMax(), trackNum);
1058         }
1059       }
1060 
1061 #ifdef TEST_SIGNAL_TABLE
1062       if (fp != NULL) {
1063         fprintf(fp, "%d %d  %d %d %d %d\n", net->getId(), level, r.xMin(),
1064                 r.yMin(), r.xMax(), r.yMax());
1065       }
1066 #endif
1067       cnt++;
1068     }
1069   }
1070   return cnt;
1071 }
1072 
addViaBoxes(dbShape & sVia,dbNet * net,uint shapeId,uint wtype)1073 uint extMain::addViaBoxes(dbShape& sVia, dbNet* net, uint shapeId, uint wtype) {
1074   int rcid = getShapeProperty(net, shapeId);
1075   wtype = 5;  // Via Type
1076 
1077   bool USE_DB_UNITS = false;
1078   uint cnt = 0;
1079 
1080   int X1[2] = {0, 0};
1081   int X2[2] = {0, 0};
1082   int Y1[2] = {0, 0};
1083   int Y2[2] = {0, 0};
1084   int id[2] = {0, 0};
1085   int LEN[2] = {0, 0};
1086 
1087   int botLevel = 0;
1088   int topLevel = 0;
1089 
1090   const char* tcut = "tcut";
1091   const char* bcut = "bcut";
1092 
1093   std::vector<dbShape> shapes;
1094   dbShape::getViaBoxes(sVia, shapes);
1095 
1096   std::vector<dbShape>::iterator shape_itr;
1097   for (shape_itr = shapes.begin(); shape_itr != shapes.end(); ++shape_itr) {
1098     dbShape s = *shape_itr;
1099 
1100     if (s.getTechLayer()->getType() == dbTechLayerType::CUT)
1101       continue;
1102 
1103     int x1 = s.xMin();
1104     int y1 = s.yMin();
1105     int x2 = s.xMax();
1106     int y2 = s.yMax();
1107     int dx = x2 - x1;
1108     int dy = y2 - y1;
1109 
1110     uint track_num;
1111     uint level = s.getTechLayer()->getRoutingLevel();
1112     uint width = s.getTechLayer()->getWidth();
1113 
1114     int len = dx;
1115     if (s.getTechLayer()->getDirection() == dbTechLayerDir::VERTICAL) {
1116       len = dy;
1117       if (width != dx)
1118         continue;
1119     } else {
1120       if (width != dy)
1121         continue;
1122     }
1123 
1124     if (USE_DB_UNITS) {
1125       track_num = _search->addBox(GetDBcoords2(x1), GetDBcoords2(y1),
1126                                   GetDBcoords2(x2), GetDBcoords2(y2), level,
1127                                   net->getId(), shapeId, wtype);
1128     } else {
1129       track_num =
1130           _search->addBox(x1, y1, x2, y2, level, net->getId(), shapeId, wtype);
1131     }
1132     // if (net->getId()==_debug_net_id) {
1133     //	debug("Search", "W", "addViaBoxes: L%d  DX=%3d DY=%d %d %d  %d %d --
1134     //%.3f %.3f  %.3f %.3f dx=%g dy=%g\n", 		level, dx, dy, x1, y1,
1135     // x2, y2, GetDBcoords1(x1), GetDBcoords1(y1), GetDBcoords1(x2),
1136     // GetDBcoords1(y2), 		GetDBcoords1(dx), GetDBcoords1(dy));
1137     //}
1138   }
1139   return cnt;
1140 }
1141 
addSignalNets(uint dir,int * bb_ll,int * bb_ur,uint wtype,dbCreateNetUtil * createDbNet)1142 uint extMain::addSignalNets(uint dir, int* bb_ll, int* bb_ur, uint wtype,
1143                             dbCreateNetUtil* createDbNet) {
1144   uint cnt = 0;
1145   dbSet<dbNet> nets = _block->getNets();
1146   dbSet<dbNet>::iterator net_itr;
1147 
1148   FILE* fp = NULL;
1149 
1150 #ifdef TEST_SIGNAL_TABLE
1151   char filename[64];
1152   sprintf(filename, "old/%d.%d.%d.sig.sdb", dir, bb_ll[dir], bb_ur[dir]);
1153   fp = fopen(filename, "w");
1154 #endif
1155 
1156   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
1157     dbNet* net = *net_itr;
1158 
1159     if ((net->getSigType().isSupply()))
1160       continue;
1161 
1162     cnt += addNetShapesOnSearch(net, dir, bb_ll, bb_ur, wtype, fp, createDbNet);
1163   }
1164   if (createDbNet == NULL)
1165     _search->adjustOverlapMakerEnd();
1166 
1167 #ifdef TEST_SIGNAL_TABLE
1168 
1169   fprintf(fp, "dir= %d   %d %d -- %d %d sigCnt= %d\n", dir, bb_ll[0], bb_ur[0],
1170           bb_ll[1], bb_ur[1], cnt);
1171 
1172   if (fp != NULL)
1173     fclose(fp);
1174 #endif
1175   return cnt;
1176 }
addPowerNets2(uint dir,int * bb_ll,int * bb_ur,uint wtype,Ath__array1D<uint> * sdbPowerTable,dbCreateNetUtil * createDbNet)1177 uint extMain::addPowerNets2(uint dir, int* bb_ll, int* bb_ur, uint wtype,
1178                             Ath__array1D<uint>* sdbPowerTable,
1179                             dbCreateNetUtil* createDbNet) {
1180   uint cnt = 0;
1181   uint netCnt = sdbPowerTable->getCnt();
1182 
1183   if (createDbNet != NULL)
1184     createDbNet->createSpecialNet(NULL, "POWER_SDB");
1185 
1186   for (uint ii = 0; ii < netCnt; ii++) {
1187     dbNet* net = dbNet::getNet(_block, sdbPowerTable->get(ii));
1188 
1189     cnt += addNetSBoxes(net, dir, bb_ll, bb_ur, wtype, createDbNet);
1190   }
1191   return cnt;
1192 }
resetNetSpefFlag(Ath__array1D<uint> * tmpNetIdTable)1193 void extMain::resetNetSpefFlag(Ath__array1D<uint>* tmpNetIdTable) {
1194   for (uint ii = 0; ii < tmpNetIdTable->getCnt(); ii++) {
1195     uint netId = tmpNetIdTable->get(ii);
1196     dbNet* net = dbNet::getNet(_block, netId);
1197     net->setSpef(false);
1198   }
1199 }
createDbNetsGS(dbBlock * block,dbCreateNetUtil * createDbNet)1200 uint extWireBin::createDbNetsGS(dbBlock* block, dbCreateNetUtil* createDbNet) {
1201   uint cnt = 0;
1202 
1203   uint prevNetId = 0;
1204   dbNet* net = NULL;
1205   dbWire* wire = NULL;
1206 
1207   char netName[128];
1208   sprintf(netName, "GS_%d_%d", _dir, _num);
1209   createDbNet->setCurrentNet(NULL);
1210 
1211   createDbNet->createSpecialNet(NULL, netName);
1212 
1213   for (uint ii = 0; ii < _table->getCnt(); ii++) {
1214     extWire* w = _table->get(ii);
1215 
1216     if (w->_netId != prevNetId) {
1217       prevNetId = w->_netId;
1218       net = dbNet::getNet(block, w->_netId);
1219       wire = net->getWire();
1220     }
1221 
1222     Rect r;
1223     if (w->_shapeId < 0) {
1224       dbSBox* s = dbSBox::getSBox(block, -w->_shapeId);
1225       s->getBox(r);
1226     } else {
1227       dbShape s;
1228       // wire->getShape(w->_shapeId, s);
1229       wire->getSegment(w->_shapeId, w->_layer, s);
1230 
1231       s.getBox(r);
1232     }
1233     createDbNet->createSpecialWire(NULL, r, w->_layer, 0);
1234     cnt++;
1235   }
1236   return cnt;
1237 }
addNets3GS(uint dir,int * lo_sdb,int * hi_sdb,int * bb_ll,int * bb_ur,uint bucketSize,extWireBin *** wireBinTable,dbCreateNetUtil * createDbNet)1238 uint extMain::addNets3GS(uint dir, int* lo_sdb, int* hi_sdb, int* bb_ll,
1239                          int* bb_ur, uint bucketSize,
1240                          extWireBin*** wireBinTable,
1241                          dbCreateNetUtil* createDbNet) {
1242   uint lo_index =
1243       getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize, lo_sdb[dir] + 1);
1244   uint hi_index =
1245       getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize, hi_sdb[dir] + 1);
1246 
1247   uint cnt = 0;
1248   for (uint bucket = lo_index; bucket <= hi_index; bucket++) {
1249     extWireBin* b = wireBinTable[dir][bucket];
1250     if (b == NULL)
1251       continue;
1252 
1253     if (createDbNet != NULL)
1254       b->createDbNetsGS(_block, createDbNet);
1255     else
1256       cnt += b->_table->getCnt();
1257   }
1258 
1259   return cnt;
1260 }
createDbNets(dbBlock * block,dbCreateNetUtil * createDbNet)1261 uint extWireBin::createDbNets(dbBlock* block, dbCreateNetUtil* createDbNet) {
1262   uint cnt = 0;
1263 
1264   uint prevNetId = 0;
1265   dbNet* net = NULL;
1266   dbWire* wire = NULL;
1267 
1268   for (uint ii = 0; ii < _table->getCnt(); ii++) {
1269     extWire* w = _table->get(ii);
1270 
1271     if (w->_netId != prevNetId) {
1272       prevNetId = w->_netId;
1273       net = dbNet::getNet(block, w->_netId);
1274       createDbNet->checkAndSet(w->_netId);
1275 
1276       if (w->_shapeId < 0)
1277         createDbNet->createSpecialNet(net, NULL);
1278       else
1279         wire = net->getWire();
1280     }
1281     if (w->_shapeId < 0) {
1282       dbSBox* s = dbSBox::getSBox(block, -w->_shapeId);
1283 
1284       Rect r;
1285       s->getBox(r);
1286 
1287       createDbNet->createSpecialWire(NULL, r, w->_layer, -w->_shapeId);
1288     } else {
1289       dbShape s;
1290       // wire->getShape(w->_shapeId, s);
1291       wire->getSegment(w->_shapeId, w->_layer, s);
1292       Rect r;
1293       s.getBox(r);
1294 
1295       createDbNet->createNetSingleWire(r, w->_layer->getRoutingLevel(),
1296                                        w->_netId, w->_shapeId);
1297     }
1298     cnt++;
1299   }
1300   return cnt;
1301 }
addNets3(uint dir,int * lo_sdb,int * hi_sdb,int * bb_ll,int * bb_ur,uint bucketSize,extWireBin *** wireBinTable,dbCreateNetUtil * createDbNet)1302 uint extMain::addNets3(uint dir, int* lo_sdb, int* hi_sdb, int* bb_ll,
1303                        int* bb_ur, uint bucketSize, extWireBin*** wireBinTable,
1304                        dbCreateNetUtil* createDbNet) {
1305   uint lo_index = getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize, lo_sdb[dir]);
1306   uint hi_index = getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize, hi_sdb[dir]);
1307 
1308   uint cnt = 0;
1309   for (uint bucket = lo_index; bucket <= hi_index; bucket++) {
1310     extWireBin* b = wireBinTable[dir][bucket];
1311     if (b == NULL)
1312       continue;
1313 
1314     if (createDbNet != NULL)
1315       b->createDbNets(_block, createDbNet);
1316     else
1317       cnt += b->_table->getCnt();
1318   }
1319 
1320   return cnt;
1321 }
addInsts(uint dir,int * lo_gs,int * hi_gs,int * bb_ll,int * bb_ur,uint bucketSize,Ath__array1D<uint> *** wireBinTable,dbCreateNetUtil * createDbNet)1322 uint extMain::addInsts(uint dir, int* lo_gs, int* hi_gs, int* bb_ll, int* bb_ur,
1323                        uint bucketSize, Ath__array1D<uint>*** wireBinTable,
1324                        dbCreateNetUtil* createDbNet) {
1325   uint lo_index = getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize, lo_gs[dir]);
1326   uint hi_index = getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize, hi_gs[dir]);
1327 
1328   uint cnt = 0;
1329   uint bucket;
1330   for (bucket = lo_index; bucket <= hi_index; bucket++) {
1331     if (wireBinTable[dir][bucket] == NULL)
1332       continue;
1333 
1334     uint instCnt = wireBinTable[dir][bucket]->getCnt();
1335     for (uint ii = 0; ii < instCnt; ii++) {
1336       uint instId = wireBinTable[dir][bucket]->get(ii);
1337       dbInst* inst0 = dbInst::getInst(_block, instId);
1338 
1339       if (inst0->getUserFlag1())
1340         continue;
1341 
1342       inst0->setUserFlag1();
1343 
1344       createDbNet->createInst(inst0);
1345       cnt++;
1346     }
1347   }
1348   for (bucket = lo_index; bucket <= hi_index; bucket++) {
1349     if (wireBinTable[dir][bucket] == NULL)
1350       continue;
1351 
1352     uint instCnt = wireBinTable[dir][bucket]->getCnt();
1353     for (uint ii = 0; ii < instCnt; ii++) {
1354       uint instId = wireBinTable[dir][bucket]->get(ii);
1355       dbInst* inst0 = dbInst::getInst(_block, instId);
1356 
1357       inst0->clearUserFlag1();
1358     }
1359   }
1360   return cnt;
1361 }
addSignalNets2(uint dir,int * lo_sdb,int * hi_sdb,int * bb_ll,int * bb_ur,uint * bucketSize,uint wtype,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> * tmpNetIdTable,dbCreateNetUtil * createDbNet)1362 uint extMain::addSignalNets2(uint dir, int* lo_sdb, int* hi_sdb, int* bb_ll,
1363                              int* bb_ur, uint* bucketSize, uint wtype,
1364                              Ath__array1D<uint>*** sdbSignalTable,
1365                              Ath__array1D<uint>* tmpNetIdTable,
1366                              dbCreateNetUtil* createDbNet) {
1367   if (sdbSignalTable == NULL)
1368     return 0;
1369 
1370   uint lo_index =
1371       getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize[dir], lo_sdb[dir]);
1372   uint hi_index =
1373       getBucketNum(bb_ll[dir], bb_ur[dir], bucketSize[dir], hi_sdb[dir]);
1374 
1375   FILE* fp = NULL;
1376 #ifdef TEST_SIGNAL_TABLE
1377   char filename[64];
1378   sprintf(filename, "new/%d.%d.%d.sig.sdb", dir, lo_sdb[dir], hi_sdb[dir]);
1379   fp = fopen(filename, "w");
1380 #endif
1381 
1382   uint cnt = 0;
1383   for (uint bucket = lo_index; bucket <= hi_index; bucket++) {
1384     if (sdbSignalTable[dir][bucket] == NULL)
1385       continue;
1386 
1387     uint netCnt = sdbSignalTable[dir][bucket]->getCnt();
1388     for (uint ii = 0; ii < netCnt; ii++) {
1389       uint netId = sdbSignalTable[dir][bucket]->get(ii);
1390       dbNet* net = dbNet::getNet(_block, netId);
1391 
1392       if (net->isSpef())  // tmp flag
1393         continue;
1394       net->setSpef(true);
1395       tmpNetIdTable->add(netId);
1396 
1397       cnt += addNetShapesOnSearch(net, dir, lo_sdb, hi_sdb, wtype, fp,
1398                                   createDbNet);
1399     }
1400   }
1401   _search->adjustOverlapMakerEnd();
1402 
1403   resetNetSpefFlag(tmpNetIdTable);
1404 
1405 #ifdef TEST_SIGNAL_TABLE
1406   fprintf(fp, "dir= %d   %d %d -- %d %d sigCnt= %d\n", dir, lo_sdb[0],
1407           hi_sdb[0], lo_sdb[1], hi_sdb[1], cnt);
1408 
1409   if (fp != NULL)
1410     fclose(fp);
1411 #endif
1412 
1413   return cnt;
1414 }
reportTableNetCnt(uint * sdbBucketCnt,Ath__array1D<uint> *** sdbSignalTable)1415 void extMain::reportTableNetCnt(uint* sdbBucketCnt,
1416                                 Ath__array1D<uint>*** sdbSignalTable) {
1417   for (uint dir = 0; dir < 2; dir++) {
1418     logger_->info(RCX, 83,
1419                   "DIR= {} -----------------------------------------------",
1420                   dir);
1421 
1422     for (uint bucket = 0; bucket < sdbBucketCnt[dir]; bucket++) {
1423       if (sdbSignalTable[dir][bucket] == NULL)
1424         continue;
1425 
1426       uint netCnt = sdbSignalTable[dir][bucket]->getCnt();
1427       logger_->info(RCX, 84, "\tbucket= {} -- {} nets", bucket, netCnt);
1428     }
1429   }
1430 }
addNets(uint dir,int * bb_ll,int * bb_ur,uint wtype,uint ptype,Ath__array1D<uint> * sdbSignalTable)1431 uint extMain::addNets(uint dir, int* bb_ll, int* bb_ur, uint wtype, uint ptype,
1432                       Ath__array1D<uint>* sdbSignalTable) {
1433   if (sdbSignalTable == NULL)
1434     return 0;
1435 
1436   uint cnt = 0;
1437   uint netCnt = sdbSignalTable->getCnt();
1438   for (uint ii = 0; ii < netCnt; ii++) {
1439     dbNet* net = dbNet::getNet(_block, sdbSignalTable->get(ii));
1440 
1441     if ((net->getSigType().isSupply()))
1442       cnt += addNetSBoxes(net, dir, bb_ll, bb_ur, ptype);
1443     else
1444       cnt += addNetShapesOnSearch(net, dir, bb_ll, bb_ur, wtype, NULL);
1445   }
1446   return cnt;
1447 }
1448 
getDir(Rect & r)1449 uint extMain::getDir(Rect& r) {
1450   return getDir(r.xMin(), r.yMin(), r.xMax(), r.yMax());
1451 }
getDir(int x1,int y1,int x2,int y2)1452 uint extMain::getDir(int x1, int y1, int x2, int y2) {
1453   uint dx = x2 - x1;
1454   uint dy = y2 - y1;
1455   uint dd = 0;  // vertical
1456   if (dx > dy)
1457     dd = 1;  // horizontal
1458 
1459   return dd;
1460 }
addShapeOnGS(dbNet * net,uint sId,Rect & r,bool plane,dbTechLayer * layer,bool gsRotated,bool swap_coords,int dir,bool specialWire,dbCreateNetUtil * createDbNet)1461 uint extMain::addShapeOnGS(dbNet* net, uint sId, Rect& r, bool plane,
1462                            dbTechLayer* layer, bool gsRotated, bool swap_coords,
1463                            int dir, bool specialWire,
1464                            dbCreateNetUtil* createDbNet) {
1465   if (dir >= 0) {
1466     if (plane) {
1467       uint rdir = 0;
1468       if (layer->getDirection() == dbTechLayerDir::HORIZONTAL)
1469         rdir = 1;
1470       // if (rdir==dir)
1471       // return 0;
1472     } else {
1473       if (matchDir(dir, r))
1474         return 0;
1475     }
1476   }
1477   bool checkFlag = false;
1478   if (createDbNet != NULL)
1479     checkFlag = true;
1480 
1481   uint level = layer->getRoutingLevel();
1482   int n = 0;
1483   if (!gsRotated) {
1484     n = _geomSeq->box(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level, checkFlag);
1485   } else {
1486     if (!swap_coords)  // horizontal
1487       n = _geomSeq->box(r.xMin(), r.yMin(), r.xMax(), r.yMax(), level,
1488                         checkFlag);
1489     else
1490       n = _geomSeq->box(r.yMin(), r.xMin(), r.yMax(), r.xMax(), level,
1491                         checkFlag);
1492   }
1493   if (n == 0) {
1494     if (createDbNet != NULL) {
1495       if (specialWire)
1496         createDbNet->createSpecialWire(NULL, r, layer, sId);
1497       else
1498         createDbNet->createNetSingleWire(r, level, net->getId(), sId);
1499     }
1500     return 1;
1501   }
1502   return 0;
1503 }
addNetShapesGs(dbNet * net,bool gsRotated,bool swap_coords,int dir,dbCreateNetUtil * createDbNet)1504 uint extMain::addNetShapesGs(dbNet* net, bool gsRotated, bool swap_coords,
1505                              int dir, dbCreateNetUtil* createDbNet) {
1506   bool USE_DB_UNITS = false;
1507   uint cnt = 0;
1508   dbWire* wire = net->getWire();
1509   if (wire == NULL)
1510     return 0;
1511 
1512   bool plane = false;
1513   if (net->getSigType() == dbSigType::ANALOG)
1514     plane = true;
1515 
1516   dbWireShapeItr shapes;
1517   dbShape s;
1518   for (shapes.begin(wire); shapes.next(s);) {
1519     if (s.isVia())
1520       continue;
1521 
1522     int shapeId = shapes.getShapeId();
1523 
1524     Rect r;
1525     s.getBox(r);
1526 
1527     if (USE_DB_UNITS)
1528       this->GetDBcoords2(r);
1529 
1530     cnt += addShapeOnGS(net, shapeId, r, plane, s.getTechLayer(), gsRotated,
1531                         swap_coords, dir, true, createDbNet);
1532     /*
1533                     if (dir>=0) {
1534                             Rect r;
1535                             s.getBox(r);
1536                             if (matchDir(dir, r))
1537                                     continue;
1538                     }
1539                     uint level= s.getTechLayer()->getRoutingLevel();
1540 
1541                     int n= 0;
1542                     if (!gsRotated) {
1543                             n= _geomSeq->box(s.xMin(), s.yMin(), s.xMax(),
1544        s.yMax(), level);
1545                     }
1546                     else {
1547                             if (!swap_coords) // horizontal
1548                                     n= _geomSeq->box(s.xMin(), s.yMin(),
1549        s.xMax(), s.yMax(), level); else n= _geomSeq->box(s.yMin(), s.xMin(),
1550        s.yMax(), s.xMax(), level);
1551                     }
1552                     if (n==0)
1553                             cnt ++;
1554     */
1555   }
1556   return cnt;
1557 }
addNetSboxesGs(dbNet * net,bool gsRotated,bool swap_coords,int dir,dbCreateNetUtil * createDbNet)1558 uint extMain::addNetSboxesGs(dbNet* net, bool gsRotated, bool swap_coords,
1559                              int dir, dbCreateNetUtil* createDbNet) {
1560   uint cnt = 0;
1561 
1562   dbSet<dbSWire> swires = net->getSWires();
1563   dbSet<dbSWire>::iterator itr;
1564 
1565   for (itr = swires.begin(); itr != swires.end(); ++itr) {
1566     dbSWire* swire = *itr;
1567     dbSet<dbSBox> wires = swire->getWires();
1568     dbSet<dbSBox>::iterator box_itr;
1569 
1570     for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
1571       dbSBox* s = *box_itr;
1572 
1573       if (s->isVia())
1574         continue;
1575 
1576       Rect r;
1577       s->getBox(r);
1578       cnt += addShapeOnGS(NULL, s->getId(), r, true, s->getTechLayer(),
1579                           gsRotated, swap_coords, dir, true, createDbNet);
1580       /*
1581                               if (dir>=0) {
1582                                       Rect r;
1583                                       s->getBox(r);
1584                                       if (matchDir(dir, r))
1585                                               continue;
1586                               }
1587 
1588                               uint level= s->getTechLayer()->getRoutingLevel();
1589 
1590                               int n= 0;
1591                               if (!gsRotated) {
1592                                       n= _geomSeq->box(s->xMin(), s->yMin(),
1593          s->xMax(), s->yMax(), level);
1594                               }
1595                               else {
1596                                       if (!swap_coords)
1597                                               n= _geomSeq->box(s->xMin(),
1598          s->yMin(), s->xMax(), s->yMax(), level); else n=
1599          _geomSeq->box(s->yMin(), s->xMin(), s->yMax(), s->xMax(), level);
1600                               }
1601                               if (n==0)
1602                                       cnt ++;
1603       */
1604     }
1605   }
1606   return cnt;
1607 }
addNetsGs(Ath__array1D<uint> * gsTable,int dir)1608 uint extMain::addNetsGs(Ath__array1D<uint>* gsTable, int dir) {
1609   if (gsTable == NULL)
1610     return 0;
1611 
1612   uint cnt = 0;
1613   uint netCnt = gsTable->getCnt();
1614   for (uint ii = 0; ii < netCnt; ii++) {
1615     dbNet* net = dbNet::getNet(_block, gsTable->get(ii));
1616 
1617     if ((net->getSigType().isSupply()))
1618       cnt += addNetSboxesGs(net, false, false, dir);
1619     else
1620       cnt += addNetShapesGs(net, false, false, dir);
1621   }
1622   return cnt;
1623 }
getXY_gs(int base,int XY,uint minRes)1624 int extMain::getXY_gs(int base, int XY, uint minRes) {
1625   uint maxRow = (XY - base) / minRes;
1626   int v = base + maxRow * minRes;
1627   return v;
1628 }
getXY_gs2(int base,int hiXY,int loXY,uint minRes)1629 int extMain::getXY_gs2(int base, int hiXY, int loXY, uint minRes) {
1630   uint hiRow = (hiXY - base) / minRes;
1631   uint loRow = (loXY - base) / minRes;
1632 
1633   uint deltaRow = hiRow - loRow;
1634 
1635   int targetRow = hiRow - deltaRow;
1636   int v = base + targetRow * minRes;
1637   return v;
1638 }
initPlanes(uint dir,int * wLL,int * wUR,uint layerCnt,uint * pitchTable,uint * widthTable,uint * dirTable,int * bb_ll,bool skipMemAlloc)1639 uint extMain::initPlanes(uint dir, int* wLL, int* wUR, uint layerCnt,
1640                          uint* pitchTable, uint* widthTable, uint* dirTable,
1641                          int* bb_ll, bool skipMemAlloc) {
1642   bool rotatedFlag = getRotatedFlag();
1643 
1644   if (_geomSeq != NULL)
1645     delete _geomSeq;
1646   _geomSeq = new gs(_seqPool);
1647 
1648   _geomSeq->setSlices(layerCnt);
1649 
1650   for (uint ii = 1; ii < layerCnt; ii++) {
1651     uint layerDir = dirTable[ii];
1652 
1653     uint res[2] = {pitchTable[ii], widthTable[ii]};  // vertical
1654     if (layerDir > 0) {                              // horizontal
1655       res[0] = widthTable[ii];
1656       res[1] = pitchTable[ii];
1657     }
1658     if (res[dir] == 0)
1659       continue;
1660     int ll[2];
1661     ll[!dir] = bb_ll[!dir];
1662     ll[dir] = getXY_gs(bb_ll[dir], wLL[dir], res[dir]);
1663 
1664     int ur[2];
1665     ur[!dir] = wUR[!dir];
1666     ur[dir] = getXY_gs(bb_ll[dir], wUR[dir], res[dir]);
1667 
1668     if (!rotatedFlag) {
1669       _geomSeq->configureSlice(ii, res[0], res[1], ll[0], ll[1], ur[0], ur[1],
1670                                skipMemAlloc);
1671     } else {
1672       if (dir > 0) {  // horizontal segment extraction
1673         _geomSeq->configureSlice(ii, res[0], res[1], ll[0], ll[1], ur[0], ur[1],
1674                                  skipMemAlloc);
1675       } else {
1676         if (layerDir > 0) {
1677           _geomSeq->configureSlice(ii, pitchTable[ii], widthTable[ii], ll[1],
1678                                    ll[0], ur[1], ur[0], skipMemAlloc);
1679 
1680         } else {
1681           _geomSeq->configureSlice(ii, widthTable[ii], pitchTable[ii], ll[1],
1682                                    ll[0], ur[1], ur[0], skipMemAlloc);
1683         }
1684       }
1685     }
1686   }
1687   return layerCnt;
1688 }
addInstsGs(Ath__array1D<uint> * instTable,Ath__array1D<uint> * tmpInstIdTable,uint dir)1689 uint extMain::addInstsGs(Ath__array1D<uint>* instTable,
1690                          Ath__array1D<uint>* tmpInstIdTable, uint dir) {
1691   if (instTable == NULL)
1692     return 0;
1693 
1694   bool rotatedGs = getRotatedFlag();
1695 
1696   uint cnt = 0;
1697   uint instCnt = instTable->getCnt();
1698 
1699   for (uint ii = 0; ii < instCnt; ii++) {
1700     uint instId = instTable->get(ii);
1701     dbInst* inst = dbInst::getInst(_block, instId);
1702 
1703     if (tmpInstIdTable != NULL) {
1704       if (inst->getUserFlag1())
1705         continue;
1706 
1707       inst->setUserFlag1();
1708       tmpInstIdTable->add(instId);
1709     }
1710 
1711     /*
1712                     Rect r;
1713                     dbBox *bb= inst->getBBox();
1714                     bb->getBox(r);
1715                     if ( !isIncludedInsearch(r, dir, bb_ll, bb_ur) )
1716                             continue;
1717     */
1718     cnt += addItermShapesOnPlanes(inst, rotatedGs, !dir);
1719     cnt += addObsShapesOnPlanes(inst, rotatedGs, !dir);
1720   }
1721   if (tmpInstIdTable != NULL) {
1722     for (uint jj = 0; jj < tmpInstIdTable->getCnt(); jj++) {
1723       uint instId = instTable->get(jj);
1724       dbInst* inst = dbInst::getInst(_block, instId);
1725 
1726       inst->clearUserFlag1();
1727     }
1728   }
1729   return cnt;
1730 }
getRotatedFlag()1731 bool extMain::getRotatedFlag() { return _rotatedGs; }
disableRotatedFlag()1732 void extMain::disableRotatedFlag() { _rotatedGs = false; }
enableRotatedFlag()1733 bool extMain::enableRotatedFlag() {
1734   _rotatedGs = (_use_signal_tables > 1) ? true : false;
1735 
1736   return _rotatedGs;
1737 }
fill_gs4(int dir,int * ll,int * ur,int * lo_gs,int * hi_gs,uint layerCnt,uint * dirTable,uint * pitchTable,uint * widthTable,dbCreateNetUtil * createDbNet)1738 uint extMain::fill_gs4(int dir, int* ll, int* ur, int* lo_gs, int* hi_gs,
1739                        uint layerCnt, uint* dirTable, uint* pitchTable,
1740                        uint* widthTable, dbCreateNetUtil* createDbNet) {
1741   bool rotatedGs = getRotatedFlag();
1742 
1743   bool skipMemAlloc = false;
1744   if (createDbNet != NULL)
1745     skipMemAlloc = true;
1746 
1747   initPlanes(dir, lo_gs, hi_gs, layerCnt, pitchTable, widthTable, dirTable, ll,
1748              skipMemAlloc);
1749 
1750   int gs_dir = dir;
1751 #ifndef GS_CROSS_LINES_ONLY
1752   gs_dir = -1;
1753 #endif
1754 
1755   uint pcnt = 0;
1756   dbSet<dbNet> nets = _block->getNets();
1757   dbSet<dbNet>::iterator net_itr;
1758 
1759   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
1760     dbNet* net = *net_itr;
1761 
1762     if (!((net->getSigType().isSupply())))
1763       continue;
1764 
1765     if (createDbNet != NULL)
1766       createDbNet->createSpecialNet(net, NULL);
1767 
1768     pcnt += addNetSboxesGs(net, rotatedGs, !dir, gs_dir, createDbNet);
1769   }
1770 
1771   /*
1772           FILE *fp= NULL;
1773 
1774   #ifdef TEST_SIGNAL_TABLE
1775           char filename[64];
1776           sprintf(filename, "old/%d.%d.%d.sig.sdb", dir, bb_ll[dir],
1777   bb_ur[dir]); fp= fopen(filename, "w"); #endif
1778   */
1779   uint scnt = 0;
1780 
1781   if (createDbNet != NULL)
1782     createDbNet->createSpecialNet(NULL, "SIGNALS_GS");
1783 
1784   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
1785     dbNet* net = *net_itr;
1786 
1787     if ((net->getSigType().isSupply()))
1788       continue;
1789 
1790     scnt += addNetShapesGs(net, rotatedGs, !dir, gs_dir, createDbNet);
1791   }
1792   if (_overCell) {
1793     Ath__array1D<uint> instGsTable(nets.size());
1794     Ath__array1D<uint> tmpNetIdTable(nets.size());
1795 
1796     dbSet<dbInst> insts = _block->getInsts();
1797     dbSet<dbInst>::iterator inst_itr;
1798     for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
1799       dbInst* inst = *inst_itr;
1800 
1801       dbBox* R = inst->getBBox();
1802 
1803       int R_ll[2] = {R->xMin(), R->yMin()};
1804       int R_ur[2] = {R->xMax(), R->yMax()};
1805 
1806       if ((R_ur[dir] < lo_gs[dir]) || (R_ll[dir] > hi_gs[dir]))
1807         continue;
1808 
1809       instGsTable.add(inst->getId());
1810     }
1811     addInstsGs(&instGsTable, &tmpNetIdTable, dir);
1812   }
1813 
1814   return pcnt + scnt;
1815 }
1816 
fill_gs3(int dir,int * ll,int * ur,int * lo_gs,int * hi_gs,uint layerCnt,uint * dirTable,uint * pitchTable,uint * widthTable,int * sdbTable_ll,int * sdbTable_ur,uint * bucketSize,Ath__array1D<uint> * powerNetTable,Ath__array1D<uint> * tmpNetIdTable,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> *** instGsTable,dbCreateNetUtil * createDbNet)1817 int extMain::fill_gs3(int dir, int* ll, int* ur, int* lo_gs, int* hi_gs,
1818                       uint layerCnt, uint* dirTable, uint* pitchTable,
1819                       uint* widthTable, int* sdbTable_ll, int* sdbTable_ur,
1820                       uint* bucketSize, Ath__array1D<uint>* powerNetTable,
1821                       Ath__array1D<uint>* tmpNetIdTable,
1822                       Ath__array1D<uint>*** sdbSignalTable,
1823                       Ath__array1D<uint>*** instGsTable,
1824                       dbCreateNetUtil* createDbNet) {
1825   if (sdbSignalTable == NULL)
1826     return 0;
1827 
1828   bool rotatedGs = getRotatedFlag();
1829 
1830   bool skipMemAlloc = false;
1831   if (createDbNet != NULL)
1832     skipMemAlloc = true;
1833 
1834   initPlanes(dir, lo_gs, hi_gs, layerCnt, pitchTable, widthTable, dirTable, ll,
1835              skipMemAlloc);
1836 
1837   int gs_dir = dir;
1838 #ifndef GS_CROSS_LINES_ONLY
1839   gs_dir = -1;
1840 #endif
1841 
1842   uint pcnt = 0;
1843   uint netCnt = powerNetTable->getCnt();
1844   for (uint ii = 0; ii < netCnt; ii++) {
1845     dbNet* net = dbNet::getNet(_block, powerNetTable->get(ii));
1846 
1847     if (createDbNet != NULL)
1848       createDbNet->createSpecialNet(net, NULL);
1849 
1850     pcnt += addNetSboxesGs(net, rotatedGs, !dir, gs_dir, createDbNet);
1851   }
1852   uint scnt = 0;
1853 
1854   uint lo_index = getBucketNum(sdbTable_ll[dir], sdbTable_ur[dir],
1855                                bucketSize[dir], lo_gs[dir]);
1856   uint hi_index = getBucketNum(sdbTable_ll[dir], sdbTable_ur[dir],
1857                                bucketSize[dir], hi_gs[dir]);
1858 
1859   if (createDbNet != NULL)
1860     createDbNet->createSpecialNet(NULL, "SIGNALS_GS");
1861 
1862   for (uint bucket = lo_index; bucket <= hi_index; bucket++) {
1863     if (sdbSignalTable[dir][bucket] == NULL)
1864       continue;
1865 
1866     uint netCnt = sdbSignalTable[dir][bucket]->getCnt();
1867 
1868     for (uint ii = 0; ii < netCnt; ii++) {
1869       uint netId = sdbSignalTable[dir][bucket]->get(ii);
1870       dbNet* net = dbNet::getNet(_block, netId);
1871 
1872       if (net->isSpef())  // tmp flag
1873         continue;
1874       net->setSpef(true);
1875       tmpNetIdTable->add(netId);
1876 
1877       scnt += addNetShapesGs(net, rotatedGs, !dir, gs_dir, createDbNet);
1878     }
1879   }
1880   resetNetSpefFlag(tmpNetIdTable);
1881 
1882   if (_overCell) {
1883     for (uint bucket = lo_index; bucket <= hi_index; bucket++) {
1884       addInstsGs(instGsTable[dir][bucket], tmpNetIdTable, dir);
1885     }
1886   }
1887 
1888 #ifdef TEST_SIGNAL_TABLE
1889   FILE* fp = NULL;
1890   char filename[64];
1891   sprintf(filename, "new/%d.%d.%d.fill", dir, minExt, hiXY);
1892   fp = fopen(filename, "w");
1893 
1894   fprintf(fp,
1895           "dir= %d   minExt= %d   hiXY= %d  %d %d -- %d %d pwrCnt= %d  sigCnt= "
1896           "%d\n",
1897           dir, minExt, hiXY, lo_gs[0], hi_gs[0], lo_gs[1], hi_gs[1], pcnt,
1898           scnt);
1899 
1900   if (fp != NULL)
1901     fclose(fp);
1902 #endif
1903 
1904   return lo_gs[dir];
1905 }
1906 
fill_gs2(int dir,int * ll,int * ur,int * lo_gs,int * hi_gs,uint layerCnt,uint * dirTable,uint * pitchTable,uint * widthTable,uint bucket,Ath__array1D<uint> *** gsTable,Ath__array1D<uint> *** instGsTable)1907 int extMain::fill_gs2(int dir, int* ll, int* ur, int* lo_gs, int* hi_gs,
1908                       uint layerCnt, uint* dirTable, uint* pitchTable,
1909                       uint* widthTable, uint bucket,
1910                       Ath__array1D<uint>*** gsTable,
1911                       Ath__array1D<uint>*** instGsTable) {
1912   initPlanes(dir, lo_gs, hi_gs, layerCnt, pitchTable, widthTable, dirTable, ll);
1913 
1914   int gs_dir = dir;
1915 #ifndef GS_CROSS_LINES_ONLY
1916   gs_dir = -1;
1917 #endif
1918 
1919   if (gsTable != NULL) {
1920     uint cnt = addNetsGs(gsTable[dir][bucket], gs_dir);
1921     if (bucket > 0)
1922       cnt += addNetsGs(gsTable[dir][bucket - 1], gs_dir);
1923 
1924     if (_overCell) {
1925       addInstsGs(instGsTable[dir][bucket], NULL, 0);
1926       if (bucket > 0)
1927         addInstsGs(instGsTable[dir][bucket], NULL, 0);
1928     }
1929   } else {
1930     addPowerGs(gs_dir);
1931     addSignalGs(gs_dir);
1932 
1933     if (_overCell)
1934       addInstShapesOnPlanes(dir);
1935 
1936 #ifdef TEST_SIGNAL_TABLE
1937     FILE* fp = NULL;
1938     char filename[64];
1939     sprintf(filename, "old/%d.%d.%d.fill", dir, minExt, hiXY);
1940     fp = fopen(filename, "w");
1941 
1942     fprintf(fp,
1943             "dir= %d   minExt= %d   hiXY= %d  %d %d -- %d %d pwrCnt= %d  "
1944             "sigCnt= %d\n",
1945             dir, minExt, hiXY, lo_gs[0], hi_gs[0], lo_gs[1], hi_gs[1], gsPcnt,
1946             gsCnt);
1947 
1948     if (fp != NULL)
1949       fclose(fp);
1950 #endif
1951   }
1952 
1953   return lo_gs[dir];
1954 }
1955 
resetGndCaps()1956 void extMain::resetGndCaps() {
1957   uint cornerCnt = _block->getCornerCount();
1958 
1959   dbSet<dbNet> nets = _block->getNets();
1960   dbSet<dbNet>::iterator net_itr;
1961 
1962   // uint cnt= 0;
1963   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
1964     dbNet* net = *net_itr;
1965 
1966     if ((net->getSigType().isSupply()))
1967       continue;
1968 
1969     // uint netId= net->getId();
1970 
1971     dbSet<dbRSeg> rcSet = net->getRSegs();
1972 
1973     dbSet<dbRSeg>::iterator rc_itr;
1974 
1975     for (rc_itr = rcSet.begin(); rc_itr != rcSet.end(); ++rc_itr) {
1976       dbRSeg* rc = *rc_itr;
1977 
1978       for (uint ii = 0; ii < cornerCnt; ii++)
1979         rc->setCapacitance(0.0, ii);
1980 
1981       uint n = rc->getShapeId();
1982       uint n1 = rc->getTargetCapNode()->getShapeId();
1983       uint n2 = rc->getSourceCapNode()->getShapeId();
1984 
1985       if (n != n1) {
1986         logger_->info(RCX, 85, "shapeIds {}: rc= {} tgt= {} src {}",
1987                       net->getConstName(), n, n1, n2);
1988       }
1989     }
1990   }
1991 }
couplingFlow(bool rlog,Rect & extRect,uint trackStep,uint ccFlag,extMeasure * m,CoupleAndCompute coupleAndCompute)1992 uint extMain::couplingFlow(bool rlog, Rect& extRect, uint trackStep,
1993                            uint ccFlag, extMeasure* m,
1994                            CoupleAndCompute coupleAndCompute) {
1995   dbIntProperty* p = (dbIntProperty*)dbProperty::find(_block, "_currentDir");
1996   if (p != NULL) {
1997     _use_signal_tables = 3;
1998     int DIR = p->getValue();
1999 
2000     extWindow* W = new extWindow(20, logger_);
2001     W->getExtProperties(_block);
2002 
2003     uint propCnt = mkNetPropertiesForRsegs(_block, DIR);
2004     logger_->info(RCX, 86, "Created {} Net Properties", propCnt);
2005 
2006     _ignoreWarning_1st = true;
2007     rcGenBlock();
2008     _ignoreWarning_1st = false;
2009     if (m->_netId > 0) {
2010       writeMapping();
2011       writeMapping(_block->getParent());
2012     } else
2013       resetGndCaps();
2014 
2015     extractWindow(rlog, W, extRect, false, m, coupleAndCompute);
2016 
2017     uint rsegCnt = invalidateNonDirShapes(_block, (uint)DIR, true);
2018     logger_->info(RCX, 87, "Extracted {} valid rsegs", rsegCnt);
2019 
2020     return 0;
2021     // return tileFlow(rlog, extRect, trackStep, ccFlag, m, coupleAndCompute);
2022   }
2023 
2024   uint ccDist = ccFlag;
2025   //	if (ccFlag>20) {
2026   //		ccDist= ccFlag % 10;
2027   //	}
2028 
2029   // trackStep *= 2;
2030   bool single_gs = false;
2031 
2032   uint sigtype = 9;
2033   uint pwrtype = 11;
2034 
2035   uint pitchTable[32];
2036   uint widthTable[32];
2037   for (uint ii = 0; ii < 32; ii++) {
2038     pitchTable[ii] = 0;
2039     widthTable[ii] = 0;
2040   }
2041   uint dirTable[16];
2042   int baseX[32];
2043   int baseY[32];
2044   uint layerCnt = initSearchForNets(baseX, baseY, pitchTable, widthTable,
2045                                     dirTable, extRect, false);
2046   for (uint i = 0; i < layerCnt + 1; i++)
2047     m->_dirTable[i] = dirTable[i];
2048 
2049   uint maxPitch = pitchTable[layerCnt - 1];
2050   //	uint minPitch= pitchTable[1];
2051 
2052   layerCnt = (int)layerCnt > _currentModel->getLayerCnt()
2053                  ? layerCnt
2054                  : _currentModel->getLayerCnt();
2055   int ll[2];
2056   int ur[2];
2057   ll[0] = extRect.xMin();
2058   ll[1] = extRect.yMin();
2059   ur[0] = extRect.xMax();
2060   ur[1] = extRect.yMax();
2061 
2062   int lo_gs[2];
2063   int hi_gs[2];
2064   int lo_sdb[2];
2065   int hi_sdb[2];
2066 
2067   Ath__overlapAdjust overlapAdj = Z_noAdjust;
2068   _useDbSdb = true;
2069   _search->setExtControl(
2070       _block, _useDbSdb, (uint)overlapAdj, _CCnoPowerSource, _CCnoPowerTarget,
2071       _ccUp, _allNet, _ccContextDepth, _ccContextArray, _ccContextLength,
2072       _dgContextArray, &_dgContextDepth, &_dgContextPlanes, &_dgContextTracks,
2073       &_dgContextBaseLvl, &_dgContextLowLvl, &_dgContextHiLvl,
2074       _dgContextBaseTrack, _dgContextLowTrack, _dgContextHiTrack,
2075       _dgContextTrackBase, m->_seqPool);
2076 
2077   _seqPool = m->_seqPool;
2078 
2079   uint maxWidth = 0;
2080   uint totPowerWireCnt = powerWireCounter(maxWidth);
2081   uint totWireCnt = signalWireCounter(maxWidth);
2082   totWireCnt += totPowerWireCnt;
2083 
2084   logger_->info(RCX, 43, "{} wires to be extracted", totWireCnt);
2085 
2086   if (single_gs) {
2087     initPlanes(layerCnt);
2088     m->_pixelTable = _geomSeq;
2089     addPowerGs();
2090     addSignalGs();
2091     if (rlog)
2092       AthResourceLog("NewFlow single GS ", 0);
2093   }
2094   uint minRes[2];
2095   minRes[1] = pitchTable[1];
2096   minRes[0] = widthTable[1];
2097 
2098   uint step_nm[2];
2099   step_nm[1] = trackStep * minRes[1];
2100   step_nm[0] = trackStep * minRes[1];
2101   if (maxWidth > ccDist * maxPitch) {
2102     step_nm[1] = ur[1] - ll[1];
2103     step_nm[0] = ur[0] - ll[0];
2104   }
2105   // _use_signal_tables
2106   Ath__array1D<uint>** sdbSignalTable[2];
2107   Ath__array1D<uint>** gsInstTable[2];
2108   Ath__array1D<uint> sdbPowerTable;
2109   Ath__array1D<uint> tmpNetIdTable(64000);
2110   uint sdbBucketCnt[2];
2111   uint sdbBucketSize[2];
2112   int sdbTable_ll[2];
2113   int sdbTable_ur[2];
2114 
2115   bool use_signal_tables = false;
2116   if ((_use_signal_tables == 1) || (_use_signal_tables == 2)) {
2117     use_signal_tables = true;
2118 
2119     logger_->info(RCX, 467, "Signal_table= {} ----------------------------- ",
2120                   _use_signal_tables);
2121 
2122     for (uint ii = 0; ii < 2; ii++) {
2123       sdbBucketCnt[ii] = 0;
2124       sdbBucketSize[ii] = 2 * step_nm[ii];
2125       sdbTable_ll[ii] = ll[ii] - step_nm[ii] / 10;
2126       sdbTable_ur[ii] = ur[ii] + step_nm[ii] / 10;
2127     }
2128 
2129     mkSignalTables2(sdbBucketSize, sdbTable_ll, sdbTable_ur, sdbSignalTable,
2130                     &sdbPowerTable, gsInstTable, sdbBucketCnt);
2131 
2132     reportTableNetCnt(sdbBucketCnt, sdbSignalTable);
2133 #ifdef TEST_SIGNAL_TABLE
2134     reportTableNetCnt(sdbBucketCnt, sdbSignalTable);
2135 #endif
2136 
2137     if (rlog)
2138       AthResourceLog("Making net tables ", 0);
2139   }
2140   uint totalWiresExtracted = 0;
2141 
2142   int** limitArray;
2143   limitArray = new int* [layerCnt];
2144   for (uint jj = 0; jj < layerCnt; jj++)
2145     limitArray[jj] = new int[10];
2146 
2147   FILE* bandinfo = NULL;
2148   if (_printBandInfo) {
2149     if (_getBandWire)
2150       bandinfo = fopen("bandInfo.getWire", "w");
2151     else
2152       bandinfo = fopen("bandInfo.extract", "w");
2153   }
2154   for (int dir = 1; dir >= 0; dir--) {
2155     if (_printBandInfo)
2156       fprintf(bandinfo, "dir = %d\n", dir);
2157     if (dir == 0)
2158       enableRotatedFlag();
2159 
2160     lo_gs[!dir] = ll[!dir];
2161     hi_gs[!dir] = ur[!dir];
2162     lo_sdb[!dir] = ll[!dir];
2163     hi_sdb[!dir] = ur[!dir];
2164 
2165     int minExtracted = ll[dir];
2166     int gs_limit = ll[dir];
2167 
2168     _search->initCouplingCapLoops(dir, ccFlag, coupleAndCompute, m);
2169     if (rlog)
2170       AthResourceLog("initCouplingCapLoops", 0);
2171 
2172     lo_sdb[dir] = ll[dir] - step_nm[dir];
2173     int hiXY = ll[dir] + step_nm[dir];
2174     if (hiXY > ur[dir])
2175       hiXY = ur[dir];
2176 
2177     uint stepNum = 0;
2178     for (; hiXY <= ur[dir]; hiXY += step_nm[dir]) {
2179       if (ur[dir] - hiXY <= (int)step_nm[dir])
2180         hiXY = ur[dir] + 5 * ccDist * maxPitch;
2181 
2182       if (!single_gs) {
2183         lo_gs[dir] = gs_limit;
2184         hi_gs[dir] = hiXY;
2185 
2186         if (use_signal_tables) {
2187           tmpNetIdTable.resetCnt();
2188           fill_gs3(dir, ll, ur, lo_gs, hi_gs, layerCnt, dirTable, pitchTable,
2189                    widthTable, sdbTable_ll, sdbTable_ur, sdbBucketSize,
2190                    &sdbPowerTable, &tmpNetIdTable, sdbSignalTable, gsInstTable);
2191         } else
2192           fill_gs4(dir, ll, ur, lo_gs, hi_gs, layerCnt, dirTable, pitchTable,
2193                    widthTable, NULL);
2194 
2195         m->_rotatedGs = getRotatedFlag();
2196         m->_pixelTable = _geomSeq;
2197         if (rlog)
2198           AthResourceLog("Fill GS", 0);
2199       }
2200       // add wires onto search such that    loX<=loX<=hiX
2201       hi_sdb[dir] = hiXY;
2202 
2203       uint processWireCnt = 0;
2204       if (use_signal_tables) {
2205         processWireCnt +=
2206             addPowerNets2(dir, lo_sdb, hi_sdb, pwrtype, &sdbPowerTable);
2207         tmpNetIdTable.resetCnt();
2208         processWireCnt += addSignalNets2(dir, lo_sdb, hi_sdb, sdbTable_ll,
2209                                          sdbTable_ur, sdbBucketSize, sigtype,
2210                                          sdbSignalTable, &tmpNetIdTable);
2211       } else {
2212         processWireCnt += addPowerNets(dir, lo_sdb, hi_sdb, pwrtype);
2213         processWireCnt += addSignalNets(dir, lo_sdb, hi_sdb, sigtype);
2214       }
2215 
2216       if (rlog)
2217         AthResourceLog("Fill Sdb", 0);
2218 
2219       uint extractedWireCnt = 0;
2220       int extractLimit = hiXY - ccDist * maxPitch;
2221       minExtracted =
2222           _search->couplingCaps(extractLimit, ccFlag, dir, extractedWireCnt,
2223                                 coupleAndCompute, m, _getBandWire, limitArray);
2224 
2225       if (rlog) {
2226         char buff[64];
2227         sprintf(buff, "CCext %d wires xy[%d]= %d ", processWireCnt, dir,
2228                 minExtracted);
2229 
2230         AthResourceLog(buff, 0);
2231       }
2232 
2233       int deallocLimit = minExtracted - (ccDist + 1) * maxPitch;
2234       if (_printBandInfo)
2235         fprintf(bandinfo,
2236                 "    step %d  hiXY=%d extLimit=%d minExtracted=%d "
2237                 "deallocLimit=%d\n",
2238                 stepNum, hiXY, extractLimit, minExtracted, deallocLimit);
2239       _search->dealloc(dir, deallocLimit);
2240 
2241       lo_sdb[dir] = hiXY;
2242       gs_limit = minExtracted - (ccDist + 2) * maxPitch;
2243 
2244       stepNum++;
2245       totalWiresExtracted += processWireCnt;
2246       float percent_extracted =
2247           Ath__double2int(100.0 * (1.0 * totalWiresExtracted / totWireCnt));
2248 
2249       if ((totWireCnt > 0) && (totalWiresExtracted > 0) &&
2250           (percent_extracted - _previous_percent_extracted >= 5.0)) {
2251         logger_->info(RCX, 442,
2252                       "{:d}% completion -- {:d} wires have been extracted",
2253                       (int)(100.0 * (1.0 * totalWiresExtracted / totWireCnt)),
2254                       totalWiresExtracted);
2255 
2256         _previous_percent_extracted = percent_extracted;
2257       }
2258     }
2259   }
2260   if (_printBandInfo)
2261     fclose(bandinfo);
2262   if (use_signal_tables) {
2263     freeSignalTables(true, sdbSignalTable, NULL, sdbBucketCnt);
2264   }
2265 
2266   if (_geomSeq != NULL) {
2267     delete _geomSeq;
2268     _geomSeq = NULL;
2269   }
2270 
2271   return 0;
2272 }
2273 
2274 //=============================================== WINDOW BASED ==============
initWindowStep(Rect & extRect,uint trackStep,uint layerCnt,uint modelLevelCnt)2275 void extWindow::initWindowStep(Rect& extRect, uint trackStep, uint layerCnt,
2276                                uint modelLevelCnt) {
2277   _maxPitch = _pitchTable[layerCnt - 1];
2278 
2279   _layerCnt = layerCnt > modelLevelCnt ? layerCnt : modelLevelCnt;
2280 
2281   _ll[0] = extRect.xMin();
2282   _ll[1] = extRect.yMin();
2283   _ur[0] = extRect.xMax();
2284   _ur[1] = extRect.yMax();
2285 
2286   uint minRes[2];
2287   minRes[1] = _pitchTable[1];
2288   minRes[0] = _widthTable[1];
2289 
2290   _step_nm[1] = trackStep * minRes[1];
2291   _step_nm[0] = trackStep * minRes[1];
2292   if (_maxWidth > _ccDist * _maxPitch) {
2293     _step_nm[1] = _ur[1] - _ll[1];
2294     _step_nm[0] = _ur[0] - _ll[0];
2295   }
2296 }
extWindow(extWindow * e,uint num,Logger * logger)2297 extWindow::extWindow(extWindow* e, uint num, Logger* logger) {
2298   logger_ = logger;
2299   _num = num;
2300 
2301   init(20);
2302 
2303   _ccDist = e->_ccDist;
2304 
2305   _maxPitch = e->_maxPitch;
2306 
2307   _maxWidth = e->_maxWidth;
2308   _layerCnt = e->_layerCnt;
2309 
2310   for (uint ii = 0; ii < 2; ii++) {
2311     _ll[ii] = e->_ll[ii];
2312     _ur[ii] = e->_ur[ii];
2313     _step_nm[ii] = e->_step_nm[ii];
2314     _lo_gs[ii] = e->_lo_gs[ii];
2315     _hi_gs[ii] = e->_hi_gs[ii];
2316     _lo_sdb[ii] = e->_lo_sdb[ii];
2317     _hi_sdb[ii] = e->_hi_sdb[ii];
2318   }
2319   _gs_limit = e->_gs_limit;
2320   _minExtracted = e->_minExtracted;
2321 
2322   for (uint i = 0; i < _layerCnt + 1; i++) {
2323     _dirTable[i] = e->_dirTable[i];
2324     _widthTable[i] = e->_widthTable[i];
2325     _pitchTable[i] = e->_pitchTable[i];
2326     //_extractLimit[i]= e->_extractLimit[i];
2327     for (uint j = 0; j < 2; j++) {
2328       _extTrack[j][i] = e->_extTrack[j][i];
2329       _extLimit[j][i] = e->_extLimit[j][i];
2330       _cntxTrack[j][i] = e->_cntxTrack[j][i];
2331       _cntxLimit[j][i] = e->_cntxLimit[j][i];
2332       _sdbBase[j][i] = e->_sdbBase[j][i];
2333     }
2334   }
2335   _extractLimit = e->_extractLimit;
2336   _totPowerWireCnt = e->_totPowerWireCnt;
2337   _totWireCnt = e->_totPowerWireCnt;
2338 
2339   _currentDir = e->_currentDir;
2340   _hiXY = e->_hiXY;
2341   _gsRotatedFlag = e->_gsRotatedFlag;
2342   _deallocLimit = e->_deallocLimit;
2343 }
initWindowSearch(Rect & extRect,uint trackStep,uint ccFlag,uint modelLevelCnt,extMeasure * m)2344 extWindow* extMain::initWindowSearch(Rect& extRect, uint trackStep, uint ccFlag,
2345                                      uint modelLevelCnt, extMeasure* m) {
2346   extWindow* W = new extWindow(20, logger_);
2347   W->_ccDist = ccFlag;
2348 
2349   uint layerCnt =
2350       initSearchForNets(W->_sdbBase[0], W->_sdbBase[1], W->_pitchTable,
2351                         W->_widthTable, W->_dirTable, extRect, false);
2352   if (m != NULL) {
2353     for (uint i = 0; i < layerCnt + 1; i++)
2354       m->_dirTable[i] = W->_dirTable[i];
2355   }
2356   uint maxWidth = 0;
2357   for (uint i = 1; i < layerCnt + 1; i++) {
2358     if (W->_widthTable[i] > maxWidth)
2359       maxWidth = W->_widthTable[i];
2360   }
2361 
2362   W->_maxWidth = maxWidth;
2363   W->initWindowStep(extRect, trackStep, layerCnt, modelLevelCnt);
2364 
2365   return W;
2366 }
init(uint maxLayerCnt)2367 void extWindow::init(uint maxLayerCnt) {
2368   _sigtype = 9;
2369   _pwrtype = 11;
2370 
2371   _maxLayerCnt = maxLayerCnt;
2372 
2373   _dirTable = new uint[maxLayerCnt];
2374   _pitchTable = new uint[maxLayerCnt];
2375   _widthTable = new uint[maxLayerCnt];
2376   //_extractLimit= new int[maxLayerCnt];
2377   for (uint i = 0; i < 2; i++) {
2378     _extTrack[i] = new int[maxLayerCnt];
2379     _extLimit[i] = new int[maxLayerCnt];
2380     _cntxTrack[i] = new int[maxLayerCnt];
2381     _cntxLimit[i] = new int[maxLayerCnt];
2382     _sdbBase[i] = new int[maxLayerCnt];
2383   }
2384 
2385   for (uint ii = 0; ii < maxLayerCnt; ii++) {
2386     _dirTable[ii] = 0;
2387     _pitchTable[ii] = 0;
2388     _widthTable[ii] = 0;
2389   }
2390   _ccDist = 0;
2391   _layerCnt = 0;
2392   _maxPitch = 0;
2393   _gsRotatedFlag = false;
2394   _totalWiresExtracted = 0;
2395   _totWireCnt = 0;
2396   _prev_percent_extracted = 0;
2397 }
updateExtLimits(int ** limitArray)2398 void extWindow::updateExtLimits(int** limitArray) {
2399   for (uint ii = 0; ii < _layerCnt; ii++) {
2400     _cntxTrack[0][ii] = limitArray[ii][0];
2401     _cntxLimit[0][ii] = limitArray[ii][1];
2402 
2403     _extTrack[0][ii] = limitArray[ii][2];
2404     _extLimit[0][ii] = limitArray[ii][3];
2405 
2406     _extTrack[1][ii] = limitArray[ii][4];
2407     _extLimit[1][ii] = limitArray[ii][5];
2408   }
2409   _lo_sdb[_currentDir] = _cntxLimit[0][1];
2410   _hi_sdb[_currentDir] = _extLimit[1][1] + _maxPitch * _ccDist;
2411 }
printLimitArray(int ** limitArray,uint layerCnt)2412 void extMain::printLimitArray(int** limitArray, uint layerCnt) {
2413   logger_->info(RCX, 89, " ------------------------ Context Lower Limits");
2414   uint ii;
2415   for (ii = 1; ii < layerCnt; ii++)
2416     logger_->info(RCX, 469, "L={} {}    {}", ii, limitArray[ii][0],
2417                   limitArray[ii][1]);
2418 
2419   logger_->info(RCX, 91, "--------------------------- EXT Lower Limits");
2420   for (ii = 1; ii < layerCnt; ii++)
2421     logger_->info(RCX, 470, "L={} {}    {}", ii, limitArray[ii][2],
2422                   limitArray[ii][3]);
2423 
2424   logger_->info(RCX, 92, " ------------------------ EXT Upper Limits");
2425   for (ii = 1; ii < layerCnt; ii++)
2426     logger_->info(RCX, 90, "L={} {}    {}", ii, limitArray[ii][4],
2427                   limitArray[ii][5]);
2428 }
getIntProperty(dbBlock * block,const char * name)2429 int extWindow::getIntProperty(dbBlock* block, const char* name) {
2430   dbProperty* p = dbProperty::find(block, name);
2431 
2432   if (p == NULL)
2433     return 0;
2434   dbIntProperty* ip = (dbIntProperty*)p;
2435 
2436   return ip->getValue();
2437 }
2438 
getExtProperties(dbBlock * block)2439 void extWindow::getExtProperties(dbBlock* block) {
2440   _num = getIntProperty(block, "_num");
2441   _currentDir = getIntProperty(block, "_currentDir");
2442   _extractLimit = getIntProperty(block, "_extractLimit");
2443   _ccDist = getIntProperty(block, "_ccDist");
2444   _maxPitch = getIntProperty(block, "_maxPitch");
2445   _lo_gs[0] = getIntProperty(block, "_lo_gs[0]");
2446   _lo_gs[1] = getIntProperty(block, "_lo_gs[1]");
2447   _hi_gs[0] = getIntProperty(block, "_hi_gs[0]");
2448   _hi_gs[1] = getIntProperty(block, "_hi_gs[1]");
2449   _gs_limit = getIntProperty(block, "_gs_limit");
2450   _layerCnt = getIntProperty(block, "_layerCnt");
2451 
2452   _ll[0] = getIntProperty(block, "_ll[0]");
2453   _ll[1] = getIntProperty(block, "_ll[1]");
2454   _ur[0] = getIntProperty(block, "_ur[0]");
2455   _ur[1] = getIntProperty(block, "_ur[1]");
2456   _hiXY = getIntProperty(block, "_hiXY");
2457   _step_nm[0] = getIntProperty(block, "_step_nm[0]");
2458   _step_nm[1] = getIntProperty(block, "_step_nm[1]");
2459 
2460   for (uint ii = 0; ii < _layerCnt; ii++) {
2461     char bufName[64];
2462     sprintf(bufName, "_extLimit[0]_%d", ii);
2463 
2464     _extLimit[0][ii] = getIntProperty(block, bufName);
2465 
2466     sprintf(bufName, "_sdbBase[0]_%d", ii);
2467 
2468     _sdbBase[0][ii] = getIntProperty(block, bufName);
2469 
2470     sprintf(bufName, "_sdbBase[1]_%d", ii);
2471 
2472     _sdbBase[1][ii] = getIntProperty(block, bufName);
2473   }
2474   for (uint j = 0; j < 2; j++) {
2475     _lo_sdb[j] = getIntArrayProperty(block, j, "_lo_sdb");
2476     _hi_sdb[j] = getIntArrayProperty(block, j, "_hi_sdb");
2477   }
2478 }
makeIntArrayProperty(dbBlock * block,uint ii,int * A,const char * name)2479 void extWindow::makeIntArrayProperty(dbBlock* block, uint ii, int* A,
2480                                      const char* name) {
2481   char bufName[64];
2482 
2483   sprintf(bufName, "%s[%d]", name, ii);
2484 
2485   dbIntProperty::create(block, bufName, A[ii]);
2486 }
getIntArrayProperty(dbBlock * block,uint ii,const char * name)2487 int extWindow::getIntArrayProperty(dbBlock* block, uint ii, const char* name) {
2488   char bufName[64];
2489 
2490   sprintf(bufName, "%s[%d]", name, ii);
2491 
2492   return getIntProperty(block, bufName);
2493 }
2494 
createExtBlock(extMeasure * m,dbBlock * mainBlock,Rect & extRect)2495 dbBlock* extWindow::createExtBlock(extMeasure* m, dbBlock* mainBlock,
2496                                    Rect& extRect) {
2497   uint nm = 1000;
2498 
2499   char design[128];
2500   char DIR[2] = {'V', 'H'};
2501 
2502   sprintf(design, "%c_%d_%d", DIR[_currentDir], _currentDir, _hiXY);
2503 
2504   dbBlock* block = dbBlock::create(mainBlock, design, '/');
2505   assert(block);
2506   block->setBusDelimeters('[', ']');
2507   block->setDefUnits(nm);
2508 
2509   block->setDieArea(extRect);
2510 
2511   dbIntProperty::create(block, "_num", _num);
2512   dbIntProperty::create(block, "_currentDir", _currentDir);
2513   dbIntProperty::create(block, "_extractLimit", _extractLimit);
2514   dbIntProperty::create(block, "_ccDist", _ccDist);
2515   dbIntProperty::create(block, "_maxPitch", _maxPitch);
2516   dbIntProperty::create(block, "_step_nm[0]", _step_nm[0]);
2517   dbIntProperty::create(block, "_step_nm[1]", _step_nm[1]);
2518   dbIntProperty::create(block, "_lo_gs[0]", _lo_gs[0]);
2519   dbIntProperty::create(block, "_lo_gs[1]", _lo_gs[1]);
2520   dbIntProperty::create(block, "_hi_gs[0]", _hi_gs[0]);
2521   dbIntProperty::create(block, "_hi_gs[1]", _hi_gs[1]);
2522   dbIntProperty::create(block, "_gs_limit", _gs_limit);
2523   dbIntProperty::create(block, "_ccDist", _ccDist);
2524   dbIntProperty::create(block, "_layerCnt", _layerCnt);
2525   dbIntProperty::create(block, "_hiXY", _hiXY);
2526 
2527   for (uint i = 0; i < 2; i++) {
2528     char bufName[64];
2529 
2530     sprintf(bufName, "_ll[%d]", i);
2531     dbIntProperty::create(block, bufName, _ll[i]);
2532 
2533     sprintf(bufName, "_ur[%d]", i);
2534     dbIntProperty::create(block, bufName, _ur[i]);
2535   }
2536 
2537   for (uint ii = 0; ii < _layerCnt; ii++) {
2538     char bufName[64];
2539     sprintf(bufName, "_extLimit[0]_%d", ii);
2540 
2541     dbIntProperty::create(block, bufName, _extLimit[0][ii]);
2542 
2543     sprintf(bufName, "_sdbBase[0]_%d", ii);
2544 
2545     dbIntProperty::create(block, bufName, _sdbBase[0][ii]);
2546 
2547     sprintf(bufName, "_sdbBase[1]_%d", ii);
2548 
2549     dbIntProperty::create(block, bufName, _sdbBase[1][ii]);
2550   }
2551   for (uint j = 0; j < 2; j++) {
2552     makeIntArrayProperty(block, j, _lo_sdb, "_lo_sdb");
2553     makeIntArrayProperty(block, j, _hi_sdb, "_hi_sdb");
2554   }
2555 
2556   return block;
2557 }
printLimits(FILE * fp,const char * header,uint maxLayer,int ** limitArray,int ** trackArray)2558 void extWindow::printLimits(FILE* fp, const char* header, uint maxLayer,
2559                             int** limitArray, int** trackArray) {
2560   fprintf(fp, "%s\n", header);
2561   for (uint ii = 1; ii < _layerCnt; ii++) {
2562     fprintf(fp, "\t%d - %d %d  - %d %d\n", ii, trackArray[0][ii],
2563             trackArray[1][ii], limitArray[0][ii], limitArray[1][ii]);
2564   }
2565 }
printExtLimits(FILE * fp)2566 void extWindow::printExtLimits(FILE* fp) {
2567   fprintf(fp, "Window[%d]: %d\n", _currentDir, _hiXY);
2568   printLimits(fp, "\nExt limits", _maxLayerCnt, _extLimit, _extTrack);
2569   printLimits(fp, "\nContext limits", _maxLayerCnt, _cntxLimit, _cntxTrack);
2570   fprintf(fp, "\n");
2571 }
2572 /*
2573 void extWindow::get_extractLimit(extWindow *e)
2574 {
2575         for (uint ii = 1; ii <_maxLayerCnt; ii++)
2576                 _extractLimit[ii]= e->_extractLimit[ii];
2577 }
2578 */
extWindow(uint maxLayerCnt,Logger * logger)2579 extWindow::extWindow(uint maxLayerCnt, Logger* logger) {
2580   logger_ = logger;
2581   init(maxLayerCnt);
2582 }
makeSdbBuckets(uint sdbBucketCnt[2],uint sdbBucketSize[2],int sdbTable_ll[2],int sdbTable_ur[2])2583 void extWindow::makeSdbBuckets(uint sdbBucketCnt[2], uint sdbBucketSize[2],
2584                                int sdbTable_ll[2], int sdbTable_ur[2]) {
2585   for (uint ii = 0; ii < 2; ii++) {
2586     sdbBucketCnt[ii] = 0;
2587     sdbBucketSize[ii] = 2 * _step_nm[ii];
2588     sdbTable_ll[ii] = _ll[ii] - _step_nm[ii] / 10;
2589     sdbTable_ur[ii] = _ur[ii] + _step_nm[ii] / 10;
2590   }
2591 }
printBoundaries(FILE * fp,bool flag)2592 void extWindow::printBoundaries(FILE* fp, bool flag) {
2593   if (!flag && fp == NULL)
2594     return;
2595 
2596   if (fp == NULL) {
2597     logger_->info(RCX, 238,
2598                   "{:15s}= {}"
2599                   "\t_currentDir\n"
2600                   "{:15s}= {} \t_hiXY\n"
2601                   "{:15s}= {} \t_lo_gs\n"
2602                   "{:15s}= {} \t_hi_gs\n"
2603                   "{:15s}= {} \t_lo_sdb\n"
2604                   "{:15s}= {} \t_hi_sdb\n"
2605                   "{:15s}= {} \t_gs_limit\n"
2606                   "{:15s}= {} \t_minExtracted\n"
2607                   "{:15s}= {} \t_deallocLimit",
2608                   _currentDir, _hiXY, _lo_gs[_currentDir], _hi_gs[_currentDir],
2609                   _lo_sdb[_currentDir], _hi_sdb[_currentDir], _gs_limit,
2610                   _minExtracted, _deallocLimit);
2611   } else {
2612     fprintf(fp, "\n%15s= %d\n", "_currentDir", _currentDir);
2613     fprintf(fp, "%15s= %d\n", "_hiXY", _hiXY);
2614     fprintf(fp, "%15s= %d\n", "_lo_gs", _lo_gs[_currentDir]);
2615     fprintf(fp, "%15s= %d\n", "_hi_gs", _hi_gs[_currentDir]);
2616     fprintf(fp, "%15s= %d\n", "_lo_sdb", _lo_sdb[_currentDir]);
2617     fprintf(fp, "%15s= %d\n", "_hi_sdb", _hi_sdb[_currentDir]);
2618     fprintf(fp, "%15s= %d\n", "_gs_limit", _gs_limit);
2619     fprintf(fp, "%15s= %d\n", "_minExtracted", _minExtracted);
2620     fprintf(fp, "%15s= %d\n\n", "_deallocLimit", _deallocLimit);
2621   }
2622 }
2623 
setExtBoundaries(uint dir)2624 int extWindow::setExtBoundaries(uint dir) {
2625   _currentDir = dir;
2626 
2627   _lo_gs[!dir] = _ll[!dir];
2628   _hi_gs[!dir] = _ur[!dir];
2629   _lo_sdb[!dir] = _ll[!dir];
2630   _hi_sdb[!dir] = _ur[!dir];
2631 
2632   _minExtracted = _ll[dir];
2633   _gs_limit = _ll[dir];
2634 
2635   _lo_sdb[dir] = _ll[dir] - _step_nm[dir];
2636 
2637   _hiXY = _ll[dir] + _step_nm[dir];
2638   if (_hiXY > _ur[dir])
2639     _hiXY = _ur[dir];
2640 
2641   if (dir == 0)
2642     _gsRotatedFlag = true;
2643 
2644   if (_gsRotatedFlag)
2645     logger_->info(RCX, 93, "======> Fast Mode enabled for d= {} <======", dir);
2646 
2647   return _hiXY;
2648 }
adjust_hiXY(int hiXY)2649 int extWindow::adjust_hiXY(int hiXY) {
2650   _hiXY = hiXY;
2651 
2652   if (_ur[_currentDir] - _hiXY <= (int)_step_nm[_currentDir])
2653     _hiXY = _ur[_currentDir] + 5 * _ccDist * _maxPitch;
2654 
2655   _hi_sdb[_currentDir] = _hiXY;
2656 
2657   _lo_gs[_currentDir] = _gs_limit;
2658   _hi_gs[_currentDir] = _hiXY;
2659 
2660   return _hiXY;
2661 }
fillWindowGs(extWindow * W,int * sdbTable_ll,int * sdbTable_ur,uint * bucketSize,Ath__array1D<uint> * powerNetTable,Ath__array1D<uint> * tmpNetIdTable,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> *** instGsTable,dbCreateNetUtil * createDbNet)2662 void extMain::fillWindowGs(extWindow* W, int* sdbTable_ll, int* sdbTable_ur,
2663                            uint* bucketSize, Ath__array1D<uint>* powerNetTable,
2664                            Ath__array1D<uint>* tmpNetIdTable,
2665                            Ath__array1D<uint>*** sdbSignalTable,
2666                            Ath__array1D<uint>*** instGsTable,
2667                            dbCreateNetUtil* createDbNet) {
2668   if (sdbSignalTable != NULL) {
2669     tmpNetIdTable->resetCnt();
2670     fill_gs3(W->_currentDir, W->_ll, W->_ur, W->_ll, W->_ur, W->_layerCnt,
2671              //		fill_gs3(W->_currentDir, W->_ll, W->_ur, W->_lo_gs,
2672              // W->_hi_gs, W->_layerCnt,
2673              W->_dirTable, W->_pitchTable, W->_widthTable, sdbTable_ll,
2674              sdbTable_ur, bucketSize, powerNetTable, tmpNetIdTable,
2675              sdbSignalTable, instGsTable, createDbNet);
2676   } else {
2677     fill_gs4(W->_currentDir, W->_ll, W->_ur, W->_lo_gs, W->_hi_gs, W->_layerCnt,
2678              W->_dirTable, W->_pitchTable, W->_widthTable, createDbNet);
2679   }
2680 }
fillWindowSearch(extWindow * W,int * lo_sdb,int * hi_sdb,int * sdbTable_ll,int * sdbTable_ur,uint * bucketSize,Ath__array1D<uint> * powerNetTable,Ath__array1D<uint> * tmpNetIdTable,Ath__array1D<uint> *** sdbSignalTable,dbCreateNetUtil * createDbNet)2681 uint extMain::fillWindowSearch(extWindow* W, int* lo_sdb, int* hi_sdb,
2682                                int* sdbTable_ll, int* sdbTable_ur,
2683                                uint* bucketSize,
2684                                Ath__array1D<uint>* powerNetTable,
2685                                Ath__array1D<uint>* tmpNetIdTable,
2686                                Ath__array1D<uint>*** sdbSignalTable,
2687                                dbCreateNetUtil* createDbNet) {
2688   int ll[2] = {lo_sdb[0], lo_sdb[1]};
2689   int ur[2] = {hi_sdb[0], hi_sdb[1]};
2690   //	ll[W->_currentDir]= W->_gs_limit;
2691   //	ur[W->_currentDir]= W->_hiXY;
2692 
2693   /*
2694   for (uint i= 0; i<2; i++) {
2695           ll[i]= W->_ll[i];
2696           ur[i]= W->_ur[i];
2697   }
2698   */
2699   char bufname[32];
2700   sprintf(bufname, "BOUNDS/%d_%d.sdb", W->_currentDir, W->_hiXY);
2701   openSearchFile(bufname);
2702 
2703   if (sdbSignalTable != NULL) {
2704     W->_processPowerWireCnt = addPowerNets2(W->_currentDir, ll, ur, W->_pwrtype,
2705                                             powerNetTable, createDbNet);
2706     tmpNetIdTable->resetCnt();
2707     W->_processSignalWireCnt = addSignalNets2(
2708         W->_currentDir, ll, ur, sdbTable_ll, sdbTable_ur, bucketSize,
2709         W->_sigtype, sdbSignalTable, tmpNetIdTable, createDbNet);
2710   } else {
2711     uint processWireCnt =
2712         addPowerNets(W->_currentDir, ll, ur, W->_pwrtype, createDbNet);
2713     processWireCnt +=
2714         addSignalNets(W->_currentDir, ll, ur, W->_sigtype, createDbNet);
2715     // uint processWireCnt += addPowerNets(dir, lo_sdb, hi_sdb, pwrtype);
2716     // processWireCnt += addSignalNets(dir, lo_sdb, hi_sdb, sigtype);
2717   }
2718   closeSearchFile();
2719 
2720   return W->_processPowerWireCnt + W->_processSignalWireCnt;
2721 }
set_extractLimit()2722 int extWindow::set_extractLimit() {
2723   _extractLimit = _hiXY - _ccDist * _maxPitch;
2724 
2725   return _extractLimit;
2726 }
reportProcessedWires(bool rlog)2727 void extWindow::reportProcessedWires(bool rlog) {
2728   if (rlog) {
2729     char buff[64];
2730     sprintf(buff, "CCext %d wires xy[%d]= %d ",
2731             _processPowerWireCnt + _processSignalWireCnt, _currentDir,
2732             _minExtracted);
2733 #ifdef _WIN32
2734     logger_->info(RCX, 214, "{}", buff);
2735 #endif
2736     AthResourceLog(buff, 0);
2737   }
2738 }
getDeallocLimit()2739 int extWindow::getDeallocLimit() {
2740   _deallocLimit = _minExtracted - (_ccDist + 1) * _maxPitch;
2741   return _deallocLimit;
2742 }
updateLoBounds(bool reportFlag)2743 void extWindow::updateLoBounds(bool reportFlag) {
2744   _lo_sdb[_currentDir] = _hiXY;
2745   _gs_limit = _minExtracted - (_ccDist + 2) * _maxPitch;
2746 
2747   _totalWiresExtracted += _processPowerWireCnt + _processSignalWireCnt;
2748   if (!reportFlag)
2749     return;
2750 
2751   double percent_extracted =
2752       (int)(100.0 * (1.0 * _totalWiresExtracted / _totWireCnt));
2753 
2754   if ((_totWireCnt > 0) && (_totalWiresExtracted > 0)) {
2755     logger_->info(RCX, 441,
2756                   "{:d}% completion -- {:d} wires have been extracted",
2757                   (int)(100.0 * (1.0 * _totalWiresExtracted / _totWireCnt)),
2758                   _totalWiresExtracted);
2759 
2760     _prev_percent_extracted = percent_extracted;
2761   }
2762 }
mkNetPropertiesForRsegs(dbBlock * blk,uint dir)2763 uint extMain::mkNetPropertiesForRsegs(dbBlock* blk, uint dir) {
2764   dbSet<dbNet> nets = blk->getNets();
2765   dbSet<dbNet>::iterator net_itr;
2766 
2767   uint cnt = 0;
2768   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
2769     dbNet* net = *net_itr;
2770 
2771     if ((net->getSigType().isSupply()))
2772       continue;
2773 
2774     dbWire* wire = net->getWire();
2775     dbWireShapeItr shapes;
2776     dbShape s;
2777     for (shapes.begin(wire); shapes.next(s);) {
2778       if (s.isVia())
2779         continue;
2780 
2781       int n = shapes.getShapeId();
2782       if (n == 0)
2783         continue;
2784 
2785       Rect r;
2786       s.getBox(r);
2787 
2788       if (!matchDir(dir, r)) {
2789         wire->setProperty(n, 0);
2790         continue;
2791       }
2792 
2793       int rsegId1 = 0;
2794       wire->getProperty(n, rsegId1);
2795       if (rsegId1 == 0)
2796         continue;
2797 
2798       char bufName[16];
2799       sprintf(bufName, "J%d", n);
2800       dbIntProperty::create(net, bufName, rsegId1);
2801       wire->setProperty(n, 0);
2802       cnt++;
2803     }
2804   }
2805   return cnt;
2806 }
invalidateNonDirShapes(dbBlock * blk,uint dir,bool setMainNet)2807 uint extMain::invalidateNonDirShapes(dbBlock* blk, uint dir, bool setMainNet) {
2808   Ath__parser parser;
2809 
2810   Ath__array1D<dbRSeg*> rsegTable;
2811 
2812   dbSet<dbNet> nets = blk->getNets();
2813   dbSet<dbNet>::iterator net_itr;
2814 
2815   uint cnt = 0;
2816   uint tot = 0;
2817   uint dCnt = 0;
2818   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
2819     dbNet* net = *net_itr;
2820 
2821     if ((net->getSigType().isSupply()))
2822       continue;
2823 
2824     int dstNetId = 0;
2825     if (setMainNet) {
2826       parser.mkWords(net->getConstName());
2827       dstNetId = parser.getInt(0, 1);
2828     }
2829 
2830     dbWire* wire = net->getWire();
2831     dbWireShapeItr shapes;
2832     dbShape s;
2833     for (shapes.begin(wire); shapes.next(s);) {
2834       if (s.isVia())
2835         continue;
2836 
2837       int shapeId = shapes.getShapeId();
2838       if (shapeId == 0)
2839         continue;
2840 
2841       Rect r;
2842       s.getBox(r);
2843 
2844       int rsegId1 = 0;
2845       wire->getProperty(shapeId, rsegId1);
2846       if (rsegId1 == 0)
2847         continue;
2848 
2849       dbRSeg* rseg1 = dbRSeg::getRSeg(blk, rsegId1);
2850       if (rseg1 == NULL) {
2851         logger_->warn(RCX, 94,
2852                       "GndCap: cannot find rseg for net [{}] {} and shapeId {}",
2853                       net->getId(), net->getConstName(), shapeId);
2854         continue;
2855       }
2856       tot++;
2857       if (!matchDir(dir, r)) {
2858         wire->setProperty(shapeId, 0);
2859         rsegTable.add(rseg1);
2860         continue;
2861       }
2862 
2863       if (!rseg1->updatedCap()) {  // context
2864         wire->setProperty(shapeId, 0);
2865         rsegTable.add(rseg1);
2866       } else {
2867         if (setMainNet) {
2868           dbCapNode* node = rseg1->getTargetCapNode();
2869           // node->setNetId(dstNetId);
2870 
2871           char bufName[16];
2872           sprintf(bufName, "J%d", shapeId);
2873           dbProperty* p = dbProperty::find(net, bufName);
2874           uint rsegId2 = 0;
2875           if (p == NULL) {
2876             rsegId2 = 0;
2877           } else {
2878             dbIntProperty* ip = (dbIntProperty*)p;
2879             rsegId2 = ip->getValue();
2880           }
2881           node->setNode(rsegId2);
2882         }
2883         cnt++;
2884       }
2885     }
2886     uint destroySegCnt = rsegTable.getCnt();
2887     dCnt += destroySegCnt;
2888     for (uint ii = 0; ii < destroySegCnt; ii++) {
2889       dbRSeg* rc = rsegTable.get(ii);
2890       dbCapNode* node = rc->getTargetCapNode();
2891       dbCapNode::destroy(node);
2892       dbRSeg::destroy(rc, net);
2893     }
2894     rsegTable.resetCnt();
2895   }
2896   logger_->info(RCX, 95,
2897                 "Deleted {} Rsegs/CapNodes from total {} with {} remaing", dCnt,
2898                 tot, cnt);
2899   return cnt;
2900 }
createNetShapePropertires(dbBlock * blk)2901 uint extMain::createNetShapePropertires(dbBlock* blk) {
2902   dbSet<dbNet> nets = blk->getNets();
2903   dbSet<dbNet>::iterator net_itr;
2904 
2905   uint cnt = 0;
2906   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
2907     dbNet* net = *net_itr;
2908 
2909     if ((net->getSigType().isSupply()))
2910       continue;
2911 
2912     // uint netId= net->getId();
2913 
2914     dbWirePath path;
2915     dbWirePathShape pshape;
2916 
2917     dbWirePathItr pitr;
2918     dbWire* wire = net->getWire();
2919 
2920     for (pitr.begin(wire); pitr.getNextPath(path);) {
2921       pitr.getNextShape(pshape);
2922       uint n = pshape.junction_id;
2923 
2924       int map = 0;
2925       wire->getProperty(n, map);
2926       if (map > 0) {
2927         char bufName[16];
2928         sprintf(bufName, "J%d", n);
2929         dbIntProperty::create(net, bufName, map);
2930         wire->setProperty(n, 0);
2931       }
2932       cnt++;
2933     }
2934   }
2935   return cnt;
2936 }
rcGenTile(dbBlock * blk)2937 uint extMain::rcGenTile(dbBlock* blk) {
2938   Ath__parser parser;
2939 
2940   dbSet<dbNet> nets = blk->getNets();
2941   dbSet<dbNet>::iterator net_itr;
2942 
2943   uint cnt = 0;
2944   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
2945     dbNet* net = *net_itr;
2946 
2947     if ((net->getSigType().isSupply()))
2948       continue;
2949 
2950     // uint netId= net->getId();
2951 
2952     dbNet* mainNet = getDstNet(net, _block, &parser);
2953 
2954     if (mainNet->isRCgraph())
2955       continue;
2956 
2957     cnt += rcNetGen(mainNet);
2958   }
2959   return cnt;
2960 }
2961 
couplingWindowFlow(bool rlog,Rect & extRect,uint trackStep,uint ccFlag,bool doExt,extMeasure * m,CoupleAndCompute coupleAndCompute)2962 uint extMain::couplingWindowFlow(bool rlog, Rect& extRect, uint trackStep,
2963                                  uint ccFlag, bool doExt, extMeasure* m,
2964                                  CoupleAndCompute coupleAndCompute) {
2965   bool single_gs = false;
2966 
2967   extWindow* W = initWindowSearch(extRect, trackStep, ccFlag,
2968                                   _currentModel->getLayerCnt(), m);
2969 
2970   Ath__overlapAdjust overlapAdj = Z_noAdjust;
2971   _useDbSdb = true;
2972   _search->setExtControl(
2973       _block, _useDbSdb, (uint)overlapAdj, _CCnoPowerSource, _CCnoPowerTarget,
2974       _ccUp, _allNet, _ccContextDepth, _ccContextArray, _ccContextLength,
2975       _dgContextArray, &_dgContextDepth, &_dgContextPlanes, &_dgContextTracks,
2976       &_dgContextBaseLvl, &_dgContextLowLvl, &_dgContextHiLvl,
2977       _dgContextBaseTrack, _dgContextLowTrack, _dgContextHiTrack,
2978       _dgContextTrackBase, m->_seqPool);
2979 
2980   _seqPool = m->_seqPool;
2981 
2982   // _use_signal_tables^M
2983   Ath__array1D<uint>** sdbSignalTable[2];
2984   Ath__array1D<uint>** gsInstTable[2];
2985   Ath__array1D<uint> sdbPowerTable;
2986   Ath__array1D<uint> tmpNetIdTable(64000);
2987   uint sdbBucketCnt[2];
2988   uint sdbBucketSize[2];
2989   int sdbTable_ll[2];
2990   int sdbTable_ur[2];
2991 
2992   bool use_signal_tables = false;
2993   if ((_use_signal_tables == 1) || (_use_signal_tables == 2)) {
2994     use_signal_tables = true;
2995 
2996     W->makeSdbBuckets(sdbBucketCnt, sdbBucketSize, sdbTable_ll, sdbTable_ur);
2997 
2998     // mkSignalTables(sdbBucketSize, sdbTable_ll, sdbTable_ur, sdbSignalTable,
2999     // NULL, gsInstTable, sdbBucketCnt);
3000     mkSignalTables2(sdbBucketSize, sdbTable_ll, sdbTable_ur, sdbSignalTable,
3001                     &sdbPowerTable, gsInstTable, sdbBucketCnt);
3002 
3003     reportTableNetCnt(sdbBucketCnt, sdbSignalTable);
3004 #ifdef TEST_SIGNAL_TABLE
3005     reportTableNetCnt(sdbBucketCnt, sdbSignalTable);
3006 #endif
3007 
3008     if (rlog)
3009       AthResourceLog("Making net tables ", 0);
3010   }
3011   uint totalWiresExtracted = 0;
3012 
3013   FILE* boundFP = fopen("window.bounds", "w");
3014   FILE* limitFP = fopen("window.limits", "w");
3015 
3016   extWindow* windowTable[1000];
3017   // extWindow **windowTable= allocWindowTable();
3018   uint windowCnt = 0;
3019 
3020   int** limitArray;
3021   limitArray = new int* [W->_layerCnt];
3022   for (uint k = 0; k < W->_layerCnt; k++)
3023     limitArray[k] = new int[10];
3024 
3025   for (int dir = 1; dir >= 0; dir--) {
3026     if (dir == 0)
3027       enableRotatedFlag();
3028     else
3029       disableRotatedFlag();
3030 
3031     _search->initCouplingCapLoops(dir, ccFlag, coupleAndCompute, m);
3032     if (rlog)
3033       AthResourceLog("initCouplingCapLoops", 0);
3034 
3035     uint stepNum = 0;
3036     int hiXY = W->setExtBoundaries(dir);
3037     for (; hiXY <= W->_ur[dir]; hiXY += W->_step_nm[dir]) {
3038       hiXY = W->adjust_hiXY(hiXY);
3039 
3040       uint extractedWireCnt = 0;
3041       W->set_extractLimit();
3042       W->_minExtracted = _search->couplingCaps(
3043           W->_extractLimit, W->_ccDist, W->_currentDir, extractedWireCnt,
3044           coupleAndCompute, m, _getBandWire, limitArray);
3045 
3046       // W->reportProcessedWires(rlog);
3047 
3048       int deallocLimit = W->getDeallocLimit();
3049       _search->dealloc(W->_currentDir, deallocLimit);
3050 
3051       // W->printBoundaries(boundFP, true);
3052 
3053       stepNum++;
3054 
3055       W->updateExtLimits(limitArray);
3056       windowTable[windowCnt] = new extWindow(W, windowCnt, logger_);
3057       windowTable[windowCnt]->printBoundaries(boundFP, true);
3058       windowCnt++;
3059 
3060       W->updateLoBounds(false /*report*/);
3061 
3062       W->printExtLimits(limitFP);
3063     }
3064   }
3065   fclose(boundFP);
3066   fclose(limitFP);
3067 
3068   bool single_sdb = false;
3069 
3070   if (single_sdb) {
3071     uint layerCnt =
3072         initSearchForNets(W->_sdbBase[0], W->_sdbBase[1], W->_pitchTable,
3073                           W->_widthTable, W->_dirTable, extRect, true);
3074     for (uint i = 0; i < layerCnt + 1; i++)
3075       m->_dirTable[i] = W->_dirTable[i];
3076 
3077     _useDbSdb = true;
3078     _search->setExtControl(
3079         _block, _useDbSdb, (uint)overlapAdj, _CCnoPowerSource, _CCnoPowerTarget,
3080         _ccUp, _allNet, _ccContextDepth, _ccContextArray, _ccContextLength,
3081         _dgContextArray, &_dgContextDepth, &_dgContextPlanes, &_dgContextTracks,
3082         &_dgContextBaseLvl, &_dgContextLowLvl, &_dgContextHiLvl,
3083         _dgContextBaseTrack, _dgContextLowTrack, _dgContextHiTrack,
3084         _dgContextTrackBase, m->_seqPool);
3085 
3086     _seqPool = m->_seqPool;
3087   }
3088 
3089   // uint prevDir= 10;
3090   bool useSdbTable = true;
3091 
3092   FILE* bndFP = fopen("window.bounds.new", "w");
3093   FILE* limFP = fopen("window.limits.after", "w");
3094 
3095   bool extractionFlag = doExt;
3096   bool skipInit = false;
3097   for (int jj = 0; jj < windowCnt; jj++) {
3098     extWindow* w = windowTable[jj];
3099 
3100     // if (W->_currentDir==1)
3101     //	continue;
3102 
3103     w->printExtLimits(limFP);
3104 
3105     if (w->_currentDir == 0)
3106       enableRotatedFlag();
3107     else
3108       disableRotatedFlag();
3109 
3110     if (!extractionFlag) {
3111       dbBlock* extBlock = w->createExtBlock(m, _block, extRect);
3112       m->_create_net_util.setBlock(extBlock, skipInit);
3113       if (!skipInit)
3114         skipInit = true;
3115 
3116       fillWindowGs(w, sdbTable_ll, sdbTable_ur, sdbBucketSize, &sdbPowerTable,
3117                    &tmpNetIdTable, sdbSignalTable, gsInstTable,
3118                    &m->_create_net_util);
3119 
3120       uint processWireCnt = fillWindowSearch(
3121           w, w->_lo_sdb, w->_hi_sdb, sdbTable_ll, sdbTable_ur, sdbBucketSize,
3122           &sdbPowerTable, &tmpNetIdTable, sdbSignalTable, &m->_create_net_util);
3123 
3124       uint signalWireCnt = createNetShapePropertires(extBlock);
3125       logger_->info(RCX, 471, "Block {} has {} signal wires",
3126                     extBlock->getConstName(), processWireCnt);
3127 
3128       continue;
3129       // break;
3130     }
3131 
3132     extractWindow(rlog, W, extRect, single_sdb, m, coupleAndCompute,
3133                   sdbTable_ll, sdbTable_ur, sdbBucketSize, &sdbPowerTable,
3134                   &tmpNetIdTable, sdbSignalTable, gsInstTable);
3135 
3136     break;
3137   }
3138   fclose(bndFP);
3139   fclose(limFP);
3140 
3141   if (use_signal_tables) {
3142     freeSignalTables(true, sdbSignalTable, NULL, sdbBucketCnt);
3143   }
3144 
3145   if (_geomSeq != NULL) {
3146     delete _geomSeq;
3147     _geomSeq = NULL;
3148   }
3149   return 0;
3150 }
3151 
extractWindow(bool rlog,extWindow * W,Rect & extRect,bool single_sdb,extMeasure * m,CoupleAndCompute coupleAndCompute,int * sdbTable_ll,int * sdbTable_ur,uint * sdbBucketSize,Ath__array1D<uint> * sdbPowerTable,Ath__array1D<uint> * tmpNetIdTable,Ath__array1D<uint> *** sdbSignalTable,Ath__array1D<uint> *** gsInstTable)3152 uint extMain::extractWindow(bool rlog, extWindow* W, Rect& extRect,
3153                             bool single_sdb, extMeasure* m,
3154                             CoupleAndCompute coupleAndCompute, int* sdbTable_ll,
3155                             int* sdbTable_ur, uint* sdbBucketSize,
3156                             Ath__array1D<uint>* sdbPowerTable,
3157                             Ath__array1D<uint>* tmpNetIdTable,
3158                             Ath__array1D<uint>*** sdbSignalTable,
3159                             Ath__array1D<uint>*** gsInstTable) {
3160   /*
3161   char bufname[128];
3162   sprintf(bufname, "BOUNDS/%d_%d.limits", W->_currentDir, W->_hiXY);
3163   FILE *limFP= fopen(bufname, "w");
3164   sprintf(bufname, "BOUNDS/%d_%d.bounds", W->_currentDir, W->_hiXY);
3165   FILE *bndFP= fopen(bufname, "w");
3166   */
3167   int** limitArray;
3168   limitArray = new int* [W->_layerCnt];
3169   for (uint k = 0; k < W->_layerCnt; k++)
3170     limitArray[k] = new int[10];
3171 
3172   uint prevDir = 10;
3173 
3174   //	if (W->_num!=0)
3175   //		return 1;
3176 
3177   disableRotatedFlag();
3178   if (W->_currentDir == 0)
3179     enableRotatedFlag();
3180 
3181   if (single_sdb) {
3182     uint layerCnt =
3183         initSearchForNets(W->_sdbBase[0], W->_sdbBase[1], W->_pitchTable,
3184                           W->_widthTable, W->_dirTable, extRect, true);
3185     for (uint i = 0; i < layerCnt + 1; i++)
3186       m->_dirTable[i] = W->_dirTable[i];
3187 
3188     _search->initCouplingCapLoops(W->_currentDir, W->_ccDist, coupleAndCompute,
3189                                   m, W->_extLimit[0]);
3190     /*
3191     if (W->_currentDir!=prevDir) {
3192             _search->initCouplingCapLoops(W->_currentDir, W->_ccDist,
3193     coupleAndCompute, m); prevDir= W->_currentDir;
3194     }
3195     */
3196   } else {
3197     uint layerCnt =
3198         initSearchForNets(W->_sdbBase[0], W->_sdbBase[1], W->_pitchTable,
3199                           W->_widthTable, W->_dirTable, extRect, true);
3200     for (uint i = 0; i < layerCnt + 1; i++)
3201       m->_dirTable[i] = W->_dirTable[i];
3202 
3203     Ath__overlapAdjust overlapAdj = Z_noAdjust;
3204     _useDbSdb = true;
3205     _search->setExtControl(
3206         _block, _useDbSdb, (uint)overlapAdj, _CCnoPowerSource, _CCnoPowerTarget,
3207         _ccUp, _allNet, _ccContextDepth, _ccContextArray, _ccContextLength,
3208         _dgContextArray, &_dgContextDepth, &_dgContextPlanes, &_dgContextTracks,
3209         &_dgContextBaseLvl, &_dgContextLowLvl, &_dgContextHiLvl,
3210         _dgContextBaseTrack, _dgContextLowTrack, _dgContextHiTrack,
3211         _dgContextTrackBase, m->_seqPool);
3212     /*
3213                     if (W->_currentDir!=prevDir) {
3214                             _search->initCouplingCapLoops(W->_currentDir,
3215        W->_ccDist, coupleAndCompute, m); prevDir= W->_currentDir;
3216                     }
3217                     else
3218     */
3219     _search->initCouplingCapLoops(W->_currentDir, W->_ccDist, coupleAndCompute,
3220                                   m, W->_extLimit[0]);
3221   }
3222 
3223   if (rlog)
3224     AthResourceLog("initCouplingCapLoops", 0);
3225 
3226   fillWindowGs(W, sdbTable_ll, sdbTable_ur, sdbBucketSize, sdbPowerTable,
3227                tmpNetIdTable, sdbSignalTable, gsInstTable);
3228 
3229   uint processWireCnt = fillWindowSearch(
3230       W, W->_lo_sdb, W->_hi_sdb, sdbTable_ll, sdbTable_ur, sdbBucketSize,
3231       sdbPowerTable, tmpNetIdTable, sdbSignalTable);
3232 
3233   if (rlog)
3234     AthResourceLog("Fill GS", 0);
3235 
3236   m->_rotatedGs = getRotatedFlag();
3237   m->_pixelTable = _geomSeq;
3238 
3239   if (rlog)
3240     AthResourceLog("Fill Sdb", 0);
3241 
3242   // W->printExtLimits(limFP);
3243   // W->printBoundaries(bndFP, true);
3244 
3245   uint extractedWireCnt = 0;
3246   _search->couplingCaps(W->_extractLimit, W->_ccDist, W->_currentDir,
3247                         extractedWireCnt, coupleAndCompute, m, false,
3248                         limitArray);
3249   // printLimitArray(limitArray, W->_layerCnt);
3250 
3251   W->reportProcessedWires(true);
3252 
3253   _search->dealloc(W->_currentDir, W->_deallocLimit);
3254 
3255   // W->printBoundaries(bndFP, true);
3256 
3257   W->updateExtLimits(limitArray);
3258   //	W->printExtLimits(limFP);
3259   //	fclose(limFP);
3260   //	fclose(bndFP);
3261 
3262   return 0;
3263 }
getDstNet(dbNet * net,dbBlock * dstBlock,Ath__parser * parser)3264 dbNet* extMain::getDstNet(dbNet* net, dbBlock* dstBlock, Ath__parser* parser) {
3265   parser->mkWords(net->getConstName());
3266   int dstNetId = parser->getInt(0, 1);
3267   dbNet* dstNet = dbNet::getNet(dstBlock, dstNetId);
3268   return dstNet;
3269 }
getMainRSeg3(dbNet * srcNet,int srcShapeId,dbNet * dstNet)3270 dbRSeg* extMain::getMainRSeg3(dbNet* srcNet, int srcShapeId, dbNet* dstNet) {
3271   char bufName[16];
3272   sprintf(bufName, "J%d", srcShapeId);
3273   dbProperty* p = dbProperty::find(srcNet, bufName);
3274   if (p == NULL)
3275     return NULL;
3276 
3277   dbIntProperty* ip = (dbIntProperty*)p;
3278   uint rsegId2 = ip->getValue();
3279 
3280   if (rsegId2 == 0)
3281     return NULL;
3282 
3283   dbRSeg* rseg2 = dbRSeg::getRSeg(dstNet->getBlock(), rsegId2);
3284 
3285   return rseg2;
3286 }
getMainRSeg(dbNet * srcNet,int srcShapeId,dbNet * dstNet)3287 dbRSeg* extMain::getMainRSeg(dbNet* srcNet, int srcShapeId, dbNet* dstNet) {
3288   char bufName[16];
3289   sprintf(bufName, "J%d", srcShapeId);
3290   dbProperty* p = dbProperty::find(srcNet, bufName);
3291   if (p == NULL)
3292     return NULL;
3293 
3294   dbIntProperty* ip = (dbIntProperty*)p;
3295   uint jid2 = ip->getValue();
3296 
3297   int rsegId2 = 0;
3298   dstNet->getWire()->getProperty(jid2, rsegId2);
3299   if (rsegId2 == 0)
3300     return NULL;
3301 
3302   dbRSeg* rseg2 = dbRSeg::getRSeg(dstNet->getBlock(), rsegId2);
3303 
3304   return rseg2;
3305 }
getMainRSeg2(dbNet * srcNet,int srcShapeId,dbNet * dstNet)3306 dbRSeg* extMain::getMainRSeg2(dbNet* srcNet, int srcShapeId, dbNet* dstNet) {
3307   int rsegId2 = 0;
3308   dstNet->getWire()->getProperty(srcShapeId, rsegId2);
3309   if (rsegId2 == 0)
3310     return NULL;
3311 
3312   dbRSeg* rseg2 = dbRSeg::getRSeg(dstNet->getBlock(), rsegId2);
3313 
3314   return rseg2;
3315 }
getRseg(dbNet * net,uint shapeId,Logger * logger)3316 dbRSeg* extMain::getRseg(dbNet* net, uint shapeId, Logger* logger) {
3317   int rsegId2 = 0;
3318   net->getWire()->getProperty(shapeId, rsegId2);
3319   if (rsegId2 == 0) {
3320     logger->warn(RCX, 239, "Zero rseg wire property {} on main net {} {}",
3321                  shapeId, net->getId(), net->getConstName());
3322     return NULL;
3323   }
3324   dbRSeg* rseg2 = dbRSeg::getRSeg(net->getBlock(), rsegId2);
3325 
3326   if (rseg2 == NULL) {
3327     logger->warn(RCX, 240,
3328                  "GndCap: cannot find rseg for rsegId {} on net {} {}", rsegId2,
3329                  net->getId(), net->getConstName());
3330     return NULL;
3331   }
3332   return rseg2;
3333 }
3334 
assemblyExt(dbBlock * mainBlock,dbBlock * blk,Logger * logger)3335 uint extMain::assemblyExt(dbBlock* mainBlock, dbBlock* blk, Logger* logger) {
3336   if (mainBlock != NULL)
3337     return assemblyExt__2(mainBlock, blk, logger);
3338   else {  // block based
3339     dbSet<dbCapNode> capNodes = blk->getCapNodes();
3340     uint csize = capNodes.size();
3341 
3342     uint gndCnt = 0;
3343     dbSet<dbCapNode>::iterator cap_node_itr = capNodes.begin();
3344     for (; cap_node_itr != capNodes.end(); ++cap_node_itr) {
3345       dbCapNode* node = *cap_node_itr;
3346       node->addToNet();
3347       gndCnt++;
3348     }
3349     logger->info(RCX, 241, "{} nodes on block {}", gndCnt, blk->getConstName());
3350     if (csize != gndCnt)
3351       logger->info(RCX, 242, "\tdifferent from {} cap nodes read", csize);
3352 
3353     dbSet<dbRSeg> rsegs = blk->getRSegs();
3354     uint rsize = rsegs.size();
3355 
3356     dbNet* net = NULL;
3357     uint rCnt = 0;
3358     dbSet<dbRSeg>::iterator rseg_itr = rsegs.begin();
3359     for (; rseg_itr != rsegs.end(); ++rseg_itr) {
3360       rCnt++;
3361       dbRSeg* rseg = *rseg_itr;
3362       uint tgtId = rseg->getTargetNode();
3363       uint srcId = rseg->getSourceNode();
3364       if ((srcId == 0) && (tgtId == rseg->getId())) {  // new net
3365         if (net != NULL) {
3366           dbSet<dbRSeg> rSet = net->getRSegs();
3367           rSet.reverse();
3368         }
3369         net = rseg->getNet();
3370       }
3371       rseg->addToNet();
3372     }
3373     if (net != NULL) {
3374       dbSet<dbRSeg> rSet = net->getRSegs();
3375       rSet.reverse();
3376     }
3377     logger->info(RCX, 243, "{} rsegs on block {}", rCnt, blk->getConstName());
3378     if (rsize != rCnt)
3379       logger->info(RCX, 244, "Different from {} rsegs read", rsize);
3380     return rCnt;
3381   }
3382 }
getMainRseg(dbCapNode * node,dbBlock * blk,Ath__parser * parser,Logger * logger)3383 dbRSeg* extMain::getMainRseg(dbCapNode* node, dbBlock* blk, Ath__parser* parser,
3384                              Logger* logger) {
3385   if (parser != NULL) {
3386     dbNet* mainNet = getDstNet(node->getNet(), blk, parser);
3387 
3388     if (mainNet == NULL) {
3389       logger->warn(RCX, 479, "CCap: cannot find main net for {}",
3390                    node->getNet()->getConstName());
3391       return NULL;
3392     }
3393     dbRSeg* rseg = getMainRSeg3(node->getNet(), node->getShapeId(), mainNet);
3394     if (rseg == NULL) {
3395       logger->warn(RCX, 246, "CCap: cannot find rseg for net for {}",
3396                    node->getNet()->getConstName());
3397       return NULL;
3398     }
3399     return rseg;
3400   } else {
3401     // uint netId= node->getNetId();
3402     uint rsegId = node->getShapeId();
3403     if (rsegId == 0) {
3404       logger->warn(RCX, 247, "CCap: cannot find rseg for capNode {}",
3405                    node->getId());
3406       return NULL;
3407     }
3408     dbRSeg* rseg = dbRSeg::getRSeg(blk, rsegId);
3409     if (rseg == NULL) {
3410       logger->warn(RCX, 248, "CCap: cannot find rseg {}", rsegId);
3411       return NULL;
3412     }
3413     return rseg;
3414   }
3415 }
updateRseg(dbRSeg * rseg1,dbRSeg * rseg2,uint cornerCnt)3416 void extMain::updateRseg(dbRSeg* rseg1, dbRSeg* rseg2, uint cornerCnt) {
3417   double gndCapTable1[10];
3418   rseg1->getCapTable(gndCapTable1);
3419 
3420   double gndCapTable2[10];
3421   rseg2->getCapTable(gndCapTable2);
3422 
3423   for (uint ii = 0; ii < cornerCnt; ii++) {
3424     double cap = gndCapTable1[ii] + gndCapTable2[ii];
3425     rseg2->setCapacitance(cap, ii);
3426   }
3427 }
assembly_RCs(dbBlock * mainBlock,dbBlock * blk,uint cornerCnt,Logger * logger)3428 uint extMain::assembly_RCs(dbBlock* mainBlock, dbBlock* blk, uint cornerCnt,
3429                            Logger* logger) {
3430   uint rcCnt = 0;
3431 
3432   Ath__parser p;
3433   Ath__parser* parser = NULL;
3434 
3435   dbSet<dbRSeg> rcSegs = blk->getRSegs();
3436   dbSet<dbRSeg>::iterator rcitr;
3437 
3438   for (rcitr = rcSegs.begin(); rcitr != rcSegs.end(); ++rcitr) {
3439     dbRSeg* rseg1 = *rcitr;
3440     if (!rseg1->updatedCap())
3441       continue;
3442 
3443     dbRSeg* rseg2 =
3444         getMainRseg(rseg1->getTargetCapNode(), mainBlock, parser, logger);
3445 
3446     if (rseg2 == NULL)
3447       continue;
3448 
3449     uint rsgeId1 = rseg1->getId();
3450     updateRseg(rseg1, rseg2, cornerCnt);
3451 
3452     rcCnt++;
3453   }
3454   return rcCnt;
3455 }
3456 
assemblyCCs(dbBlock * mainBlock,dbBlock * blk,uint cornerCnt,uint & missCCcnt,Logger * logger)3457 uint extMain::assemblyCCs(dbBlock* mainBlock, dbBlock* blk, uint cornerCnt,
3458                           uint& missCCcnt, Logger* logger) {
3459   uint ccCnt = 0;
3460 
3461   Ath__parser p;
3462   Ath__parser* parser = NULL;
3463 
3464   dbSet<dbCCSeg> ccSegs = blk->getCCSegs();
3465   dbSet<dbCCSeg>::iterator ccitr;
3466 
3467   for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
3468     dbCCSeg* cc = *ccitr;
3469 
3470     dbRSeg* srcRC =
3471         getMainRseg(cc->getSourceCapNode(), mainBlock, parser, logger);
3472 
3473     if (srcRC == NULL) {
3474       missCCcnt++;
3475       continue;
3476     }
3477     dbRSeg* dstRC =
3478         getMainRseg(cc->getTargetCapNode(), mainBlock, parser, logger);
3479     if (dstRC == NULL) {
3480       missCCcnt++;
3481       continue;
3482     }
3483 
3484     dbCCSeg* ccap = dbCCSeg::create(srcRC->getTargetCapNode(),
3485                                     dstRC->getTargetCapNode(), false);
3486 
3487     for (uint ii = 0; ii < cornerCnt; ii++) {
3488       double cap = cc->getCapacitance(ii);
3489       ;
3490       ccap->setCapacitance(cap, ii);
3491     }
3492     ccCnt++;
3493   }
3494   return ccCnt;
3495 }
3496 
assemblyExt__2(dbBlock * mainBlock,dbBlock * blk,Logger * logger)3497 uint extMain::assemblyExt__2(dbBlock* mainBlock, dbBlock* blk, Logger* logger) {
3498   bool flag = true;
3499 
3500   uint cornerCnt = mainBlock->getCornerCount();
3501   if (flag) {
3502     uint rcCnt = assembly_RCs(mainBlock, blk, cornerCnt, logger);
3503     uint missCCcnt = 0;
3504     uint ccCnt = assemblyCCs(mainBlock, blk, cornerCnt, missCCcnt, logger);
3505 
3506     int numOfNet, numOfRSeg, numOfCapNode, numOfCCSeg;
3507     mainBlock->getExtCount(numOfNet, numOfRSeg, numOfCapNode, numOfCCSeg);
3508 
3509     logger->info(RCX, 249, "Updated {} rsegs and added {} ccsegs of {} from {}",
3510                  rcCnt, ccCnt, mainBlock->getConstName(), blk->getConstName());
3511 
3512     return rcCnt;
3513   }
3514 
3515   Ath__parser parser;
3516 
3517   dbSet<dbNet> nets = blk->getNets();
3518   dbSet<dbNet>::iterator net_itr;
3519 
3520   uint missCCcnt = 0;
3521   uint gndCnt = 0;
3522   uint ccCnt = 0;
3523   uint cnt = 0;
3524   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
3525     dbNet* net = *net_itr;
3526 
3527     if ((net->getSigType().isSupply()))
3528       continue;
3529 
3530     dbNet* dstNet = getDstNet(net, mainBlock, &parser);
3531     if (dstNet == NULL)
3532       continue;
3533 
3534     dbWire* wire = net->getWire();
3535 
3536     uint netId = dstNet->getId();
3537 
3538     if (wire == NULL)
3539       continue;
3540 
3541     dbWireShapeItr shapes;
3542     dbShape s;
3543     for (shapes.begin(wire); shapes.next(s);) {
3544       if (s.isVia())
3545         continue;
3546 
3547       int shapeId = shapes.getShapeId();
3548       if (shapeId == 0)
3549         continue;
3550 
3551       int rsegId1 = 0;
3552       wire->getProperty(shapeId, rsegId1);
3553       if (rsegId1 == 0) {
3554         continue;
3555       }
3556       dbRSeg* rseg1 = dbRSeg::getRSeg(blk, rsegId1);
3557 
3558       cnt++;
3559       dbRSeg* rseg2 = getMainRSeg3(net, shapeId, dstNet);
3560 
3561       if (rseg2 == NULL) {
3562         logger->warn(RCX, 484,
3563                      "GndCap: cannot find rseg for rsegId {} on net {} {}",
3564                      rsegId1, dstNet->getId(), dstNet->getConstName());
3565         continue;
3566       }
3567 
3568       double gndCapTable1[10];
3569       rseg1->getCapTable(gndCapTable1);
3570 
3571       double gndCapTable2[10];
3572       rseg2->getCapTable(gndCapTable2);
3573 
3574       for (uint ii = 0; ii < cornerCnt; ii++) {
3575         double cap = gndCapTable1[ii] + gndCapTable2[ii];
3576         rseg2->setCapacitance(cap, ii);
3577       }
3578       gndCnt++;
3579 
3580       continue;
3581 
3582       dbCapNode* srcCapNode1 = rseg1->getTargetCapNode();
3583       dbSet<dbCCSeg> ccSegs = srcCapNode1->getCCSegs();
3584       dbSet<dbCCSeg>::iterator ccitr;
3585 
3586       for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
3587         dbCCSeg* cc = *ccitr;
3588 
3589         if (cc->isMarked())
3590           continue;
3591 
3592         cc->setMark(true);
3593 
3594         dbCapNode* dstCapNode1 = cc->getTargetCapNode();
3595         if (cc->getSourceCapNode() != srcCapNode1) {
3596           dstCapNode1 = cc->getSourceCapNode();
3597           if (cc->getTargetCapNode() != srcCapNode1) {
3598             logger->warn(RCX, 250, "Mismatch for CCap {} for net {}",
3599                          cc->getId(), dstNet->getId());
3600           }
3601         }
3602 
3603         dbNet* dstTgtNet =
3604             extMain::getDstNet(dstCapNode1->getNet(), mainBlock, &parser);
3605         if (dstTgtNet == NULL) {
3606           logger->warn(RCX, 245, "CCap: cannot find main net for {}",
3607                        dstCapNode1->getNet()->getConstName());
3608           continue;
3609         }
3610 
3611         // dbRSeg *tgtRseg2= extMain::getRseg(dstTgtNet,
3612         // dstCapNode1->getShapeId());
3613 
3614         dbRSeg* tgtRseg2 = getMainRSeg3(dstCapNode1->getNet(),
3615                                         dstCapNode1->getShapeId(), dstTgtNet);
3616 
3617         if (tgtRseg2 == NULL) {
3618           missCCcnt++;
3619           continue;
3620         }
3621 
3622         dbCCSeg* ccap = dbCCSeg::create(rseg2->getTargetCapNode(),
3623                                         tgtRseg2->getTargetCapNode(), true);
3624 
3625         for (uint ii = 0; ii < cornerCnt; ii++) {
3626           double cap = cc->getCapacitance(ii);
3627           ;
3628           ccap->setCapacitance(cap, ii);
3629         }
3630         ccCnt++;
3631       }
3632     }
3633   }
3634   ccCnt = assemblyCCs(mainBlock, blk, cornerCnt, missCCcnt, logger);
3635 
3636   int numOfNet, numOfRSeg, numOfCapNode, numOfCCSeg;
3637   mainBlock->getExtCount(numOfNet, numOfRSeg, numOfCapNode, numOfCCSeg);
3638 
3639   logger->info(
3640       RCX, 251,
3641       "Updated {} nets, {} rsegs, and added {} ({}) ccsegs of {} from {}", cnt,
3642       gndCnt, ccCnt, numOfCCSeg, mainBlock->getConstName(),
3643       blk->getConstName());
3644 
3645   return cnt;
3646 }
3647 
extTileSystem(Rect & extRect,uint * size)3648 extTileSystem::extTileSystem(Rect& extRect, uint* size) {
3649   _ll[0] = extRect.xMin();
3650   _ll[1] = extRect.yMin();
3651   _ur[0] = extRect.xMax();
3652   _ur[1] = extRect.yMax();
3653 
3654   for (uint dd = 0; dd < 2; dd++) {
3655     _tileSize[dd] = size[dd] / 4;
3656 
3657     _tileCnt[dd] = (_ur[dd] - _ll[dd]) / _tileSize[dd] + 2;
3658 
3659     uint n = _tileCnt[dd];
3660 
3661     _signalTable[dd] = new Ath__array1D<uint>* [n];
3662     _instTable[dd] = new Ath__array1D<uint>* [n];
3663 
3664     for (uint jj = 0; jj < n; jj++) {
3665       _signalTable[dd][jj] = NULL;
3666       _instTable[dd][jj] = NULL;
3667     }
3668   }
3669 
3670   _powerTable = new Ath__array1D<uint>(512);
3671   _tmpIdTable = new Ath__array1D<uint>(64000);
3672 }
mkTileBoundaries(bool skipPower,bool skipInsts)3673 uint extMain::mkTileBoundaries(bool skipPower, bool skipInsts) {
3674   uint cnt = 0;
3675   dbSet<dbNet> nets = _block->getNets();
3676   dbSet<dbNet>::iterator net_itr;
3677 
3678   for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
3679     dbNet* net = *net_itr;
3680 
3681     uint netId = net->getId();
3682 
3683     if ((net->getSigType().isSupply())) {
3684       if (!skipPower)
3685         _tiles->_powerTable->add(net->getId());
3686       continue;
3687     }
3688 
3689     Rect maxRect;
3690     uint cnt1 = getNetBbox(net, maxRect);
3691     if (cnt1 == 0)
3692       continue;
3693 
3694     net->setSpef(false);
3695 
3696     for (uint dir = 0; dir < 2; dir++) {
3697       addNetOnTable(net->getId(), dir, &maxRect, _tiles->_tileSize, _tiles->_ll,
3698                     _tiles->_ur, _tiles->_signalTable);
3699     }
3700     cnt += cnt1;
3701   }
3702   if (_overCell || !skipInsts) {
3703     dbSet<dbInst> insts = _block->getInsts();
3704     dbSet<dbInst>::iterator inst_itr;
3705 
3706     for (inst_itr = insts.begin(); inst_itr != insts.end(); ++inst_itr) {
3707       dbInst* inst = *inst_itr;
3708       dbBox* bb = inst->getBBox();
3709 
3710       Rect s;
3711       bb->getBox(s);
3712 
3713       for (uint dir = 0; dir < 2; dir++)
3714         addNetOnTable(inst->getId(), dir, &s, _tiles->_tileSize, _tiles->_ll,
3715                       _tiles->_ur, _tiles->_instTable);
3716 
3717       inst->clearUserFlag1();
3718     }
3719   }
3720   return cnt;
3721 }
mkTileNets(uint dir,int * lo_sdb,int * hi_sdb,bool powerNets,dbCreateNetUtil * createDbNet,uint & rcCnt,bool countOnly)3722 uint extMain::mkTileNets(uint dir, int* lo_sdb, int* hi_sdb, bool powerNets,
3723                          dbCreateNetUtil* createDbNet, uint& rcCnt,
3724                          bool countOnly) {
3725   if (_tiles == NULL)
3726     return 0;
3727 
3728   if (powerNets) {
3729     uint pCnt = mkTilePowerNets(dir, lo_sdb, hi_sdb, createDbNet);
3730     logger_->info(RCX, 97, "created {} power wires for block {}", pCnt,
3731                   _block->getConstName());
3732   }
3733 
3734   uint lo_index = getBucketNum(_tiles->_ll[dir], _tiles->_ur[dir],
3735                                _tiles->_tileSize[dir], lo_sdb[dir]);
3736   uint hi_index = getBucketNum(_tiles->_ll[dir], _tiles->_ur[dir],
3737                                _tiles->_tileSize[dir], hi_sdb[dir]);
3738 
3739   FILE* fp = NULL;
3740 #ifdef TEST_SIGNAL_TABLE
3741   char filename[64];
3742   sprintf(filename, "new/%d.%d.%d.sig.sdb", dir, lo_sdb[dir], hi_sdb[dir]);
3743   fp = fopen(filename, "w");
3744 #endif
3745 
3746   uint tot = 0;
3747   uint cnt1 = 0;
3748   uint local = 0;
3749   for (uint bucket = lo_index; bucket <= hi_index; bucket++) {
3750     if (_tiles->_signalTable[dir][bucket] == NULL)
3751       continue;
3752 
3753     uint netCnt = _tiles->_signalTable[dir][bucket]->getCnt();
3754 
3755     for (uint ii = 0; ii < netCnt; ii++) {
3756       uint netId = _tiles->_signalTable[dir][bucket]->get(ii);
3757       dbNet* net = dbNet::getNet(_block, netId);
3758 
3759       if (net->isSpef())  // tmp flag
3760         continue;
3761       net->setSpef(true);
3762       _tiles->_tmpIdTable->add(netId);
3763 
3764       dbWire* wire = net->getWire();
3765       if (wire == NULL)
3766         continue;
3767 
3768       Rect R;
3769       uint cnt = getNetBbox(net, R);
3770 
3771       int ll[2] = {R.xMin(), R.yMin()};
3772       int ur[2] = {R.xMax(), R.yMax()};
3773 
3774       tot += cnt;
3775 
3776       if ((ur[dir] < lo_sdb[dir]) || (ll[dir] > hi_sdb[dir]))
3777         continue;
3778 
3779       cnt1 += cnt;
3780 
3781       bool inside = false;
3782       if ((ur[dir] <= hi_sdb[dir]) && (ll[dir] >= lo_sdb[dir])) {
3783         inside = true;
3784         local += cnt;
3785       }
3786 
3787       cnt += wire->length();
3788 
3789       if (countOnly)
3790         continue;
3791 
3792       if (!net->isRCgraph())
3793         rcCnt += rcNetGen(net);
3794 
3795       createDbNet->copyNet(net, false);
3796 
3797       /*
3798       if (local) {
3799               createDbNet->copyNet(net, false);
3800       }
3801       else {
3802               createDbNet->copyNet(net, false);
3803               continue;
3804       }
3805 
3806       Rect maxRectV;
3807       Rect maxRectH;
3808       Rect *maxRect[2];
3809       maxRect[0]= &maxRectH;
3810       maxRect[1]= &maxRectV;
3811 
3812       uint cnt1= getNetBbox(net, maxRect);
3813       */
3814     }
3815   }
3816   logger_->info(RCX, 98, "{} local out of {} tile wires out of {} total", local,
3817                 cnt1, tot);
3818 
3819   resetNetSpefFlag(_tiles->_tmpIdTable);
3820 
3821 #ifdef TEST_SIGNAL_TABLE
3822   fprintf(fp, "dir= %d   %d %d -- %d %d sigCnt= %d\n", dir, lo_sdb[0],
3823           hi_sdb[0], lo_sdb[1], hi_sdb[1], cnt);
3824 
3825   if (fp != NULL)
3826     fclose(fp);
3827 #endif
3828 
3829   return cnt1;
3830 }
mkTilePowerNets(uint dir,int * lo_sdb,int * hi_sdb,dbCreateNetUtil * createDbNet)3831 uint extMain::mkTilePowerNets(uint dir, int* lo_sdb, int* hi_sdb,
3832                               dbCreateNetUtil* createDbNet) {
3833   Rect tileRect;
3834   tileRect.reset(lo_sdb[0], lo_sdb[1], hi_sdb[0], hi_sdb[1]);
3835 
3836   uint netCnt = _tiles->_powerTable->getCnt();
3837 
3838   createDbNet->setCurrentNet(NULL);
3839   uint cnt = 0;
3840   for (uint ii = 0; ii < netCnt; ii++) {
3841     uint netId = _tiles->_powerTable->get(ii);
3842 
3843     dbNet* net = dbNet::getNet(_block, netId);
3844     createDbNet->createSpecialNet(net, NULL);
3845 
3846     dbSet<dbSWire> swires = net->getSWires();
3847     dbSet<dbSWire>::iterator itr;
3848     for (itr = swires.begin(); itr != swires.end(); ++itr) {
3849       dbSWire* swire = *itr;
3850 
3851       dbSet<dbSBox> wires = swire->getWires();
3852       dbSet<dbSBox>::iterator box_itr;
3853 
3854       for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
3855         dbSBox* s = *box_itr;
3856         if (s->isVia())
3857           continue;
3858 
3859         Rect r;
3860         s->getBox(r);
3861 
3862         if (!tileRect.intersects(r))
3863           continue;
3864 
3865         createDbNet->createSpecialWire(NULL, r, s->getTechLayer(), 0);
3866         cnt++;
3867       }
3868     }
3869   }
3870   return cnt;
3871 }
3872 
createWindowsDB(bool rlog,Rect & extRect,uint trackStep,uint ccFlag,uint use_bin_tables)3873 uint extMain::createWindowsDB(bool rlog, Rect& extRect, uint trackStep,
3874                               uint ccFlag, uint use_bin_tables) {
3875   bool single_gs = false;
3876 
3877   extWindow* W = initWindowSearch(extRect, trackStep, ccFlag, 0, NULL);
3878 
3879   Ath__overlapAdjust overlapAdj = Z_noAdjust;
3880   _useDbSdb = true;
3881   _search->setExtControl(
3882       _block, _useDbSdb, (uint)overlapAdj, _CCnoPowerSource, _CCnoPowerTarget,
3883       _ccUp, _allNet, _ccContextDepth, _ccContextArray, _ccContextLength,
3884       _dgContextArray, &_dgContextDepth, &_dgContextPlanes, &_dgContextTracks,
3885       &_dgContextBaseLvl, &_dgContextLowLvl, &_dgContextHiLvl,
3886       _dgContextBaseTrack, _dgContextLowTrack, _dgContextHiTrack,
3887       _dgContextTrackBase, NULL);
3888 
3889   extWindow* windowTable[1000];
3890   uint windowCnt = 0;
3891 
3892   int** limitArray;
3893   limitArray = new int* [W->_layerCnt];
3894   for (uint k = 0; k < W->_layerCnt; k++)
3895     limitArray[k] = new int[10];
3896 
3897   _tiles = NULL;
3898 
3899   _wireBinTable = NULL;
3900   _cntxBinTable = NULL;
3901   _cntxInstTable = NULL;
3902   uint binCnt[2];
3903   AthPool<extWire>* wpool = NULL;
3904 
3905   bool use_signal_tables = false;
3906   if ((use_bin_tables == 1) || (use_bin_tables == 2)) {
3907     use_signal_tables = true;
3908 
3909     logger_->info(RCX, 88, "Signal_table= {} ----------------------------- ",
3910                   _use_signal_tables);
3911 
3912     wpool = new AthPool<extWire>(false, 1024);
3913 
3914     _wireBinTable = mkSignalBins(W->_maxPitch * W->_ccDist, W->_ll, W->_ur,
3915                                  binCnt, wpool, false);
3916     //_cntxBinTable= mkSignalBins(W->_step_nm[0], W->_ll, W->_ur, binCnt, wpool,
3917     // true);
3918     _cntxInstTable =
3919         mkInstBins(W->_maxPitch * W->_ccDist, W->_ll, W->_ur, binCnt);
3920 
3921     if (rlog)
3922       AthResourceLog("Making net tables ", 0);
3923   } else if (use_bin_tables == 3) {  // signal_table based tiling
3924     _tiles = new extTileSystem(extRect, W->_step_nm);
3925     bool skipPower = false;
3926     bool skipInsts = false;
3927     uint wireCnt = mkTileBoundaries(skipPower, skipInsts);
3928   }
3929 
3930   for (int dir = 1; dir >= 0; dir--) {
3931     if (dir == 0)
3932       enableRotatedFlag();
3933     else
3934       disableRotatedFlag();
3935 
3936     //_search->initCouplingCapLoops(dir, ccFlag, coupleAndCompute, m);
3937     _search->initCouplingCapLoops(dir, ccFlag, NULL, NULL);
3938 
3939     uint stepNum = 0;
3940     int hiXY = W->setExtBoundaries(dir);
3941     for (; hiXY <= W->_ur[dir]; hiXY += W->_step_nm[dir]) {
3942       hiXY = W->adjust_hiXY(hiXY);
3943 
3944       uint extractedWireCnt = 0;
3945       int extractLimit = W->set_extractLimit();
3946       W->_minExtracted = _search->couplingCaps(
3947           W->_extractLimit, W->_ccDist, W->_currentDir, extractedWireCnt, NULL,
3948           NULL, _getBandWire, limitArray);
3949 
3950       int deallocLimit = W->getDeallocLimit();
3951       _search->dealloc(W->_currentDir, deallocLimit);
3952 
3953       W->updateExtLimits(limitArray);
3954 
3955       extWindow* W1 = new extWindow(W, windowCnt, logger_);
3956       windowTable[windowCnt++] = W1;
3957 
3958       W->updateLoBounds(false /*report*/);
3959 
3960       dbBlock* extBlock = W1->createExtBlock(NULL, _block, extRect);
3961     }
3962   }
3963   return 1;
3964 }
fillWindowsDB(bool rlog,Rect & extRect,uint use_signal_tables)3965 uint extMain::fillWindowsDB(bool rlog, Rect& extRect, uint use_signal_tables) {
3966   dbIntProperty* p = (dbIntProperty*)dbProperty::find(_block, "_currentDir");
3967   if (p == NULL) {
3968     logger_->warn(RCX, 99, "Block {} has no defined extraction boundaries",
3969                   _block->getConstName());
3970     return 0;
3971   }
3972   bool rcgenFlag = use_signal_tables > 1 ? true : false;
3973 
3974   extWindow* W = new extWindow(20, logger_);
3975   W->getExtProperties(_block);
3976 
3977   dbBlock* extBlock = _block;
3978   setBlock(_block->getParent());
3979 
3980   if (use_signal_tables == 2) {
3981     uint extWireCnt = 0;
3982     uint rcCnt = 0;
3983     if (_tiles != NULL)
3984       extWireCnt = mkTileNets(W->_currentDir, W->_lo_sdb, W->_hi_sdb, false,
3985                               NULL, rcCnt, true);
3986     else
3987       extWireCnt =
3988           addNets3(W->_currentDir, W->_lo_sdb, W->_hi_sdb, W->_ll, W->_ur,
3989                    W->_maxPitch * W->_ccDist, _wireBinTable, NULL);
3990 
3991     dbIntProperty::create(extBlock, "_estimatedWireCnt", extWireCnt);
3992     setBlock(extBlock);
3993     return extWireCnt;
3994   }
3995 
3996   dbCreateNetUtil createNetUtil;
3997 
3998   createNetUtil.setBlock(extBlock, false);
3999   if (use_signal_tables == 3) {
4000     dbBlock::copyViaTable(extBlock, _block);
4001   }
4002 
4003   uint extWireCnt = 0;
4004   if (use_signal_tables == 0) {
4005     fillWindowGs(W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &createNetUtil);
4006 
4007     uint processWireCnt =
4008         fillWindowSearch(W, W->_lo_sdb, W->_hi_sdb, NULL, NULL, NULL, NULL,
4009                          NULL, NULL, &createNetUtil);
4010   } else if (use_signal_tables == 3) {
4011     bool powerNets = true;
4012 
4013     uint rcCnt = 0;
4014 
4015     extWireCnt = mkTileNets(W->_currentDir, W->_lo_sdb, W->_hi_sdb, powerNets,
4016                             &createNetUtil, rcCnt);
4017     logger_->info(RCX, 100,
4018                   "BBlock {} has {} signal wires and {} rcSegs were generated",
4019                   extBlock->getConstName(), extWireCnt, rcCnt);
4020     rcgenFlag = false;
4021   } else {
4022     createNetUtil.allocMapArray(2000000);
4023     extWireCnt =
4024         addNets3(W->_currentDir, W->_lo_sdb, W->_hi_sdb, W->_ll, W->_ur,
4025                  W->_maxPitch * W->_ccDist, _wireBinTable, &createNetUtil);
4026 
4027     uint cntxCnt =
4028         addNets3GS(W->_currentDir, W->_lo_gs, W->_hi_gs, W->_ll, W->_ur,
4029                    W->_step_nm[0], _cntxBinTable, &createNetUtil);
4030 
4031     uint instCnt =
4032         addInsts(W->_currentDir, W->_lo_gs, W->_hi_gs, W->_ll, W->_ur,
4033                  W->_maxPitch * W->_ccDist, _cntxInstTable, &createNetUtil);
4034     uint signalWireCnt = createNetShapePropertires(extBlock);
4035     logger_->info(RCX, 96, "Block {} has {} signal wires",
4036                   extBlock->getConstName(), signalWireCnt);
4037   }
4038 
4039   if (rcgenFlag) {
4040     uint rcCnt = rcGenTile(extBlock);
4041     logger_->info(RCX, 101, "{} rsegs for {}", rcCnt, extBlock->getConstName());
4042   }
4043   return extWireCnt;
4044 }
rcNetGen(dbNet * net)4045 uint extMain::rcNetGen(dbNet* net) {
4046   dbSigType type = net->getSigType();
4047   if ((type == dbSigType::POWER) || (type == dbSigType::GROUND))
4048     return 0;
4049   if (!_allNet && !net->isMarked())
4050     return 0;
4051 
4052   _connectedBTerm.clear();
4053   _connectedITerm.clear();
4054 
4055   uint cnt = makeNetRCsegs(net);
4056 
4057   uint tt;
4058   for (tt = 0; tt < _connectedBTerm.size(); tt++)
4059     ((dbBTerm*)_connectedBTerm[tt])->setMark(0);
4060   for (tt = 0; tt < _connectedITerm.size(); tt++)
4061     ((dbITerm*)_connectedITerm[tt])->setMark(0);
4062 
4063   return cnt;
4064 }
rcGen(const char * netNames,double resBound,bool mergeViaRes,uint debug,bool rlog,ZInterface * Interface)4065 uint extMain::rcGen(const char* netNames, double resBound, bool mergeViaRes,
4066                     uint debug, bool rlog, ZInterface* Interface) {
4067   if (debug != 77)
4068     logger_->info(RCX, 102, "RC segment generation {} ...",
4069                   getBlock()->getName().c_str());
4070 
4071   if (!_lefRC && (getRCmodel(0) == NULL)) {
4072     logger_->warn(RCX, 103, "No RC model was read with command <load_model>");
4073     logger_->warn(RCX, 104, "Can't perform RC generation!");
4074     return 0;
4075   }
4076   if (setMinTypMax(false, false, false, NULL, false, false, -1, -1, -1, 1) <
4077       0) {
4078     logger_->warn(RCX, 105, "Wrong combination of corner related options");
4079     return 0;
4080   }
4081   _mergeViaRes = mergeViaRes;
4082   _mergeResBound = resBound;
4083 
4084   _foreign = false;  // extract after read_spef
4085 
4086   std::vector<dbNet*> inets;
4087   _allNet = !((dbBlock*)_block)->findSomeNet(netNames, inets);
4088 
4089   uint j;
4090   for (j = 0; j < inets.size(); j++) {
4091     dbNet* net = inets[j];
4092     net->setMark(true);
4093   }
4094   uint cnt = 0;
4095 
4096   // if (_couplingFlag>1 && !_lefRC)
4097   getResCapTable(true);
4098 
4099   if (debug == 77) {
4100     logger_->info(RCX, 106, "Setup for RCgen done!");
4101     return 0;
4102   }
4103   dbSet<dbNet> bnets = _block->getNets();
4104   dbSet<dbNet>::iterator net_itr;
4105   for (net_itr = bnets.begin(); net_itr != bnets.end(); ++net_itr) {
4106     dbNet* net = *net_itr;
4107 
4108     cnt += rcNetGen(net);
4109   }
4110   logger_->info(RCX, 39, "Final {} rc segments", cnt);
4111   return cnt;
4112 }
rcGenBlock(dbBlock * block)4113 uint extMain::rcGenBlock(dbBlock* block) {
4114   if (block == NULL)
4115     block = _block;
4116 
4117   uint cnt = 0;
4118 
4119   dbSet<dbNet> bnets = block->getNets();
4120   dbSet<dbNet>::iterator net_itr;
4121   for (net_itr = bnets.begin(); net_itr != bnets.end(); ++net_itr) {
4122     dbNet* net = *net_itr;
4123 
4124     cnt += rcNetGen(net);
4125   }
4126   logger_->info(RCX, 41, "Final {} rc segments", cnt);
4127   return cnt;
4128 }
writeMapping(dbBlock * block)4129 void extMain::writeMapping(dbBlock* block) {
4130   if (block == NULL)
4131     block = _block;
4132 
4133   char buf[1024];
4134   sprintf(buf, "%s.netMap", block->getConstName());
4135   FILE* fp = fopen(buf, "w");
4136 
4137   uint cnt = 0;
4138 
4139   dbSet<dbNet> bnets = block->getNets();
4140   dbSet<dbNet>::iterator net_itr;
4141   for (net_itr = bnets.begin(); net_itr != bnets.end(); ++net_itr) {
4142     dbNet* net = *net_itr;
4143 
4144     net->printNetName(fp, true, true);
4145 
4146     dbWire* wire = net->getWire();
4147 
4148     if (wire == NULL)
4149       continue;
4150 
4151     dbWireShapeItr shapes;
4152     dbShape s;
4153     for (shapes.begin(wire); shapes.next(s);) {
4154       if (s.isVia())
4155         continue;
4156 
4157       Rect r;
4158       s.getBox(r);
4159 
4160       fprintf(fp, "\t\t%d  %d %d  %d %d  %d %d\n", shapes.getShapeId(), r.dx(),
4161               r.dy(), r.xMin(), r.yMin(), r.xMax(), r.yMax());
4162     }
4163   }
4164   fclose(fp);
4165 }
4166 
4167 }  // namespace rcx
4168