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