1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32
33 #include <stdio.h>
34
35 #include <algorithm>
36
37 #include "ZInterface.h"
38 #include "dbLogger.h"
39 #include "wire.h"
40 //#define ZDEBUG 1
41 uint ttttGetDgOverlap;
42 //#define TEST_GetDgOverlap
43
44 namespace rcx {
45 CoupleOptions coupleOptionsNull{0};
46 };
47
trackContextOn(int orig,int end,int base,int width,uint firstContextTrack,Ath__array1D<int> * context)48 uint Ath__track::trackContextOn(int orig, int end, int base, int width,
49 uint firstContextTrack,
50 Ath__array1D<int>* context) {
51 Ath__wire* swire = getTargetWire();
52 if (!swire)
53 return 0;
54 while (swire && swire->_xy + swire->_len < base)
55 swire = nextTargetWire(0); // context of both power/noPower
56 if (!swire || swire->_xy >= (base + width) ||
57 (!firstContextTrack && swire->_srcId))
58 return 0;
59 int p1 = swire->_base > orig ? swire->_base : orig;
60 int send = swire->_base + swire->_width;
61 int p2 = send < end ? send : end;
62 if (p2 <= p1)
63 return 0;
64 context->add(p1);
65 context->add(p2);
66 return p2 - p1;
67 }
68
gridContextOn(int orig,int len,int base,int width)69 void Ath__grid::gridContextOn(int orig, int len, int base, int width) {
70 Ath__array1D<int>* context = _gridtable->contextArray()[_level];
71 context->resetCnt(0);
72 context->add(orig);
73 int end = orig + len;
74 uint lowTrack = getMinMaxTrackNum(orig);
75 uint hiTrack = getMinMaxTrackNum(orig + len);
76 Ath__track* track, *btrack;
77 uint jj;
78 uint firstContextTrack = 1;
79 uint clength = 0;
80 bool tohi = _gridtable->targetHighTracks() > 0 ? true : false;
81 for (jj = lowTrack; jj <= hiTrack; jj++) {
82 btrack = _trackTable[jj];
83 if (btrack == NULL)
84 continue;
85 track = NULL;
86 while ((track = btrack->getNextSubTrack(track, tohi))) {
87 clength += track->trackContextOn(orig, end, base, width,
88 firstContextTrack, context);
89 firstContextTrack = 0;
90 }
91 }
92 context->add(end);
93 _gridtable->setContextLength(_level, clength);
94 }
95
contextsOn(int orig,int len,int base,int width)96 void Ath__grid::contextsOn(int orig, int len, int base, int width) {
97 uint sdepth = _gridtable->contextDepth();
98 if (sdepth == 0)
99 return;
100 uint ii = _dir ? 0 : 1;
101 uint jj;
102 for (jj = 1; jj <= sdepth && (jj + _level) < _gridtable->getColCnt(); jj++)
103 _gridtable->getGrid(ii, jj + _level)->gridContextOn(orig, len, base, width);
104 for (jj = 1; jj <= sdepth && (_level - jj) > 0; jj++)
105 _gridtable->getGrid(ii, _level - jj)->gridContextOn(orig, len, base, width);
106 }
107
108 // Extraction Coupling Caps
109
findOverlap(Ath__wire * origWire,uint ccThreshold,Ath__array1D<Ath__wire * > * wTable,Ath__array1D<Ath__wire * > * nwTable,Ath__grid * ccGrid,Ath__array1D<Ath__wire * > * ccTable,ZInterface * context,uint met,rcx::CoupleAndCompute coupleAndCompute,void * compPtr)110 uint Ath__track::findOverlap(
111 Ath__wire* origWire, uint ccThreshold, Ath__array1D<Ath__wire*>* wTable,
112 Ath__array1D<Ath__wire*>* nwTable, Ath__grid* ccGrid,
113 Ath__array1D<Ath__wire*>* ccTable, ZInterface* context, uint met,
114 rcx::CoupleAndCompute coupleAndCompute, void* compPtr) {
115 rcx::CoupleOptions coupleOptions;
116
117 AthPool<Ath__wire>* wirePool = _grid->getWirePoolPtr();
118
119 uint NoPowerTarget = _grid->getGridTable()->noPowerTarget();
120 bool srcMarked = origWire->getNet()->isMarked();
121 uint TargetHighMarkedNet = _grid->getGridTable()->targetHighMarkedNet();
122 bool allNet = _grid->getGridTable()->allNet();
123 bool needMarkedNetW2 = !allNet && TargetHighMarkedNet && !srcMarked;
124 int TTTnoInNetCC = 0;
125 int len1, len2, len3, rc;
126 Ath__wire* w2 = getTargetWire();
127 bool targetHiTrack =
128 _grid->getGridTable()->targetHighTracks() > 0 ? true : false;
129 bool targetReversed = _grid->getGridTable()->targetTrackReversed();
130 bool useDbSdb = _grid->getGridTable()->usingDbSdb();
131
132 uint last = wTable->getCnt();
133 bool inThreshold, skipCCgen;
134 bool notExtractedW2;
135 int exid;
136 for (uint ii = 0; ii < last; ii++) {
137 Ath__wire* w1 = wTable->get(ii);
138
139 if (w2 == NULL) {
140 nwTable->add(w1);
141 continue;
142 }
143
144 while (1) {
145 notExtractedW2 =
146 useDbSdb && !w2->isPower() && !w2->isVia() &&
147 w2->getNet()->getWire() &&
148 (!w2->getNet()->getWire()->getProperty((int)w2->_otherId, exid) ||
149 exid == 0);
150 len1 = 0;
151 len2 = 0;
152 len3 = 0;
153 rc = 0;
154
155 // context->event( "CCW","xy", Z_INT, w2->_xy,"len", Z_INT,
156 // w2->_len,NULL);
157
158 inThreshold = true;
159 if ((targetHiTrack &&
160 w2->_base >= w1->_base + (int)(w1->_width + ccThreshold)) ||
161 (!targetHiTrack &&
162 w1->_base >= w2->_base + (int)(w2->_width + ccThreshold)))
163 inThreshold = false;
164
165 skipCCgen = _grid->getGridTable()->handleEmptyOnly() ||
166 (needMarkedNetW2 && !w2->getNet()->isMarked());
167 rc = w1->wireOverlap(w2, &len1, &len2, &len3);
168
169 if (inThreshold == true && rc == 0) {
170 if (len1 > 0) {
171 // create empty wire and ADD on emptyTable!
172 Ath__wire* newEmptyWire = origWire->makeWire(wirePool, w1->_xy, len1);
173 nwTable->add(newEmptyWire);
174 }
175 Ath__wire* wtwo = w2->_srcId ? _grid->getWirePtr(w2->_srcId) : w2;
176 // create cc and ADD on ccTable
177 if (!notExtractedW2 && len2 > 0 && !skipCCgen &&
178 (!TTTnoInNetCC || wtwo->isPower() || origWire->isPower() ||
179 origWire->getNet() != wtwo->getNet()) &&
180 (!targetReversed || wtwo->isPower() ||
181 !wtwo->getNet()->isMarked())) {
182 if (coupleAndCompute == NULL) {
183 Ath__wire* ovWire = origWire->makeCoupleWire(
184 ccGrid->getWirePoolPtr(), targetHiTrack, wtwo, w1->_xy + len1,
185 len2, ccGrid->defaultWireType());
186
187 if (ovWire == NULL)
188 _grid->getGridTable()->incrCCshorts();
189 else {
190 ccTable->add(ovWire);
191 ccGrid->placeWire(ovWire);
192 ovWire->_flags = ccGrid->defaultWireType();
193 }
194 } else {
195 Ath__wire* topwire = targetHiTrack ? wtwo : origWire;
196 Ath__wire* botwire = targetHiTrack ? origWire : wtwo;
197 int dist = topwire->_base - (botwire->_base + botwire->_width);
198
199 if (dist > 0) {
200 _grid->contextsOn(w1->_xy + len1, len2,
201 botwire->_base + botwire->_width, dist);
202 coupleOptions[0] = met;
203
204 int bBoxId = (int)botwire->_boxId;
205 if (useDbSdb)
206 bBoxId = botwire->getRsegId();
207
208 // DF 820 if (botwire->_otherId && useDbSdb && !botwire->isVia())
209 // botwire->getNet()->getWire()->getProperty((int)botwire->_otherId,
210 // bBoxId);
211 coupleOptions[1] = bBoxId; // dbRSeg id for SRC segment
212
213 if (botwire->_otherId == 0)
214 coupleOptions[1] = -bBoxId; // POwer SBox Id
215
216 int tBoxId = (int)topwire->_boxId;
217
218 if (useDbSdb)
219 tBoxId = topwire->getRsegId();
220
221 // DF 820 if (topwire->_otherId && useDbSdb && !topwire->isVia())
222 // topwire->getNet()->getWire()->getProperty((int)topwire->_otherId,
223 // tBoxId);
224 coupleOptions[2] = tBoxId; // dbRSeg id for TARGET segment
225 if (topwire->_otherId == 0)
226 coupleOptions[2] = -tBoxId; // POwer SBox Id
227
228 coupleOptions[3] = len2;
229 coupleOptions[4] = dist;
230 coupleOptions[5] = w1->_xy + len1;
231 coupleOptions[6] = botwire->_dir;
232
233 coupleOptions[7] = botwire->_width;
234 coupleOptions[8] = topwire->_width;
235 coupleOptions[9] = botwire->_base;
236 coupleOptions[11] = targetHiTrack ? 1 : 0;
237 coupleOptions[18] = botwire->_track->getTrackNum();
238 coupleAndCompute(coupleOptions, compPtr);
239 }
240 }
241 }
242
243 // context->event( "OV","xy", Z_INT, ovWire->_xy,"len", Z_INT,
244 // ovWire->_len,NULL);
245
246 if (len3 > 0) {
247 w1->setXY(w1->_xy + len1 + len2, len3);
248 w2 = nextTargetWire(NoPowerTarget);
249 if (!w2) {
250 nwTable->add(w1);
251 break;
252 }
253 continue;
254 }
255 wirePool->free(w1);
256 break;
257 }
258 if (inThreshold == false && rc == 0) {
259 if (len3 > 0) {
260 w2 = nextTargetWire(NoPowerTarget);
261 if (!w2) {
262 nwTable->add(w1);
263 break;
264 }
265 continue;
266 } else {
267 nwTable->add(w1);
268 break;
269 }
270 }
271 if (rc == 1) {
272 w2 = nextTargetWire(NoPowerTarget);
273 if (!w2) {
274 nwTable->add(w1);
275 break;
276 }
277 continue;
278 }
279 // (rc == 2)
280 nwTable->add(w1);
281 break;
282 }
283 }
284 return nwTable->getCnt();
285 }
286
initTargetTracks(uint srcTrack,uint trackDist,bool tohi)287 uint Ath__track::initTargetTracks(uint srcTrack, uint trackDist, bool tohi) {
288 uint delt = 0;
289 // uint tgtTrack = 0;
290 uint trackFound = 0;
291 bool noPowerTarget =
292 _grid->getGridTable()->noPowerTarget() > 0 ? true : false;
293 Ath__track* tstrack = this;
294 while (nextSubTrackInRange(tstrack, delt, trackDist, srcTrack, tohi)) {
295 tstrack->initTargetWire(noPowerTarget);
296 trackFound = 1;
297 }
298 return trackFound;
299 }
300
nextTrackInRange(uint & delt,uint trackDist,uint srcTrack,bool tohi)301 Ath__track* Ath__track::nextTrackInRange(uint& delt, uint trackDist,
302 uint srcTrack, bool tohi) {
303 Ath__track* ttrack = NULL;
304 uint tgtTnum;
305 while (ttrack == NULL) {
306 delt++;
307 if (delt > trackDist || (!tohi && srcTrack < delt))
308 return NULL;
309 tgtTnum = tohi ? srcTrack + delt : srcTrack - delt;
310 if (tgtTnum >= _grid->getTrackCnt())
311 return NULL;
312 ttrack = _grid->getTrackPtr(tgtTnum);
313 }
314 return ttrack;
315 }
316
nextSubTrackInRange(Ath__track * & tstrack,uint & delt,uint trackDist,uint srcTrack,bool tohi)317 int Ath__track::nextSubTrackInRange(Ath__track*& tstrack, uint& delt,
318 uint trackDist, uint srcTrack, bool tohi) {
319 tstrack = getNextSubTrack(tstrack, tohi);
320 if (tstrack)
321 return 1;
322 Ath__track* ttrack = nextTrackInRange(delt, trackDist, srcTrack, tohi);
323 if (ttrack == NULL)
324 return 0;
325 tstrack = tohi ? ttrack : ttrack->getLowTrack();
326 return 1;
327 }
328
couplingCaps(Ath__grid * ccGrid,uint srcTrack,uint trackDist,uint ccThreshold,ZInterface * context,Ath__array1D<uint> * ccIdTable,uint met,rcx::CoupleAndCompute coupleAndCompute,void * compPtr)329 uint Ath__track::couplingCaps(Ath__grid* ccGrid, uint srcTrack, uint trackDist,
330 uint ccThreshold, ZInterface* context,
331 Ath__array1D<uint>* ccIdTable, uint met,
332 rcx::CoupleAndCompute coupleAndCompute,
333 void* compPtr) {
334 Ath__track* tstrack;
335 bool tohi = _grid->getGridTable()->targetHighTracks() > 0 ? true : false;
336 initTargetTracks(srcTrack, trackDist, tohi);
337 // need to process "empty wire" (non-coupled wire)
338 // if (!trackFound)
339 // return 0;
340
341 uint dir = _grid->getDir();
342 rcx::CoupleOptions coupleOptions;
343
344 Ath__array1D<Ath__wire*> w1Table;
345 Ath__array1D<Ath__wire*> w2Table;
346 Ath__array1D<Ath__wire*>* wTable, *nwTable, *twTable;
347 Ath__array1D<Ath__wire*> ccTable;
348
349 bool useDbSdb = _grid->getGridTable()->usingDbSdb();
350 int noPowerSource = _grid->getGridTable()->noPowerSource();
351 uint TargetHighMarkedNet = _grid->getGridTable()->targetHighMarkedNet();
352 bool allNet = _grid->getGridTable()->allNet();
353 AthPool<Ath__wire>* wirePool = _grid->getWirePoolPtr();
354 uint wireCnt = 0;
355 Ath__wire* origWire = NULL;
356 // bool srcMarked;
357 uint delt;
358 int exid;
359
360 if (ttttGetDgOverlap) {
361 // to initTargetSeq
362 coupleOptions[0] = -met;
363 coupleOptions[5] = 1;
364 coupleAndCompute(coupleOptions, compPtr);
365 }
366 int nexy, nelen;
367 Ath__wire* wire = NULL;
368 Ath__wire* pwire = NULL;
369 Ath__wire* nwire = getNextWire(wire);
370 for (wire = nwire; wire; pwire = wire, wire = nwire) {
371 nwire = getNextWire(wire);
372 #ifdef TEST_GetDgOverlap
373 if (ttttGetDgOverlap) {
374 if (wire->isPower() || wire->_srcId > 0 ||
375 _grid->getGridTable()->handleEmptyOnly())
376 continue;
377 coupleOptions[0] = -met;
378 coupleOptions[1] = wire->_xy;
379 coupleOptions[2] = wire->_xy + wire->_len;
380 coupleOptions[3] = wire->_base;
381 coupleOptions[4] = wire->_base + wire->_width;
382 coupleOptions[5] = 2;
383 coupleOptions[6] = wire->_dir;
384 coupleAndCompute(coupleOptions, compPtr);
385 continue;
386 }
387 #endif
388 if (!wire->isPower() && nwire && nwire->isPower() &&
389 nwire->_xy < wire->_xy + wire->_len)
390 coupleOptions[19] = 0; // bp
391 if (wire->isPower() && nwire && !nwire->isPower() &&
392 nwire->_xy < wire->_xy + wire->_len)
393 coupleOptions[19] = 0; // bp
394
395 if (noPowerSource && wire->isPower())
396 continue;
397 // if (wire->isVia())
398 // continue;
399
400 if (!allNet && !TargetHighMarkedNet &&
401 !wire->getNet()->isMarked()) // when !TargetHighMarkedNet, need only
402 // marked source
403 continue;
404 if (tohi &&
405 _grid->getMinMaxTrackNum(wire->_base + wire->_width) != srcTrack)
406 continue;
407 if (!tohi && wire->_srcId > 0)
408 continue;
409 if (useDbSdb && !wire->isPower() && !wire->isVia() &&
410 wire->getNet()->getWire() &&
411 (!wire->getNet()->getWire()->getProperty((int)wire->_otherId, exid) ||
412 exid == 0))
413 continue;
414
415 wireCnt++;
416
417 // ccGrid->placeWire(wire);
418
419 w1Table.resetCnt();
420 wTable = &w1Table;
421 nwTable = &w2Table;
422 nexy = wire->_xy;
423 nelen = wire->_len;
424 int delta;
425 if (pwire)
426 delta = pwire->_xy + pwire->_len - wire->_xy;
427 if (pwire && delta > 0 &&
428 wire->_base + wire->_width < pwire->_base + pwire->_width) {
429 nexy += delta;
430 nelen -= delta;
431 }
432 if (nwire)
433 delta = wire->_xy + wire->_len - nwire->_xy;
434 if (nwire && delta > 0 &&
435 wire->_base + wire->_width < nwire->_base + nwire->_width)
436 nelen -= delta;
437 // assert (nelen > 0);
438 //// assert (nelen >= 0);
439 //// if (nelen == 0) // or nelen < wire->_width
440 if (nelen <= 0) // or nelen < wire->_width
441 continue;
442 Ath__wire* newEmptyWire = wire->makeWire(wirePool, nexy, nelen);
443 wTable->add(newEmptyWire);
444
445 delt = 0;
446 tstrack = this;
447 while (nextSubTrackInRange(tstrack, delt, trackDist, srcTrack, tohi)) {
448 nwTable->resetCnt();
449
450 origWire = wire->_srcId ? _grid->getWirePtr(wire->_srcId) : wire;
451 tstrack->findOverlap(origWire, ccThreshold, wTable, nwTable, ccGrid,
452 &ccTable, context, met, coupleAndCompute, compPtr);
453
454 twTable = wTable;
455 wTable = nwTable;
456 nwTable = twTable;
457
458 if (wTable->getCnt() == 0)
459 break;
460 }
461 if (coupleAndCompute != NULL) {
462 bool visited = false;
463 int wBoxId = 0;
464
465 for (uint kk = 0; kk < wTable->getCnt(); kk++) {
466 Ath__wire* empty = wTable->get(kk);
467
468 coupleOptions[0] = met;
469
470 wBoxId = (int)wire->_boxId;
471 if (useDbSdb)
472 wBoxId = wire->getRsegId();
473
474 coupleOptions[1] = wBoxId; // dbRSeg id
475 if (wire->_otherId == 0)
476 coupleOptions[1] = -wBoxId; // dbRSeg id
477
478 coupleOptions[2] = 0; // dbRSeg id
479
480 coupleOptions[3] = empty->_len;
481 coupleOptions[4] = -1;
482 coupleOptions[5] = empty->_xy;
483 coupleOptions[6] = wire->_dir;
484
485 coupleOptions[7] = wire->_width;
486 coupleOptions[8] = 0;
487 coupleOptions[9] = wire->_base;
488 coupleOptions[10] = dir;
489
490 coupleOptions[11] = tohi ? 1 : 0;
491
492 bool ignore_visited = true;
493 if (ignore_visited || (wire->_visited == 0 && wire->_srcWire == NULL) ||
494 (wire->_srcWire != NULL && wire->_srcWire->_visited == 0)) {
495 // notice(0, "coupleAndCompute: net= %d-%d base %d xy %d L%d %s\n",
496 // wire->getNet()->getId(), wire->_otherId, wire->_base, wire->_xy,
497 // wire->_len,
498 // wire->getNet()->getConstName() );
499 if (wire->_srcWire != NULL) {
500 coupleOptions[20] = wire->_srcWire->_ouLen;
501 } else {
502 coupleOptions[20] = wire->_ouLen;
503 }
504 coupleAndCompute(coupleOptions, compPtr);
505 visited = true;
506 if (wire->_srcWire != NULL)
507 wire->_srcWire->_ouLen = coupleOptions[20];
508 else
509 wire->_ouLen = coupleOptions[20];
510 }
511 wirePool->free(empty);
512 }
513 if (visited)
514 wire->_visited = 1;
515 }
516 }
517 if (coupleAndCompute == NULL) {
518 for (uint kk = 0; kk < ccTable.getCnt(); kk++) {
519 Ath__wire* v = ccTable.get(kk);
520 ccIdTable->add(v->_id);
521
522 // compute and/or add on a grid
523 }
524 }
525 // notice(0, "\t%d wires make %d ccaps\n", wireCnt, ccTable.getCnt());
526 // return ccTable.getCnt();
527 return wireCnt;
528 }
529
couplingCaps(Ath__grid * resGrid,uint couplingDist,ZInterface * context,Ath__array1D<uint> * ccTable,rcx::CoupleAndCompute coupleAndCompute,void * compPtr)530 uint Ath__grid::couplingCaps(Ath__grid* resGrid, uint couplingDist,
531 ZInterface* context, Ath__array1D<uint>* ccTable,
532 rcx::CoupleAndCompute coupleAndCompute,
533 void* compPtr) {
534 // Ath__array1D<Ath__wire*> ccTable;
535 // Ath__array1D<Ath__wire*> wTable;
536
537 uint coupleTrackNum = couplingDist; // EXT-OPTIMIZE
538 uint ccThreshold = coupleTrackNum * _pitch;
539 uint TargetHighMarkedNet = _gridtable->targetHighMarkedNet();
540 bool allNet = _gridtable->allNet();
541
542 uint domainAdjust = allNet || !TargetHighMarkedNet ? 0 : couplingDist;
543 initContextGrids();
544 setSearchDomain(domainAdjust);
545 uint cnt = 0;
546 for (uint ii = _searchLowTrack; ii <= _searchHiTrack; ii++) {
547 Ath__track* btrack = _trackTable[ii];
548 if (btrack == NULL)
549 continue;
550
551 int base = btrack->getBase();
552 _gridtable->buildDgContext(base, _level, _dir);
553 if (!ttttGetDgOverlap)
554 coupleAndCompute(rcx::coupleOptionsNull, compPtr); // try print dgContext
555
556 Ath__track* track = NULL;
557 bool tohi = true;
558 while ((track = btrack->getNextSubTrack(track, tohi))) {
559 _gridtable->setHandleEmptyOnly(false);
560 uint cnt1 =
561 track->couplingCaps(resGrid, ii, coupleTrackNum, ccThreshold, context,
562 ccTable, _level, coupleAndCompute, compPtr);
563 cnt += cnt1;
564 if (allNet || TargetHighMarkedNet)
565 _gridtable->setHandleEmptyOnly(true);
566 _gridtable->reverseTargetTrack();
567 cnt1 =
568 track->couplingCaps(resGrid, ii, coupleTrackNum, ccThreshold, context,
569 ccTable, _level, coupleAndCompute, compPtr);
570 cnt += cnt1;
571 _gridtable->reverseTargetTrack();
572 }
573 // notice(0, "CC: Track - %5d : %d out of %d\n", ii, cnt1, cnt);
574 }
575
576 return cnt;
577 }
setDefaultWireType(uint v)578 void Ath__gridTable::setDefaultWireType(uint v) {
579 for (uint ii = 0; ii < _rowCnt; ii++) {
580 for (uint jj = 0; jj < _colCnt; jj++) {
581 if (_gridTable[ii][jj] == NULL)
582 continue;
583
584 _gridTable[ii][jj]->setDefaultWireType(v);
585 }
586 }
587 }
588
getTrackWires(std::vector<Ath__wire * > & ctxwire)589 void Ath__track::getTrackWires(std::vector<Ath__wire*>& ctxwire) {
590 uint midx;
591 Ath__wire* wire;
592 Ath__wire* srcwire;
593 for (midx = 0; midx < _markerCnt; midx++) {
594 wire = _marker[midx];
595 while (wire) {
596 srcwire = wire->_srcId ? _grid->getWirePtr(wire->_srcId) : wire;
597 if (srcwire->_ext == 0) {
598 srcwire->_ext = 1;
599 ctxwire.push_back(srcwire);
600 }
601 wire = wire->_next;
602 }
603 }
604 }
605
606 class compareAthWire {
607 public:
operator ()(Ath__wire * wire1,Ath__wire * wire2)608 bool operator()(Ath__wire* wire1, Ath__wire* wire2) {
609 return (wire1->getXY() < wire2->getXY() ? true : false);
610 }
611 };
612
613 // FIXME MATT
buildDgContext(Ath__array1D<SEQ * > * dgContext,Ath__wire ** & allWire,int & awcnt,int & awsize)614 void Ath__track::buildDgContext(Ath__array1D<SEQ*>* dgContext,
615 Ath__wire**& allWire, int& awcnt, int& awsize) {
616 std::vector<Ath__wire*> ctxwire;
617 Ath__track* track = NULL;
618 bool tohi = true;
619 uint tcnt = 0;
620 while ((track = getNextSubTrack(track, tohi))) {
621 tcnt++;
622 track->getTrackWires(ctxwire);
623 }
624 uint ctxsize = ctxwire.size();
625 if (ctxsize == 0)
626 return;
627 if (tcnt > 1 && ctxsize > 1)
628 std::sort(ctxwire.begin(), ctxwire.end(), compareAthWire());
629 uint jj;
630 Ath__wire* nwire;
631 uint xidx = 0;
632 uint yidx = 1;
633 uint lidx, bidx;
634 AthPool<SEQ>* seqPool = _grid->getGridTable()->seqPool();
635 SEQ* seq;
636 int rsegid;
637 for (jj = 0; jj < ctxsize; jj++) {
638 if (awcnt == awsize) {
639 awsize += 1024;
640 allWire = (Ath__wire**)realloc(allWire, sizeof(Ath__wire*) * awsize);
641 }
642 nwire = ctxwire[jj];
643 allWire[awcnt++] = nwire;
644 seq = seqPool->alloc();
645 lidx = _grid->getDir() == 1 ? xidx : yidx;
646 bidx = _grid->getDir() == 1 ? yidx : xidx;
647 seq->_ll[lidx] = nwire->_xy;
648 seq->_ll[bidx] = nwire->_base;
649 seq->_ur[lidx] = nwire->_xy + nwire->_len;
650 seq->_ur[bidx] = nwire->_base + nwire->_width;
651 if (nwire->isPower())
652 seq->type = 0;
653 else if (nwire->isVia())
654 seq->type = 0;
655 else {
656 nwire->getNet()->getWire()->getProperty((int)nwire->_otherId, rsegid);
657 seq->type = rsegid;
658 }
659 dgContext->add(seq);
660 }
661 }
662
buildDgContext(int gridn,int base)663 void Ath__grid::buildDgContext(int gridn, int base) {
664 static Ath__wire** allCtxwire = NULL;
665 static int awcnt;
666 static int awsize;
667 if (allCtxwire == NULL) {
668 allCtxwire = (Ath__wire**)calloc(sizeof(Ath__wire*), 4096);
669 awsize = 4096;
670 }
671 awcnt = 0;
672 uint btrackN = getMinMaxTrackNum(base);
673 uint dgContextTrackRange = _gridtable->getCcFlag();
674 int lowtrack =
675 btrackN >= dgContextTrackRange ? -dgContextTrackRange : -btrackN;
676 int hitrack = btrackN + dgContextTrackRange < _trackCnt
677 ? dgContextTrackRange
678 : _trackCnt - 1 - btrackN;
679 _gridtable->dgContextBaseTrack()[gridn] = btrackN;
680 _gridtable->dgContextLowTrack()[gridn] = lowtrack;
681 _gridtable->dgContextHiTrack()[gridn] = hitrack;
682 int tt;
683 for (tt = lowtrack; tt <= hitrack; tt++) {
684 Ath__array1D<SEQ*>* dgContext =
685 _gridtable->renewDgContext(gridn, dgContextTrackRange + tt);
686 Ath__track* ttrack = _trackTable[btrackN + tt];
687 if (!ttrack)
688 continue;
689 _gridtable->dgContextTrackBase()[gridn][dgContextTrackRange + tt] =
690 ttrack->getBase();
691 ttrack->buildDgContext(dgContext, allCtxwire, awcnt, awsize);
692 }
693 int jj;
694 for (jj = 0; jj < awcnt; jj++)
695 allCtxwire[jj]->_ext = 0;
696 }
renewDgContext(uint gridn,uint trackn)697 Ath__array1D<SEQ*>* Ath__gridTable::renewDgContext(uint gridn, uint trackn) {
698 Ath__array1D<SEQ*>* dgContext = _dgContextArray[gridn][trackn];
699 for (uint ii = 0; ii < dgContext->getCnt(); ii++)
700 _seqPool->free(dgContext->get(ii));
701 dgContext->resetCnt(0);
702 SEQ* seq = _seqPool->alloc();
703 seq->_ll[0] = 0;
704 seq->_ll[1] = 0;
705 seq->_ur[0] = 0;
706 seq->_ur[1] = 0;
707 dgContext->add(seq);
708 return dgContext;
709 }
710
buildDgContext(int base,uint level,uint dir)711 void Ath__gridTable::buildDgContext(int base, uint level, uint dir) {
712 *_dgContextBaseLvl = level;
713 *_dgContextLowLvl = (int)level - (int)*_dgContextDepth >= 1
714 ? -(int)*_dgContextDepth
715 : 1 - (int)level;
716 *_dgContextHiLvl = (int)level + (int)*_dgContextDepth < (int)_colCnt
717 ? (int)*_dgContextDepth
718 : (int)_colCnt - 1 - (int)level;
719 int jj;
720 for (jj = *_dgContextLowLvl; jj <= *_dgContextHiLvl; jj++) {
721 _gridTable[dir][level + jj]->buildDgContext(*_dgContextDepth + jj, base);
722 }
723 // for the glitich between def _layerCnt and extRule _layerCnt,
724 // extmeasure may look up one extra layer
725 int dgContextTrackRange = _ccFlag;
726 int tt;
727 for (jj = -(int)*_dgContextDepth; jj < *_dgContextLowLvl; jj++) {
728 for (tt = -dgContextTrackRange; tt <= dgContextTrackRange; tt++)
729 renewDgContext(*_dgContextDepth + jj, dgContextTrackRange + tt);
730 }
731 for (jj = *_dgContextHiLvl + 1; jj < (int)*_dgContextDepth; jj++) {
732 for (tt = -dgContextTrackRange; tt <= dgContextTrackRange; tt++)
733 renewDgContext(*_dgContextDepth + jj, dgContextTrackRange + tt);
734 }
735 }
736
couplingCaps(Ath__gridTable * resGridTable,uint couplingDist,ZInterface * context,Ath__array1D<uint> * ccTable,rcx::CoupleAndCompute coupleAndCompute,void * compPtr)737 uint Ath__gridTable::couplingCaps(Ath__gridTable* resGridTable,
738 uint couplingDist, ZInterface* context,
739 Ath__array1D<uint>* ccTable,
740 rcx::CoupleAndCompute coupleAndCompute,
741 void* compPtr) {
742 // ttttGetDgOverlap= 0;
743 // if (couplingDist>20) {
744 // couplingDist= couplingDist % 10;
745 // ttttGetDgOverlap= 1;
746 // }
747 ttttGetDgOverlap = 1;
748 setCCFlag(couplingDist);
749 _CCshorts = 0;
750 uint cnt = 0;
751 for (uint jj = 0; jj < _colCnt; jj++) {
752 // for (uint ii= 0; ii<_rowCnt; ii++) {
753 for (int ii = _rowCnt - 1; ii >= 0; ii--) {
754 Ath__grid* resGrid = NULL;
755 if (resGridTable != NULL)
756 resGrid = resGridTable->getGrid(ii, jj);
757 // notice(0, "-----------------------------Grid
758 // dir= %d Layer=%d\n", ii, jj);
759
760 Ath__grid* netGrid = _gridTable[ii][jj];
761 if (netGrid == NULL)
762 continue;
763
764 // netGrid->adjustMarkers();
765
766 cnt += netGrid->couplingCaps(resGrid, couplingDist, context, ccTable,
767 coupleAndCompute, compPtr);
768
769 #ifdef ZDEBUG
770 context->event("GRID", "dir", Z_INT, ii, "layer", Z_INT, jj, NULL);
771 #endif
772 }
773 }
774 notice(0, "Final %d ccaps\n", cnt);
775 notice(0, " %d interTrack shorts\n", _CCshorts);
776 return cnt;
777 }
couplingCaps(uint row,uint col,Ath__grid * resGrid,uint couplingDist,ZInterface * context)778 uint Ath__gridTable::couplingCaps(uint row, uint col, Ath__grid* resGrid,
779 uint couplingDist, ZInterface* context) {
780 return 0;
781 // return _gridTable[row][col]->couplingCaps(resGrid, couplingDist, context);
782 }
couplingCaps(int hiXY,uint couplingDist,uint & wireCnt,rcx::CoupleAndCompute coupleAndCompute,void * compPtr,int * limitArray)783 int Ath__grid::couplingCaps(int hiXY, uint couplingDist, uint& wireCnt,
784 rcx::CoupleAndCompute coupleAndCompute,
785 void* compPtr, int* limitArray) {
786 // CHECK ccTable
787
788 // Ath__array1D<Ath__wire*> ccTable;
789 // Ath__array1D<Ath__wire*> wTable;
790
791 uint coupleTrackNum = couplingDist; // EXT-OPTIMIZE
792 uint ccThreshold = coupleTrackNum * _pitch;
793 uint TargetHighMarkedNet = _gridtable->targetHighMarkedNet();
794 bool allNet = _gridtable->allNet();
795
796 uint domainAdjust = allNet || !TargetHighMarkedNet ? 0 : couplingDist;
797
798 initContextGrids();
799 setSearchDomain(domainAdjust);
800
801 limitArray[0] = _lastFreeTrack;
802 limitArray[1] = _base + _lastFreeTrack * _pitch;
803
804 limitArray[6] = _searchHiTrack;
805 limitArray[7] = _base + _searchHiTrack * _pitch;
806
807 limitArray[2] = _currentTrack;
808 limitArray[3] = _base + _currentTrack * _pitch;
809
810 for (uint ii = _currentTrack; ii <= _searchHiTrack; ii++) {
811 int baseXY = _base + _pitch * ii; // TO_VERIFY for continuation of track
812 // minExtracted= baseXY; // TO_VERIFY for continuation of track
813 int hiEnd = hiXY - (ccThreshold + _pitch);
814 if (baseXY >= hiEnd) {
815 // if (baseXY>=hiXY) {
816 _currentTrack = ii;
817
818 limitArray[4] = ii;
819 limitArray[5] = _base + ii * _pitch;
820
821 return baseXY;
822 }
823
824 Ath__track* btrack = _trackTable[ii];
825 if (btrack == NULL)
826 continue;
827
828 int base = btrack->getBase();
829 _gridtable->buildDgContext(base, _level, _dir);
830 if (!ttttGetDgOverlap)
831 coupleAndCompute(rcx::coupleOptionsNull, compPtr); // try print dgContext
832
833 Ath__track* track = NULL;
834 bool tohi = true;
835 while ((track = btrack->getNextSubTrack(track, tohi))) {
836 _gridtable->setHandleEmptyOnly(false);
837 uint cnt1 =
838 track->couplingCaps(NULL, ii, coupleTrackNum, ccThreshold, NULL, NULL,
839 _level, coupleAndCompute, compPtr);
840 wireCnt += cnt1;
841 if (allNet || TargetHighMarkedNet)
842 _gridtable->setHandleEmptyOnly(true);
843 _gridtable->reverseTargetTrack();
844 // cnt1= track->couplingCaps(resGrid, ii, coupleTrackNum, ccThreshold,
845 // context, ccTable, _level, coupleAndCompute, compPtr);
846 cnt1 = track->couplingCaps(NULL, ii, coupleTrackNum, ccThreshold, NULL,
847 NULL, _level, coupleAndCompute, compPtr);
848 wireCnt += cnt1;
849 _gridtable->reverseTargetTrack();
850 }
851 // notice(0, "CC: Track - %5d : %d out of %d\n", ii, cnt1, cnt);
852 }
853 limitArray[4] = _searchHiTrack;
854 limitArray[5] = hiXY;
855 return hiXY; // finished
856 }
dealloc(int hiXY)857 int Ath__grid::dealloc(int hiXY) {
858 // uint cnt= 0;
859 for (uint ii = _lastFreeTrack; ii <= _searchHiTrack; ii++) {
860 int baseXY = _base + _pitch * ii; // TO_VERIFY for continuation of track
861 if (baseXY >= hiXY) {
862 _lastFreeTrack = ii;
863 return baseXY;
864 }
865
866 Ath__track* btrack = _trackTable[ii];
867 if (btrack == NULL)
868 continue;
869
870 Ath__track* track = NULL;
871 bool tohi = true;
872 while ((track = btrack->getNextSubTrack(track, tohi))) {
873 track->dealloc(_wirePoolPtr);
874 _trackPoolPtr->free(track);
875 }
876 _trackTable[ii] = NULL;
877
878 // btrack->dealloc(_wirePoolPtr);
879 //_trackPoolPtr->free(btrack);
880 }
881 _lastFreeTrack = _searchHiTrack;
882 return hiXY;
883 }
dealloc(uint dir,int hiXY)884 int Ath__gridTable::dealloc(uint dir, int hiXY) {
885 for (uint jj = 1; jj < _colCnt; jj++) {
886 Ath__grid* netGrid = _gridTable[dir][jj];
887 if (netGrid == NULL)
888 continue;
889
890 netGrid->dealloc(hiXY);
891 }
892 return hiXY;
893 }
894
getBandWires(Ath__array1D<Ath__wire * > * bandWire)895 int Ath__track::getBandWires(Ath__array1D<Ath__wire*>* bandWire) {
896 uint midx;
897 Ath__wire* wire;
898 Ath__wire* srcwire;
899 int cnt = 0;
900 for (midx = 0; midx < _markerCnt; midx++) {
901 wire = _marker[midx];
902 while (wire) {
903 srcwire = wire->_srcId ? _grid->getWirePtr(wire->_srcId) : wire;
904 if (srcwire->_ext == 0) {
905 srcwire->_ext = 1;
906 bandWire->add(srcwire);
907 cnt++;
908 }
909 wire = wire->_next;
910 }
911 }
912 return cnt;
913 }
914
getBandWires(int hiXY,uint couplingDist,uint & wireCnt,Ath__array1D<Ath__wire * > * bandWire,int * limitArray)915 int Ath__grid::getBandWires(int hiXY, uint couplingDist, uint& wireCnt,
916 Ath__array1D<Ath__wire*>* bandWire,
917 int* limitArray) {
918 // CHECK ccTable
919
920 // Ath__array1D<Ath__wire*> ccTable;
921 // Ath__array1D<Ath__wire*> wTable;
922
923 uint coupleTrackNum = couplingDist; // EXT-OPTIMIZE
924 uint ccThreshold = coupleTrackNum * _pitch;
925 uint TargetHighMarkedNet = _gridtable->targetHighMarkedNet();
926 bool allNet = _gridtable->allNet();
927
928 uint domainAdjust = allNet || !TargetHighMarkedNet ? 0 : couplingDist;
929
930 // initContextGrids();
931 setSearchDomain(domainAdjust);
932
933 int hiEnd = hiXY - (ccThreshold + _pitch);
934 int endTrack = getMinMaxTrackNum(hiEnd);
935 // int startTrack = _currentTrack;
936 _currentTrack = endTrack;
937 if (_base + _pitch * endTrack < hiEnd)
938 _currentTrack++;
939 if (_currentTrack > _searchHiTrack)
940 _currentTrack = _searchHiTrack;
941 int minExtracted = _base + _pitch * _currentTrack;
942 int baseXY = minExtracted;
943 if (_currentTrack == _searchHiTrack)
944 baseXY = hiXY;
945
946 int fullEndTrack = getMinMaxTrackNum(hiXY) + coupleTrackNum + 2;
947 if (fullEndTrack >= (int)_trackCnt)
948 fullEndTrack = _trackCnt - 1;
949 int jj;
950 bool tohi = true;
951 Ath__track* ttrack;
952 Ath__track* strack;
953 bandWire->resetCnt(0);
954
955 limitArray[0] = _lastFreeTrack;
956 limitArray[1] = _base + _lastFreeTrack * _pitch;
957 limitArray[6] = fullEndTrack;
958 limitArray[7] = _base + fullEndTrack * _pitch;
959
960 limitArray[2] = _currentTrack;
961 limitArray[3] = _base + _currentTrack * _pitch;
962
963 // for (jj = startTrack; jj <= _currentTrack; jj++)
964 for (jj = _lastFreeTrack; jj <= fullEndTrack; jj++) {
965 ttrack = _trackTable[jj];
966 strack = NULL;
967 while ((strack = ttrack->getNextSubTrack(strack, tohi)))
968 strack->getBandWires(bandWire);
969 }
970 limitArray[4] = fullEndTrack;
971 limitArray[5] = _base + fullEndTrack * _pitch;
972
973 for (jj = 0; jj < (int)bandWire->getCnt(); jj++)
974 bandWire->get(jj)->_ext = 0;
975 return baseXY;
976 }
977
couplingCaps(int hiXY,uint couplingDist,uint dir,uint & wireCnt,rcx::CoupleAndCompute coupleAndCompute,void * compPtr,bool getBandWire,int ** limitArray)978 int Ath__gridTable::couplingCaps(int hiXY, uint couplingDist, uint dir,
979 uint& wireCnt,
980 rcx::CoupleAndCompute coupleAndCompute,
981 void* compPtr, bool getBandWire,
982 int** limitArray) {
983 // ttttGetDgOverlap= 0;
984 // if (couplingDist>20) {
985 // couplingDist= couplingDist % 10;
986 // ttttGetDgOverlap= 1;
987 // }
988 ttttGetDgOverlap = 1;
989 setCCFlag(couplingDist);
990
991 if (getBandWire) {
992 if (_bandWire == NULL)
993 _bandWire = new Ath__array1D<Ath__wire*>(4096);
994 } else {
995 if (_bandWire)
996 delete (_bandWire);
997 _bandWire = NULL;
998 }
999 int minExtracted = hiXY;
1000 for (uint jj = 1; jj < _colCnt; jj++) {
1001 Ath__grid* netGrid = _gridTable[dir][jj];
1002 if (netGrid == NULL)
1003 continue;
1004
1005 int lastExtracted1;
1006 if (getBandWire)
1007 lastExtracted1 = netGrid->getBandWires(hiXY, couplingDist, wireCnt,
1008 _bandWire, limitArray[jj]);
1009 else
1010 lastExtracted1 =
1011 netGrid->couplingCaps(hiXY, couplingDist, wireCnt, coupleAndCompute,
1012 compPtr, limitArray[jj]);
1013
1014 if (minExtracted > lastExtracted1)
1015 minExtracted = lastExtracted1;
1016 }
1017 return minExtracted;
1018 }
initCouplingCapLoops(uint couplingDist,rcx::CoupleAndCompute coupleAndCompute,void * compPtr,bool startSearchTrack,int startXY)1019 int Ath__grid::initCouplingCapLoops(uint couplingDist,
1020 rcx::CoupleAndCompute coupleAndCompute,
1021 void* compPtr, bool startSearchTrack,
1022 int startXY) {
1023 //_coupleAndCompute= coupleAndCompute;
1024 //_compPtr= compPtr;
1025
1026 // uint coupleTrackNum= couplingDist; // EXT-OPTIMIZE
1027 // uint ccThreshold = coupleTrackNum*_pitch;
1028 uint TargetHighMarkedNet = _gridtable->targetHighMarkedNet();
1029 bool allNet = _gridtable->allNet();
1030
1031 uint domainAdjust = allNet || !TargetHighMarkedNet ? 0 : couplingDist;
1032
1033 initContextGrids();
1034 setSearchDomain(domainAdjust);
1035 if (startSearchTrack) {
1036 _currentTrack = _searchLowTrack;
1037 } else {
1038 _currentTrack = (startXY - _base) / _pitch;
1039 }
1040 _lastFreeTrack = 0;
1041
1042 return _base + _pitch * _searchHiTrack;
1043 }
initCouplingCapLoops(uint dir,uint couplingDist,rcx::CoupleAndCompute coupleAndCompute,void * compPtr,int * startXY)1044 void Ath__gridTable::initCouplingCapLoops(
1045 uint dir, uint couplingDist, rcx::CoupleAndCompute coupleAndCompute,
1046 void* compPtr, int* startXY) {
1047 // ttttGetDgOverlap= 0;
1048 // if (couplingDist>20) {
1049 // couplingDist= couplingDist % 10;
1050 // ttttGetDgOverlap= 1;
1051 // }
1052 ttttGetDgOverlap = 1;
1053 setCCFlag(couplingDist);
1054
1055 for (uint jj = 1; jj < _colCnt; jj++) {
1056 Ath__grid* netGrid = _gridTable[dir][jj];
1057 if (netGrid == NULL)
1058 continue;
1059
1060 if (startXY == NULL)
1061 netGrid->initCouplingCapLoops(couplingDist, coupleAndCompute, compPtr);
1062 else
1063 netGrid->initCouplingCapLoops(couplingDist, coupleAndCompute, compPtr,
1064 false, startXY[jj]);
1065 }
1066 }
1067