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