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 "rcx/extRCap.h"
36 #include "rcx/extprocess.h"
37 
38 #ifdef _WIN32
39 #include "direct.h"
40 #endif
41 
42 #include <map>
43 #include <vector>
44 
45 #include "utl/Logger.h"
46 
47 //#define SKIP_SOLVER
48 namespace rcx {
49 
50 using utl::RCX;
51 
52 bool OUREVERSEORDER = false;
53 
getMetIndexOverUnder(int met,int mUnder,int mOver,int layerCnt,int maxCnt=10000)54 static int getMetIndexOverUnder(int met, int mUnder, int mOver,
55                                 int layerCnt, int maxCnt=10000) {
56   int n = layerCnt - met - 1;
57   n *= mUnder - 1;
58   n += mOver - met - 1;
59 
60   if ((n < 0) || (n >= maxCnt)) {
61     return -1;
62   }
63 
64   return n;
65 }
getMaxMetIndexOverUnder(int met,int layerCnt)66 static int getMaxMetIndexOverUnder(int met, int layerCnt) {
67   int n = 0;
68   for (uint u = met - 1; u > 0; u--) {
69     for (uint o = met + 1; o < layerCnt; o++) {
70       int metIndex = getMetIndexOverUnder(met, u, o, layerCnt);
71       if (n < metIndex)
72         n = metIndex;
73     }
74   }
75   return n;
76 }
77 
lineSegment(double X,double x1,double x2,double y1,double y2)78 static double lineSegment(double X, double x1, double x2, double y1,
79                           double y2) {
80   double slope = (y2 - y1) / (x2 - x1);
81   double retVal = y2 - slope * (x2 - X);
82 
83   return retVal;
84 }
interpolate(uint d,extDistRC * rc1,extDistRC * rc2)85 void extDistRC::interpolate(uint d, extDistRC* rc1, extDistRC* rc2) {
86   _sep = d;
87   _coupling =
88       lineSegment(d, rc1->_sep, rc2->_sep, rc1->_coupling, rc2->_coupling);
89   _fringe = lineSegment(d, rc1->_sep, rc2->_sep, rc1->_fringe, rc2->_fringe);
90   _res = lineSegment(d, rc1->_sep, rc2->_sep, rc1->_res, rc2->_res);
91 }
interpolate_res(uint d,extDistRC * rc2)92 double extDistRC::interpolate_res(uint d, extDistRC* rc2) {
93   return lineSegment(d, _coupling, rc2->_coupling, _res, rc2->_res);
94 }
set(uint d,double cc,double fr,double a,double r)95 void extDistRC::set(uint d, double cc, double fr, double a, double r) {
96   _sep = d;
97   _coupling = cc;
98   _fringe = fr;
99   //	_area= a;
100   _diag = a;
101   _res = r;
102 }
readRC(Ath__parser * parser,double dbFactor)103 void extDistRC::readRC(Ath__parser* parser, double dbFactor) {
104   _sep = Ath__double2int(dbFactor * 1000 * parser->getDouble(0));
105   _coupling = parser->getDouble(1) / dbFactor;
106   _fringe = parser->getDouble(2) / dbFactor;
107   //	_area= a;
108   _res = parser->getDouble(3) / dbFactor;
109 }
readRC_res2(Ath__parser * parser,double dbFactor)110 void extDistRC::readRC_res2(Ath__parser* parser, double dbFactor) {
111   _sep = Ath__double2int(dbFactor * 1000 * parser->getDouble(1));
112   _coupling = Ath__double2int(dbFactor * 1000 * parser->getDouble(0));
113   _fringe = parser->getDouble(2) / dbFactor;
114   //	_area= a;
115   _res = parser->getDouble(3) / dbFactor;
116 }
getCoupling()117 double extDistRC::getCoupling() { return _coupling; }
getFringe()118 double extDistRC::getFringe() { return _fringe; }
getDiag()119 double extDistRC::getDiag() { return _diag; }
getRes()120 double extDistRC::getRes() { return _res; }
writeRC()121 void extDistRC::writeRC() {
122   logger_->info(RCX, 208, "{} {} {} {}  {}", 0.001 * _sep, _coupling, _fringe,
123                 _res, _coupling + _fringe);
124 }
writeRC(FILE * fp,bool bin)125 void extDistRC::writeRC(FILE* fp, bool bin) {
126   // fprintf(fp, "%g %g %g %g\n", _dist, _coupling, _fringe, _res);
127   fprintf(fp, "%g %g %g %g\n", 0.001 * _sep, _coupling, _fringe, _res);
128 }
makeCapTableOver()129 void extRCTable::makeCapTableOver() {
130   _over = true;
131 
132   for (uint jj = 1; jj < _maxCnt1; jj++) {
133     _inTable[jj] = new Ath__array1D<extDistRC*>* [jj];
134     _table[jj] = new Ath__array1D<extDistRC*>* [jj];
135 
136     for (uint kk = 0; kk < jj; kk++) {
137       _inTable[jj][kk] = new Ath__array1D<extDistRC*>(32);
138       _table[jj][kk] = new Ath__array1D<extDistRC*>(512);
139     }
140   }
141 }
makeCapTableUnder()142 void extRCTable::makeCapTableUnder() {
143   _over = false;
144   for (uint jj = 1; jj < _maxCnt1; jj++) {
145     _inTable[jj] = new Ath__array1D<extDistRC*>* [_maxCnt1];
146     _table[jj] = new Ath__array1D<extDistRC*>* [_maxCnt1];
147 
148     for (uint ii = 0; ii < jj; ii++) {
149       _inTable[jj][ii] = NULL;
150       _table[jj][ii] = NULL;
151     }
152     for (uint kk = jj + 1; kk < _maxCnt1; kk++) {
153       _inTable[jj][kk] = new Ath__array1D<extDistRC*>(32);
154       _table[jj][kk] = new Ath__array1D<extDistRC*>(512);
155     }
156   }
157 }
158 
extDistRCTable(uint distCnt)159 extDistRCTable::extDistRCTable(uint distCnt) {
160   uint n = 16 * (distCnt / 16 + 1);
161   _measureTable = new Ath__array1D<extDistRC*>(n);
162 
163   _computeTable = NULL;
164 }
165 
~extDistRCTable()166 extDistRCTable::~extDistRCTable() {
167   if (_measureTable != NULL)
168     delete _measureTable;
169   if (_computeTable != NULL)
170     delete _computeTable;
171 }
mapExtrapolate(uint loDist,extDistRC * rc2,uint distUnit,AthPool<extDistRC> * rcPool)172 uint extDistRCTable::mapExtrapolate(uint loDist, extDistRC* rc2, uint distUnit,
173                                     AthPool<extDistRC>* rcPool) {
174   uint cnt = 0;
175   uint d1 = loDist;
176   uint d2 = rc2->_sep;
177 
178   for (uint d = d1; d <= d2; d += distUnit) {
179     extDistRC* rc = rcPool->alloc();
180 
181     rc->_sep = d;
182     rc->_coupling = rc2->_coupling;
183     rc->_fringe = rc2->_fringe;
184     rc->_res = rc2->_res;
185 
186     // rc->_coupling= lineSegment(d, rc1->_dist, rc2->_dist, rc1->_coupling,
187     // rc1->_coupling); rc->_fringe= lineSegment(d,   rc1->_dist, rc2->_dist,
188     // rc1->_coupling, rc1->_coupling); rc->_res= lineSegment(d, rc1->_dist,
189     // rc2->_dist, rc1->_res, rc1->_res);
190 
191     uint n = d / distUnit;
192 
193     _computeTable->set(n, rc);
194 
195     cnt++;
196   }
197   return cnt;
198 }
mapInterpolate(extDistRC * rc1,extDistRC * rc2,uint distUnit,int maxDist,AthPool<extDistRC> * rcPool)199 uint extDistRCTable::mapInterpolate(extDistRC* rc1, extDistRC* rc2,
200                                     uint distUnit, int maxDist,
201                                     AthPool<extDistRC>* rcPool) {
202   uint cnt = 0;
203   uint d1 = rc1->_sep;
204   uint d2 = rc2->_sep;
205 
206   if ((int)d2 > maxDist)
207     d2 = maxDist;
208 
209   for (uint d = d1; d <= d2; d += distUnit) {
210     extDistRC* rc = rcPool->alloc();
211 
212     rc->_sep = d;
213     rc->interpolate(rc->_sep, rc1, rc2);
214 
215     uint n = d / distUnit;
216 
217     _computeTable->set(n, rc);
218 
219     cnt++;
220   }
221   return cnt;
222 }
interpolate(uint distUnit,int maxDist,AthPool<extDistRC> * rcPool)223 uint extDistRCTable::interpolate(uint distUnit, int maxDist,
224                                  AthPool<extDistRC>* rcPool) {
225   uint cnt = _measureTable->getCnt();
226   uint Cnt = cnt;
227   if (cnt == 0)
228     return 0;
229 
230   if (maxDist < 0) {
231     extDistRC* lastRC = _measureTable->get(cnt - 1);
232     maxDist = lastRC->_sep;
233     if (maxDist == 100000) {
234       maxDist = _measureTable->get(cnt - 2)->_sep;
235       if (maxDist == 99000) {
236         maxDist = _measureTable->get(cnt - 3)->_sep;
237         Cnt = cnt - 2;
238       } else
239         Cnt = cnt - 1;
240       extDistRC* rc31 = rcPool->alloc();
241       rc31->set(0, 0.0, 0.0, 0.0, 0.0);
242       _measureTable->set(31, rc31);
243     }
244   }
245 
246   makeComputeTable(maxDist, distUnit);
247 
248   mapExtrapolate(0, _measureTable->get(0), distUnit, rcPool);
249 
250   for (uint ii = 0; ii < Cnt - 1; ii++) {
251     extDistRC* rc1 = _measureTable->get(ii);
252     extDistRC* rc2 = _measureTable->get(ii + 1);
253 
254     mapInterpolate(rc1, rc2, distUnit, maxDist, rcPool);
255   }
256   if (Cnt != cnt) {
257     extDistRC* rc1 = _measureTable->get(Cnt);
258     extDistRC* rc = rcPool->alloc();
259     rc->set(rc1->_sep, rc1->_coupling, rc1->_fringe, 0.0, rc1->_res);
260     _computeTable->set(_computeTable->getSize() - 1, rc);
261   }
262 
263   return _computeTable->getCnt();
264 }
writeRules(FILE * fp,Ath__array1D<extDistRC * > * table,double w,bool bin)265 uint extDistRCTable::writeRules(FILE* fp, Ath__array1D<extDistRC*>* table,
266                                 double w, bool bin) {
267   uint cnt = table->getCnt();
268   if (cnt > 0) {
269     extDistRC* rc1 = table->get(cnt - 1);
270     if (rc1 != NULL)
271       rc1->set(rc1->_sep, 0, rc1->_coupling + rc1->_fringe, 0.0, rc1->_res);
272   }
273 
274   fprintf(fp, "DIST count %d width %g\n", cnt, w);
275 
276   for (uint ii = 0; ii < cnt; ii++)
277     table->get(ii)->writeRC(fp, bin);
278 
279   fprintf(fp, "END DIST\n");
280   return cnt;
281 }
writeDiagRules(FILE * fp,Ath__array1D<extDistRC * > * table,double w1,double w2,double s,bool bin)282 uint extDistRCTable::writeDiagRules(FILE* fp, Ath__array1D<extDistRC*>* table,
283                                     double w1, double w2, double s, bool bin) {
284   uint cnt = table->getCnt();
285 
286   fprintf(fp, "DIST count %d width %g diag_width %g diag_dist %g\n", cnt, w1,
287           w2, s);
288   for (uint ii = 0; ii < cnt; ii++)
289     table->get(ii)->writeRC(fp, bin);
290 
291   fprintf(fp, "END DIST\n");
292   return cnt;
293 }
writeRules(FILE * fp,double w,bool compute,bool bin)294 uint extDistRCTable::writeRules(FILE* fp, double w, bool compute, bool bin) {
295   if (compute)
296     return writeRules(fp, _computeTable, w, bin);
297   else
298     return writeRules(fp, _measureTable, w, bin);
299 }
writeDiagRules(FILE * fp,double w1,double w2,double s,bool compute,bool bin)300 uint extDistRCTable::writeDiagRules(FILE* fp, double w1, double w2, double s,
301                                     bool compute, bool bin) {
302   if (compute)
303     return writeDiagRules(fp, _computeTable, w1, w2, s, bin);
304   else
305     return writeDiagRules(fp, _measureTable, w1, w2, s, bin);
306 }
readRCstats(Ath__parser * parser)307 uint extMetRCTable::readRCstats(Ath__parser* parser) {
308   uint cnt = 0;
309 
310   extMeasure m;
311 
312   while (parser->parseNextLine() > 0) {
313     cnt++;
314 
315     m._overUnder = false;
316     m._over = false;
317 
318     if ((parser->isKeyword(2, "OVER")) && (parser->isKeyword(4, "UNDER"))) {
319       m._met = parser->getInt(1);
320       m._overMet = parser->getInt(5);
321       m._underMet = parser->getInt(3);
322       m._overUnder = true;
323 
324       m._w_m = parser->getDouble(7);
325       m._w_nm = Ath__double2int(m._w_m * 1000);
326 
327       m._s_m = parser->getDouble(9);
328       m._s_nm = Ath__double2int(m._s_m * 1000);
329 
330       extDistRC* rc = _rcPoolPtr->alloc();
331 
332       rc->set(m._s_nm, parser->getDouble(10), parser->getDouble(11), 0.0,
333               parser->getDouble(12));
334 
335       m._tmpRC = rc;
336     } else if (parser->isKeyword(2, "UNDER") ||
337                parser->isKeyword(2, "DIAGUNDER")) {
338       m._met = parser->getInt(1);
339       m._overMet = parser->getInt(4);
340       m._underMet = -1;
341 
342       m._w_m = parser->getDouble(6);
343       m._w_nm = Ath__double2int(m._w_m * 1000);
344 
345       m._s_m = parser->getDouble(8);
346       m._s_nm = Ath__double2int(m._s_m * 1000);
347 
348       extDistRC* rc = _rcPoolPtr->alloc();
349 
350       rc->set(m._s_nm, parser->getDouble(9), parser->getDouble(10), 0.0,
351               parser->getDouble(11));
352 
353       m._tmpRC = rc;
354     } else if (parser->isKeyword(2, "OVER")) {
355       m._met = parser->getInt(1);
356       m._underMet = parser->getInt(4);
357       m._overMet = -1;
358       m._over = true;
359 
360       m._w_m = parser->getDouble(6);
361       m._w_nm = Ath__double2int(m._w_m * 1000);
362 
363       m._s_m = parser->getDouble(8);
364       m._s_nm = Ath__double2int(m._s_m * 1000);
365 
366       extDistRC* rc = _rcPoolPtr->alloc();
367 
368       rc->set(m._s_nm, parser->getDouble(9), parser->getDouble(10), 0.0,
369               parser->getDouble(11));
370 
371       m._tmpRC = rc;
372     }
373     addRCw(&m);
374   }
375   mkWidthAndSpaceMappings();
376   return cnt;
377 }
readRules_res2(Ath__parser * parser,AthPool<extDistRC> * rcPool,bool compute,bool bin,bool ignore,double dbFactor)378 uint extDistRCTable::readRules_res2(Ath__parser* parser,
379                                     AthPool<extDistRC>* rcPool, bool compute,
380                                     bool bin, bool ignore, double dbFactor) {
381   parser->parseNextLine();
382   uint cnt = parser->getInt(2);
383   if (cnt < 32)
384     cnt = 32;
385   // _measureTable= NULL;
386 
387   Ath__array1D<extDistRC*>* table = NULL;
388   if (!ignore)
389     table = new Ath__array1D<extDistRC*>(cnt);
390 
391   Ath__array1D<extDistRC*>* table0 = new Ath__array1D<extDistRC*>(8);
392   //_computeTableR = new Ath__array1D<extDistRC*>[8];
393   int cnt1 = 0;
394   int kk = 0;
395   extDistRC* rc0 = NULL;
396   while (parser->parseNextLine() > 0) {
397     if (parser->isKeyword(0, "END"))
398       break;
399 
400     if (ignore)
401       continue;
402 
403     extDistRC* rc = rcPool->alloc();
404     rc->readRC_res2(parser, dbFactor);
405     // if (rc0!=NULL && rc0->_res==rc->_res && rc0->_coupling==rc->_coupling) {
406     //   continue;
407     // }
408     table->add(rc);
409     if (rc0 != NULL && rc0->_coupling != rc->_coupling) {
410       _measureTable = table0;
411       if (table0->getCnt() > 1) {
412         interpolate(4, -1, rcPool);
413         _computeTableR[kk] = _computeTable;
414       }
415       _measureTableR[kk] = table0;
416       kk++;
417 
418       table0 = new Ath__array1D<extDistRC*>(cnt1);
419       cnt1 = 0;
420 
421       _maxDist = rc0->_sep;
422     }
423     if (rc0 == NULL) {
424       table0->add(rc);
425     } else if (cnt1 == 0) {
426       table0->add(rc);
427     } else if (rc0->_res != rc->_res) {
428       table0->add(rc);
429     }
430     cnt1++;
431     rc0 = rc;
432   }
433   _distCnt = kk + 1;
434   _measureTableR[kk] = table0;
435   _measureTable = table;
436 
437   return cnt;
438 }
readRules(Ath__parser * parser,AthPool<extDistRC> * rcPool,bool compute,bool bin,bool ignore,double dbFactor)439 uint extDistRCTable::readRules(Ath__parser* parser, AthPool<extDistRC>* rcPool,
440                                bool compute, bool bin, bool ignore,
441                                double dbFactor) {
442   parser->parseNextLine();
443   uint cnt = parser->getInt(2);
444   if (cnt < 32)
445     cnt = 32;
446   // _measureTable= NULL;
447 
448   Ath__array1D<extDistRC*>* table = NULL;
449   if (!ignore)
450     table = new Ath__array1D<extDistRC*>(cnt);
451 
452   while (parser->parseNextLine() > 0) {
453     if (parser->isKeyword(0, "END"))
454       break;
455 
456     if (ignore)
457       continue;
458 
459     extDistRC* rc = rcPool->alloc();
460     rc->readRC(parser, dbFactor);
461     table->add(rc);
462   }
463   bool SCALE_RES_ON_MAX_DIST = true;
464   if (SCALE_RES_ON_MAX_DIST) {
465     double SUB_MULT_RES = 0.5;
466     // ScaleRes(SUB_MULT_RES, table);
467   }
468   if (ignore)
469     return cnt;
470 
471   _measureTable = table;
472 
473   if (compute)
474 #ifdef HI_ACC_1
475     // interpolate(12, -1, rcPool);
476     interpolate(4, -1, rcPool);
477 #else
478     interpolate(4, -1, rcPool);
479 #endif
480 
481   return cnt;
482 }
ScaleRes(double SUB_MULT_RES,Ath__array1D<extDistRC * > * table)483 void extDistRCTable::ScaleRes(double SUB_MULT_RES,
484                               Ath__array1D<extDistRC*>* table) {
485   uint cnt = table->getCnt();
486   if (cnt == 0)
487     return;
488 
489   extDistRC* rc_last = table->get(cnt - 1);
490 
491   for (uint jj = 0; jj < cnt; jj++) {
492     extDistRC* rc = table->get(jj);
493     double delta = rc->_res - rc_last->_res;
494     if (delta < 0)
495       delta = -delta;
496     if (delta > 0.000001)
497       continue;
498 
499     rc->_res *= SUB_MULT_RES;
500   }
501 }
makeComputeTable(uint maxDist,uint distUnit)502 void extDistRCTable::makeComputeTable(uint maxDist, uint distUnit) {
503   _unit = distUnit;  // in nm
504   uint n = maxDist / distUnit;
505   n = distUnit * (n / distUnit + 1);
506 
507   _computeTable = new Ath__array1D<extDistRC*>(n + 1);
508   // TODO
509 }
addMeasureRC(extDistRC * rc)510 uint extDistRCTable::addMeasureRC(extDistRC* rc) {
511   return _measureTable->add(rc);
512 }
getRC_99()513 extDistRC* extDistRCTable::getRC_99() {
514   if (_measureTable == NULL)
515     return NULL;
516 
517   uint cnt = _measureTable->getCnt();
518   if (cnt < 2)
519     return NULL;
520 
521   extDistRC* before_lastRC = _measureTable->get(cnt - 2);
522   if (before_lastRC->_sep == 99000)
523     return before_lastRC;
524 
525   extDistRC* lastRC =
526       _measureTable->getLast();  // assuming last is 100 equivalent to inf
527   if (lastRC->_sep == 99000)
528     return lastRC;
529 
530   return NULL;
531 }
getComputeRC(uint dist)532 extDistRC* extDistRCTable::getComputeRC(uint dist) {
533   if (_measureTable == NULL)
534     return NULL;
535 
536   if (_measureTable->getCnt() <= 0)
537     return NULL;
538 
539   extDistRC* firstRC = _measureTable->get(0);
540   uint firstDist = firstRC->_sep;
541   if (dist <= firstDist) {
542     return firstRC;
543   }
544 
545   /*
546   extDistRC* secondRC= _measureTable->get(1);
547         if (dist<=secondRC->_sep)
548                 return secondRC;
549   */
550   if (_measureTable->getLast()->_sep == 100000) {
551     extDistRC* before_lastRC =
552         _measureTable->getLast() - 1;  // assuming last is 100 equivalent to inf
553     uint lastDist = before_lastRC->_sep;
554 
555     if (lastDist == 99000)
556       before_lastRC = before_lastRC - 1;
557 
558     lastDist = before_lastRC->_sep;
559     if (dist >= lastDist) {  // send Inf dist
560       if (dist == lastDist)  // send Inf dist
561         return before_lastRC;
562       if (dist <= 2 * lastDist) {  // send Inf dist
563 
564         uint cnt = _measureTable->getCnt();
565         extDistRC* rc31 = _measureTable->geti(31);
566         extDistRC* rc2 = _measureTable->get(cnt - 2);
567         extDistRC* rc3 = _measureTable->get(cnt - 3);
568 
569         rc31->_sep = dist;
570         rc31->interpolate(dist, rc3, rc2);
571 
572         rc31->_coupling =
573             (before_lastRC->_coupling / dist) * before_lastRC->_sep;
574         rc31->_fringe = before_lastRC->_fringe;
575         // rc31->_fringe= (before_lastRC->_fringe / dist) * before_lastRC->_sep;
576         return rc31;
577         // return before_lastRC;
578       }
579       if (dist > lastDist) {  // send Inf dist
580         return _measureTable->getLast();
581       }
582     }
583   } else {
584     extDistRC* before_lastRC =
585         _measureTable->getLast();  // assuming last is 100 equivalent to inf
586     uint lastDist = before_lastRC->_sep;
587     if (dist >= lastDist - _unit && lastDist > 0)  // send Inf dist
588       return _measureTable->getLast();
589   }
590 
591   uint n = dist / _unit;
592   return _computeTable->geti(n);
593 }
594 /*
595 extDistRC* extDistRCTable::getComputeRC(double dist)
596 {
597         uint n= dist/_unit);
598         return _computeTable->get(n);
599 }
600 */
getWidthIndex(uint w)601 uint extDistWidthRCTable::getWidthIndex(uint w) {
602   // To notify that the RC info for a particular pattern
603   // is empty
604   if (_lastWidth == -1)
605     return -1;
606 
607   if ((int)w >= _lastWidth)
608     return _widthTable->getCnt() - 1;
609 
610   int v = w - _firstWidth;
611   if (v < 0)
612     return 0;
613 
614   return _widthMapTable->geti(v / _modulo);
615 }
getDiagWidthIndex(uint m,uint w)616 uint extDistWidthRCTable::getDiagWidthIndex(uint m, uint w) {
617   if (_lastDiagWidth == NULL)  // TO_DEBUG 620
618     return -1;
619 
620   if ((int)w >= _lastDiagWidth->geti(m))
621     return _diagWidthTable[m]->getCnt() - 1;
622 
623   int v = w - _firstDiagWidth->geti(m);
624   if (v < 0)
625     return 0;
626 
627   return _diagWidthMapTable[m]->geti(v / _modulo);
628 }
getDiagDistIndex(uint m,uint s)629 uint extDistWidthRCTable::getDiagDistIndex(uint m, uint s) {
630   if ((int)s >= _lastDiagDist->geti(m))
631     return _diagDistTable[m]->getCnt() - 1;
632 
633   int v = s - _firstDiagDist->geti(m);
634   if (v < 0)
635     return 0;
636 
637   return _diagDistMapTable[m]->geti(v / _modulo);
638 }
639 /*
640 void extDistWidthRCTable::setOUReverseOrder()
641 {
642         _ouReadReverse = true;
643 }
644 */
extDistWidthRCTable(bool over,uint met,uint layerCnt,uint metCnt,uint maxWidthCnt,AthPool<extDistRC> * rcPool)645 extDistWidthRCTable::extDistWidthRCTable(bool over, uint met, uint layerCnt,
646                                          uint metCnt, uint maxWidthCnt,
647                                          AthPool<extDistRC>* rcPool) {
648   _ouReadReverse = OUREVERSEORDER;
649   _over = over;
650   _layerCnt = layerCnt;
651   _met = met;
652 
653   _widthTable = new Ath__array1D<int>(maxWidthCnt);
654 
655   _firstWidth = 0;
656   _lastWidth = std::numeric_limits<int>::max();
657   _modulo = 4;
658 
659   _widthTableAllocFlag = false;
660   _widthMapTable = NULL;
661 
662   _metCnt = metCnt;
663 
664   _rcDistTable = new extDistRCTable** [_metCnt];
665   uint jj;
666   for (jj = 0; jj < _metCnt; jj++) {
667     _rcDistTable[jj] = new extDistRCTable* [maxWidthCnt];
668     for (uint ii = 0; ii < maxWidthCnt; ii++)
669       _rcDistTable[jj][ii] = new extDistRCTable(10);
670   }
671   _rcPoolPtr = rcPool;
672 
673   _firstDiagWidth = NULL;
674   _lastDiagWidth = NULL;
675   _firstDiagDist = NULL;
676   _lastDiagDist = NULL;
677 
678   for (jj = 0; jj < 16; jj++) {
679     _diagWidthMapTable[jj] = NULL;
680     _diagDistMapTable[jj] = NULL;
681     _diagWidthTable[jj] = NULL;
682     _diagDistTable[jj] = NULL;
683   }
684   _rcDiagDistTable = NULL;
685   _rc31 = rcPool->alloc();
686 }
createWidthMap()687 void extDistWidthRCTable::createWidthMap() {
688   uint widthCnt = _widthTable->getCnt();
689   if (widthCnt == 0)
690     return;
691 
692   _firstWidth = _widthTable->get(0);
693   _lastWidth = _widthTable->getLast();
694   _modulo = 4;
695 
696   _widthTableAllocFlag = true;
697   _widthMapTable = new Ath__array1D<uint>(10 * widthCnt);
698 
699   uint jj;
700   for (jj = 0; jj < widthCnt - 1; jj++) {
701     double v1 = _widthTable->get(jj);
702     double v2 = _widthTable->get(jj + 1);
703 
704     int w1 = Ath__double2int(v1);
705     int w2 = Ath__double2int(v2);
706 
707     for (int w = w1; w <= w2; w += _modulo) {
708       if (w >= _lastWidth)
709         continue;
710 
711       uint n = 0;
712       int v = w - _firstWidth;
713       if (v > 0)
714         n = v / _modulo;
715 
716       _widthMapTable->set(n, jj);
717     }
718   }
719 }
makeWSmapping()720 void extDistWidthRCTable::makeWSmapping() {
721   createWidthMap();
722 
723   for (uint jj = 0; jj < _metCnt; jj++)
724     for (uint ii = 0; ii < _widthTable->getCnt(); ii++)
725       _rcDistTable[jj][ii]->interpolate(4, -1, _rcPoolPtr);
726 }
extDistWidthRCTable(bool dummy,uint met,uint layerCnt,uint widthCnt)727 extDistWidthRCTable::extDistWidthRCTable(bool dummy, uint met, uint layerCnt,
728                                          uint widthCnt) {
729   _ouReadReverse = OUREVERSEORDER;
730   _met = met;
731   _layerCnt = layerCnt;
732 
733   _widthTable = new Ath__array1D<int>(widthCnt);
734   for (uint ii = 0; ii < widthCnt; ii++) {
735     _widthTable->add(0);
736   }
737 
738   _widthMapTable = NULL;
739   _widthTableAllocFlag = true;
740 
741   // _metCnt= 1;
742   _metCnt = layerCnt;
743 
744   _rcDistTable = new extDistRCTable** [_metCnt];
745   uint jj;
746   for (jj = 0; jj < _metCnt; jj++) {
747     _rcDistTable[jj] = new extDistRCTable* [widthCnt];
748     for (uint ii = 0; ii < widthCnt; ii++)
749       _rcDistTable[jj][ii] = new extDistRCTable(1);
750   }
751   _firstDiagWidth = NULL;
752   _lastDiagWidth = NULL;
753   _firstDiagDist = NULL;
754   _rcDiagDistTable = NULL;
755   _lastDiagDist = NULL;
756   for (jj = 0; jj < 32; jj++) {
757     _diagWidthMapTable[jj] = NULL;
758     _diagDistMapTable[jj] = NULL;
759     _diagWidthTable[jj] = NULL;
760     _diagDistTable[jj] = NULL;
761   }
762   _rc31 = NULL;
763 }
extDistWidthRCTable(bool over,uint met,uint layerCnt,uint metCnt,Ath__array1D<double> * widthTable,AthPool<extDistRC> * rcPool,double dbFactor)764 extDistWidthRCTable::extDistWidthRCTable(bool over, uint met, uint layerCnt,
765                                          uint metCnt,
766                                          Ath__array1D<double>* widthTable,
767                                          AthPool<extDistRC>* rcPool,
768                                          double dbFactor) {
769   _ouReadReverse = OUREVERSEORDER;
770   _over = over;
771   _layerCnt = layerCnt;
772   _met = met;
773 
774   if (widthTable->getCnt() == 0)
775     return;
776 
777   int widthCnt = widthTable->getCnt();
778   _widthTable = new Ath__array1D<int>(widthCnt);
779   for (uint ii = 0; ii < widthCnt; ii++) {
780     int w = Ath__double2int(dbFactor * 1000 * widthTable->get(ii));
781     _widthTable->add(w);
782   }
783   if (widthCnt > 0) {
784     _firstWidth = _widthTable->get(0);
785     _lastWidth = _widthTable->get(widthCnt - 1);
786   }
787 
788   _modulo = 4;
789 
790   _widthTableAllocFlag = true;
791   _widthMapTable = new Ath__array1D<uint>(10 * widthCnt);
792 
793   uint jj;
794   for (jj = 0; jj < widthCnt - 1; jj++) {
795     double v1 = _widthTable->get(jj);
796     double v2 = _widthTable->get(jj + 1);
797 
798     int w1 = Ath__double2int(v1);
799     int w2 = Ath__double2int(v2);
800 
801     for (int w = w1; w <= w2; w += _modulo) {
802       if (w >= _lastWidth)
803         continue;
804 
805       uint n = 0;
806       int v = w - _firstWidth;
807       if (v > 0)
808         n = v / _modulo;
809 
810       _widthMapTable->set(n, jj);
811     }
812   }
813 
814   _metCnt = metCnt;
815 
816   _rcDistTable = new extDistRCTable** [_metCnt];
817   for (jj = 0; jj < _metCnt; jj++) {
818     _rcDistTable[jj] = new extDistRCTable* [widthCnt];
819     for (uint ii = 0; ii < widthCnt; ii++)
820       _rcDistTable[jj][ii] = new extDistRCTable(10);
821   }
822   _rcPoolPtr = rcPool;
823 
824   _firstDiagWidth = NULL;
825   _lastDiagWidth = NULL;
826   _firstDiagDist = NULL;
827   _lastDiagDist = NULL;
828   for (jj = 0; jj < 12; jj++) {
829     _diagWidthMapTable[jj] = NULL;
830     _diagDistMapTable[jj] = NULL;
831     _diagWidthTable[jj] = NULL;
832     _diagDistTable[jj] = NULL;
833   }
834   _rcDiagDistTable = NULL;
835   _rc31 = rcPool->alloc();
836 }
extDistWidthRCTable(bool over,uint met,uint layerCnt,uint metCnt,Ath__array1D<double> * widthTable,int diagWidthCnt,int diagDistCnt,AthPool<extDistRC> * rcPool,double dbFactor)837 extDistWidthRCTable::extDistWidthRCTable(bool over, uint met, uint layerCnt,
838                                          uint metCnt,
839                                          Ath__array1D<double>* widthTable,
840                                          int diagWidthCnt, int diagDistCnt,
841                                          AthPool<extDistRC>* rcPool,
842                                          double dbFactor) {
843   _ouReadReverse = OUREVERSEORDER;
844   _over = over;
845   _layerCnt = layerCnt;
846   _met = met;
847 
848   uint widthCnt = widthTable->getCnt();
849   _widthTable = new Ath__array1D<int>(widthCnt);
850   for (uint ii = 0; ii < widthCnt; ii++) {
851     int w = Ath__double2int(dbFactor * 1000 * widthTable->get(ii));
852     _widthTable->add(w);
853   }
854   for (uint i = 0; i < layerCnt; i++) {
855     _diagWidthTable[i] = new Ath__array1D<int>(diagWidthCnt);
856     _diagDistTable[i] = new Ath__array1D<int>(diagDistCnt);
857     _diagWidthMapTable[i] = new Ath__array1D<uint>(10 * diagWidthCnt);
858     _diagDistMapTable[i] = new Ath__array1D<uint>(10 * diagDistCnt);
859   }
860 
861   _firstWidth = _widthTable->get(0);
862   _lastWidth = _widthTable->get(widthCnt - 1);
863   _firstDiagWidth = new Ath__array1D<int>(layerCnt);
864   _lastDiagWidth = new Ath__array1D<int>(layerCnt);
865   _firstDiagDist = new Ath__array1D<int>(layerCnt);
866   _lastDiagDist = new Ath__array1D<int>(layerCnt);
867 
868   _modulo = 4;
869 
870   _widthTableAllocFlag = true;
871   _widthMapTable = new Ath__array1D<uint>(10 * widthCnt);
872   uint jj;
873   for (jj = 0; jj < widthCnt - 1; jj++) {
874     double v1 = _widthTable->get(jj);
875     double v2 = _widthTable->get(jj + 1);
876 
877     int w1 = Ath__double2int(v1);
878     int w2 = Ath__double2int(v2);
879 
880     for (int w = w1; w <= w2; w += _modulo) {
881       if (w >= _lastWidth)
882         continue;
883 
884       uint n = 0;
885       int v = w - _firstWidth;
886       if (v > 0)
887         n = v / _modulo;
888 
889       _widthMapTable->set(n, jj);
890     }
891   }
892 
893   _metCnt = metCnt;
894   _rcDiagDistTable = new extDistRCTable**** [_metCnt];
895   for (jj = 0; jj < _metCnt; jj++) {
896     _rcDiagDistTable[jj] = new extDistRCTable*** [widthCnt];
897     for (uint ii = 0; ii < widthCnt; ii++) {
898       _rcDiagDistTable[jj][ii] = new extDistRCTable** [diagWidthCnt];
899       for (int kk = 0; kk < diagWidthCnt; kk++) {
900         _rcDiagDistTable[jj][ii][kk] = new extDistRCTable* [diagDistCnt];
901         for (int ll = 0; ll < diagDistCnt; ll++)
902           _rcDiagDistTable[jj][ii][kk][ll] = new extDistRCTable(10);
903       }
904     }
905   }
906   _rcPoolPtr = rcPool;
907   _rcDistTable = NULL;
908 
909   _rc31 = rcPool->alloc();
910 }
setDiagUnderTables(uint met,Ath__array1D<double> * diagWidthTable,Ath__array1D<double> * diagDistTable,double dbFactor)911 void extDistWidthRCTable::setDiagUnderTables(
912     uint met, Ath__array1D<double>* diagWidthTable,
913     Ath__array1D<double>* diagDistTable, double dbFactor) {
914   uint diagWidthCnt = diagWidthTable->getCnt();
915   _diagWidthTable[met]->resetCnt();
916   uint ii;
917   for (ii = 0; ii < diagWidthCnt; ii++) {
918     int w = Ath__double2int(dbFactor * 1000 * diagWidthTable->get(ii));
919     _diagWidthTable[met]->add(w);
920   }
921   _firstDiagWidth->set(met, _diagWidthTable[met]->get(0));
922   _lastDiagWidth->set(met, _diagWidthTable[met]->get(diagWidthCnt - 1));
923   uint diagDistCnt = diagDistTable->getCnt();
924   _diagDistTable[met]->resetCnt();
925   for (ii = 0; ii < diagDistCnt; ii++) {
926     int s = Ath__double2int(dbFactor * 1000 * diagDistTable->get(ii));
927     _diagDistTable[met]->add(s);
928   }
929   _firstDiagDist->set(met, _diagDistTable[met]->get(0));
930   _lastDiagDist->set(met, _diagDistTable[met]->get(diagDistCnt - 1));
931   uint jj;
932   for (jj = 0; jj < diagWidthCnt - 1; jj++) {
933     double v1 = _diagWidthTable[met]->get(jj);
934     double v2 = _diagWidthTable[met]->get(jj + 1);
935 
936     int w1 = Ath__double2int(v1);
937     int w2 = Ath__double2int(v2);
938 
939     for (int w = w1; w <= w2; w += _modulo) {
940       if (w >= _lastDiagWidth->geti(met))
941         continue;
942 
943       uint n = 0;
944       int v = w - _firstDiagWidth->geti(met);
945       if (v > 0)
946         n = v / _modulo;
947 
948       _diagWidthMapTable[met]->set(n, jj);
949     }
950   }
951   for (jj = 0; jj < diagDistCnt - 1; jj++) {
952     double v1 = _diagDistTable[met]->get(jj);
953     double v2 = _diagDistTable[met]->get(jj + 1);
954 
955     int s1 = Ath__double2int(v1);
956     int s2 = Ath__double2int(v2);
957 
958     for (int s = s1; s <= s2; s += _modulo) {
959       if (s >= _lastDiagDist->geti(met))
960         continue;
961 
962       int d = (s2 - s1) / 2;
963 
964       uint n = 0;
965       int v = s - _firstDiagDist->geti(met);
966       if (v > 0)
967         n = v / _modulo;
968 
969       if (v < s1 + d)
970         _diagDistMapTable[met]->set(n, jj);
971       else
972         _diagDistMapTable[met]->set(n, jj + 1);
973     }
974   }
975 }
~extDistWidthRCTable()976 extDistWidthRCTable::~extDistWidthRCTable() {
977   uint ii, jj, kk, ll;
978   if (_rcDistTable) {
979     for (jj = 0; jj < _metCnt; jj++) {
980       for (ii = 0; ii < _widthTable->getCnt(); ii++)
981         if (_rcDistTable[jj][ii])
982           delete _rcDistTable[jj][ii];
983 
984       if (_rcDistTable[jj])
985         delete[] _rcDistTable[jj];
986     }
987     delete[] _rcDistTable;
988   }
989 
990   if (_rcDiagDistTable) {
991     for (jj = 0; jj < _metCnt; jj++) {
992       for (ii = 0; ii < _widthTable->getCnt(); ii++) {
993         for (kk = 0; kk < _diagWidthTable[jj]->getCnt(); kk++) {
994           for (ll = 0; ll < _diagDistTable[jj]->getCnt(); ll++)
995             delete _rcDiagDistTable[jj][ii][kk][ll];
996           delete[] _rcDiagDistTable[jj][ii][kk];
997         }
998         delete[] _rcDiagDistTable[jj][ii];
999       }
1000       delete[] _rcDiagDistTable[jj];
1001     }
1002     delete[] _rcDiagDistTable;
1003   }
1004 
1005   //	if (_widthTableAllocFlag)
1006   if (_widthTable)
1007     delete _widthTable;
1008   if (_widthMapTable)
1009     delete _widthMapTable;
1010   if (_firstDiagWidth)
1011     delete _firstDiagWidth;
1012   if (_lastDiagWidth)
1013     delete _lastDiagWidth;
1014   if (_firstDiagDist)
1015     delete _firstDiagDist;
1016   if (_lastDiagDist)
1017     delete _lastDiagDist;
1018   for (uint i = 0; i < _layerCnt; i++) {
1019     if (_diagWidthTable[i] != NULL)
1020       delete _diagWidthTable[i];
1021     if (_diagDistTable[i] != NULL)
1022       delete _diagDistTable[i];
1023     if (_diagWidthMapTable[i] != NULL)
1024       delete _diagWidthMapTable[i];
1025     if (_diagDistMapTable[i] != NULL)
1026       delete _diagDistMapTable[i];
1027   }
1028 }
writeWidthTable(FILE * fp,bool bin)1029 uint extDistWidthRCTable::writeWidthTable(FILE* fp, bool bin) {
1030   uint widthCnt = _widthTable->getCnt();
1031   fprintf(fp, "WIDTH Table %d entries: ", widthCnt);
1032   for (uint ii = 0; ii < widthCnt; ii++)
1033     fprintf(fp, " %g", 0.001 * _widthTable->get(ii));
1034   fprintf(fp, "\n");
1035   return widthCnt;
1036 }
writeDiagWidthTable(FILE * fp,uint met,bool bin)1037 uint extDistWidthRCTable::writeDiagWidthTable(FILE* fp, uint met, bool bin) {
1038   uint diagWidthCnt = _diagWidthTable[met]->getCnt();
1039   fprintf(fp, "DIAG_WIDTH Table %d entries: ", diagWidthCnt);
1040   for (uint ii = 0; ii < diagWidthCnt; ii++)
1041     fprintf(fp, " %g", 0.001 * _diagWidthTable[met]->get(ii));
1042   fprintf(fp, "\n");
1043   return diagWidthCnt;
1044 }
writeDiagTablesCnt(FILE * fp,uint met,bool bin)1045 void extDistWidthRCTable::writeDiagTablesCnt(FILE* fp, uint met, bool bin) {
1046   uint diagWidthCnt = _diagWidthTable[met]->getCnt();
1047   uint diagDistCnt = _diagDistTable[met]->getCnt();
1048   fprintf(fp, "DIAG_WIDTH Table Count: %d\n", diagWidthCnt);
1049   fprintf(fp, "DIAG_DIST Table Count: %d\n", diagDistCnt);
1050 }
writeDiagDistTable(FILE * fp,uint met,bool bin)1051 uint extDistWidthRCTable::writeDiagDistTable(FILE* fp, uint met, bool bin) {
1052   uint diagDistCnt = _diagDistTable[met]->getCnt();
1053   fprintf(fp, "DIAG_DIST Table %d entries: ", diagDistCnt);
1054   for (uint ii = 0; ii < diagDistCnt; ii++)
1055     fprintf(fp, " %g", 0.001 * _diagDistTable[met]->get(ii));
1056   fprintf(fp, "\n");
1057   return diagDistCnt;
1058 }
writeRulesOver(FILE * fp,bool bin)1059 uint extDistWidthRCTable::writeRulesOver(FILE* fp, bool bin) {
1060   uint cnt = 0;
1061   fprintf(fp, "\nMetal %d OVER\n", _met);
1062 
1063   writeWidthTable(fp, bin);
1064   uint widthCnt = _widthTable->getCnt();
1065 
1066   for (uint ii = 0; ii < _met; ii++) {
1067     fprintf(fp, "\nMetal %d OVER %d\n", _met, ii);
1068 
1069     for (uint jj = 0; jj < widthCnt; jj++) {
1070       cnt += _rcDistTable[ii][jj]
1071                  ->writeRules(fp, 0.001 * _widthTable->get(jj), false, bin);
1072     }
1073   }
1074   return cnt;
1075 }
writeRulesOver_res(FILE * fp,bool bin)1076 uint extDistWidthRCTable::writeRulesOver_res(FILE* fp, bool bin) {
1077   uint cnt = 0;
1078   fprintf(fp, "\nMetal %d RESOVER\n", _met);
1079 
1080   writeWidthTable(fp, bin);
1081   uint widthCnt = _widthTable->getCnt();
1082 
1083   for (uint ii = 0; ii < _met; ii++) {
1084     fprintf(fp, "\nMetal %d RESOVER %d\n", _met, ii);
1085 
1086     for (uint jj = 0; jj < widthCnt; jj++) {
1087       cnt += _rcDistTable[ii][jj]
1088                  ->writeRules(fp, 0.001 * _widthTable->get(jj), false, bin);
1089     }
1090   }
1091   return cnt;
1092 }
readMetalHeader(Ath__parser * parser,uint & met,const char * keyword,bool bin,bool ignore)1093 uint extDistWidthRCTable::readMetalHeader(Ath__parser* parser, uint& met,
1094                                           const char* keyword, bool bin,
1095                                           bool ignore) {
1096   if (!(parser->parseNextLine() > 0))
1097     return 0;
1098 
1099   //	uint cnt= 0;
1100   if (parser->isKeyword(0, "Metal") && (strcmp(parser->get(2), keyword) == 0)) {
1101     met = parser->getInt(1);
1102     return 1;
1103   }
1104 
1105   return 0;
1106 }
readRulesOver(Ath__parser * parser,uint widthCnt,bool bin,bool ignore,const char * OVER,double dbFactor)1107 uint extDistWidthRCTable::readRulesOver(Ath__parser* parser, uint widthCnt,
1108                                         bool bin, bool ignore, const char* OVER,
1109                                         double dbFactor) {
1110   bool res = strcmp(OVER, "RESOVER") == 0;
1111   uint cnt = 0;
1112   for (uint ii = 0; ii < _met; ii++) {
1113     uint met = 0;
1114     if (readMetalHeader(parser, met, OVER, bin, ignore) <= 0)
1115       return 0;
1116 
1117     parser->getInt(3);
1118 
1119     for (uint jj = 0; jj < widthCnt; jj++) {
1120       if (res) {
1121         if (!ignore)
1122           cnt += _rcDistTable[ii][jj]->readRules_res2(parser, _rcPoolPtr, true,
1123                                                       bin, ignore, dbFactor);
1124         else
1125           cnt += _rcDistTable[0][0]->readRules_res2(parser, _rcPoolPtr, true,
1126                                                     bin, ignore, dbFactor);
1127       } else {
1128         if (!ignore)
1129           cnt += _rcDistTable[ii][jj]->readRules(parser, _rcPoolPtr, true, bin,
1130                                                  ignore, dbFactor);
1131         else
1132           cnt += _rcDistTable[0][0]->readRules(parser, _rcPoolPtr, true, bin,
1133                                                ignore, dbFactor);
1134       }
1135     }
1136   }
1137   return cnt;
1138 }
readRulesUnder(Ath__parser * parser,uint widthCnt,bool bin,bool ignore,double dbFactor)1139 uint extDistWidthRCTable::readRulesUnder(Ath__parser* parser, uint widthCnt,
1140                                          bool bin, bool ignore,
1141                                          double dbFactor) {
1142   uint cnt = 0;
1143   for (uint ii = _met + 1; ii < _layerCnt; ii++) {
1144     uint met = 0;
1145     if (readMetalHeader(parser, met, "UNDER", bin, ignore) <= 0)
1146       return 0;
1147 
1148     uint metIndex = getMetIndexUnder(ii);
1149     if (ignore)
1150       metIndex = 0;
1151 
1152     parser->getInt(3);
1153 
1154     for (uint jj = 0; jj < widthCnt; jj++) {
1155       cnt += _rcDistTable[metIndex][jj]
1156                  ->readRules(parser, _rcPoolPtr, true, bin, ignore, dbFactor);
1157     }
1158   }
1159   return cnt;
1160 }
readRulesDiagUnder(Ath__parser * parser,uint widthCnt,uint diagWidthCnt,uint diagDistCnt,bool bin,bool ignore,double dbFactor)1161 uint extDistWidthRCTable::readRulesDiagUnder(Ath__parser* parser, uint widthCnt,
1162                                              uint diagWidthCnt,
1163                                              uint diagDistCnt, bool bin,
1164                                              bool ignore, double dbFactor) {
1165   uint cnt = 0;
1166   for (uint ii = _met + 1; ii < _met + 5 && ii < _layerCnt; ii++) {
1167     uint met = 0;
1168     if (readMetalHeader(parser, met, "DIAGUNDER", bin, ignore) <= 0)
1169       return 0;
1170     Ath__array1D<double>* dwTable = NULL;
1171     Ath__array1D<double>* ddTable = NULL;
1172     parser->parseNextLine();
1173     dwTable = parser->readDoubleArray("DIAG_WIDTH", 4);
1174     parser->parseNextLine();
1175     ddTable = parser->readDoubleArray("DIAG_DIST", 4);
1176     uint diagWidthCnt = dwTable->getCnt();
1177     uint diagDistCnt = ddTable->getCnt();
1178     //		setDiagUnderTables(ii, dwTable, ddTable);
1179 
1180     uint metIndex = getMetIndexUnder(ii);
1181 
1182     if (!ignore)
1183       setDiagUnderTables(metIndex, dwTable, ddTable);
1184 
1185     parser->getInt(3);
1186 
1187     for (uint jj = 0; jj < widthCnt; jj++) {
1188       for (uint kk = 0; kk < diagWidthCnt; kk++) {
1189         for (uint ll = 0; ll < diagDistCnt; ll++) {
1190           if (!ignore)
1191             cnt += _rcDiagDistTable[metIndex][jj][kk][ll]->readRules(
1192                 parser, _rcPoolPtr, true, bin, ignore, dbFactor);
1193           else
1194             cnt += _rcDistTable[0][0]->readRules(parser, _rcPoolPtr, true, bin,
1195                                                  ignore, dbFactor);
1196         }
1197       }
1198     }
1199     delete dwTable;
1200     delete ddTable;
1201   }
1202   return cnt;
1203 }
readRulesDiagUnder(Ath__parser * parser,uint widthCnt,bool bin,bool ignore,double dbFactor)1204 uint extDistWidthRCTable::readRulesDiagUnder(Ath__parser* parser, uint widthCnt,
1205                                              bool bin, bool ignore,
1206                                              double dbFactor) {
1207   uint cnt = 0;
1208   for (uint ii = _met + 1; ii < _layerCnt; ii++) {
1209     uint met = 0;
1210     if (readMetalHeader(parser, met, "DIAGUNDER", bin, ignore) <= 0)
1211       return 0;
1212 
1213     uint metIndex = getMetIndexUnder(ii);
1214     parser->getInt(3);
1215 
1216     for (uint jj = 0; jj < widthCnt; jj++) {
1217       cnt += _rcDistTable[metIndex][jj]
1218                  ->readRules(parser, _rcPoolPtr, true, bin, ignore, dbFactor);
1219     }
1220   }
1221   return cnt;
1222 }
readRulesOverUnder(Ath__parser * parser,uint widthCnt,bool bin,bool ignore,double dbFactor)1223 uint extDistWidthRCTable::readRulesOverUnder(Ath__parser* parser, uint widthCnt,
1224                                              bool bin, bool ignore,
1225                                              double dbFactor) {
1226   uint cnt = 0;
1227   for (uint u = 1; u < _met; u++) {
1228     for (uint o = _met + 1; o < _layerCnt; o++) {
1229       uint mUnder = u;
1230       uint mOver = o;
1231 
1232       uint met = 0;
1233       if (readMetalHeader(parser, met, "OVER", bin, ignore) <= 0)
1234         return 0;
1235 
1236       if (_ouReadReverse)
1237         mOver = parser->getInt(5);
1238 
1239       mUnder = parser->getInt(3);
1240 
1241       // Commented out this code per Dimitris...
1242       // The variable mOver is already defined above...
1243       // uint mOver= parser->getInt(5);
1244 
1245       int metIndex = 0;
1246       if (!ignore)
1247         metIndex =
1248             getMetIndexOverUnder(_met, mUnder, mOver, _layerCnt, _metCnt);
1249       int mcnt = 0;
1250       for (uint jj = 0; jj < widthCnt; jj++) {
1251         if (!ignore)
1252           mcnt += _rcDistTable[metIndex][jj]->readRules(
1253               parser, _rcPoolPtr, true, bin, ignore, dbFactor);
1254         else
1255           mcnt += _rcDistTable[0][0]->readRules(parser, _rcPoolPtr, true, bin,
1256                                                 ignore, dbFactor);
1257       }
1258       cnt += mcnt;
1259     }
1260   }
1261   return cnt;
1262 }
getMetIndexUnder(uint mOver)1263 uint extDistWidthRCTable::getMetIndexUnder(uint mOver) {
1264   return mOver - _met - 1;
1265 }
writeRulesUnder(FILE * fp,bool bin)1266 uint extDistWidthRCTable::writeRulesUnder(FILE* fp, bool bin) {
1267   uint cnt = 0;
1268   fprintf(fp, "\nMetal %d UNDER\n", _met);
1269 
1270   writeWidthTable(fp, bin);
1271   uint widthCnt = _widthTable->getCnt();
1272 
1273   for (uint ii = _met + 1; ii < _layerCnt; ii++) {
1274     fprintf(fp, "\nMetal %d UNDER %d\n", _met, ii);
1275 
1276     uint metIndex = getMetIndexUnder(ii);
1277 
1278     for (uint jj = 0; jj < widthCnt; jj++) {
1279       cnt += _rcDistTable[metIndex][jj]
1280                  ->writeRules(fp, 0.001 * _widthTable->get(jj), false, bin);
1281     }
1282   }
1283   return cnt;
1284 }
writeRulesDiagUnder2(FILE * fp,bool bin)1285 uint extDistWidthRCTable::writeRulesDiagUnder2(FILE* fp, bool bin) {
1286   uint cnt = 0;
1287   fprintf(fp, "\nMetal %d DIAGUNDER\n", _met);
1288 
1289   writeWidthTable(fp, bin);
1290   uint widthCnt = _widthTable->getCnt();
1291   writeDiagTablesCnt(fp, _met + 1, bin);
1292 
1293   for (uint ii = _met + 1; ii < _met + 5 && ii < _layerCnt; ii++) {
1294     fprintf(fp, "\nMetal %d DIAGUNDER %d\n", _met, ii);
1295     writeDiagWidthTable(fp, ii, bin);
1296     uint diagWidthCnt = _diagWidthTable[ii]->getCnt();
1297     writeDiagDistTable(fp, ii, bin);
1298     uint diagDistCnt = _diagDistTable[ii]->getCnt();
1299 
1300     uint metIndex = getMetIndexUnder(ii);
1301 
1302     for (uint jj = 0; jj < widthCnt; jj++) {
1303       for (uint kk = 0; kk < diagWidthCnt; kk++) {
1304         for (uint ll = 0; ll < diagDistCnt; ll++) {
1305           cnt += _rcDiagDistTable[metIndex][jj][kk][ll]->writeDiagRules(
1306               fp, 0.001 * _widthTable->get(jj),
1307               0.001 * _diagWidthTable[ii]->get(kk),
1308               0.001 * _diagDistTable[ii]->get(ll), false, bin);
1309         }
1310       }
1311     }
1312   }
1313   return cnt;
1314 }
writeRulesDiagUnder(FILE * fp,bool bin)1315 uint extDistWidthRCTable::writeRulesDiagUnder(FILE* fp, bool bin) {
1316   uint cnt = 0;
1317   fprintf(fp, "\nMetal %d DIAGUNDER\n", _met);
1318 
1319   writeWidthTable(fp, bin);
1320   uint widthCnt = _widthTable->getCnt();
1321 
1322   for (uint ii = _met + 1; ii < _layerCnt; ii++) {
1323     fprintf(fp, "\nMetal %d DIAGUNDER %d\n", _met, ii);
1324 
1325     uint metIndex = getMetIndexUnder(ii);
1326 
1327     for (uint jj = 0; jj < widthCnt; jj++) {
1328       cnt += _rcDistTable[metIndex][jj]
1329                  ->writeRules(fp, 0.001 * _widthTable->get(jj), false, bin);
1330     }
1331   }
1332   return cnt;
1333 }
writeRulesOverUnder(FILE * fp,bool bin)1334 uint extDistWidthRCTable::writeRulesOverUnder(FILE* fp, bool bin) {
1335   uint cnt = 0;
1336   fprintf(fp, "\nMetal %d OVERUNDER\n", _met);
1337 
1338   writeWidthTable(fp, bin);
1339   uint widthCnt = _widthTable->getCnt();
1340 
1341   for (uint mUnder = 1; mUnder < _met; mUnder++) {
1342     for (uint mOver = _met + 1; mOver < _layerCnt; mOver++) {
1343       fprintf(fp, "\nMetal %d OVER %d UNDER %d\n", _met, mUnder, mOver);
1344 
1345       int metIndex =
1346           getMetIndexOverUnder(_met, mUnder, mOver, _layerCnt, _metCnt);
1347       assert(metIndex >= 0);
1348 
1349       for (uint jj = 0; jj < widthCnt; jj++) {
1350         cnt += _rcDistTable[metIndex][jj]
1351                    ->writeRules(fp, 0.001 * _widthTable->get(jj), false, bin);
1352       }
1353     }
1354   }
1355   return cnt;
1356 }
extMetRCTable(uint layerCnt,AthPool<extDistRC> * rcPool,Logger * logger)1357 extMetRCTable::extMetRCTable(uint layerCnt, AthPool<extDistRC>* rcPool,
1358                              Logger* logger) {
1359   logger_ = logger;
1360   _layerCnt = layerCnt;
1361 
1362   _resOver = new extDistWidthRCTable* [layerCnt];
1363   _capOver = new extDistWidthRCTable* [layerCnt];
1364   _capDiagUnder = new extDistWidthRCTable* [layerCnt];
1365   _capUnder = new extDistWidthRCTable* [layerCnt];
1366   _capOverUnder = new extDistWidthRCTable* [layerCnt];
1367   for (uint ii = 0; ii < layerCnt; ii++) {
1368     _resOver[ii] = NULL;
1369     _capOver[ii] = NULL;
1370     _capDiagUnder[ii] = NULL;
1371     _capUnder[ii] = NULL;
1372     _capOverUnder[ii] = NULL;
1373   }
1374   _rcPoolPtr = rcPool;
1375   _rate = -1000.0;
1376 }
~extMetRCTable()1377 extMetRCTable::~extMetRCTable() {
1378   for (uint ii = 0; ii < _layerCnt; ii++) {
1379     if (_capUnder[ii] != NULL)
1380       delete _capUnder[ii];
1381     if (_capDiagUnder[ii] != NULL)
1382       delete _capDiagUnder[ii];
1383     if (_resOver[ii] != NULL)
1384       delete _resOver[ii];
1385     if (_capOver[ii] != NULL)
1386       delete _capOver[ii];
1387     if (_capOverUnder[ii] != NULL)
1388       delete _capOverUnder[ii];
1389   }
1390   delete[] _resOver;
1391   delete[] _capOver;
1392   delete[] _capDiagUnder;
1393   delete[] _capUnder;
1394   delete[] _capOverUnder;
1395 }
allocOverTable(uint met,Ath__array1D<double> * wTable,double dbFactor)1396 void extMetRCTable::allocOverTable(uint met, Ath__array1D<double>* wTable,
1397                                    double dbFactor) {
1398   _capOver[met] = new extDistWidthRCTable(true, met, _layerCnt, met, wTable,
1399                                           _rcPoolPtr, dbFactor);
1400   _resOver[met] = new extDistWidthRCTable(true, met, _layerCnt, met, wTable,
1401                                           _rcPoolPtr, dbFactor);
1402 }
allocDiagUnderTable(uint met,Ath__array1D<double> * wTable,int diagWidthCnt,int diagDistCnt,double dbFactor)1403 void extMetRCTable::allocDiagUnderTable(uint met, Ath__array1D<double>* wTable,
1404                                         int diagWidthCnt, int diagDistCnt,
1405                                         double dbFactor) {
1406   _capDiagUnder[met] = new extDistWidthRCTable(
1407       false, met, _layerCnt, _layerCnt - met - 1, wTable, diagWidthCnt,
1408       diagDistCnt, _rcPoolPtr, dbFactor);
1409 }
setDiagUnderTables(uint met,uint overMet,Ath__array1D<double> * diagWTable,Ath__array1D<double> * diagSTable,double dbFactor)1410 void extMetRCTable::setDiagUnderTables(uint met, uint overMet,
1411                                        Ath__array1D<double>* diagWTable,
1412                                        Ath__array1D<double>* diagSTable,
1413                                        double dbFactor) {
1414   _capDiagUnder[met]
1415       ->setDiagUnderTables(overMet, diagWTable, diagSTable, dbFactor);
1416 }
allocDiagUnderTable(uint met,Ath__array1D<double> * wTable,double dbFactor)1417 void extMetRCTable::allocDiagUnderTable(uint met, Ath__array1D<double>* wTable,
1418                                         double dbFactor) {
1419   _capDiagUnder[met] = new extDistWidthRCTable(
1420       false, met, _layerCnt, _layerCnt - met - 1, wTable, _rcPoolPtr, dbFactor);
1421 }
allocUnderTable(uint met,Ath__array1D<double> * wTable,double dbFactor)1422 void extMetRCTable::allocUnderTable(uint met, Ath__array1D<double>* wTable,
1423                                     double dbFactor) {
1424   _capUnder[met] = new extDistWidthRCTable(
1425       false, met, _layerCnt, _layerCnt - met - 1, wTable, _rcPoolPtr, dbFactor);
1426 }
allocOverUnderTable(uint met,Ath__array1D<double> * wTable,double dbFactor)1427 void extMetRCTable::allocOverUnderTable(uint met, Ath__array1D<double>* wTable,
1428                                         double dbFactor) {
1429   if (met < 2)
1430     return;
1431 
1432   int n = getMaxMetIndexOverUnder(met, _layerCnt);
1433   _capOverUnder[met] = new extDistWidthRCTable(false, met, _layerCnt, n + 1,
1434                                                wTable, _rcPoolPtr, dbFactor);
1435 }
extRCTable(bool over,uint layerCnt)1436 extRCTable::extRCTable(bool over, uint layerCnt) {
1437   _maxCnt1 = layerCnt + 1;
1438   _inTable = new Ath__array1D<extDistRC*>** [_maxCnt1];
1439   _table = new Ath__array1D<extDistRC*>** [_maxCnt1];
1440 
1441   if (over)
1442     makeCapTableOver();
1443   else
1444     makeCapTableUnder();
1445 }
getCapOver(uint met,uint metUnder)1446 extDistRC* extRCTable::getCapOver(uint met, uint metUnder) {
1447   return _inTable[met][metUnder]->get(0);
1448 }
getTotCapOverSub(uint met)1449 double extRCModel::getTotCapOverSub(uint met) {
1450   extDistRC* rc = _capOver->getCapOver(met, 0);
1451   return rc->getFringe();
1452 }
1453 /*
1454 double extRCModel::getFringeOver(uint met, uint mUnder, uint w, uint s)
1455 {
1456 
1457         if ((_tmpDataRate<=0)||(_modelTable!=NULL))
1458                 return 0.0;
1459 */
1460 
getRC_index(int n)1461 extDistRC* extDistRCTable::getRC_index(int n) {
1462   int cnt = _measureTable->getCnt();
1463   if (n >= cnt)
1464     return NULL;
1465   return _measureTable->get(n);
1466 }
1467 
getLastRC()1468 extDistRC* extDistRCTable::getLastRC() {
1469   int cnt = _measureTable->getCnt();
1470   return _measureTable->get(cnt - 1);
1471 }
1472 
getRC(uint s,bool compute)1473 extDistRC* extDistRCTable::getRC(uint s, bool compute) {
1474   if (compute)
1475     return getComputeRC(s);
1476   else
1477     return NULL;
1478   // return interpolate _measureTable->findNextBiggestIndex((double) s);
1479 }
getFringeTable(Ath__array1D<int> * sTable,Ath__array1D<double> * rcTable,bool compute)1480 void extDistRCTable::getFringeTable(Ath__array1D<int>* sTable,
1481                                     Ath__array1D<double>* rcTable,
1482                                     bool compute) {
1483   Ath__array1D<extDistRC*>* table = _computeTable;
1484   if (!compute)
1485     table = _measureTable;
1486 
1487   for (uint ii = 0; ii < table->getCnt(); ii++) {
1488     extDistRC* rc = table->get(ii);
1489     sTable->add(rc->_sep);
1490     rcTable->add(rc->_fringe);
1491   }
1492 }
getFringeTable(uint mou,uint w,Ath__array1D<int> * sTable,Ath__array1D<double> * rcTable,bool map)1493 void extDistWidthRCTable::getFringeTable(uint mou, uint w,
1494                                          Ath__array1D<int>* sTable,
1495                                          Ath__array1D<double>* rcTable,
1496                                          bool map) {
1497   uint wIndex = 0;
1498   if (map) {
1499     wIndex = getWidthIndex(w);
1500   } else
1501     wIndex = _widthTable->findNextBiggestIndex(w);
1502 
1503   _rcDistTable[mou][wIndex]->getFringeTable(sTable, rcTable, true);
1504 }
1505 /*
1506 extDistRC* extDistWidthRCTable::getRC(uint mou, uint w, uint s)
1507 {
1508         int wIndex= _widthTable->findNextBiggestIndex(w);
1509         if ((wIndex<0) || (wIndex>=_widthTable->getCnt()))
1510                 return NULL;
1511 
1512         if (mou>=_metCnt || wIndex>=_widthTable->getCnt() ||
1513 _rcDistTable[mou][wIndex] == NULL) return NULL; return
1514 _rcDistTable[mou][wIndex]->getRC( s, true);
1515 }
1516 */
getFringeRC(uint mou,uint w,int index_dist)1517 extDistRC* extDistWidthRCTable::getFringeRC(uint mou, uint w, int index_dist) {
1518   int wIndex = getWidthIndex(w);
1519   if ((wIndex < 0) || (wIndex >= (int)_widthTable->getCnt()))
1520     return NULL;
1521 
1522   if (mou >= _metCnt || wIndex >= (int)_widthTable->getCnt() ||
1523       _rcDistTable[mou][wIndex] == NULL)
1524     return NULL;
1525 
1526   extDistRC* rc;
1527   if (index_dist < 0)
1528     rc = _rcDistTable[mou][wIndex]->getLastRC();
1529   else
1530     rc = _rcDistTable[mou][wIndex]->getRC_index(index_dist);
1531   /*
1532   if (rc!=NULL) {
1533           rc->writeRC();
1534   }
1535   */
1536   return rc;
1537 }
getLastWidthFringeRC(uint mou)1538 extDistRC* extDistWidthRCTable::getLastWidthFringeRC(uint mou) {
1539   if (mou >= _metCnt)
1540     return NULL;
1541 
1542   int wIndex = _widthTable->getCnt() - 1;
1543 
1544   if (wIndex >= (int)_widthTable->getCnt() || _rcDistTable[mou][wIndex] == NULL)
1545     return NULL;
1546 
1547   return _rcDistTable[mou][wIndex]->getLastRC();
1548 }
getRC(uint mou,uint w,uint s)1549 extDistRC* extDistWidthRCTable::getRC(uint mou, uint w, uint s) {
1550   int wIndex = getWidthIndex(w);
1551   if (wIndex < 0)
1552     return NULL;
1553 
1554   return _rcDistTable[mou][wIndex]->getRC(s, true);
1555 }
getRC(uint mou,uint w,uint dw,uint ds,uint s)1556 extDistRC* extDistWidthRCTable::getRC(uint mou, uint w, uint dw, uint ds,
1557                                       uint s) {
1558   int wIndex = getWidthIndex(w);
1559   if (wIndex < 0)
1560     return NULL;
1561   int dwIndex = getDiagWidthIndex(mou, dw);
1562   if (dwIndex < 0)
1563     return NULL;
1564   int dsIndex = getDiagDistIndex(mou, ds);
1565   if (dsIndex < 0)
1566     return NULL;
1567   return _rcDiagDistTable[mou][wIndex][dwIndex][dsIndex]->getRC(s, true);
1568 }
getRC_99(uint mou,uint w,uint dw,uint ds)1569 extDistRC* extDistWidthRCTable::getRC_99(uint mou, uint w, uint dw, uint ds) {
1570   int wIndex = getWidthIndex(w);
1571   if (wIndex < 0)
1572     return NULL;
1573 
1574   int dwIndex = getDiagWidthIndex(mou, dw);
1575   if (dwIndex < 0)
1576     return NULL;
1577 
1578   int dsIndex = getDiagDistIndex(mou, ds);
1579   if (dsIndex < 0)
1580     return NULL;
1581 
1582   uint s2 = _diagDistTable[mou]->get(dsIndex);
1583   extDistRC* rc2 = _rcDiagDistTable[mou][wIndex][dwIndex][dsIndex]->getRC_99();
1584   if (dsIndex == 0)
1585     return rc2;
1586 
1587   if ((int)ds == _diagDistTable[mou]->get(dsIndex))
1588     return rc2;
1589 
1590   _rc31->_sep = ds;
1591 
1592   uint lastDist = _lastDiagDist->geti(mou);
1593   if (ds > lastDist) {  // extrapolate
1594     _rc31->_fringe = (rc2->_fringe / ds) * lastDist;
1595 
1596     return _rc31;
1597   }
1598   // interpolate;
1599   uint s1 = _diagDistTable[mou]->get(dsIndex - 1);
1600 
1601   if (ds <= (s1 - s2) / 4)  // too close!
1602     return rc2;
1603 
1604   extDistRC* rc1 =
1605       _rcDiagDistTable[mou][wIndex][dwIndex][dsIndex - 1]->getRC_99();
1606 
1607   _rc31->_fringe = lineSegment(ds, s1, s2, rc1->_fringe, rc2->_fringe);
1608 
1609   return _rc31;
1610 }
getFringeOver(uint met,uint mUnder,uint w,uint s)1611 double extRCModel::getFringeOver(uint met, uint mUnder, uint w, uint s) {
1612   extDistRC* rc = _modelTable[_tmpDataRate]->_capOver[met]->getRC(mUnder, w, s);
1613 
1614   return rc->getFringe();
1615 }
getCouplingOver(uint met,uint mUnder,uint w,uint s)1616 double extRCModel::getCouplingOver(uint met, uint mUnder, uint w, uint s) {
1617   extDistRC* rc = _modelTable[_tmpDataRate]->_capOver[met]->getRC(mUnder, w, s);
1618 
1619   return rc->getCoupling();
1620 }
getOverRC(extMeasure * m)1621 extDistRC* extRCModel::getOverRC(extMeasure* m) {
1622   if (_modelTable[_tmpDataRate] == NULL ||
1623       _modelTable[_tmpDataRate]->_capOver[m->_met] == NULL)
1624     return NULL;
1625   extDistRC* rc = _modelTable[_tmpDataRate]->_capOver[m->_met]->getRC(
1626       m->_underMet, m->_width, m->_dist);
1627 
1628   return rc;
1629 }
getUnderRC(extMeasure * m)1630 extDistRC* extRCModel::getUnderRC(extMeasure* m) {
1631   uint n = getUnderIndex(m);
1632   if (_modelTable[_tmpDataRate] == NULL ||
1633       _modelTable[_tmpDataRate]->_capUnder[m->_met] == NULL)
1634     return NULL;
1635   extDistRC* rc = _modelTable[_tmpDataRate]->_capUnder[m->_met]->getRC(
1636       n, m->_width, m->_dist);
1637 
1638   return rc;
1639 }
getOverUnderRC(extMeasure * m)1640 extDistRC* extRCModel::getOverUnderRC(extMeasure* m) {
1641   uint maxOverUnderIndex =
1642       _modelTable[_tmpDataRate]->_capOverUnder[m->_met]->_metCnt;
1643   uint n = getOverUnderIndex(m, maxOverUnderIndex);
1644   extDistRC* rc = _modelTable[_tmpDataRate]->_capOverUnder[m->_met]->getRC(
1645       n, m->_width, m->_dist);
1646 
1647   return rc;
1648 }
getOverFringeRC(uint met,uint underMet,uint width)1649 extDistRC* extRCModel::getOverFringeRC(uint met, uint underMet, uint width) {
1650   if (met >= _layerCnt)
1651     return NULL;
1652 
1653   extDistRC* rc =
1654       _modelTable[_tmpDataRate]->_capOver[met]->getFringeRC(underMet, width);
1655 
1656   return rc;
1657 }
getOverFringeRC(extMeasure * m,int index_dist)1658 extDistRC* extMetRCTable::getOverFringeRC(extMeasure* m, int index_dist) {
1659   if (m->_met >= (int)_layerCnt)
1660     return NULL;
1661 
1662   extDistRC* rc =
1663       _capOver[m->_met]->getFringeRC(m->_underMet, m->_width, index_dist);
1664 
1665   return rc;
1666 }
getOverFringeRC_last(int met,int width)1667 extDistRC* extMetRCTable::getOverFringeRC_last(int met, int width) {
1668   if (met >= (int)_layerCnt)
1669     return NULL;
1670 
1671   extDistRC* rc = _capOver[met]->getFringeRC(0, width, -1);
1672 
1673   return rc;
1674 }
getOverFringeRC(extMeasure * m)1675 extDistRC* extRCModel::getOverFringeRC(extMeasure* m) {
1676   if (m->_met >= (int)_layerCnt)
1677     return NULL;
1678 
1679   extDistRC* rc = _modelTable[_tmpDataRate]->_capOver[m->_met]->getFringeRC(
1680       m->_underMet, m->_width);
1681 
1682   return rc;
1683 }
getUnderFringeRC(extMeasure * m)1684 extDistRC* extRCModel::getUnderFringeRC(extMeasure* m) {
1685   uint n = getUnderIndex(m);
1686   if (_modelTable[_tmpDataRate] == NULL ||
1687       _modelTable[_tmpDataRate]->_capUnder[m->_met] == NULL)
1688     return NULL;
1689   extDistRC* rc =
1690       _modelTable[_tmpDataRate]->_capUnder[m->_met]->getFringeRC(n, m->_width);
1691 
1692   return rc;
1693 }
getOverUnderFringeRC(extMeasure * m)1694 extDistRC* extRCModel::getOverUnderFringeRC(extMeasure* m) {
1695   uint maxCnt = _modelTable[_tmpDataRate]->_capOverUnder[m->_met]->_metCnt;
1696   uint n = getOverUnderIndex(m, maxCnt);
1697   if (_modelTable[_tmpDataRate] == NULL ||
1698       _modelTable[_tmpDataRate]->_capOverUnder[m->_met] == NULL)
1699     return NULL;
1700   extDistRC* rc =
1701       _modelTable[_tmpDataRate]->_capOverUnder[m->_met]->getFringeRC(n,
1702                                                                      m->_width);
1703 
1704   return rc;
1705 }
getOverUnderFringeRC(extMetRCTable * rcModel)1706 extDistRC* extMeasure::getOverUnderFringeRC(extMetRCTable* rcModel) {
1707   //	uint n= getOverUnderIndex();
1708   uint maxCnt = _currentModel->getMaxCnt(_met);
1709   int n = getMetIndexOverUnder(_met, _underMet, _overMet, _layerCnt, maxCnt);
1710 
1711   if (rcModel == NULL || rcModel->_capOverUnder[_met] == NULL)
1712     return NULL;
1713 
1714   extDistRC* rc = rcModel->_capOverUnder[_met]->getFringeRC(n, _width);
1715 
1716   return rc;
1717 }
getOverUnderRC(extMetRCTable * rcModel)1718 extDistRC* extMeasure::getOverUnderRC(extMetRCTable* rcModel) {
1719   //	uint n= getOverUnderIndex();
1720   uint maxCnt = _currentModel->getMaxCnt(_met);
1721   int n = getMetIndexOverUnder(_met, _underMet, _overMet, _layerCnt, maxCnt);
1722 
1723   extDistRC* rc = NULL;
1724   if (_dist < 0)
1725     rc = rcModel->_capOverUnder[_met]->getFringeRC(n, _width);
1726   else
1727     rc = rcModel->_capOverUnder[_met]->getRC(n, _width, _dist);
1728 
1729   return rc;
1730 }
getOverRC(extMetRCTable * rcModel)1731 extDistRC* extMeasure::getOverRC(extMetRCTable* rcModel) {
1732   if (_met >= (int)_layerCnt)
1733     return NULL;
1734 
1735   extDistRC* rc = NULL;
1736   if (_dist < 0)
1737     rc = rcModel->_capOver[_met]->getFringeRC(_underMet, _width);
1738   else
1739     rc = rcModel->_capOver[_met]->getRC(_underMet, _width, _dist);
1740 
1741   return rc;
1742 }
getUnderIndex(uint overMet)1743 uint extMeasure::getUnderIndex(uint overMet) { return overMet - _met - 1; }
getUnderIndex()1744 uint extMeasure::getUnderIndex() { return _overMet - _met - 1; }
getUnderLastWidthDistRC(extMetRCTable * rcModel,uint overMet)1745 extDistRC* extMeasure::getUnderLastWidthDistRC(extMetRCTable* rcModel,
1746                                                uint overMet) {
1747   if (rcModel->_capUnder[_met] == NULL)
1748     return NULL;
1749 
1750   uint n = getUnderIndex(overMet);
1751 
1752   return rcModel->_capUnder[_met]->getLastWidthFringeRC(n);
1753 }
1754 
getUnderRC(extMetRCTable * rcModel)1755 extDistRC* extMeasure::getUnderRC(extMetRCTable* rcModel) {
1756   if (rcModel->_capUnder[_met] == NULL)
1757     return NULL;
1758 
1759   uint n = getUnderIndex();
1760 
1761   extDistRC* rc = NULL;
1762   if (_dist < 0)
1763     rc = rcModel->_capUnder[_met]->getFringeRC(n, _width);
1764   else
1765     rc = rcModel->_capUnder[_met]->getRC(n, _width, _dist);
1766 
1767   return rc;
1768 }
getVerticalUnderRC(extMetRCTable * rcModel,uint diagDist,uint tgtWidth,uint overMet)1769 extDistRC* extMeasure::getVerticalUnderRC(extMetRCTable* rcModel, uint diagDist,
1770                                           uint tgtWidth, uint overMet) {
1771   if (rcModel->_capDiagUnder[_met] == NULL) {
1772     return getUnderRC(rcModel);  // DELETE
1773     return NULL;
1774   }
1775 
1776   uint n = getUnderIndex(overMet);
1777 
1778   //	uint couplingDist= 99000;
1779   extDistRC* rc =
1780       rcModel->_capDiagUnder[_met]->getRC_99(n, _width, tgtWidth, diagDist);
1781 
1782   return rc;
1783 }
getDiagUnderCC(extMetRCTable * rcModel,uint dist,uint overMet)1784 double extMeasure::getDiagUnderCC(extMetRCTable* rcModel, uint dist,
1785                                   uint overMet) {
1786   if (rcModel->_capDiagUnder[_met] == NULL)
1787     return 0.0;
1788 
1789   uint n = getUnderIndex(overMet);
1790 
1791   extDistRC* rc = rcModel->_capDiagUnder[_met]->getRC(n, _width, dist);
1792 
1793   if (rc != NULL) {
1794     if (IsDebugNet()) {
1795       int dbUnit = _extMain->_block->getDbUnitsPerMicron();
1796       rc->printDebugRC_diag(_met, overMet, 0, _width, dist, dbUnit, logger_);
1797     }
1798     return rc->_fringe;  // TODO 620
1799   } else
1800     return 0.0;
1801 }
getDiagUnderCC(extMetRCTable * rcModel,uint diagWidth,uint diagDist,uint overMet)1802 double extMeasure::getDiagUnderCC(extMetRCTable* rcModel, uint diagWidth,
1803                                   uint diagDist, uint overMet) {
1804   if (rcModel->_capDiagUnder[_met] == NULL)
1805     return 0.0;
1806 
1807   uint n = getUnderIndex(overMet);
1808 
1809   extDistRC* rc = rcModel->_capDiagUnder[_met]
1810                       ->getRC(n, _width, diagWidth, diagDist, _dist);
1811 
1812   if (rc != NULL)
1813     return rc->_fringe;
1814   else
1815     return 0.0;
1816 }
getDiagUnderCC2(extMetRCTable * rcModel,uint diagWidth,uint diagDist,uint overMet)1817 extDistRC* extMeasure::getDiagUnderCC2(extMetRCTable* rcModel, uint diagWidth,
1818                                        uint diagDist, uint overMet) {
1819   if (rcModel->_capDiagUnder[_met] == NULL)
1820     return NULL;
1821 
1822   uint n = getUnderIndex(overMet);
1823 
1824   extDistRC* rc = rcModel->_capDiagUnder[_met]
1825                       ->getRC(n, _width, diagWidth, diagDist, _dist);
1826 
1827   if (rc == NULL)
1828     return NULL;
1829   return rc;
1830 }
getRes(uint met)1831 double extRCModel::getRes(uint met) {
1832   if (met > 13)
1833     return 0;
1834 
1835   extDistRC* rc = _capOver->getCapOver(met, 0);
1836   if (rc == NULL)
1837     return 0;
1838 
1839   return rc->getRes();
1840 }
addCapOver(uint met,uint metUnder,extDistRC * rc)1841 uint extRCTable::addCapOver(uint met, uint metUnder, extDistRC* rc) {
1842   return _inTable[met][metUnder]->add(rc);
1843 }
extRCModel(uint layerCnt,const char * name,Logger * logger)1844 extRCModel::extRCModel(uint layerCnt, const char* name, Logger* logger) {
1845   logger_ = logger;
1846   _layerCnt = layerCnt;
1847   strcpy(_name, name);
1848   _resOver = new extRCTable(true, layerCnt);
1849   _capOver = new extRCTable(true, layerCnt);
1850   _capUnder = new extRCTable(false, layerCnt);
1851   _capDiagUnder = new extRCTable(false, layerCnt);
1852   _rcPoolPtr = new AthPool<extDistRC>(false, 1024);
1853   _process = NULL;
1854   _maxMinFlag = false;
1855 
1856   _wireDirName = new char[2048];
1857   _topDir = new char[1024];
1858   _patternName = new char[1024];
1859   _parser = new Ath__parser();
1860   _solverFileName = new char[1024];
1861   _wireFileName = new char[1024];
1862   _capLogFP = NULL;
1863   _logFP = NULL;
1864 
1865   _readCapLog = false;
1866   _commentFlag = false;
1867 
1868   _modelCnt = 0;
1869   _dataRateTable = NULL;
1870   _modelTable = NULL;
1871   _tmpDataRate = 0;
1872   _extMain = NULL;
1873   _ruleFileName = NULL;
1874   _diagModel = 0;
1875   _verticalDiag = false;
1876   _keepFile = false;
1877   _metLevel = 0;
1878 }
extRCModel(const char * name,Logger * logger)1879 extRCModel::extRCModel(const char* name, Logger* logger) {
1880   logger = logger;
1881   _layerCnt = 0;
1882   strcpy(_name, name);
1883   _resOver = NULL;
1884   _capOver = NULL;
1885   _capUnder = NULL;
1886   _capDiagUnder = NULL;
1887   _rcPoolPtr = new AthPool<extDistRC>(false, 1024);
1888   _process = NULL;
1889   _maxMinFlag = false;
1890 
1891   _wireDirName = new char[2048];
1892   _topDir = new char[1024];
1893   _patternName = new char[1024];
1894   _parser = new Ath__parser();
1895   _solverFileName = new char[1024];
1896   _wireFileName = new char[1024];
1897   _capLogFP = NULL;
1898   _logFP = NULL;
1899 
1900   _readCapLog = false;
1901   _commentFlag = false;
1902 
1903   _modelCnt = 0;
1904   _modelTable = NULL;
1905   _tmpDataRate = 0;
1906 
1907   _noVariationIndex = -1;
1908 
1909   _extMain = NULL;
1910   _ruleFileName = NULL;
1911   _diagModel = 0;
1912   _verticalDiag = false;
1913   _keepFile = false;
1914   _metLevel = 0;
1915 }
1916 
~extRCModel()1917 extRCModel::~extRCModel() {
1918   delete _resOver;
1919   delete _capOver;
1920   delete _capUnder;
1921   delete _capDiagUnder;
1922   delete _rcPoolPtr;
1923 
1924   delete[] _wireDirName;
1925   delete[] _topDir;
1926   delete[] _patternName;
1927   delete _parser;
1928   delete[] _solverFileName;
1929   delete[] _wireFileName;
1930 
1931   if (_modelCnt > 0) {
1932     for (uint ii = 0; ii < _modelCnt; ii++)
1933       delete _modelTable[ii];
1934 
1935     delete[] _modelTable;
1936     delete _dataRateTable;
1937   }
1938 }
setExtMain(extMain * x)1939 void extRCModel::setExtMain(extMain* x) { _extMain = x; }
getProcess()1940 extProcess* extRCModel::getProcess() { return _process; }
setProcess(extProcess * p)1941 void extRCModel::setProcess(extProcess* p) { _process = p; }
createModelTable(uint n,uint layerCnt)1942 void extRCModel::createModelTable(uint n, uint layerCnt) {
1943   _layerCnt = layerCnt;
1944   _modelCnt = n;
1945 
1946   _dataRateTable = new Ath__array1D<double>(_modelCnt);
1947   _modelTable = new extMetRCTable* [_modelCnt];
1948   for (uint jj = 0; jj < _modelCnt; jj++)
1949     _modelTable[jj] = new extMetRCTable(_layerCnt, _rcPoolPtr, logger_);
1950 }
setDataRateTable(uint met)1951 void extRCModel::setDataRateTable(uint met) {
1952   if (_process == NULL)
1953     return;
1954   /*
1955           FILE *fp= openFile("./", "ou", NULL, "w");
1956           for (uint m= 1; m<_layerCnt; m++) {
1957                   for (uint mUnder= 1; mUnder<m; mUnder++) {
1958                           for (uint mOver= m+1; mOver<_layerCnt; mOver++) {
1959                                   fprintf(fp, "met= %d   over %d   under %d
1960      index= %d\n", m, mUnder, mOver, getMetIndexOverUnder(m, mUnder, mOver,
1961      _layerCnt));
1962 
1963                           }
1964                   }
1965                   fprintf(fp, "\n");
1966           }
1967           fclose(fp);
1968   */
1969   _maxMinFlag = _process->getMaxMinFlag();
1970   bool thickVarFlag = _process->getThickVarFlag();
1971   extVariation* xvar = _process->getVariation(met);
1972 
1973   if (xvar != NULL) {
1974     Ath__array1D<double>* dTable = xvar->getDataRateTable();
1975 
1976     createModelTable(dTable->getCnt() + 1, _layerCnt);
1977 
1978     _dataRateTable->add(0.0);
1979     for (uint ii = 0; ii < dTable->getCnt(); ii++)
1980       _dataRateTable->add(dTable->get(ii));
1981 
1982   } else if (_maxMinFlag) {
1983     createModelTable(3, _layerCnt);
1984     for (uint i = 0; i < 3; i++)
1985       _dataRateTable->add(i);
1986   } else if (thickVarFlag) {
1987     Ath__array1D<double>* dTable = _process->getDataRateTable(1);
1988     createModelTable(dTable->getCnt(), _layerCnt);
1989     for (uint ii = 0; ii < dTable->getCnt(); ii++)
1990       _dataRateTable->add(dTable->get(ii));
1991   } else {
1992     createModelTable(1, _layerCnt);
1993     //		_dataRateTable->set(0, 0.0);
1994     _dataRateTable->add(0.0);
1995   }
1996   _tmpDataRate = 0;
1997 }
addLefTotRC(uint met,uint underMet,double fr,double r)1998 uint extRCModel::addLefTotRC(uint met, uint underMet, double fr, double r) {
1999   extDistRC* rc = _rcPoolPtr->alloc();
2000   rc->set(0, 0.0, fr, 0.0, r);
2001 
2002   uint n = _capOver->addCapOver(met, underMet, rc);
2003   return n;
2004 }
2005 
addCapOver(uint met,uint underMet,uint d,double cc,double fr,double a,double r)2006 uint extRCModel::addCapOver(uint met, uint underMet, uint d, double cc,
2007                             double fr, double a, double r) {
2008   extDistRC* rc = _rcPoolPtr->alloc();
2009   rc->set(d, cc, fr, a, r);
2010 
2011   uint n = _capOver->addCapOver(met, underMet, rc);
2012   return n;
2013 }
2014 /*
2015 uint extRCModel::addCapUnder(uint met, uint overMet, uint d, double cc, double
2016 fr, double a, double r)
2017 {
2018         extDistRC *rc= _rcPoolPtr->alloc();
2019         rc->set(d, cc, fr, a, r);
2020 
2021         uint n= _capOver->addCapUnder(met, overMet, rc);
2022         return n;
2023 }
2024 */
extMeasure()2025 extMeasure::extMeasure() {
2026   _met = -1;
2027   _underMet = -1;
2028   _overMet = -1;
2029 
2030   _w_m = 0.0;
2031   _s_m = 0.0;
2032   _w_nm = 0;
2033   _s_nm = 0;
2034   _r = 0.0;
2035   _t = 0.0;
2036   _h = 0.0;
2037   _w2_m = 0.0;
2038   _s2_m = 0.0;
2039   _w2_nm = 0;
2040   _s2_nm = 0;
2041 
2042   _topWidth = 0.0;
2043   _botWidth = 0.0;
2044   _teff = 0.0;
2045   _heff = 0.0;
2046   _seff = 0.0;
2047 
2048   _topWidthR = 0.0;
2049   _botWidthR = 0.0;
2050   _teffR = 0.0;
2051 
2052   _varFlag = false;
2053   _3dFlag = false;
2054   _rcValid = false;
2055   _benchFlag = false;
2056   _diag = false;
2057   _verticalDiag = false;
2058   _plate = false;
2059   _metExtFlag = false;
2060 
2061   for (uint ii = 0; ii < 20; ii++) {
2062     _rc[ii] = new extDistRC();
2063     _rc[ii]->setLogger(logger_);
2064   }
2065 
2066   _tmpRC = _rc[0];
2067 
2068   _capTable = NULL;
2069   _ll[0] = 0;
2070   _ll[1] = 0;
2071   _ur[0] = 0;
2072   _ur[1] = 0;
2073 
2074   _maxCapNodeCnt = 100;
2075   for (int n = 0; n < (int)_maxCapNodeCnt; n++) {
2076     for (int k = 0; k < (int)_maxCapNodeCnt; k++) {
2077       _capMatrix[n][k] = 0.0;
2078     }
2079   }
2080   _extMain = NULL;
2081 
2082   _2dBoxPool = new AthPool<ext2dBox>(false, 1024);
2083 
2084   _lenOUPool = NULL;
2085   _lenOUtable = NULL;
2086 
2087   _totCCcnt = 0;
2088   _totSmallCCcnt = 0;
2089   _totBigCCcnt = 0;
2090   _totSignalSegCnt = 0;
2091   _totSegCnt = 0;
2092 
2093   _tmpDstTable = new Ath__array1D<SEQ*>(32);
2094   _tmpSrcTable = new Ath__array1D<SEQ*>(32);
2095   _diagTable = new Ath__array1D<SEQ*>(32);
2096   _tmpTable = new Ath__array1D<SEQ*>(32);
2097   _ouTable = new Ath__array1D<SEQ*>(32);
2098   _overTable = new Ath__array1D<SEQ*>(32);
2099   _underTable = new Ath__array1D<SEQ*>(32);
2100 
2101   _seqPool = new AthPool<SEQ>(false, 1024);
2102 
2103   _dgContextFile = NULL;
2104   _diagFlow = false;
2105   _btermThreshold = false;
2106   _rotatedGs = false;
2107   _sameNetFlag = false;
2108 }
allocOUpool()2109 void extMeasure::allocOUpool() {
2110   _lenOUPool = new AthPool<extLenOU>(false, 128);
2111   _lenOUtable = new Ath__array1D<extLenOU*>(128);
2112 }
~extMeasure()2113 extMeasure::~extMeasure() {
2114   for (uint ii = 0; ii < 20; ii++)
2115     delete _rc[ii];
2116 
2117   delete _tmpDstTable;
2118   delete _tmpSrcTable;
2119   delete _diagTable;
2120   delete _tmpTable;
2121   delete _ouTable;
2122   delete _overTable;
2123   delete _underTable;
2124 
2125   delete _seqPool;
2126 
2127   delete _2dBoxPool;
2128   if (_lenOUPool != NULL) {
2129     delete _lenOUPool;
2130     delete _lenOUtable;
2131   }
2132 }
2133 
setMets(int m,int u,int o)2134 void extMeasure::setMets(int m, int u, int o) {
2135   _met = m;
2136   _underMet = u;
2137   _overMet = o;
2138   _over = false;
2139   _overUnder = false;
2140   if ((u > 0) && (o > 0))
2141     _overUnder = true;
2142   else if ((u >= 0) && (o < 0))
2143     _over = true;
2144 }
setTargetParams(double w,double s,double r,double t,double h,double w2,double s2)2145 void extMeasure::setTargetParams(double w, double s, double r, double t,
2146                                  double h, double w2, double s2) {
2147   _w_m = w;
2148   _s_m = s;
2149   _w_nm = Ath__double2int(1000 * w);
2150   _s_nm = Ath__double2int(1000 * s);
2151   _r = r;
2152   _t = t;
2153   _h = h;
2154   if (w2 > 0.0) {
2155     _w2_m = w2;
2156     _w2_nm = Ath__double2int(1000 * w2);
2157   } else {
2158     _w2_m = _w_m;
2159     _w2_nm = _w_nm;
2160   }
2161   //	if (s2>0.0 || (s2==0.0 && _diag && _benchFlag)) {
2162   if (s2 > 0.0 || (s2 == 0.0 && _diag)) {
2163     _s2_m = s2;
2164     _s2_nm = Ath__double2int(1000 * s2);
2165   } else {
2166     _s2_m = _s_m;
2167     _s2_nm = _s_nm;
2168   }
2169 }
setEffParams(double wTop,double wBot,double teff)2170 void extMeasure::setEffParams(double wTop, double wBot, double teff) {
2171   _topWidth = wTop;
2172   _botWidth = wBot;
2173   _teff = teff;
2174   //_heff= _h+_t-teff;
2175   _heff = _h;
2176   /*
2177           if (_diag)
2178                   _seff= _s_m;
2179           else
2180   */
2181   if (!_metExtFlag && _s_m != 99)
2182     _seff = _w_m + _s_m - wTop;
2183   else
2184     _seff = _s_m;
2185 }
addRC(extDistRC * rcUnit,uint len,uint jj)2186 extDistRC* extMeasure::addRC(extDistRC* rcUnit, uint len, uint jj) {
2187   if (rcUnit == NULL)
2188     return NULL;
2189   int dbUnit = _extMain->_block->getDbUnitsPerMicron();
2190   if (IsDebugNet())
2191     rcUnit->printDebugRC(_met, _overMet, _underMet, _width, _dist, dbUnit,
2192                          logger_);
2193 
2194   if (_sameNetFlag) {  // TO OPTIMIZE
2195     _rc[jj]->_fringe += 0.5 * rcUnit->_fringe * len;
2196   } else {
2197     _rc[jj]->_fringe += rcUnit->_fringe * len;
2198 
2199     if (_dist > 0)  // dist based
2200       _rc[jj]->_coupling += rcUnit->_coupling * len;
2201   }
2202 
2203   _rc[jj]->_res += rcUnit->_res * len;
2204   if (IsDebugNet()) {
2205     _rc[jj]->printDebugRC_sum(len, dbUnit, logger_);
2206   }
2207   return rcUnit;
2208 }
computeOverUnderRC(uint len)2209 extDistRC* extMeasure::computeOverUnderRC(uint len) {
2210   extDistRC* rcUnit = NULL;
2211 
2212   for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
2213     extMetRCTable* rcModel = _metRCTable.get(ii);
2214 
2215     rcUnit = getOverUnderRC(rcModel);
2216 
2217     addRC(rcUnit, len, ii);
2218   }
2219   return rcUnit;
2220 }
computeOverRC(uint len)2221 extDistRC* extMeasure::computeOverRC(uint len) {
2222   extDistRC* rcUnit = NULL;
2223 
2224   for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
2225     extMetRCTable* rcModel = _metRCTable.get(ii);
2226 
2227     rcUnit = getOverRC(rcModel);
2228 
2229     addRC(rcUnit, len, ii);
2230   }
2231   return rcUnit;
2232 }
computeR(uint len,double * valTable)2233 extDistRC* extMeasure::computeR(uint len, double* valTable) {
2234   extDistRC* rcUnit = NULL;
2235 
2236   for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
2237     extMetRCTable* rcModel = _metRCTable.get(ii);
2238 
2239     rcUnit = getOverRC(rcModel);
2240     if (rcUnit != NULL)
2241       _rc[ii]->_res += rcUnit->_res * len;
2242   }
2243   return rcUnit;
2244 }
computeUnderRC(uint len)2245 extDistRC* extMeasure::computeUnderRC(uint len) {
2246   extDistRC* rcUnit = NULL;
2247 
2248   for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
2249     extMetRCTable* rcModel = _metRCTable.get(ii);
2250 
2251     rcUnit = getUnderRC(rcModel);
2252 
2253     addRC(rcUnit, len, ii);
2254   }
2255   return rcUnit;
2256 }
2257 /*
2258 void extMeasure::addCap()
2259 {
2260         return;
2261         if (! _rcValid)
2262                 return;
2263 
2264         if (_underMet>0)
2265                 _capTable->addCapOver(_met, _underMet, _rc);
2266 
2267         else if (_overMet>0)
2268                 _capTable->addCapOver(_met, _overMet, _rc);
2269 }
2270 */
printMets(FILE * fp)2271 void extMeasure::printMets(FILE* fp) {
2272   if (_overUnder)
2273     fprintf(fp, "M%d over M%d under M%d ", _met, _underMet, _overMet);
2274   else if (_over) {
2275     if (_diag)
2276       fprintf(fp, "M%d over diag M%d ", _met, _underMet);
2277     else
2278       fprintf(fp, "M%d over M%d ", _met, _underMet);
2279   } else {
2280     if (_diag)
2281       fprintf(fp, "M%d under diag M%d ", _met, _overMet);
2282     else
2283       fprintf(fp, "M%d under M%d ", _met, _overMet);
2284   }
2285 }
printStats(FILE * fp)2286 void extMeasure::printStats(FILE* fp) {
2287   fprintf(fp, "<==> w= %g[%g %g]  s= %g[%g]  th= %g[%g]  h= %g[%g]  r= %g",
2288           _w_m, _topWidth, _botWidth, _s_m, _seff, _t, _teff, _h, _heff, _r);
2289 }
2290 
openFile(const char * topDir,const char * name,const char * suffix,const char * permissions)2291 FILE* extRCModel::openFile(const char* topDir, const char* name,
2292                            const char* suffix, const char* permissions) {
2293   char filename[2048];
2294 
2295   if (topDir != NULL)
2296     sprintf(filename, "%s", topDir);
2297 
2298   if (suffix == NULL)
2299     sprintf(filename, "%s/%s", filename, name);
2300   else
2301     sprintf(filename, "%s/%s%s", filename, name, suffix);
2302 
2303   FILE* fp = fopen(filename, permissions);
2304   if (fp == NULL) {
2305     logger_->info(RCX, 485, "Cannot open file {} with permissions {}", filename,
2306                   permissions);
2307     return NULL;
2308   }
2309   return fp;
2310 }
2311 
getCapValues(uint lastNode,double & cc1,double & cc2,double & fr,double & tot,extMeasure * m)2312 uint extRCModel::getCapValues(uint lastNode, double& cc1, double& cc2,
2313                               double& fr, double& tot, extMeasure* m) {
2314   double totCap = 0.0;
2315   uint wireNum = m->_wireCnt / 2 + 1;  // assume odd numebr
2316   if (m->_diag && _diagModel == 2) {
2317     fr = m->_capMatrix[1][0];   // diag
2318     cc1 = m->_capMatrix[1][1];  // left cc in diag side
2319     cc2 = m->_capMatrix[1][2];  // right cc
2320     fprintf(_capLogFP, "\n");
2321     m->printMets(_capLogFP);
2322     fprintf(_capLogFP, " diag= %g, cc1=%g, cc2=%g  ", fr, cc1, cc2);
2323     m->printStats(_capLogFP);
2324     fprintf(_capLogFP, "\n\nEND\n\n");
2325     return lastNode;
2326   }
2327   if (m->_diag && _diagModel == 1) {
2328     cc1 = m->_capMatrix[1][0];
2329     fprintf(_capLogFP, "\n");
2330     m->printMets(_capLogFP);
2331     fprintf(_capLogFP, " diag= %g  ", cc1);
2332     m->printStats(_capLogFP);
2333     fprintf(_capLogFP, "\n\nEND\n\n");
2334     return lastNode;
2335   }
2336 
2337   if (lastNode == 1) {
2338     totCap = m->_capMatrix[1][0];
2339     fr = totCap;
2340     if (m->_plate)
2341       fr /= 100000;
2342     fprintf(_capLogFP, "\n");
2343     m->printMets(_capLogFP);
2344     tot = cc1 + cc2 + fr;
2345 
2346     fprintf(_capLogFP, " cc1= %g  cc2= %g  fr= %g  tot= %g  ", cc1, cc2, fr,
2347             tot);
2348 
2349     m->printStats(_capLogFP);
2350     fprintf(_capLogFP, "\n\nEND\n\n");
2351 
2352     return lastNode;
2353   } else if (lastNode > 1) {
2354     totCap = m->_capMatrix[1][0];
2355     cc1 = m->_capMatrix[1][1];  // left cc
2356     cc2 = m->_capMatrix[1][2];
2357   }
2358 
2359   if (lastNode != m->_wireCnt) {
2360     //		return 0;
2361     logger_->warn(RCX, 418, "Reads only {} nodes from {}", lastNode,
2362                   _wireDirName);
2363   }
2364 
2365   fprintf(_capLogFP, "\n");
2366   m->printMets(_capLogFP);
2367   fr = totCap - cc1 - cc2;
2368 
2369   fprintf(_capLogFP, " cc1= %g  cc2= %g  fr= %g  tot= %g  ", cc1, cc2, fr,
2370           totCap);
2371 
2372   m->printStats(_capLogFP);
2373   fprintf(_capLogFP, "\n\nEND\n\n");
2374 
2375   return lastNode;
2376 }
2377 
getCapValues3D(uint lastNode,double & cc1,double & cc2,double & fr,double & tot,extMeasure * m)2378 uint extRCModel::getCapValues3D(uint lastNode, double& cc1, double& cc2,
2379                                 double& fr, double& tot, extMeasure* m) {
2380   double totCap = 0.0;
2381   uint wireNum = m->_wireCnt / 2 + 1;  // assume odd numebr
2382   if (m->_diag) {
2383     cc1 = m->_capMatrix[1][0];
2384     fprintf(_capLogFP, "\n");
2385     m->printMets(_capLogFP);
2386     fprintf(_capLogFP, " diag= %g  ", cc1);
2387     m->printStats(_capLogFP);
2388     fprintf(_capLogFP, "\n\nEND\n\n");
2389     return lastNode;
2390   }
2391 
2392   uint n = 1;
2393   for (; n <= lastNode; n++) {
2394     if (n != wireNum)
2395       continue;
2396     totCap = m->_capMatrix[1][0];
2397 
2398     cc1 = m->_capMatrix[1][n - 1];
2399     cc2 = m->_capMatrix[1][n + 1];
2400     break;
2401   }
2402   totCap += m->getCCfringe3D(lastNode, n, 2, 3);
2403 
2404   fr = totCap;
2405 
2406   if (lastNode != m->_wireCnt) {
2407     //                return 0;
2408     logger_->info(RCX, 209, "Reads only {} nodes from {}", lastNode,
2409                   _wireDirName);
2410   }
2411 
2412   fprintf(_capLogFP, "\n");
2413   m->printMets(_capLogFP);
2414   tot = cc1 + cc2 + fr;
2415 
2416   fprintf(_capLogFP, " cc1= %g  cc2= %g  fr= %g  tot= %g  ", cc1, cc2, fr, tot);
2417 
2418   m->printStats(_capLogFP);
2419   fprintf(_capLogFP, "\n\nEND\n\n");
2420 
2421   return lastNode;
2422 }
2423 
getCapMatrixValues(uint lastNode,extMeasure * m)2424 uint extRCModel::getCapMatrixValues(uint lastNode, extMeasure* m) {
2425   uint ccCnt = 0;
2426   for (uint n = 1; n <= lastNode; n++) {
2427     double frCap = m->_capMatrix[n][0] * m->_len;
2428     m->_capMatrix[n][0] = 0.0;
2429 
2430     logger_->info(RCX, 417, "FrCap for netId {} (nodeId= {})  {}",
2431                   m->_idTable[n], n, frCap);
2432 
2433     //		uint w= 0;
2434     double res = _extMain->getLefResistance(m->_met, m->_w_nm, m->_len,
2435                                             m->_rIndex);  // TO_TEST
2436 
2437     dbRSeg* rseg1 = m->getFirstDbRseg(m->_idTable[n]);
2438     rseg1->setResistance(res);
2439 
2440     uint k = n + 1;
2441     if (k <= lastNode) {
2442       double cc1 = m->_capMatrix[n][k] * m->_len;
2443       m->_capMatrix[n][k] = 0.0;
2444 
2445       logger_->info(RCX, 416, "\tccCap for netIds {}({}), {}({}) {}",
2446                     m->_idTable[n], n, m->_idTable[k], k, cc1);
2447       ccCnt++;
2448 
2449       dbRSeg* rseg2 = m->getFirstDbRseg(m->_idTable[k]);
2450       m->_extMain->updateCCCap(rseg1, rseg2, cc1);
2451     }
2452     double ccFr = m->getCCfringe(lastNode, n, 2, 3) * m->_len;
2453 
2454     frCap += ccFr;
2455     rseg1->setCapacitance(frCap);
2456 
2457     logger_->info(RCX, 414, "\tfrCap from CC for netId {}({}) {}",
2458                   m->_idTable[n], n, ccFr);
2459     logger_->info(RCX, 411, "\ttotFrCap for netId {}({}) {}", m->_idTable[n], n,
2460                   frCap);
2461   }
2462   m->printStats(_capLogFP);
2463   fprintf(_capLogFP, "\n\nEND\n\n");
2464 
2465   for (uint ii = 1; ii <= lastNode; ii++) {
2466     for (uint jj = ii + 1; jj <= lastNode; jj++) {
2467       m->_capMatrix[ii][jj] = 0.0;
2468     }
2469   }
2470   return ccCnt;
2471 }
getCapMatrixValues3D(uint lastNode,extMeasure * m)2472 uint extRCModel::getCapMatrixValues3D(uint lastNode, extMeasure* m) {
2473   uint wireNum = m->_wireCnt / 2 + 1;  // assume odd numebr
2474   uint n;
2475   if (lastNode == 1) {
2476     n = 1;
2477     double frCap = m->_capMatrix[1][0];
2478     m->_capMatrix[1][0] = 0.0;
2479 
2480     logger_->info(RCX, 210, "FrCap for netId {} (nodeId= {})  {}",
2481                   m->_idTable[n], n, frCap);
2482 
2483     //                uint w= 0;
2484     dbRSeg* rseg1 = m->getFirstDbRseg(m->_idTable[n]);
2485     rseg1->setCapacitance(frCap);
2486     logger_->info(RCX, 412, "\ttotFrCap for netId {}({}) {}", m->_idTable[n], n,
2487                   m->_capMatrix[1][n]);
2488     m->printStats(_capLogFP);
2489     fprintf(_capLogFP, "\n\nEND\n\n");
2490     return 0;
2491   }
2492 
2493   for (n = 1; n <= lastNode; n++) {
2494     if (n != wireNum)
2495       continue;
2496     double frCap = m->_capMatrix[1][0];
2497     m->_capMatrix[1][0] = 0.0;
2498 
2499     logger_->info(RCX, 413, "FrCap for netId {} (nodeId= {})  {}",
2500                   m->_idTable[n], n, frCap);
2501 
2502     //                uint w= 0;
2503     //                double res= _extMain->getLefResistance(m->_met,
2504     //                1000*m->_w, m->_len);
2505 
2506     dbRSeg* rseg1 = m->getFirstDbRseg(m->_idTable[n]);
2507     //                rseg1->setResistance(res);
2508 
2509     double cc1 = m->_capMatrix[1][n - 1];
2510     m->_capMatrix[1][n - 1] = 0.0;
2511     logger_->info(RCX, 415, "\tccCap for netIds {}({}), {}({}) {}",
2512                   m->_idTable[n], n, m->_idTable[n - 1], n - 1, cc1);
2513     dbRSeg* rseg2 = m->getFirstDbRseg(m->_idTable[n - 1]);
2514     m->_extMain->updateCCCap(rseg1, rseg2, cc1);
2515     double cc2 = m->_capMatrix[1][n + 1];
2516     m->_capMatrix[1][n + 1] = 0.0;
2517     logger_->info(RCX, 211, "\tccCap for netIds {}({}), {}({}) {}",
2518                   m->_idTable[n], n, m->_idTable[n + 1], n + 1, cc2);
2519     uint netId3 = m->_idTable[n + 1];
2520     dbRSeg* rseg3 = m->getFirstDbRseg(netId3);
2521     m->_extMain->updateCCCap(rseg1, rseg3, cc2);
2522 
2523     double ccFr = m->getCCfringe3D(lastNode, n, 2, 3);
2524     frCap += ccFr;
2525     rseg1->setCapacitance(frCap);
2526 
2527     logger_->info(RCX, 212, "\tfrCap from CC for netId {}({}) {}",
2528                   m->_idTable[n], n, ccFr);
2529     logger_->info(RCX, 213, "\ttotFrCap for netId {}({}) {}", m->_idTable[n], n,
2530                   m->_capMatrix[1][n]);
2531   }
2532   m->printStats(_capLogFP);
2533   fprintf(_capLogFP, "\n\nEND\n\n");
2534 
2535   for (uint ii = 1; ii <= lastNode; ii++) {
2536     m->_idTable[ii] = 0;
2537     for (uint jj = ii + 1; jj <= lastNode; jj++) {
2538       m->_capMatrix[ii][jj] = 0.0;
2539     }
2540   }
2541   return 0;
2542 }
2543 
readCapacitanceBench(bool readCapLog,extMeasure * m)2544 uint extRCModel::readCapacitanceBench(bool readCapLog, extMeasure* m) {
2545   double units = 1.0e+12;
2546 
2547   FILE* solverFP = NULL;
2548   if (!readCapLog) {
2549     solverFP = openSolverFile();
2550     if (solverFP == NULL) {
2551       return 0;
2552     }
2553     _parser->setInputFP(solverFP);
2554   }
2555 
2556   Ath__parser wParser;
2557 
2558   bool matrixFlag = false;
2559   /*
2560    C_1_2 M1_w1 M1_w2 6.367907e-17
2561    C_1_3 M1_w1 M1_w3 4.394765e-18
2562    C_1_0 M1_w1 GROUND_RC2 4.842417e-17
2563    C_2_3 M1_w2 M1_w3 6.367920e-17
2564    C_2_0 M1_w2 GROUND_RC2 2.877861e-17
2565    C_3_0 M1_w3 GROUND_RC2 4.842436e-17
2566   */
2567 
2568   uint n = m->_wireCnt / 2 + 1;
2569   uint cnt = 0;
2570   m->_capMatrix[1][0] = 0.0;
2571   m->_capMatrix[1][1] = 0.0;
2572   m->_capMatrix[1][2] = 0.0;
2573   //	while (_parser->parseNextLine()>0) {
2574   while (1) {
2575     if (!_parser->isKeyword(0, "BEGIN") || matrixFlag)
2576       if (!(_parser->parseNextLine() > 0))
2577         break;
2578     if (matrixFlag) {
2579       if (_parser->isKeyword(0, "END"))
2580         break;
2581 
2582       if (!_parser->isKeyword(0, "Charge"))
2583         continue;
2584 
2585       //_parser->printWords(stdout);
2586       _parser->printWords(_capLogFP);
2587 
2588       double cap = _parser->getDouble(4);
2589       if (cap < 0.0)
2590         cap = -cap;
2591       cap *= units;
2592 
2593       wParser.mkWords(_parser->get(2), "M");
2594       if (!m->_benchFlag && wParser.getInt(0) != 0) {
2595         if (wParser.mkWords(_parser->get(2), "w") < 2)
2596           continue;
2597         uint n1 = wParser.getInt(1);
2598         if (n1 == n - 1) {
2599           m->_capMatrix[1][1] = cap;  // left cc
2600           cnt++;
2601         } else if (n1 == n) {
2602           m->_capMatrix[1][0] = cap;
2603           m->_idTable[cnt] = n1;
2604           cnt++;
2605         } else if (n1 == n + 1) {
2606           m->_capMatrix[1][2] = cap;  // right cc
2607           cnt++;
2608         }
2609       }
2610       continue;
2611     }
2612 
2613     if (_parser->isKeyword(0, "***") && _parser->isKeyword(1, "POTENTIAL")) {
2614       matrixFlag = true;
2615 
2616       //			if (_parser->isKeyword(4, "Total")) {
2617 
2618       fprintf(_capLogFP, "BEGIN %s\n", _wireDirName);
2619       fprintf(_capLogFP, "%s\n", _commentLine);
2620       if (_keepFile && m != NULL) {
2621         if (m->_benchFlag)
2622           writeWires2(_capLogFP, m, m->_wireCnt);
2623         else
2624           writeRuleWires(_capLogFP, m, m->_wireCnt);
2625       }
2626       //			}
2627       continue;
2628     } else if (_parser->isKeyword(0, "BEGIN") &&
2629                (strcmp(_parser->get(1), _wireDirName) == 0)) {
2630       matrixFlag = true;
2631 
2632       fprintf(_capLogFP, "BEGIN %s\n", _wireDirName);
2633 
2634       continue;
2635     } else if (_parser->isKeyword(0, "BEGIN") &&
2636                (strcmp(_parser->get(1), _wireDirName) != 0)) {
2637       matrixFlag = false;
2638       break;
2639     }
2640   }
2641   if (solverFP != NULL)
2642     fclose(solverFP);
2643 
2644   return cnt;
2645 }
readCapacitanceBenchDiag(bool readCapLog,extMeasure * m)2646 uint extRCModel::readCapacitanceBenchDiag(bool readCapLog, extMeasure* m) {
2647   int met;
2648   if (m->_overMet > 0)
2649     met = m->_overMet;
2650   else if (m->_underMet > 0)
2651     met = m->_underMet;
2652   uint n = m->_wireCnt / 2 + 1;
2653 
2654   double units = 1.0e+12;
2655 
2656   FILE* solverFP = NULL;
2657   if (!readCapLog) {
2658     solverFP = openSolverFile();
2659     if (solverFP == NULL) {
2660       return 0;
2661     }
2662     _parser->setInputFP(solverFP);
2663   }
2664 
2665   Ath__parser wParser;
2666 
2667   bool matrixFlag = false;
2668   uint cnt = 0;
2669   m->_capMatrix[1][0] = 0.0;
2670   m->_capMatrix[1][1] = 0.0;
2671   m->_capMatrix[1][2] = 0.0;
2672   //        while (_parser->parseNextLine()>0) {
2673   while (1) {
2674     if (!_parser->isKeyword(0, "BEGIN") || matrixFlag)
2675       if (!(_parser->parseNextLine() > 0))
2676         break;
2677     if (matrixFlag) {
2678       if (_parser->isKeyword(0, "END"))
2679         break;
2680 
2681       if (!_parser->isKeyword(0, "Charge"))
2682         continue;
2683 
2684       //_parser->printWords(stdout);
2685       _parser->printWords(_capLogFP);
2686       double cap = _parser->getDouble(4);
2687       if (cap < 0.0)
2688         cap = -cap;
2689       cap *= units;
2690 
2691       wParser.mkWords(_parser->get(2), "M");
2692       if (_diagModel == 1) {
2693         if (wParser.getInt(0) != met)
2694           continue;
2695         wParser.mkWords(_parser->get(2), "w");
2696         uint n1 = wParser.getInt(1);
2697         if (n1 != n)
2698           continue;
2699         m->_capMatrix[1][0] = cap;
2700         m->_idTable[cnt] = n1;
2701         cnt++;
2702       }
2703       if (_diagModel == 2) {
2704         if (wParser.getInt(0) == met) {
2705           wParser.mkWords(_parser->get(2), "w");
2706           uint n1 = wParser.getInt(1);
2707           if (n1 != n)
2708             continue;
2709           m->_capMatrix[1][0] = cap;  // diag
2710           m->_idTable[cnt] = n1;
2711           cnt++;
2712         } else if (!m->_benchFlag && wParser.getInt(0) != 0) {
2713           wParser.mkWords(_parser->get(2), "w");
2714           uint n1 = wParser.getInt(1);
2715           if (n1 == n - 1) {
2716             m->_capMatrix[1][1] = cap;  // left cc in diag side
2717             cnt++;
2718           }
2719           if (n1 == n + 1) {
2720             m->_capMatrix[1][2] = cap;  // right cc
2721             cnt++;
2722           }
2723         }
2724       }
2725       continue;
2726     }
2727 
2728     if (_parser->isKeyword(0, "***") && _parser->isKeyword(1, "POTENTIAL")) {
2729       matrixFlag = true;
2730 
2731       fprintf(_capLogFP, "BEGIN %s\n", _wireDirName);
2732       fprintf(_capLogFP, "%s\n", _commentLine);
2733       if (_keepFile && m != NULL) {
2734         if (m->_benchFlag)
2735           writeWires2(_capLogFP, m, m->_wireCnt);
2736         else
2737           writeRuleWires(_capLogFP, m, m->_wireCnt);
2738       }
2739       continue;
2740     } else if (_parser->isKeyword(0, "BEGIN") &&
2741                (strcmp(_parser->get(1), _wireDirName) == 0)) {
2742       matrixFlag = true;
2743 
2744       fprintf(_capLogFP, "BEGIN %s\n", _wireDirName);
2745       continue;
2746     } else if (_parser->isKeyword(0, "BEGIN") &&
2747                (strcmp(_parser->get(1), _wireDirName) != 0)) {
2748       matrixFlag = false;
2749       break;
2750     }
2751   }
2752 
2753   if (solverFP != NULL)
2754     fclose(solverFP);
2755 
2756   return cnt;
2757 }
2758 // void extRCModel::mkFileNames(uint met, const char* ou, uint ouMet, double w,
2759 // double s, double r)
mkFileNames(extMeasure * m,char * wiresNameSuffix)2760 void extRCModel::mkFileNames(extMeasure* m, char* wiresNameSuffix) {
2761   char overUnder[128];
2762 
2763   if ((m->_overMet > 0) && (m->_underMet > 0))
2764     sprintf(overUnder, "M%doM%duM%d", m->_met, m->_underMet, m->_overMet);
2765 
2766   else if (m->_overMet > 0)
2767     if (m->_diag)
2768       sprintf(overUnder, "M%dduM%d", m->_met, m->_overMet);
2769     else
2770       sprintf(overUnder, "M%duM%d", m->_met, m->_overMet);
2771 
2772   else if (m->_underMet >= 0)
2773     sprintf(overUnder, "M%doM%d", m->_met, m->_underMet);
2774 
2775   else
2776     sprintf(overUnder, "Uknown");
2777 
2778   double w = m->_w_m;
2779   double s = m->_s_m;
2780   double r = m->_r;
2781   double w2 = m->_w2_m;
2782   double s2 = m->_s2_m;
2783 
2784   /*
2785           if ((r!=0)&&(s>0))
2786                   sprintf(_wireDirName, "%s/%s/%s/W%g/S%g__D%g", _topDir,
2787      _patternName, overUnder, w, s, r); else if (s>0) sprintf(_wireDirName,
2788      "%s/%s/%s/W%g/S%g", _topDir, _patternName, overUnder, w, s); else
2789                   sprintf(_wireDirName, "%s/%s/%s/W%g", _topDir, _patternName,
2790      overUnder, w);
2791   */
2792   if (!m->_benchFlag) {
2793     if (m->_diag) {
2794       if (_diagModel == 2)
2795         sprintf(_wireDirName, "%s/%s/%s/D%g/W%g/DW%g/DS%g/S%g", _topDir,
2796                 _patternName, overUnder, r, w, w2, s2, s);
2797       if (_diagModel == 1)
2798         sprintf(_wireDirName, "%s/%s/%s/D%g/W%g/S%g", _topDir, _patternName,
2799                 overUnder, r, w, s);
2800     } else
2801       sprintf(_wireDirName, "%s/%s/%s/D%g/W%g/S%g", _topDir, _patternName,
2802               overUnder, r, w, s);
2803   } else {
2804     sprintf(_wireDirName, "%s/%s/%s/W%g_W%g/S%g_S%g", _topDir, _patternName,
2805             overUnder, w, w2, s, s2);
2806   }
2807 
2808   if (wiresNameSuffix != NULL)
2809     sprintf(_wireFileName, "%s.%s", "wires", wiresNameSuffix);
2810   else
2811     sprintf(_wireFileName, "%s", "wires");
2812 
2813   fprintf(_logFP, "pattern Dir %s\n\n", _wireDirName);
2814   fflush(_logFP);
2815 }
get_nm(extMeasure * m,double n)2816 double get_nm(extMeasure* m, double n) {
2817   if (n == 0)
2818     return 0;
2819   double a = 1000 * 1000.0 * n / m->_dbunit;
2820   return a;
2821 }
get_nm(int n,int units)2822 int get_nm(int n, int units) {
2823   if (n == 0)
2824     return 0;
2825   int a = (1000 * n) / units;
2826   return a;
2827 }
mkNet_prefix(extMeasure * m,const char * wiresNameSuffix)2828 void extRCModel::mkNet_prefix(extMeasure* m, const char* wiresNameSuffix) {
2829   char overUnder[128];
2830 
2831   if ((m->_overMet > 0) && (m->_underMet > 0))
2832     sprintf(overUnder, "M%doM%duM%d", m->_met, m->_underMet, m->_overMet);
2833 
2834   else if (m->_overMet > 0)
2835     if (m->_diag)
2836       sprintf(overUnder, "M%duuM%d", m->_met, m->_overMet);
2837     else
2838       sprintf(overUnder, "M%duM%d", m->_met, m->_overMet);
2839 
2840   else if (m->_underMet >= 0) {
2841     if (m->_diag)
2842       sprintf(overUnder, "M%duuM%d", m->_underMet, m->_met);
2843     else
2844       sprintf(overUnder, "M%doM%d", m->_met, m->_underMet);
2845   } else
2846     sprintf(overUnder, "Unknown");
2847 
2848   double w = m->_w_m;
2849   double s = m->_s_m;
2850   double r = m->_r;
2851   double w2 = m->_w2_m;
2852   double s2 = m->_s2_m;
2853 
2854   int n = get_nm(m, m->_s_m);
2855   sprintf(_wireDirName, "%s_%s_W%gW%g_S%gS%g", _patternName, overUnder,
2856           get_nm(m, m->_w_m), get_nm(m, m->_w2_m), get_nm(m, m->_s_m),
2857           get_nm(m, m->_s2_m));
2858   sprintf(_wireDirName, "%s_%s_W%gW%g_S%05dS%05d", _patternName, overUnder,
2859           get_nm(m, m->_w_m), get_nm(m, m->_w2_m), get_nm(m->_s_nm, m->_dbunit),
2860           get_nm(m->_s2_nm, m->_dbunit));
2861 
2862   if (wiresNameSuffix != NULL)
2863     sprintf(_wireFileName, "%s.%s", "wires", wiresNameSuffix);
2864   else
2865     sprintf(_wireFileName, "%s", "wires");
2866 
2867   fprintf(_logFP, "pattern Dir %s\n\n", _wireDirName);
2868   fflush(_logFP);
2869 }
2870 
mkPatternFile()2871 FILE* extRCModel::mkPatternFile() {
2872   _parser->mkDirTree(_wireDirName, "/");
2873 
2874   FILE* fp = openFile(_wireDirName, _wireFileName, NULL, "w");
2875   if (fp == NULL)
2876     return NULL;
2877 
2878   fprintf(fp, "$pattern %s\n\n", _wireDirName);
2879 
2880   return fp;
2881 }
openSolverFile()2882 FILE* extRCModel::openSolverFile() {
2883   FILE* fp = openFile(_wireDirName, _wireFileName, ".out", "r");
2884   if (fp != NULL)
2885     _parser->setInputFP(fp);
2886 
2887   return fp;
2888 }
openCapLogFile()2889 bool extRCModel::openCapLogFile() {
2890   _readCapLog = false;
2891   if (_readSolver && !_runSolver)
2892     _readCapLog = true;
2893 
2894   const char* capLog = "caps.log";
2895 
2896   char buff[1024];
2897   sprintf(buff, "%s/%s", _topDir, _patternName);
2898   _parser->mkDirTree(buff, "/");
2899 
2900   FILE* fp = openFile(buff, capLog, NULL, "r");
2901 
2902   if (fp == NULL) {  // no previous run
2903     _capLogFP = openFile(buff, capLog, NULL, "w");
2904     _parser->setInputFP(_capLogFP);
2905     return false;
2906   }
2907   fclose(fp);
2908 
2909   char cmd[4000];
2910 
2911   FILE* fp1 = NULL;
2912   if (_readCapLog) {
2913     fp1 = openFile(buff, capLog, NULL, "r");
2914     _capLogFP = openFile(buff, capLog, "out", "a");
2915   } else if (_metLevel > 0) {
2916     _capLogFP = openFile(buff, capLog, NULL, "a");
2917   } else {
2918     sprintf(cmd, "mv %s/%s/%s %s/%s/%s.in", _topDir, _patternName, capLog,
2919             _topDir, _patternName, capLog);
2920     system(cmd);
2921 
2922     _capLogFP = openFile(buff, capLog, NULL, "w");
2923 
2924     fp1 = openFile(buff, capLog, ".in", "r");
2925   }
2926   if (fp1 == NULL)
2927     return false;
2928 
2929   _parser->setInputFP(fp1);
2930 
2931   _readCapLog = true;
2932   return true;
2933 }
closeCapLogFile()2934 void extRCModel::closeCapLogFile() { fclose(_capLogFP); }
writeRuleWires(FILE * fp,extMeasure * measure,uint wireCnt)2935 void extRCModel::writeRuleWires(FILE* fp, extMeasure* measure, uint wireCnt) {
2936   extMasterConductor* m = _process->getMasterConductor(measure->_met);
2937   double minWidth = _process->getConductor(measure->_met)->_min_width;
2938   double minSpace = _process->getConductor(measure->_met)->_min_spacing;
2939   double top_ext = _process->getConductor(measure->_met)->_top_ext;
2940   double pitch;
2941   if (measure->_diag && _diagModel == 1) {
2942     //		pitch= measure->_topWidth + 2*minSpace;
2943     if (measure->_metExtFlag)
2944       pitch = measure->_topWidth - 2 * top_ext + minSpace;
2945     else
2946       pitch = measure->_topWidth + minSpace;
2947   } else {
2948     if (measure->_metExtFlag)
2949       pitch = measure->_topWidth - 2 * top_ext + measure->_seff;
2950     else
2951       pitch = measure->_topWidth + measure->_seff;
2952   }
2953   double min_pitch = minWidth + minSpace;
2954 
2955   uint n = wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
2956   double orig = 0.0;
2957   double x;
2958   uint ii;
2959 
2960   if (!measure->_plate) {
2961     // assume origin = (0,0)
2962     x = -min_pitch * (n - 1) - pitch - 0.5 * measure->_topWidth - top_ext +
2963         orig;
2964     for (ii = 0; ii < n - 1; ii++) {
2965       m->writeRaphaelConformalPoly(fp, minWidth, x, _process);
2966       m->writeRaphaelPoly(fp, ii + 1, minWidth, x, 0.0, _process);
2967       x += min_pitch;
2968     }
2969     x += 0.5 * measure->_topWidth;
2970     m->writeRaphaelConformalPoly(fp, 0.0, x, _process);
2971     m->writeRaphaelPoly(fp, n, x, 0.0);
2972 
2973     m->writeRaphaelConformalPoly(fp, 0.0, orig, _process);
2974     m->writeRaphaelPoly(fp, n + 1, orig, 1.0);
2975     x = orig + pitch;
2976     m->writeRaphaelConformalPoly(fp, 0.0, x, _process);
2977     m->writeRaphaelPoly(fp, n + 2, x, 0.0);
2978 
2979     x += 0.5 * measure->_topWidth - top_ext + minSpace;
2980     for (uint jj = n + 2; jj < wireCnt; jj++) {
2981       m->writeRaphaelConformalPoly(fp, minWidth, x, _process);
2982       m->writeRaphaelPoly(fp, jj + 1, minWidth, x, 0.0, _process);
2983       x += min_pitch;
2984     }
2985   } else {
2986     m->writeRaphaelConformalPoly(fp, 100, -50, _process);
2987     m->writeRaphaelPoly(fp, n + 1, 100, -50, 1.0, _process);
2988   }
2989 
2990   if (!measure->_diag)
2991     return;
2992   int met;
2993   if (measure->_overMet > 0)
2994     met = measure->_overMet;
2995   else if (measure->_underMet > 0)
2996     met = measure->_underMet;
2997   else
2998     return;
2999 
3000   m = _process->getMasterConductor(met);
3001   minWidth = _process->getConductor(met)->_min_width;
3002   minSpace = _process->getConductor(met)->_min_spacing;
3003   min_pitch = minWidth + minSpace;
3004   pitch = measure->_w2_m + measure->_s2_m;
3005 
3006   if (_diagModel == 2) {
3007     if (measure->_seff != 99) {
3008       x = orig - measure->_s2_m - min_pitch * n - 0.5 * measure->_w2_m;
3009       for (ii = 0; ii < n; ii++) {
3010         m->writeRaphaelConformalPoly(fp, minWidth, x, _process);
3011         m->writeRaphaelPoly(fp, ii + 1, minWidth, x, 0.0, _process);
3012 
3013         x += min_pitch;
3014       }
3015       m->writeRaphaelConformalPoly(fp, measure->_w2_m, x, _process);
3016       m->writeRaphaelPoly(fp, ii + 1, measure->_w2_m, x, 0.0, _process);
3017     } else {
3018       x = orig - measure->_s2_m - 0.5 * measure->_w2_m;
3019       m->writeRaphaelConformalPoly(fp, measure->_w2_m, x, _process);
3020       m->writeRaphaelPoly(fp, n + 1, measure->_w2_m, x, 0.0, _process);
3021     }
3022   }
3023   if (_diagModel == 1) {
3024     x = orig - measure->_seff - min_pitch * n - 0.5 * minWidth;
3025     for (ii = 0; ii < n + 1; ii++) {
3026       m->writeRaphaelConformalPoly(fp, minWidth, x, _process);
3027       m->writeRaphaelPoly(fp, ii + 1, minWidth, x, 0.0, _process);
3028       x += min_pitch;
3029     }
3030   }
3031 }
writeWires2(FILE * fp,extMeasure * measure,uint wireCnt)3032 void extRCModel::writeWires2(FILE* fp, extMeasure* measure, uint wireCnt) {
3033   extMasterConductor* m = _process->getMasterConductor(measure->_met);
3034   double pitch = measure->_topWidth + measure->_seff;
3035   double min_pitch = 0.001 * (measure->_minWidth + measure->_minSpace);
3036 
3037   uint n = wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
3038   double orig = 0.0;
3039 
3040   // assume origin = (0,0)
3041   double x = -min_pitch * (n - 1) - pitch - 0.5 * measure->_topWidth + orig;
3042   for (uint ii = 0; ii < n - 1; ii++) {
3043     m->writeRaphaelPoly(fp, ii + 1, 0.001 * measure->_minWidth, x, 0.0);
3044     x += min_pitch;
3045   }
3046   x += 0.5 * measure->_topWidth;
3047   m->writeRaphaelPoly(fp, n, x, 0.0);
3048 
3049   m->writeRaphaelPoly(fp, n + 1, orig, 1.0);
3050   x = 0.5 * measure->_w_m + measure->_s2_m;
3051   m->writeRaphaelPoly(fp, n + 2, measure->_w2_m, x, 0.0);
3052 
3053   //	x= orig+pitch;
3054   x = orig + 0.5 * measure->_topWidth + measure->_w2_m + measure->_s2_m +
3055       0.001 * measure->_minSpace;
3056   for (uint jj = n + 2; jj < wireCnt; jj++) {
3057     m->writeRaphaelPoly(fp, jj + 1, 0.001 * measure->_minWidth, x, 0.0);
3058     x += min_pitch;
3059   }
3060 }
writeRuleWires_3D(FILE * fp,extMeasure * measure,uint wireCnt)3061 void extRCModel::writeRuleWires_3D(FILE* fp, extMeasure* measure,
3062                                    uint wireCnt) {
3063   extMasterConductor* m = _process->getMasterConductor(measure->_met);
3064   double pitch = measure->_topWidth + measure->_seff;
3065   double minWidth = _process->getConductor(measure->_met)->_min_width;
3066   double minSpace = _process->getConductor(measure->_met)->_min_spacing;
3067   double min_pitch = minWidth + minSpace;
3068 
3069   uint n = wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
3070   double orig = 0.0;
3071 
3072   // assume origin = (0,0)
3073   double x = -min_pitch * (n - 1) - pitch - 0.5 * measure->_topWidth + orig;
3074   for (uint ii = 0; ii < n - 1; ii++) {
3075     m->writeRaphaelPoly3D(fp, ii + 1, minWidth, measure->_len * 0.001, 0.0);
3076     x += min_pitch;
3077   }
3078   x += 0.5 * measure->_topWidth;
3079   m->writeRaphaelPoly(fp, n, x, measure->_len * 0.001, 0.0);
3080 
3081   m->writeRaphaelPoly3D(fp, n + 1, orig, measure->_len * 0.001, 1.0);
3082   x = orig + pitch;
3083   m->writeRaphaelPoly3D(fp, n + 2, measure->_len * 0.001, x, 0.0);
3084 
3085   x += 0.5 * measure->_topWidth + minSpace;
3086   for (uint jj = n + 2; jj < wireCnt; jj++) {
3087     m->writeRaphaelPoly3D(fp, jj + 1, minWidth, measure->_len * 0.001, x, 0.0);
3088     x += min_pitch;
3089   }
3090 }
3091 
writeWires2_3D(FILE * fp,extMeasure * measure,uint wireCnt)3092 void extRCModel::writeWires2_3D(FILE* fp, extMeasure* measure, uint wireCnt) {
3093   extMasterConductor* m = _process->getMasterConductor(measure->_met);
3094   double pitch = measure->_topWidth + measure->_seff;
3095   double min_pitch = 0.001 * (measure->_minWidth + measure->_minSpace);
3096 
3097   uint n = wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
3098   double orig = 0.0;
3099 
3100   // assume origin = (0,0)
3101   double x = -min_pitch * (n - 1) - pitch - 0.5 * measure->_topWidth + orig;
3102   for (uint ii = 0; ii < n - 1; ii++) {
3103     m->writeRaphaelPoly3D(fp, ii + 1, 0.001 * measure->_minWidth,
3104                           measure->_len * 0.001, 0.0);
3105     x += min_pitch;
3106   }
3107   x += 0.5 * measure->_topWidth;
3108   m->writeRaphaelPoly(fp, n, x, measure->_len * 0.001, 0.0);
3109 
3110   m->writeRaphaelPoly3D(fp, n + 1, orig, measure->_len * 0.001, 1.0);
3111   x = 0.5 * measure->_w_m + measure->_s2_m;
3112   m->writeRaphaelPoly3D(fp, n + 2, measure->_w2_m, measure->_len * 0.001, x,
3113                         0.0);
3114 
3115   x = orig + 0.5 * measure->_topWidth + measure->_w2_m + measure->_s2_m +
3116       0.001 * measure->_minSpace;
3117   for (uint jj = n + 2; jj < wireCnt; jj++) {
3118     m->writeRaphaelPoly3D(fp, jj + 1, 0.001 * measure->_minWidth,
3119                           measure->_len * 0.001, x, 0.0);
3120     x += min_pitch;
3121   }
3122 }
writeBenchWires(FILE * fp,extMeasure * measure)3123 int extRCModel::writeBenchWires(FILE* fp, extMeasure* measure) {
3124   uint grid_gap_cnt = 20;
3125 
3126   int bboxLL[2];
3127   bboxLL[measure->_dir] = measure->_ur[measure->_dir];
3128   bboxLL[!measure->_dir] = measure->_ll[!measure->_dir];
3129 
3130   extMasterConductor* m = _process->getMasterConductor(measure->_met);
3131 
3132   int n =
3133       measure->_wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
3134 
3135   double pitchUp_print;
3136   /*
3137           if (measure->_diag)
3138                   pitchUp_print= measure->_topWidth +
3139      0.001*2*measure->_minSpace; else
3140   */
3141   pitchUp_print = measure->_topWidth + measure->_seff;
3142   //	double pitchDown_print= measure->_topWidth + measure->_seff;
3143   double pitch_print = 0.001 * (measure->_minWidth + measure->_minSpace);
3144 
3145   uint w_layout = measure->_minWidth;
3146   uint s_layout = measure->_minSpace;
3147 
3148   double x = -(measure->_topWidth * 0.5 + pitchUp_print + pitch_print);
3149 
3150   measure->clean2dBoxTable(measure->_met, false);
3151 
3152   double x_tmp[50];
3153   uint netIdTable[50];
3154   uint idCnt = 1;
3155   int ii;
3156   for (ii = 0; ii < n - 1; ii++) {
3157     netIdTable[idCnt] =
3158         measure->createNetSingleWire(_wireDirName, idCnt, w_layout, s_layout);
3159     idCnt++;
3160     x_tmp[ii] = x;
3161     x -= pitch_print;
3162   }
3163 
3164   double X[50];
3165   ii--;
3166   int cnt = 0;
3167   for (; ii >= 0; ii--)
3168     X[cnt++] = x_tmp[ii];
3169 
3170   uint WW = measure->_w_nm;
3171   uint SS1;
3172   //	if (measure->_diag)
3173   //		SS1= 2*measure->_minSpace;
3174   //	else
3175   SS1 = measure->_s_nm;
3176   uint WW2 = measure->_w2_nm;
3177   uint SS2 = measure->_s2_nm;
3178 
3179   X[cnt++] = -pitchUp_print;
3180   int mid = cnt;
3181   netIdTable[idCnt] =
3182       measure->createNetSingleWire(_wireDirName, idCnt, WW, s_layout);
3183   idCnt++;
3184 
3185   X[cnt++] = 0.0;
3186   netIdTable[idCnt] =
3187       measure->createNetSingleWire(_wireDirName, idCnt, WW, SS1);
3188   idCnt++;
3189   uint base = measure->_ll[measure->_dir] + WW / 2;
3190 
3191   X[cnt++] = (SS2 + WW * 0.5) * 0.001;
3192   netIdTable[idCnt] =
3193       measure->createNetSingleWire(_wireDirName, idCnt, WW2, SS2);
3194   idCnt++;
3195 
3196   //	x= measure->_topWidth*0.5+pitchUp_print+0.001*measure->_minSpace;
3197   x = measure->_topWidth * 0.5 + 0.001 * (WW2 + SS2 + measure->_minSpace);
3198   for (int jj = 0; jj < n - 1; jj++) {
3199     X[cnt++] = x;
3200     x += pitch_print;
3201     netIdTable[idCnt] =
3202         measure->createNetSingleWire(_wireDirName, idCnt, w_layout, s_layout);
3203     idCnt++;
3204   }
3205 
3206   for (ii = 0; ii < cnt; ii++) {
3207     uint length = measure->getBoxLength(ii, measure->_met, false);
3208     // layout;
3209     if (ii == mid) {
3210       if (measure->_3dFlag)
3211         //				m->writeRaphaelPoly3D(fp,
3212         // netIdTable[ii+1], X[ii], measure->_len*0.001, 1.0);
3213         m->writeRaphaelPoly3D(fp, netIdTable[ii + 1], X[ii], length * 0.001,
3214                               1.0);
3215       else
3216         m->writeRaphaelPoly(fp, netIdTable[ii + 1], X[ii], 1.0);
3217     } else if (ii == mid - 1) {
3218       if (measure->_3dFlag)
3219         //				m->writeRaphaelPoly3D(fp,
3220         // netIdTable[ii+1], X[ii], measure->_len*0.001, 0.0);
3221         m->writeRaphaelPoly3D(fp, netIdTable[ii + 1], X[ii], length * 0.001,
3222                               0.0);
3223       else
3224         m->writeRaphaelPoly(fp, netIdTable[ii + 1], X[ii], 0.0);
3225     } else if (ii == mid + 1) {
3226       if (measure->_3dFlag)
3227         m->writeRaphaelPoly3D(fp, netIdTable[ii + 1], 0.001 * WW2,
3228                               length * 0.001, X[ii], 0.0);
3229       else
3230         m->writeRaphaelPoly(fp, netIdTable[ii + 1], 0.001 * WW2, X[ii], 0.0);
3231     } else {
3232       if (measure->_3dFlag)
3233         //				m->writeRaphaelPoly3D(fp,
3234         // netIdTable[ii+1], 0.001*measure->_minWidth, measure->_len*0.001,
3235         // X[ii], 0.0);
3236         m->writeRaphaelPoly3D(fp, netIdTable[ii + 1],
3237                               0.001 * measure->_minWidth, length * 0.001, X[ii],
3238                               0.0);
3239       else
3240         m->writeRaphaelPoly(fp, netIdTable[ii + 1], 0.001 * measure->_minWidth,
3241                             X[ii], 0.0);
3242     }
3243   }
3244 
3245   if (measure->_diag) {
3246     int met;
3247     if (measure->_overMet > 0)
3248       met = measure->_overMet;
3249     else if (measure->_underMet > 0)
3250       met = measure->_underMet;
3251 
3252     m = _process->getMasterConductor(met);
3253     double minWidth = _process->getConductor(met)->_min_width;
3254     double minSpace = _process->getConductor(met)->_min_spacing;
3255     double min_pitch = minWidth + minSpace;
3256     measure->clean2dBoxTable(met, false);
3257     int i;
3258     uint begin = base - Ath__double2int(measure->_seff * 1000) +
3259                  Ath__double2int(minWidth * 1000) / 2;
3260     for (i = 0; i < n + 1; i++) {
3261       netIdTable[idCnt] = measure->createDiagNetSingleWire(
3262           _wireDirName, idCnt, begin, Ath__double2int(1000 * minWidth),
3263           Ath__double2int(1000 * minSpace), measure->_dir);
3264       begin -= Ath__double2int(min_pitch * 1000);
3265       idCnt++;
3266     }
3267 
3268     double h = _process->getConductor(met)->_height;
3269     double t = _process->getConductor(met)->_thickness;
3270     measure->writeDiagRaphael3D(fp, met, false, base, h, t);
3271 
3272     measure->_ur[measure->_dir] += grid_gap_cnt * (w_layout + s_layout);
3273 
3274     if (measure->_3dFlag) {
3275       fprintf(fp, "\nOPTIONS SET_GRID=1000000;\n\n");
3276       fprintf(fp, "POTENTIAL\n");
3277     } else {
3278       fprintf(fp, "\nOPTIONS SET_GRID=10000;\n\n");
3279       fprintf(fp, "POTENTIAL");
3280       /*
3281                               for (ii= 0; ii<cnt; ii++)
3282                                       m->writeBoxName(fp, netIdTable[ii+1]);
3283       */
3284       fprintf(fp, " \n");
3285     }
3286 
3287     return cnt;
3288   }
3289 
3290   int bboxUR[2] = {measure->_ur[0], measure->_ur[1]};
3291 
3292   double pitchMult = 1.0;
3293 
3294   measure->clean2dBoxTable(measure->_underMet, true);
3295   measure->createContextNets(_wireDirName, bboxLL, bboxUR, measure->_underMet,
3296                              pitchMult);
3297 
3298   measure->clean2dBoxTable(measure->_overMet, true);
3299   measure->createContextNets(_wireDirName, bboxLL, bboxUR, measure->_overMet,
3300                              pitchMult);
3301 
3302   //	double mainNetStart= X[0];
3303   int main_xlo, main_ylo, main_xhi, main_yhi, low;
3304   measure->getBox(measure->_met, false, main_xlo, main_ylo, main_xhi, main_yhi);
3305   if (!measure->_dir)
3306     low = main_ylo - measure->_minWidth / 2;
3307   else
3308     low = main_xlo - measure->_minWidth / 2;
3309   uint contextRaphaelCnt = 0;
3310   if (measure->_underMet > 0) {
3311     double h = _process->getConductor(measure->_underMet)->_height;
3312     double t = _process->getConductor(measure->_underMet)->_thickness;
3313     /*
3314                     dbTechLayer
3315        *layer=measure->_tech->findRoutingLayer(_underMet); uint minWidth=
3316        layer->getWidth(); uint minSpace= layer->getSpacing(); uint pitch=
3317        1000*((minWidth+minSpace)*pitchMult)/1000; uint offset=
3318        2*(minWidth+minSpace); int start= mainNetStart+offset; contextRaphaelCnt=
3319        measure->writeRaphael3D(fp, measure->_underMet, true, mainNetStart, h,
3320        t);
3321     */
3322     contextRaphaelCnt =
3323         measure->writeRaphael3D(fp, measure->_underMet, true, low, h, t);
3324   }
3325 
3326   if (measure->_overMet > 0) {
3327     double h = _process->getConductor(measure->_overMet)->_height;
3328     double t = _process->getConductor(measure->_overMet)->_thickness;
3329     /*
3330                     dbTechLayer
3331        *layer=measure->_tech->findRoutingLayer(_overMet); uint minWidth=
3332        layer->getWidth(); uint minSpace= layer->getSpacing(); uint pitch=
3333        1000*((minWidth+minSpace)*pitchMult)/1000; uint offset=
3334        2*(minWidth+minSpace); int start= mainNetStart+offset; contextRaphaelCnt
3335        += measure->writeRaphael3D(fp, measure->_overMet, true, mainNetStart, h,
3336        t);
3337     */
3338     contextRaphaelCnt +=
3339         measure->writeRaphael3D(fp, measure->_overMet, true, low, h, t);
3340   }
3341 
3342   measure->_ur[measure->_dir] += grid_gap_cnt * (w_layout + s_layout);
3343 
3344   if (measure->_3dFlag) {
3345     fprintf(fp, "\nOPTIONS SET_GRID=1000000;\n\n");
3346     fprintf(fp, "POTENTIAL\n");
3347   } else {
3348     fprintf(fp, "\nOPTIONS SET_GRID=10000;\n\n");
3349     fprintf(fp, "POTENTIAL");
3350     /*
3351                     for (ii= 0; ii<cnt; ii++)
3352                             m->writeBoxName(fp, netIdTable[ii+1]);
3353     */
3354     fprintf(fp, " \n");
3355   }
3356 
3357   return cnt;
3358 }
writeRaphaelCaps(FILE * fp,extMeasure * measure,uint wireCnt)3359 void extRCModel::writeRaphaelCaps(FILE* fp, extMeasure* measure, uint wireCnt) {
3360   extMasterConductor* m = _process->getMasterConductor(measure->_met);
3361 
3362   fprintf(fp, "\nOPTIONS SET_GRID=10000;\n\n");
3363   fprintf(fp, "POTENTIAL\n");
3364   /*
3365           if (measure->_diag)
3366                   fprintf(fp, "POTENTIAL\n");
3367           else {
3368                   fprintf(fp, "POTENTIAL");
3369                   if (!measure->_plate) {
3370                           for (uint kk= 1; kk<=wireCnt; kk++)
3371                                   m->writeBoxName(fp, kk);
3372                   } else  {
3373                           m->writeBoxName(fp, wireCnt/2+1);
3374                           if (measure->_overMet>0)
3375                                   fprintf(fp, "M%d__%s;",
3376      measure->_overMet,"GND");
3377                   }
3378                   fprintf(fp, " \n");
3379           }
3380   */
3381 }
writeRaphaelCaps3D(FILE * fp,extMeasure * measure,uint wireCnt)3382 void extRCModel::writeRaphaelCaps3D(FILE* fp, extMeasure* measure,
3383                                     uint wireCnt) {
3384   //        extMasterConductor *m= _process->getMasterConductor(measure->_met);
3385 
3386   fprintf(fp, "\nOPTIONS SET_GRID=1000000;\n\n");
3387   fprintf(fp, "POTENTIAL\n");
3388 }
writeWires(FILE * fp,extMeasure * measure,uint wireCnt)3389 void extRCModel::writeWires(FILE* fp, extMeasure* measure, uint wireCnt) {
3390   extMasterConductor* m = _process->getMasterConductor(measure->_met);
3391   double pitch = measure->_topWidth + measure->_seff;
3392 
3393   uint n = wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
3394 
3395   if (_commentFlag)
3396     fprintf(fp, "%s\n", _commentLine);
3397 
3398   // assume origin = (0,0)
3399   double x = -pitch * n;
3400   m->writeRaphaelPoly(fp, 1, x, 1.0);
3401 
3402   for (uint ii = 1; ii < wireCnt; ii++) {
3403     x += pitch;
3404     m->writeRaphaelPoly(fp, ii + 1, x, 0.0);
3405   }
3406 
3407   fprintf(fp, "\nOPTIONS SET_GRID=10000;\n\n");
3408   fprintf(fp, "POTENTIAL\n");
3409   /*
3410           fprintf(fp, "CAPACITANCE ");
3411           for (uint kk= 1; kk<=wireCnt; kk++)
3412                   m->writeBoxName(fp, kk);
3413           fprintf(fp, " \n");
3414   */
3415 }
writeWires(FILE * fp,extMasterConductor * m,uint wireCnt,double X,double width,double space)3416 void extRCModel::writeWires(FILE* fp, extMasterConductor* m, uint wireCnt,
3417                             double X, double width, double space) {
3418   uint n = wireCnt / 2;  // ASSUME odd number of wires, 2 will also work
3419   double x = X - (width + space) * n;
3420 
3421   x = m->writeRaphaelBox(fp, 1, width, x, 1.0);
3422   for (uint ii = 1; ii < wireCnt; ii++)
3423     x = m->writeRaphaelBox(fp, ii + 1, width, x + space, 0.0);
3424 
3425   fprintf(fp, "\nOPTIONS SET_GRID=10000;\n\n");
3426   fprintf(fp, "POTENTIAL\n");
3427   /*
3428           fprintf(fp, "CAPACITANCE ");
3429           for (uint kk= 1; kk<=wireCnt; kk++)
3430                   m->writeBoxName(fp, kk);
3431           fprintf(fp, " \n");
3432   */
3433 }
setOptions(const char * topDir,const char * pattern,bool writeFiles,bool readFiles,bool runSolver,bool keepFile,uint metLevel)3434 void extRCModel::setOptions(const char* topDir, const char* pattern,
3435                             bool writeFiles, bool readFiles, bool runSolver,
3436                             bool keepFile, uint metLevel) {
3437   _logFP = openFile("./", "rulesGen", ".log", "w");
3438   strcpy(_topDir, topDir);
3439   strcpy(_patternName, pattern);
3440 
3441   _writeFiles = true;
3442   _readSolver = true;
3443   _runSolver = true;
3444 
3445   if (writeFiles) {
3446     _writeFiles = true;
3447     _readSolver = false;
3448     _runSolver = false;
3449   } else if (readFiles) {
3450     _writeFiles = false;
3451     _readSolver = true;
3452     _runSolver = false;
3453   } else if (runSolver) {
3454     _writeFiles = false;
3455     _readSolver = false;
3456     _runSolver = true;
3457   }
3458   if (keepFile)
3459     _keepFile = true;
3460   if (metLevel)
3461     _metLevel = metLevel;
3462 #ifdef _WIN32
3463   _runSolver = false;
3464 #endif
3465 }
setOptions(const char * topDir,const char * pattern,bool writeFiles,bool readFiles,bool runSolver)3466 void extRCModel::setOptions(const char* topDir, const char* pattern,
3467                             bool writeFiles, bool readFiles, bool runSolver) {
3468   _logFP = openFile("./", "rulesGen", ".log", "w");
3469   strcpy(_topDir, topDir);
3470   strcpy(_patternName, pattern);
3471 
3472   _writeFiles = true;
3473   _readSolver = true;
3474   _runSolver = true;
3475   _keepFile = true;
3476 
3477   if (writeFiles) {
3478     _writeFiles = true;
3479     _readSolver = false;
3480     _runSolver = false;
3481   } else if (readFiles) {
3482     _writeFiles = false;
3483     _readSolver = true;
3484     _runSolver = false;
3485   } else if (runSolver) {
3486     _writeFiles = false;
3487     _readSolver = false;
3488     _runSolver = true;
3489   }
3490 #ifdef _WIN32
3491   _runSolver = false;
3492 #endif
3493 }
closeFiles()3494 void extRCModel::closeFiles() {
3495   fflush(_logFP);
3496 
3497   if (_logFP != NULL)
3498     fclose(_logFP);
3499 }
runSolver(const char * solverOption)3500 void extRCModel::runSolver(const char* solverOption) {
3501   char cmd[4000];
3502 #ifndef _WIN32
3503   //	sprintf(cmd, "cd %s ; /opt/ads/bin/casyn raphael %s %s ; cd
3504   //../../../../../../ ", _wireDirName, solverOption, _wireFileName);
3505   // this is for check in
3506   if (_diagModel == 2)
3507     sprintf(cmd, "ca raphael %s %s/%s -o %s/%s.out", solverOption, _wireDirName,
3508             _wireFileName, _wireDirName, _wireFileName);
3509   else
3510     sprintf(cmd, "ca raphael %s %s/%s -o %s/%s.out", solverOption, _wireDirName,
3511             _wireFileName, _wireDirName, _wireFileName);
3512 
3513   // this is for local run
3514   /*	if (_diagModel==2)
3515                   sprintf(cmd, "/opt/ads/bin/casyn raphael %s %s/%s -o
3516      %s/%s.out", solverOption, _wireDirName, _wireFileName, _wireDirName,
3517      _wireFileName); else sprintf(cmd, "/opt/ads/bin/casyn raphael %s %s/%s -o
3518      %s/%s.out", solverOption, _wireDirName, _wireFileName, _wireDirName,
3519      _wireFileName);
3520   */
3521 
3522   //	sprintf(cmd, "cd %s ; ca raphael %s %s ; cd ../../../../../../ ",
3523   //_wireDirName, solverOption, _wireFileName);
3524   logger_->info(RCX, 69, "{}", cmd);
3525 #endif
3526 #ifdef _WIN32
3527   if (_diagModel == 2)
3528     sprintf(cmd, "cd %s ; dir ; cd ../../../../../../../../ ", _wireDirName);
3529   else
3530     sprintf(cmd, "cd %s ; dir ; cd ../../../../../../ ", _wireDirName);
3531   logger_->info(RCX, 73, "{}", cmd);
3532 #endif
3533   system(cmd);
3534 }
cleanFiles()3535 void extRCModel::cleanFiles() {
3536   char cmd[4000];
3537   sprintf(cmd, "rm -rf %s ", _wireDirName);
3538   system(cmd);
3539 }
getOverUnderIndex(extMeasure * m,uint maxCnt)3540 int extRCModel::getOverUnderIndex(extMeasure* m, uint maxCnt) {
3541   return getMetIndexOverUnder(m->_met, m->_underMet, m->_overMet, _layerCnt,
3542                               maxCnt);
3543 }
getUnderIndex(extMeasure * m)3544 uint extRCModel::getUnderIndex(extMeasure* m) {
3545   return m->_overMet - m->_met - 1;
3546 }
addRCw(uint n,uint w,extDistRC * rc)3547 void extDistWidthRCTable::addRCw(uint n, uint w, extDistRC* rc) {
3548   int wIndex = _widthTable->findIndex(w);
3549   if (wIndex < 0)
3550     wIndex = _widthTable->add(w);
3551 
3552   _rcDistTable[n][wIndex]->addMeasureRC(rc);
3553 }
3554 
addRCw(extMeasure * m)3555 void extMetRCTable::addRCw(extMeasure* m) {
3556   extDistWidthRCTable* table = NULL;
3557   int n;
3558   if (m->_overUnder) {
3559     n = getMetIndexOverUnder(m->_met, m->_underMet, m->_overMet, _layerCnt,
3560                              _capOverUnder[m->_met]->_metCnt);
3561     assert(n >= 0);
3562     table = _capOverUnder[m->_met];
3563   } else if (m->_over) {
3564     n = m->_underMet;
3565     if (m->_res) {
3566       table = _resOver[m->_met];
3567     } else {
3568       table = _capOver[m->_met];
3569     }
3570   } else if (m->_diag) {
3571     n = m->getUnderIndex();
3572     if (m->_diagModel == 1) {  // TODO 0620 : diagModel=2
3573       table = _capDiagUnder[m->_met];
3574     }
3575   } else {
3576     n = m->getUnderIndex();
3577     table = _capUnder[m->_met];
3578   }
3579   if (table != NULL)
3580     table->addRCw(n, m->_w_nm, m->_tmpRC);
3581 }
addRC(extMeasure * m)3582 void extRCModel::addRC(extMeasure* m) {
3583   if (m->_overUnder) {
3584     uint maxCnt = _modelTable[m->_rIndex]->_capOverUnder[m->_met]->_metCnt;
3585     uint n = getOverUnderIndex(m, maxCnt);
3586     _modelTable[m->_rIndex]
3587         ->_capOverUnder[m->_met]
3588         ->_rcDistTable[n][m->_wIndex]
3589         ->addMeasureRC(m->_tmpRC);
3590   } else if (m->_over) {
3591     if (m->_res) {
3592       _modelTable[m->_rIndex]
3593           ->_resOver[m->_met]
3594           ->_rcDistTable[m->_underMet][m->_wIndex]
3595           ->addMeasureRC(m->_tmpRC);
3596     } else {
3597       _modelTable[m->_rIndex]
3598           ->_capOver[m->_met]
3599           ->_rcDistTable[m->_underMet][m->_wIndex]
3600           ->addMeasureRC(m->_tmpRC);
3601     }
3602   } else if (m->_diag) {
3603     uint n = getUnderIndex(m);
3604     if (_diagModel == 2)
3605       _modelTable[m->_rIndex]
3606           ->_capDiagUnder[m->_met]
3607           ->_rcDiagDistTable[n][m->_wIndex][m->_dwIndex][m->_dsIndex]
3608           ->addMeasureRC(m->_tmpRC);
3609     else
3610       _modelTable[m->_rIndex]
3611           ->_capDiagUnder[m->_met]
3612           ->_rcDistTable[n][m->_wIndex]
3613           ->addMeasureRC(m->_tmpRC);
3614   } else {
3615     uint n = getUnderIndex(m);
3616     _modelTable[m->_rIndex]
3617         ->_capUnder[m->_met]
3618         ->_rcDistTable[n][m->_wIndex]
3619         ->addMeasureRC(m->_tmpRC);
3620   }
3621 }
mkWidthAndSpaceMappings()3622 void extMetRCTable::mkWidthAndSpaceMappings() {
3623   for (uint ii = 1; ii < _layerCnt; ii++) {
3624     if (_capOver[ii] != NULL)
3625       _capOver[ii]->makeWSmapping();
3626     else
3627       logger_->info(RCX, 72, "Can't find <OVER> rules for {}", ii);
3628 
3629     if (_resOver[ii] != NULL)
3630       _resOver[ii]->makeWSmapping();
3631     else
3632       logger_->info(RCX, 358, "Can't find <RESOVER> Res rules for {}", ii);
3633 
3634     if (_capUnder[ii] != NULL)
3635       _capUnder[ii]->makeWSmapping();
3636     else
3637       logger_->info(RCX, 216, "Can't find <UNDER> rules for {}", ii);
3638 
3639     if (_capOverUnder[ii] != NULL)
3640       _capOverUnder[ii]->makeWSmapping();
3641     else if ((ii > 1) && (ii < _layerCnt - 1))
3642       logger_->info(RCX, 217, "Can't find <OVERUNDER> rules for {}", ii);
3643   }
3644 }
writeRules(char * name,bool binary)3645 void extRCModel::writeRules(char* name, bool binary) {
3646   bool writeRes = true;
3647   //	FILE *fp= openFile("./", name, NULL, "w");
3648   FILE* fp = fopen(name, "w");
3649 
3650   uint cnt = 0;
3651   fprintf(fp, "Extraction Rules for OpenRCX\n\n");
3652   if (_diag || _diagModel > 0) {
3653     if (_diagModel == 1)
3654       fprintf(fp, "DIAGMODEL ON\n\n");
3655     else if (_diagModel == 2)
3656       fprintf(fp, "DIAGMODEL TRUE\n\n");
3657   }
3658 
3659   fprintf(fp, "LayerCount %d\n", _layerCnt - 1);
3660   fprintf(fp, "DensityRate %d ", _modelCnt);
3661   for (uint kk = 0; kk < _modelCnt; kk++)
3662     fprintf(fp, " %g", _dataRateTable->get(kk));
3663   fprintf(fp, "\n");
3664 
3665   for (uint m = 0; m < _modelCnt; m++) {
3666     fprintf(fp, "\nDensityModel %d\n", m);
3667 
3668     for (uint ii = 1; ii < _layerCnt; ii++) {
3669       if (writeRes) {
3670         if (_modelTable[m]->_resOver[ii] != NULL)
3671           cnt += _modelTable[m]->_resOver[ii]->writeRulesOver_res(fp, binary);
3672         else if ((m > 0) && (_modelTable[0]->_resOver[ii] != NULL))
3673           cnt += _modelTable[0]->_resOver[ii]->writeRulesOver_res(fp, binary);
3674         else if (m == 0) {
3675           logger_->info(RCX, 410,
3676                         "Cannot write <OVER> Res rules for <DensityModel> {} "
3677                         "and layer {}",
3678                         m, ii);
3679         }
3680       }
3681       if (_modelTable[m]->_capOver[ii] != NULL)
3682         cnt += _modelTable[m]->_capOver[ii]->writeRulesOver(fp, binary);
3683       else if ((m > 0) && (_modelTable[0]->_capOver[ii] != NULL))
3684         cnt += _modelTable[0]->_capOver[ii]->writeRulesOver(fp, binary);
3685       else if (m == 0) {
3686         logger_->info(
3687             RCX, 218,
3688             "Cannot write <OVER> rules for <DensityModel> {} and layer {}", m,
3689             ii);
3690       }
3691 
3692       if (_modelTable[m]->_capUnder[ii] != NULL)
3693         cnt += _modelTable[m]->_capUnder[ii]->writeRulesUnder(fp, binary);
3694       else if ((m > 0) && (_modelTable[0]->_capUnder[ii] != NULL))
3695         cnt += _modelTable[0]->_capUnder[ii]->writeRulesUnder(fp, binary);
3696       else if (m == 0) {
3697         logger_->info(
3698             RCX, 219,
3699             "Cannot write <UNDER> rules for <DensityModel> {} and layer {}", m,
3700             ii);
3701       }
3702 
3703       if (_modelTable[m]->_capDiagUnder[ii] != NULL) {
3704         if (_diagModel == 1)
3705           cnt += _modelTable[m]->_capDiagUnder[ii]->writeRulesDiagUnder(fp,
3706                                                                         binary);
3707         if (_diagModel == 2)
3708           cnt += _modelTable[m]->_capDiagUnder[ii]->writeRulesDiagUnder2(
3709               fp, binary);
3710       } else if ((m > 0) && (_modelTable[0]->_capDiagUnder[ii] != NULL)) {
3711         if (_diagModel == 1)
3712           cnt += _modelTable[0]->_capDiagUnder[ii]->writeRulesDiagUnder(fp,
3713                                                                         binary);
3714         if (_diagModel == 2)
3715           cnt += _modelTable[0]->_capDiagUnder[ii]->writeRulesDiagUnder2(
3716               fp, binary);
3717       } else if (m == 0) {
3718         logger_->info(
3719             RCX, 220,
3720             "Cannot write <DIAGUNDER> rules for <DensityModel> {} and layer {}",
3721             m, ii);
3722       }
3723 
3724       if (_modelTable[m]->_capOverUnder[ii] != NULL)
3725         cnt +=
3726             _modelTable[m]->_capOverUnder[ii]->writeRulesOverUnder(fp, binary);
3727       else if ((m > 0) && (_modelTable[0]->_capOverUnder[ii] != NULL))
3728         cnt +=
3729             _modelTable[0]->_capOverUnder[ii]->writeRulesOverUnder(fp, binary);
3730       else if ((m == 0) && (ii > 1) && (ii < _layerCnt - 1)) {
3731         logger_->info(
3732             RCX, 221,
3733             "Cannot write <OVERUNDER> rules for <DensityModel> {} and layer {}",
3734             m, ii);
3735       }
3736     }
3737     fprintf(fp, "END DensityModel %d\n", m);
3738   }
3739   fclose(fp);
3740 }
readMetalHeader(Ath__parser * parser,uint & met,const char * keyword,bool bin,bool ignore)3741 uint extRCModel::readMetalHeader(Ath__parser* parser, uint& met,
3742                                  const char* keyword, bool bin, bool ignore) {
3743   if (parser->isKeyword(0, "END") &&
3744       (strcmp(parser->get(1), "DensityModel") == 0))
3745     return 0;
3746 
3747   if (!(parser->parseNextLine() > 0)) {
3748     return 0;
3749   }
3750 
3751   //	uint cnt= 0;
3752   if (parser->isKeyword(0, "Metal") && (strcmp(parser->get(2), keyword) == 0)) {
3753     met = parser->getInt(1);
3754     return 1;
3755   }
3756 
3757   return 0;
3758 }
allocateInitialTables(uint layerCnt,uint widthCnt,bool over,bool under,bool diag)3759 void extMetRCTable::allocateInitialTables(uint layerCnt, uint widthCnt,
3760                                           bool over, bool under, bool diag) {
3761   for (uint met = 1; met < _layerCnt; met++) {
3762     if (over && under && (met > 1) && (met < _layerCnt - 1)) {
3763       int n = getMaxMetIndexOverUnder(met, layerCnt);
3764       _capOverUnder[met] = new extDistWidthRCTable(false, met, layerCnt, n + 1,
3765                                                    widthCnt, _rcPoolPtr);
3766     }
3767     if (over) {
3768       _capOver[met] = new extDistWidthRCTable(true, met, layerCnt, met,
3769                                               widthCnt, _rcPoolPtr);
3770       _resOver[met] = new extDistWidthRCTable(true, met, layerCnt, met,
3771                                               widthCnt, _rcPoolPtr);
3772     }
3773     if (under) {
3774       _capUnder[met] = new extDistWidthRCTable(
3775           false, met, layerCnt, _layerCnt - met - 1, widthCnt, _rcPoolPtr);
3776     }
3777     if (diag) {
3778       _capDiagUnder[met] = new extDistWidthRCTable(
3779           false, met, layerCnt, _layerCnt - met - 1, widthCnt, _rcPoolPtr);
3780     }
3781   }
3782 }
readHeaderAndWidth(Ath__parser * parser,uint & met,const char * ouKey,const char * wKey,bool bin,bool ignore)3783 Ath__array1D<double>* extRCModel::readHeaderAndWidth(Ath__parser* parser,
3784                                                      uint& met,
3785                                                      const char* ouKey,
3786                                                      const char* wKey, bool bin,
3787                                                      bool ignore) {
3788   if (readMetalHeader(parser, met, ouKey, bin, ignore) <= 0)
3789     return NULL;
3790 
3791   if (!(parser->parseNextLine() > 0))
3792     return NULL;
3793 
3794   return parser->readDoubleArray("WIDTH", 4);
3795 }
readRules(Ath__parser * parser,uint m,uint ii,const char * ouKey,const char * wKey,bool over,bool under,bool bin,bool diag,bool ignore,double dbFactor)3796 uint extRCModel::readRules(Ath__parser* parser, uint m, uint ii,
3797                            const char* ouKey, const char* wKey, bool over,
3798                            bool under, bool bin, bool diag, bool ignore,
3799                            double dbFactor) {
3800   uint cnt = 0;
3801   uint met = 0;
3802   Ath__array1D<double>* wTable =
3803       readHeaderAndWidth(parser, met, ouKey, wKey, bin, false);
3804 
3805   if (wTable == NULL)
3806     return 0;
3807 
3808   uint widthCnt = wTable->getCnt();
3809 
3810   extDistWidthRCTable* dummy = NULL;
3811   if (ignore)
3812     dummy = new extDistWidthRCTable(true, met, _layerCnt, widthCnt);
3813 
3814   uint diagWidthCnt = 0;
3815   uint diagDistCnt = 0;
3816 
3817   if (diag && strcmp(ouKey, "DIAGUNDER") == 0 && _diagModel == 2) {
3818     parser->parseNextLine();
3819     if (parser->isKeyword(0, "DIAG_WIDTH"))
3820       diagWidthCnt = parser->getInt(3);
3821     parser->parseNextLine();
3822     if (parser->isKeyword(0, "DIAG_DIST"))
3823       diagDistCnt = parser->getInt(3);
3824   }
3825 
3826   if (over && under && (met > 1)) {
3827     if (!ignore) {
3828       _modelTable[m]->allocOverUnderTable(met, wTable, dbFactor);
3829       _modelTable[m]->_capOverUnder[met]->readRulesOverUnder(
3830           parser, widthCnt, bin, ignore, dbFactor);
3831     } else
3832       dummy->readRulesOverUnder(parser, widthCnt, bin, ignore, dbFactor);
3833   } else if (over) {
3834     if (strcmp(ouKey, "OVER") == 0) {
3835       if (!ignore) {
3836         // Read RESOVER fisrt _modelTable[m]->allocOverTable(met, wTable,
3837         // dbFactor);
3838         _modelTable[m]->_capOver[met]->readRulesOver(parser, widthCnt, bin,
3839                                                      ignore, "OVER", dbFactor);
3840       } else
3841         dummy->readRulesOver(parser, widthCnt, bin, ignore, "OVER", dbFactor);
3842     } else {  // RESOVER
3843       if (!ignore) {
3844         _modelTable[m]->allocOverTable(met, wTable, dbFactor);
3845         _modelTable[m]->_resOver[met]->readRulesOver(
3846             parser, widthCnt, bin, ignore, "RESOVER", dbFactor);
3847       } else
3848         dummy->readRulesOver(parser, widthCnt, bin, ignore, "RESOVER",
3849                              dbFactor);
3850     }
3851   } else if (under) {
3852     if (!ignore) {
3853       _modelTable[m]->allocUnderTable(met, wTable, dbFactor);
3854       _modelTable[m]->_capUnder[met]->readRulesUnder(parser, widthCnt, bin,
3855                                                      ignore, dbFactor);
3856     } else
3857       dummy->readRulesUnder(parser, widthCnt, bin, ignore, dbFactor);
3858   } else if (diag) {
3859     if (!ignore && _diagModel == 2) {
3860       _modelTable[m]->allocDiagUnderTable(met, wTable, diagWidthCnt,
3861                                           diagDistCnt, dbFactor);
3862       _modelTable[m]->_capDiagUnder[met]->readRulesDiagUnder(
3863           parser, widthCnt, diagWidthCnt, diagDistCnt, bin, ignore, dbFactor);
3864     } else if (!ignore && _diagModel == 1) {
3865       _modelTable[m]->allocDiagUnderTable(met, wTable, dbFactor);
3866       _modelTable[m]->_capDiagUnder[met]->readRulesDiagUnder(
3867           parser, widthCnt, bin, ignore, dbFactor);
3868     } else if (ignore) {
3869       if (_diagModel == 2)
3870         dummy->readRulesDiagUnder(parser, widthCnt, diagWidthCnt, diagDistCnt,
3871                                   bin, ignore, dbFactor);
3872       else if (_diagModel == 1)
3873         dummy->readRulesDiagUnder(parser, widthCnt, bin, ignore, dbFactor);
3874     }
3875   }
3876   if (ignore)
3877     delete dummy;
3878 
3879   if (wTable != NULL)
3880     delete wTable;
3881 
3882   return cnt;
3883 }
3884 
readRules(char * name,bool bin,bool over,bool under,bool overUnder,bool diag,uint cornerCnt,uint * cornerTable,double dbFactor)3885 bool extRCModel::readRules(char* name, bool bin, bool over, bool under,
3886                            bool overUnder, bool diag, uint cornerCnt,
3887                            uint* cornerTable, double dbFactor) {
3888   OUREVERSEORDER = false;
3889   diag = false;
3890   uint cnt = 0;
3891   _ruleFileName = strdup(name);
3892   Ath__parser parser;
3893   // parser.setDbg(1);
3894   parser.addSeparator("\r");
3895   parser.openFile(name);
3896   while (parser.parseNextLine() > 0) {
3897     if (parser.isKeyword(0, "OUREVERSEORDER")) {
3898       if (strcmp(parser.get(1), "ON") == 0) {
3899         OUREVERSEORDER = true;
3900       }
3901     }
3902     if (parser.isKeyword(0, "DIAGMODEL")) {
3903       if (strcmp(parser.get(1), "ON") == 0) {
3904         _diagModel = 1;
3905         diag = true;
3906       } else if (strcmp(parser.get(1), "TRUE") == 0) {
3907         _diagModel = 2;
3908         diag = true;
3909       }
3910       continue;
3911     }
3912 
3913     if (parser.isKeyword(0, "rcStats")) {  // TO_TEST
3914       _layerCnt = parser.getInt(2);
3915       createModelTable(1, _layerCnt);
3916       for (uint kk = 0; kk < _modelCnt; kk++)
3917         _dataRateTable->add(0.0);
3918 
3919       _modelTable[0]->allocateInitialTables(_layerCnt, 10, true, true, true);
3920 
3921       _modelTable[0]->readRCstats(&parser);
3922 
3923       continue;
3924     }
3925     if (parser.isKeyword(0, "Layer")) {
3926       _layerCnt = parser.getInt(2);
3927       continue;
3928     }
3929     if (parser.isKeyword(0, "LayerCount")) {
3930       _layerCnt = parser.getInt(1) + 1;
3931       _verticalDiag = true;
3932       continue;
3933     }
3934     if (parser.isKeyword(0, "DensityRate")) {
3935       uint rulesFileModelCnt = parser.getInt(1);
3936       if (cornerCnt > 0) {
3937         if ((rulesFileModelCnt > 0) && (rulesFileModelCnt < cornerCnt)) {
3938           logger_->warn(
3939               RCX, 222,
3940               "There were {} extraction models defined but only {} exists "
3941               "in the extraction rules file {}",
3942               cornerCnt, rulesFileModelCnt, name);
3943           return false;
3944         }
3945         createModelTable(cornerCnt, _layerCnt);
3946 
3947         for (uint jj = 0; jj < cornerCnt; jj++) {
3948           uint modelIndex = cornerTable[jj];
3949 
3950           uint kk;
3951           for (kk = 0; kk < rulesFileModelCnt; kk++) {
3952             if (modelIndex != kk)
3953               continue;
3954             _dataRateTable->add(parser.getDouble(kk + 2));
3955             break;
3956           }
3957           if (kk == rulesFileModelCnt) {
3958             logger_->warn(RCX, 223,
3959                           "Cannot find model index {} in extRules file {}",
3960                           modelIndex, name);
3961             return false;
3962           }
3963         }
3964       } else {  // old behavior;
3965                 // david 7.20
3966                 // createModelTable(rulesFileModelCnt,
3967         // _layerCnt);
3968         createModelTable(1, _layerCnt);
3969 
3970         for (uint kk = 0; kk < _modelCnt; kk++) {
3971           _dataRateTable->add(parser.getDouble(kk + 2));
3972         }
3973         for (uint ii = 0; ii < _modelCnt; ii++) {
3974           _modelTable[ii]->_rate = _dataRateTable->get(ii);
3975         }
3976       }
3977       continue;
3978     }
3979     // parser.setDbg(1);
3980 
3981     if (parser.isKeyword(0, "DensityModel")) {
3982       uint m = parser.getInt(1);
3983       uint modelIndex = m;
3984       bool skipModel = false;
3985       if (cornerCnt > 0) {
3986         uint jj = 0;
3987         for (; jj < cornerCnt; jj++) {
3988           if (m == cornerTable[jj])
3989             break;
3990         }
3991         if (jj == cornerCnt) {
3992           skipModel = true;
3993           modelIndex = 0;
3994         } else {
3995           skipModel = false;
3996           modelIndex = jj;
3997         }
3998       } else {  // david 7.20
3999         if (modelIndex)
4000           skipModel = true;
4001       }
4002       // skipModel= true;
4003       bool res_skipModel = false;
4004 
4005       for (uint ii = 1; ii < _layerCnt; ii++) {
4006         if (!res_skipModel) {
4007           cnt += readRules(&parser, modelIndex, ii, "RESOVER", "WIDTH", over,
4008                            false, bin, false, res_skipModel, dbFactor);
4009         }
4010         cnt += readRules(&parser, modelIndex, ii, "OVER", "WIDTH", over, false,
4011                          bin, false, skipModel, dbFactor);
4012         if (ii < _layerCnt - 1) {
4013           cnt += readRules(&parser, modelIndex, ii, "UNDER", "WIDTH", false,
4014                            under, bin, false, skipModel, dbFactor);
4015           if (diag)
4016             cnt += readRules(&parser, modelIndex, ii, "DIAGUNDER", "WIDTH",
4017                              false, false, bin, diag, skipModel, dbFactor);
4018         }
4019 
4020         if ((ii > 1) && (ii < _layerCnt - 1))
4021           cnt +=
4022               readRules(&parser, modelIndex, ii, "OVERUNDER", "WIDTH",
4023                         overUnder, overUnder, bin, false, skipModel, dbFactor);
4024       }
4025       // break;
4026       parser.parseNextLine();
4027     }
4028   }
4029   return true;
4030 }
measureResistance(extMeasure * m,double ro,double top_widthR,double bot_widthR,double thicknessR)4031 double extRCModel::measureResistance(extMeasure* m, double ro,
4032                                      double top_widthR, double bot_widthR,
4033                                      double thicknessR) {
4034   double r = ro / ((top_widthR + bot_widthR) * thicknessR * 0.5);
4035   return r;
4036 }
solverStep(extMeasure * m)4037 bool extRCModel::solverStep(extMeasure* m) {
4038 #ifndef SKIP_SOLVER
4039   if (_runSolver) {
4040     if (m->_3dFlag)
4041       runSolver("rc3 -n -x -z");
4042     else
4043       runSolver("rc2 -n -x -z");
4044     return true;
4045   }
4046 #endif
4047 
4048   return false;
4049 }
measurePatternVar(extMeasure * m,double top_width,double bot_width,double thickness,uint wireCnt,char * wiresNameSuffix,double res)4050 bool extRCModel::measurePatternVar(extMeasure* m, double top_width,
4051                                    double bot_width, double thickness,
4052                                    uint wireCnt, char* wiresNameSuffix,
4053                                    double res) {
4054   m->setEffParams(top_width, bot_width, thickness);
4055   double thicknessChange =
4056       _process->adjustMasterLayersForHeight(m->_met, thickness);
4057 
4058   // _process->getMasterConductor(m->_met)->reset(m->_heff, top_width,
4059   // bot_width, thickness);
4060   _process->getMasterConductor(m->_met)->resetWidth(top_width, bot_width);
4061 
4062   mkFileNames(m, wiresNameSuffix);
4063 
4064   printCommentLine('$', m);
4065   fprintf(_logFP, "%s\n", _commentLine);
4066   fprintf(_logFP, "%c %g thicknessChange\n", '$', thicknessChange);
4067   fflush(_logFP);
4068 
4069   if (_writeFiles) {
4070     FILE* wfp = mkPatternFile();
4071 
4072     if (wfp == NULL)
4073       return false;  // should be an exception!! and return!
4074 
4075     double maxHeight =
4076         _process->adjustMasterDielectricsForHeight(m->_met, thicknessChange);
4077     maxHeight *= 1.2;
4078 
4079     if (m->_3dFlag) {
4080       //			double W = (m->_ur[m->_dir] -
4081       // m->_ll[m->_dir])*10;
4082       double W = 40;
4083       // DKF  _process->writeProcessAndGround3D(wfp, "GND", m->_underMet,
4084       // m->_overMet, -30.0, 60.0, m->_len*0.001, maxHeight, W);
4085       _process->writeProcessAndGround3D(wfp, "GND", -1, -1, -30.0, 60.0,
4086                                         m->_len * 0.001, maxHeight, W,
4087                                         m->_diag);
4088     } else {
4089       if (m->_diag) {
4090         int met = -1;
4091         if (m->_overMet + 1 < (int)_layerCnt)
4092           met = m->_overMet + 1;
4093         _process->writeProcessAndGround(wfp, "GND", m->_met - 1, met, -50.0,
4094                                         100.0, maxHeight, m->_diag);
4095       } else
4096         _process->writeProcessAndGround(wfp, "GND", m->_underMet, m->_overMet,
4097                                         -50.0, 100.0, maxHeight, m->_diag);
4098     }
4099 
4100     if (_commentFlag)
4101       fprintf(wfp, "%s\n", _commentLine);
4102 
4103     if (m->_benchFlag) {
4104       writeBenchWires(wfp, m);
4105     } else {
4106       if (m->_3dFlag) {  // 3d based extraction rules
4107                          //				writeWires2_3D(wfp, m,
4108                          // wireCnt);
4109         writeRuleWires_3D(wfp, m, wireCnt);
4110         writeRaphaelCaps3D(wfp, m, wireCnt);
4111       } else {
4112         //				writeWires2(wfp, m, wireCnt);
4113         writeRuleWires(wfp, m, wireCnt);
4114         writeRaphaelCaps(wfp, m, wireCnt);
4115       }
4116     }
4117 
4118     fclose(wfp);
4119   }
4120   solverStep(m);
4121 
4122   // if (!m->_benchFlag && _readSolver) {
4123   if (_readSolver) {
4124     uint lineCnt = 0;
4125 
4126     if (m->_3dFlag)
4127       lineCnt = readCapacitanceBench3D(_readCapLog, m, true);
4128     else {
4129       if (m->_diag)
4130         lineCnt = readCapacitanceBenchDiag(_readCapLog, m);
4131       else
4132         lineCnt = readCapacitanceBench(_readCapLog, m);
4133     }
4134     if (lineCnt <= 0 && _keepFile) {
4135       _readCapLog = false;
4136 
4137       solverStep(m);
4138 
4139       if (m->_3dFlag)
4140         lineCnt = readCapacitanceBench3D(_readCapLog, m, true);
4141       else {
4142         if (m->_diag)
4143           lineCnt = readCapacitanceBenchDiag(_readCapLog, m);
4144         else
4145           lineCnt = readCapacitanceBench(_readCapLog, m);
4146       }
4147     }
4148     if (!m->_benchFlag && (lineCnt > 0)) {
4149       double cc1 = 0.0, cc2 = 0.0, fr = 0.0, tot = 0.0;
4150       if (m->_3dFlag)
4151         getCapValues3D(lineCnt, cc1, cc2, fr, tot, m);
4152       else
4153         getCapValues(lineCnt, cc1, cc2, fr, tot, m);
4154 
4155       m->_rcValid = false;
4156 
4157       if (wiresNameSuffix != NULL)
4158         return true;
4159 
4160       if (lineCnt <= 0) {
4161         logger_->info(RCX, 224, "Not valid cap values from solver dir {}",
4162                       _wireDirName);
4163         return true;
4164       }
4165 
4166       extDistRC* rc = _rcPoolPtr->alloc();
4167 
4168       if (m->_diag && _diagModel == 2)
4169         rc->set(m->_s_nm, (cc1 + cc2) * 0.5, fr, 0.0, 0.001 * res);
4170       else
4171         rc->set(m->_s_nm, cc1, 0.5 * fr, 0.0, 0.001 * res);
4172       m->_tmpRC = rc;
4173 
4174       m->_rcValid = true;
4175 
4176       // m->addCap();
4177       addRC(m);
4178     }
4179     if (m->_benchFlag && (lineCnt > 0)) {
4180       if (m->_3dFlag)
4181         getCapMatrixValues3D(lineCnt, m);
4182       else
4183         getCapMatrixValues(lineCnt, m);
4184     }
4185   }
4186   if (!_keepFile)
4187     cleanFiles();
4188   return true;
4189 }
readCapacitanceBench3D(bool readCapLog,extMeasure * m,bool skipPrintWires)4190 uint extRCModel::readCapacitanceBench3D(bool readCapLog, extMeasure* m,
4191                                         bool skipPrintWires) {
4192   double units = 1.0e+15;
4193 
4194   FILE* solverFP = NULL;
4195   if (!readCapLog) {
4196     solverFP = openSolverFile();
4197     if (solverFP == NULL) {
4198       return 0;
4199     }
4200     _parser->setInputFP(solverFP);
4201   }
4202 
4203   Ath__parser wParser;
4204 
4205   bool matrixFlag = false;
4206   uint cnt = 0;
4207   m->_capMatrix[1][0] = 0.0;
4208   while (_parser->parseNextLine() > 0) {
4209     if (matrixFlag) {
4210       if (_parser->isKeyword(0, "END"))
4211         break;
4212 
4213       if (!_parser->isKeyword(0, "Charge"))
4214         continue;
4215 
4216       //_parser->printWords(stdout);
4217       _parser->printWords(_capLogFP);
4218 
4219       double cap = _parser->getDouble(4);
4220       if (cap < 0.0)
4221         cap = -cap;
4222       cap *= units;
4223 
4224       wParser.mkWords(_parser->get(2), "w");
4225       uint n1 = wParser.getInt(1);
4226       if (!n1) {
4227         m->_capMatrix[1][0] += cap;
4228         continue;
4229       }
4230       m->_capMatrix[1][cnt + 1] = cap;
4231       m->_idTable[cnt + 1] = n1;
4232       cnt++;
4233       continue;
4234     }
4235 
4236     if (_parser->isKeyword(0, "***") && _parser->isKeyword(1, "POTENTIAL")) {
4237       matrixFlag = true;
4238 
4239       fprintf(_capLogFP, "BEGIN %s\n", _wireDirName);
4240       fprintf(_capLogFP, "%s\n", _commentLine);
4241       if (!skipPrintWires) {
4242         if (m != NULL) {
4243           if (m->_benchFlag)
4244             writeWires2_3D(_capLogFP, m, m->_wireCnt);
4245           else
4246             writeRuleWires_3D(_capLogFP, m, m->_wireCnt);
4247         }
4248       }
4249       continue;
4250     } else if (_parser->isKeyword(0, "BEGIN") &&
4251                (strcmp(_parser->get(1), _wireDirName) == 0)) {
4252       matrixFlag = true;
4253 
4254       fprintf(_capLogFP, "BEGIN %s\n", _wireDirName);
4255 
4256       continue;
4257     }
4258   }
4259 
4260   for (uint i = 1; i < cnt; i++) {
4261     for (uint j = i + 1; j < cnt + 1; j++) {
4262       if (m->_idTable[j] < m->_idTable[i]) {
4263         uint t = m->_idTable[i];
4264         double tt = m->_capMatrix[1][i];
4265         m->_idTable[i] = m->_idTable[j];
4266         m->_capMatrix[1][i] = m->_capMatrix[1][j];
4267         m->_idTable[j] = t;
4268         m->_capMatrix[1][j] = tt;
4269       }
4270     }
4271   }
4272 
4273   if (solverFP != NULL)
4274     fclose(solverFP);
4275 
4276   return cnt;
4277 }
printCommentLine(char commentChar,extMeasure * m)4278 void extRCModel::printCommentLine(char commentChar, extMeasure* m) {
4279   sprintf(_commentLine,
4280           "%c %s w= %g s= %g r= %g\n\n%c %s %6.3f %6.3f top_width\n%c %s %6.3f "
4281           "%g bot_width\n%c %s %6.3f %6.3f spacing\n%c %s %6.3f %6.3f height "
4282           "\n%c %s %6.3f %6.3f thicknes\n",
4283           commentChar, "Layout params", m->_w_m, m->_s_m, m->_r, commentChar,
4284           "Layout/Eff", m->_w_m, m->_topWidth, commentChar, "Layout/Eff",
4285           m->_w_m, m->_botWidth, commentChar, "Layout/Eff", m->_s_m, m->_seff,
4286           commentChar, "Layout/Eff", m->_h, m->_heff, commentChar, "Layout/Eff",
4287           m->_t, m->_teff);
4288   _commentFlag = true;
4289 }
getDiagTables(extMeasure * m,uint widthCnt,uint spaceCnt)4290 void extRCModel::getDiagTables(extMeasure* m, uint widthCnt, uint spaceCnt) {
4291   Ath__array1D<double>* diagSTable0 = NULL;
4292   Ath__array1D<double>* diagWTable0 = NULL;
4293   diagSTable0 = _process->getDiagSpaceTable(m->_overMet);
4294   diagWTable0 = _process->getWidthTable(m->_overMet);
4295   m->_diagWidthTable0.resetCnt();
4296   if (diagWTable0) {
4297     for (uint wIndex = 0;
4298          (wIndex < diagWTable0->getCnt()) && (wIndex < widthCnt); wIndex++) {
4299       double w = diagWTable0->get(wIndex);
4300       m->_diagWidthTable0.add(w);
4301     }
4302   }
4303   m->_diagSpaceTable0.resetCnt();
4304   if (diagSTable0) {
4305     for (uint dsIndex = 0;
4306          (dsIndex < diagSTable0->getCnt()) && (dsIndex < spaceCnt); dsIndex++) {
4307       double ds = diagSTable0->get(dsIndex);
4308       m->_diagSpaceTable0.add(ds);
4309     }
4310   }
4311 }
computeTables(extMeasure * m,uint wireCnt,uint widthCnt,uint spaceCnt,uint dCnt)4312 void extRCModel::computeTables(extMeasure* m, uint wireCnt, uint widthCnt,
4313                                uint spaceCnt, uint dCnt) {
4314   //	extVariation *xvar= _process->getVariation(m->_met);
4315   extVariation* xvar = NULL;
4316   if (!_maxMinFlag)
4317     xvar = _process->getVariation(m->_met);
4318 
4319   m->_thickVarFlag = _process->getThickVarFlag();
4320 
4321   Ath__array1D<double>* wTable = NULL;
4322   Ath__array1D<double>* sTable = NULL;
4323   Ath__array1D<double>* dTable = NULL;
4324   Ath__array1D<double>* pTable = NULL;
4325   Ath__array1D<double>* wTable0 = NULL;
4326   Ath__array1D<double>* sTable0 = NULL;
4327   Ath__array1D<double>* diagSTable0 = NULL;
4328   Ath__array1D<double>* diagWTable0 = NULL;
4329   if (xvar != NULL) {
4330     wTable = xvar->getWidthTable();
4331     sTable = xvar->getSpaceTable();
4332     dTable = xvar->getDataRateTable();
4333     pTable = xvar->getPTable();
4334     wTable0 = _process->getWidthTable(m->_met);
4335     sTable0 = _process->getSpaceTable(m->_met);
4336     if (_diagModel == 2 && m->_overMet < (int)_layerCnt) {
4337       diagSTable0 = _process->getDiagSpaceTable(m->_overMet);
4338       diagWTable0 = _process->getWidthTable(m->_overMet);
4339     } else {
4340       diagSTable0 = _process->getDiagSpaceTable(m->_met);
4341     }
4342   } else {  // no variation
4343     wTable = _process->getWidthTable(m->_met);
4344     sTable = _process->getSpaceTable(m->_met);
4345     dTable = _process->getDataRateTable(m->_met);
4346     wTable0 = _process->getWidthTable(m->_met);
4347     sTable0 = _process->getSpaceTable(m->_met);
4348     if (_diagModel == 2 && m->_overMet < (int)_layerCnt) {
4349       diagSTable0 = _process->getDiagSpaceTable(m->_overMet);
4350       diagWTable0 = _process->getWidthTable(m->_overMet);
4351     } else {
4352       diagSTable0 = _process->getDiagSpaceTable(m->_met);
4353     }
4354     if (_maxMinFlag)
4355       for (uint i = 1; i < 3; i++) {
4356         dTable->add(i);
4357       }
4358   }
4359   m->_widthTable.resetCnt();
4360   for (uint wIndex = 0; (wIndex < wTable->getCnt()) && (wIndex < widthCnt);
4361        wIndex++) {
4362     double w = wTable->get(wIndex);  // layout
4363     m->_widthTable.add(w);
4364   }
4365   if (_diagModel == 2 && m->_overMet < (int)_layerCnt) {
4366     m->_diagWidthTable0.resetCnt();
4367     if (diagWTable0) {
4368       for (uint wIndex = 0;
4369            (wIndex < diagWTable0->getCnt()) && (wIndex < widthCnt); wIndex++) {
4370         double w = diagWTable0->get(wIndex);
4371         m->_diagWidthTable0.add(w);
4372       }
4373     }
4374   }
4375   m->_spaceTable.resetCnt();
4376   if (m->_diagModel == 1) {
4377     m->_spaceTable.add(0.0);
4378   }
4379   for (uint sIndex = 0; (sIndex < sTable->getCnt()) && (sIndex < spaceCnt);
4380        sIndex++) {
4381     double s = sTable->get(sIndex);  // layout
4382     m->_spaceTable.add(s);
4383   }
4384   if (m->_diagModel == 2)
4385     m->_spaceTable.add(99);
4386   m->_spaceTable.add(100);
4387   m->_diagSpaceTable0.resetCnt();
4388   if (diagSTable0) {
4389     for (uint dsIndex = 0;
4390          (dsIndex < diagSTable0->getCnt()) && (dsIndex < spaceCnt); dsIndex++) {
4391       double ds = diagSTable0->get(dsIndex);
4392       m->_diagSpaceTable0.add(ds);
4393     }
4394   }
4395   m->_dataTable.resetCnt();
4396   //	if (xvar!=NULL || _maxMinFlag) {
4397   if (!_maxMinFlag && xvar != NULL)
4398     m->_dataTable.add(0.0);
4399   m->_widthTable0.resetCnt();
4400   for (uint wIndex1 = 0; (wIndex1 < wTable0->getCnt()) && (wIndex1 < widthCnt);
4401        wIndex1++) {
4402     double w = wTable0->get(wIndex1);
4403     m->_widthTable0.add(w);
4404   }
4405   m->_spaceTable0.resetCnt();
4406   if (m->_diagModel == 1) {
4407     m->_spaceTable0.add(0.0);
4408   }
4409   for (uint sIndex1 = 0; (sIndex1 < sTable0->getCnt()) && (sIndex1 < spaceCnt);
4410        sIndex1++) {
4411     double s = sTable0->get(sIndex1);
4412     m->_spaceTable0.add(s);
4413   }
4414   if (m->_diagModel == 2)
4415     m->_spaceTable0.add(99);
4416   m->_spaceTable0.add(100);
4417   //	}
4418 
4419   for (uint dIndex = 0; (dIndex < dTable->getCnt()) && (dIndex < dCnt);
4420        dIndex++) {
4421     double r = dTable->get(dIndex);  // layout
4422     m->_dataTable.add(r);
4423   }
4424   if (pTable != NULL) {
4425     m->_pTable.resetCnt();
4426     for (uint pIndex = 0; pIndex < pTable->getCnt(); pIndex++) {
4427       double p = pTable->get(pIndex);
4428       m->_pTable.add(p);
4429     }
4430   }
4431 }
measureDiagWithVar(extMeasure * measure)4432 uint extRCModel::measureDiagWithVar(extMeasure* measure) {
4433   uint cnt = 0;
4434   int met = measure->_met;
4435   extVariation* xvar = _process->getVariation(measure->_met);
4436 
4437   extConductor* cond = _process->getConductor(met);
4438   double t = cond->_thickness;
4439   double h = cond->_height;
4440   double ro = cond->_p;
4441   double res = 0.0;
4442   double top_ext = cond->_top_ext;
4443   double bot_ext = cond->_bot_ext;
4444 
4445   //        extMasterConductor* m= _process->getMasterConductor(met);
4446   if (top_ext != 0.0 || bot_ext != 0.0) {
4447     xvar = NULL;
4448     measure->_metExtFlag = true;
4449   }
4450 
4451   for (uint dIndex = 0; dIndex < measure->_dataTable.getCnt(); dIndex++) {
4452     double r = measure->_dataTable.get(dIndex);  // layout
4453     measure->_rIndex = dIndex;
4454 
4455     uint wcnt;
4456     uint scnt;
4457     uint dwcnt;
4458     uint dscnt;
4459     if (dIndex) {
4460       wcnt = measure->_widthTable.getCnt();
4461       scnt = measure->_spaceTable.getCnt();
4462       dwcnt = measure->_diagWidthTable0.getCnt();
4463       dscnt = measure->_diagSpaceTable0.getCnt();
4464     } else {
4465       wcnt = measure->_widthTable0.getCnt();
4466       scnt = measure->_spaceTable0.getCnt();
4467       dwcnt = measure->_diagWidthTable0.getCnt();
4468       dscnt = measure->_diagSpaceTable0.getCnt();
4469     }
4470     for (uint wIndex = 0; wIndex < wcnt; wIndex++) {
4471       double w;
4472       if (!dIndex)
4473         w = measure->_widthTable0.get(wIndex);
4474       else
4475         w = measure->_widthTable.get(wIndex);  // layout
4476       measure->_wIndex = wIndex;
4477       for (uint dwIndex = 0; dwIndex < dwcnt; dwIndex++) {
4478         double dw;
4479         dw = measure->_diagWidthTable0.get(dwIndex);
4480         measure->_dwIndex = dwIndex;
4481         for (uint dsIndex = 0; dsIndex < dscnt; dsIndex++) {
4482           double ds;
4483           ds = measure->_diagSpaceTable0.get(dsIndex);
4484           measure->_dsIndex = dsIndex;
4485           for (uint sIndex = 0; sIndex < scnt; sIndex++) {
4486             double s;
4487             if (!dIndex)
4488               s = measure->_spaceTable0.get(sIndex);
4489             else
4490               s = measure->_spaceTable.get(sIndex);
4491             double top_width = w + 2 * top_ext;
4492             double top_widthR = w + 2 * top_ext;
4493             double bot_width = w + 2 * bot_ext;
4494             double thickness = t;
4495             double bot_widthR = w + 2 * bot_ext;
4496             double thicknessR = t;
4497 
4498             if (r == 0.0) {
4499               //                                        		top_width=
4500               //                                        w;
4501               //                                        top_widthR= w;
4502               if (xvar != NULL) {
4503                 double a = xvar->getP(w);
4504                 if (a != 0.0)
4505                   ro = a;
4506               }
4507               res = measureResistance(measure, ro, top_widthR, bot_widthR,
4508                                       thicknessR);
4509             } else if (xvar != NULL && !_maxMinFlag) {
4510               uint ss;
4511               //							if
4512               //(sIndex < scnt-1)
4513               if (sIndex < scnt - 2)
4514                 ss = sIndex;
4515               else
4516                 //								ss
4517                 //= scnt-2;
4518                 ss = scnt - 3;
4519               top_width = xvar->getTopWidth(wIndex, ss);
4520               top_widthR = xvar->getTopWidthR(wIndex, ss);
4521               bot_width = xvar->getBottomWidth(w, dIndex - 1);
4522               bot_width = top_width - bot_width;
4523               thickness = xvar->getThickness(w, dIndex - 1);
4524               bot_widthR = xvar->getBottomWidthR(w, dIndex - 1);
4525               bot_widthR = top_widthR - bot_widthR;
4526               thicknessR = xvar->getThicknessR(w, dIndex - 1);
4527               double a = xvar->getP(w);
4528               if (a != 0.0)
4529                 ro = a;
4530               res = measureResistance(measure, ro, top_widthR, bot_widthR,
4531                                       thicknessR);
4532             } else if (_maxMinFlag && r == 1.0) {
4533               top_width = w - 2 * cond->_min_cw_del;
4534               thickness = t - cond->_min_ct_del;
4535               bot_width = top_width - 2 * thickness * cond->_min_ca;
4536               if (bot_width > w)
4537                 bot_width = w;
4538               res = measureResistance(measure, ro, top_widthR, bot_widthR,
4539                                       thicknessR);
4540             } else if (_maxMinFlag && r == 2.0) {
4541               top_width = w + 2 * cond->_max_cw_del;
4542               thickness = t + cond->_max_ct_del;
4543               bot_width = top_width - 2 * thickness * cond->_max_ca;
4544               if (bot_width < w)
4545                 bot_width = w;
4546               res = measureResistance(measure, ro, top_widthR, bot_widthR,
4547                                       thicknessR);
4548             } else if (measure->_thickVarFlag) {
4549               thickness *= 1 + r;
4550               thicknessR *= 1 + r;
4551             } else {
4552               continue;
4553             }
4554             measure->setTargetParams(w, s, r, t, h, dw, ds);
4555             measurePatternVar(measure, top_width, bot_width, thickness,
4556                               measure->_wireCnt, NULL, res * 0.5);
4557 
4558             cnt++;
4559           }
4560         }
4561       }
4562     }
4563   }
4564   return cnt;
4565 }
measureWithVar(extMeasure * measure)4566 uint extRCModel::measureWithVar(extMeasure* measure) {
4567   uint cnt = 0;
4568   int met = measure->_met;
4569   extVariation* xvar = _process->getVariation(measure->_met);
4570 
4571   extConductor* cond = _process->getConductor(met);
4572   double t = cond->_thickness;
4573   double h = cond->_height;
4574   double ro = cond->_p;
4575   double res = 0.0;
4576   double top_ext = cond->_top_ext;
4577   double bot_ext = cond->_bot_ext;
4578 
4579   //	extMasterConductor* m= _process->getMasterConductor(met);
4580   if (top_ext != 0.0 || bot_ext != 0.0) {
4581     xvar = NULL;
4582     measure->_metExtFlag = true;
4583   }
4584 
4585   for (uint dIndex = 0; dIndex < measure->_dataTable.getCnt(); dIndex++) {
4586     double r = measure->_dataTable.get(dIndex);  // layout
4587     measure->_rIndex = dIndex;
4588 
4589     uint wcnt;
4590     uint scnt;
4591     if (dIndex) {
4592       wcnt = measure->_widthTable.getCnt();
4593       if (!measure->_diag)
4594         scnt = measure->_spaceTable.getCnt();
4595       else
4596         //      scnt=measure->_spaceTable0.getCnt();
4597         scnt = measure->_diagSpaceTable0.getCnt();
4598     } else {
4599       wcnt = measure->_widthTable0.getCnt();
4600       if (!measure->_diag)
4601         scnt = measure->_spaceTable0.getCnt();
4602       else
4603         scnt = measure->_diagSpaceTable0.getCnt();
4604     }
4605     for (uint wIndex = 0; wIndex < wcnt; wIndex++) {
4606       double w;
4607       if (!dIndex)
4608         w = measure->_widthTable0.get(wIndex);
4609       else
4610         w = measure->_widthTable.get(wIndex);  // layout
4611       measure->_wIndex = wIndex;
4612 
4613       for (uint sIndex = 0; sIndex < scnt; sIndex++) {
4614         double s;
4615         if (!measure->_diag) {
4616           if (!dIndex)
4617             s = measure->_spaceTable0.get(sIndex);
4618           else
4619             s = measure->_spaceTable.get(sIndex);  // layout
4620           if (sIndex == scnt - 1 && wIndex == wcnt - 1 && !measure->_overUnder)
4621             measure->_plate = true;
4622           else
4623             measure->_plate = false;
4624         } else
4625           s = measure->_diagSpaceTable0.get(sIndex);
4626 
4627         double top_width = w + 2 * top_ext;
4628         double top_widthR = w + 2 * top_ext;
4629         double bot_width = w + 2 * bot_ext;
4630         double thickness = t;
4631         double bot_widthR = w + 2 * bot_ext;
4632         double thicknessR = t;
4633 
4634         if (r == 0.0) {
4635           //					top_width= w;
4636           //					top_widthR= w;
4637           if (xvar != NULL) {
4638             double a = xvar->getP(w);
4639             if (a != 0.0)
4640               ro = a;
4641           }
4642           res = measureResistance(measure, ro, top_widthR, bot_widthR,
4643                                   thicknessR);
4644         } else if (xvar != NULL && !_maxMinFlag) {
4645           uint ss;
4646           if (measure->_diag)
4647             ss = 5;
4648           else {
4649             if (sIndex < scnt - 1)
4650               ss = sIndex;
4651             else
4652               ss = scnt - 2;
4653           }
4654           /*
4655                                                   top_width=
4656              xvar->getTopWidth(wIndex, sIndex); top_widthR=
4657              xvar->getTopWidthR(wIndex, sIndex);
4658           */
4659           top_width = xvar->getTopWidth(wIndex, ss);
4660           top_widthR = xvar->getTopWidthR(wIndex, ss);
4661 
4662           bot_width = xvar->getBottomWidth(w, dIndex - 1);
4663           bot_width = top_width - bot_width;
4664 
4665           thickness = xvar->getThickness(w, dIndex - 1);
4666 
4667           bot_widthR = xvar->getBottomWidthR(w, dIndex - 1);
4668           bot_widthR = top_widthR - bot_widthR;
4669 
4670           thicknessR = xvar->getThicknessR(w, dIndex - 1);
4671           double a = xvar->getP(w);
4672           if (a != 0.0)
4673             ro = a;
4674           res = measureResistance(measure, ro, top_widthR, bot_widthR,
4675                                   thicknessR);
4676         } else if (_maxMinFlag && r == 1.0) {
4677           top_width = w - 2 * cond->_min_cw_del;
4678           thickness = t - cond->_min_ct_del;
4679           bot_width = top_width - 2 * thickness * cond->_min_ca;
4680           if (bot_width > w)
4681             bot_width = w;
4682           res = measureResistance(measure, ro, top_widthR, bot_widthR,
4683                                   thicknessR);
4684         } else if (_maxMinFlag && r == 2.0) {
4685           top_width = w + 2 * cond->_max_cw_del;
4686           thickness = t + cond->_max_ct_del;
4687           bot_width = top_width - 2 * thickness * cond->_max_ca;
4688           if (bot_width < w)
4689             bot_width = w;
4690           res = measureResistance(measure, ro, top_widthR, bot_widthR,
4691                                   thicknessR);
4692         } else if (measure->_thickVarFlag) {
4693           thickness *= 1 + r;
4694           thicknessR *= 1 + r;
4695         } else {
4696           continue;
4697         }
4698 
4699         measure->setTargetParams(w, s, r, t, h);
4700         measurePatternVar(measure, top_width, bot_width, thickness,
4701                           measure->_wireCnt, NULL, res * 0.5);
4702 
4703         //				measure->setTargetParams(w, s, 0.0, t,
4704         // h); 				measurePatternVar(measure, w, w, t,
4705         // measure->_wireCnt, "2");
4706 
4707         cnt++;
4708       }
4709     }
4710   }
4711 
4712   return cnt;
4713 }
allocOverTable(extMeasure * measure)4714 void extRCModel::allocOverTable(extMeasure* measure) {
4715   for (uint ii = 0; ii < measure->_dataTable.getCnt(); ii++) {
4716     if (!ii)
4717       _modelTable[ii]->allocOverTable(measure->_met, &measure->_widthTable0);
4718     else
4719       _modelTable[ii]->allocOverTable(measure->_met, &measure->_widthTable);
4720   }
4721 }
allocDiagUnderTable(extMeasure * measure)4722 void extRCModel::allocDiagUnderTable(extMeasure* measure) {
4723   for (uint ii = 0; ii < measure->_dataTable.getCnt(); ii++) {
4724     if (!ii) {
4725       if (_diagModel == 2)
4726         _modelTable[ii]
4727             ->allocDiagUnderTable(measure->_met, &measure->_widthTable0,
4728                                   measure->_diagWidthTable0.getCnt(),
4729                                   measure->_diagSpaceTable0.getCnt());
4730       else if (_diagModel == 1)
4731         _modelTable[ii]
4732             ->allocDiagUnderTable(measure->_met, &measure->_widthTable0);
4733     } else {
4734       if (_diagModel == 2)
4735         _modelTable[ii]
4736             ->allocDiagUnderTable(measure->_met, &measure->_widthTable,
4737                                   measure->_diagWidthTable0.getCnt(),
4738                                   measure->_diagSpaceTable0.getCnt());
4739       else if (_diagModel == 1)
4740         _modelTable[ii]
4741             ->allocDiagUnderTable(measure->_met, &measure->_widthTable);
4742     }
4743   }
4744 }
setDiagUnderTables(extMeasure * measure)4745 void extRCModel::setDiagUnderTables(extMeasure* measure) {
4746   for (uint ii = 0; ii < measure->_dataTable.getCnt(); ii++)
4747     _modelTable[ii]->setDiagUnderTables(measure->_met, measure->_overMet,
4748                                         &measure->_diagWidthTable0,
4749                                         &measure->_diagSpaceTable0);
4750 }
allocUnderTable(extMeasure * measure)4751 void extRCModel::allocUnderTable(extMeasure* measure) {
4752   for (uint ii = 0; ii < measure->_dataTable.getCnt(); ii++) {
4753     if (!ii)
4754       _modelTable[ii]->allocUnderTable(measure->_met, &measure->_widthTable0);
4755     else
4756       _modelTable[ii]->allocUnderTable(measure->_met, &measure->_widthTable);
4757   }
4758 }
allocOverUnderTable(extMeasure * measure)4759 void extRCModel::allocOverUnderTable(extMeasure* measure) {
4760   for (uint ii = 0; ii < measure->_dataTable.getCnt(); ii++) {
4761     if (!ii)
4762       _modelTable[ii]
4763           ->allocOverUnderTable(measure->_met, &measure->_widthTable0);
4764     else
4765       _modelTable[ii]
4766           ->allocOverUnderTable(measure->_met, &measure->_widthTable);
4767   }
4768 }
linesOver(uint wireCnt,uint widthCnt,uint spaceCnt,uint dCnt,uint metLevel)4769 uint extRCModel::linesOver(uint wireCnt, uint widthCnt, uint spaceCnt,
4770                            uint dCnt, uint metLevel) {
4771   sprintf(_patternName, "Over%d", wireCnt);
4772 
4773   openCapLogFile();
4774   uint cnt = 0;
4775 
4776   extMeasure measure;
4777   measure._wireCnt = wireCnt;
4778 
4779   for (uint met = 1; met < _layerCnt; met++) {
4780     if (metLevel > 0 && met != metLevel)
4781       continue;
4782 
4783     measure._met = met;
4784     computeTables(&measure, wireCnt, widthCnt, spaceCnt, dCnt);
4785 
4786     allocOverTable(&measure);
4787 
4788     for (uint underMet = 0; underMet < met; underMet++) {
4789       measure.setMets(met, underMet, -1);
4790       measure._capTable = _capOver;
4791 
4792       uint cnt1 = measureWithVar(&measure);
4793 
4794       logger_->info(RCX, 225,
4795                     "Finished {} measurements for pattern M{}_over_M{}", cnt1,
4796                     met, underMet);
4797 
4798       cnt += cnt1;
4799     }
4800   }
4801   if (metLevel < 0)
4802     logger_->info(RCX, 226, "Finished {} measurements for pattern MET_OVER_MET",
4803                   cnt);
4804 
4805   closeCapLogFile();
4806   return cnt;
4807 }
linesDiagUnder(uint wireCnt,uint widthCnt,uint spaceCnt,uint dCnt,uint metLevel)4808 uint extRCModel::linesDiagUnder(uint wireCnt, uint widthCnt, uint spaceCnt,
4809                                 uint dCnt, uint metLevel) {
4810   _diag = true;
4811   sprintf(_patternName, "DiagUnder%d", wireCnt);
4812   openCapLogFile();
4813   uint cnt = 0;
4814 
4815   extMeasure measure;
4816   measure._wireCnt = wireCnt;
4817   measure._diag = true;
4818   measure._diagModel = _diagModel;
4819 
4820   for (uint met = 1; met < _layerCnt - 1; met++) {
4821     if (metLevel > 0 && met != metLevel)
4822       continue;
4823 
4824     measure._met = met;
4825     measure._overMet = met;
4826     computeTables(&measure, wireCnt, widthCnt, spaceCnt, dCnt);
4827 
4828     allocDiagUnderTable(&measure);
4829 
4830     for (uint overMet = met + 1; overMet < met + 5 && overMet < _layerCnt;
4831          overMet++) {  // the max overMet need to be the same as in functions
4832                        // writeRulesDiagUnder readRulesDiagUnder
4833       measure.setMets(met, 0, overMet);
4834       uint cnt1;
4835       if (_diagModel == 2) {
4836         getDiagTables(&measure, widthCnt, spaceCnt);
4837         setDiagUnderTables(&measure);
4838         measure._capTable = _capDiagUnder;
4839         cnt1 = measureDiagWithVar(&measure);
4840       } else if (_diagModel == 1) {
4841         measure._capTable = _capDiagUnder;
4842         cnt1 = measureWithVar(&measure);
4843       }
4844 
4845       logger_->info(RCX, 227,
4846                     "Finished {} measurements for pattern M{}_diagUnder_M{}",
4847                     cnt1, met, overMet);
4848 
4849       cnt += cnt1;
4850     }
4851   }
4852   if (metLevel < 0)
4853     logger_->info(RCX, 228,
4854                   "Finished {} measurements for pattern MET_DIAGUNDER_MET",
4855                   cnt);
4856 
4857   closeCapLogFile();
4858   return cnt;
4859 }
linesUnder(uint wireCnt,uint widthCnt,uint spaceCnt,uint dCnt,uint metLevel)4860 uint extRCModel::linesUnder(uint wireCnt, uint widthCnt, uint spaceCnt,
4861                             uint dCnt, uint metLevel) {
4862   sprintf(_patternName, "Under%d", wireCnt);
4863   openCapLogFile();
4864   uint cnt = 0;
4865 
4866   extMeasure measure;
4867   measure._wireCnt = wireCnt;
4868 
4869   for (uint met = 1; met < _layerCnt; met++) {
4870     if (metLevel > 0 && met != metLevel)
4871       continue;
4872 
4873     measure._met = met;
4874     computeTables(&measure, wireCnt, widthCnt, spaceCnt, dCnt);
4875 
4876     allocUnderTable(&measure);
4877 
4878     for (uint overMet = met + 1; overMet < _layerCnt; overMet++) {
4879       measure.setMets(met, 0, overMet);
4880       measure._capTable = _capUnder;
4881 
4882       uint cnt1 = measureWithVar(&measure);
4883 
4884       logger_->info(RCX, 229,
4885                     "Finished {} measurements for pattern M{}_under_M{}", cnt1,
4886                     met, overMet);
4887 
4888       cnt += cnt1;
4889     }
4890   }
4891   if (metLevel < 0)
4892     logger_->info(RCX, 409,
4893                   "Finished {} measurements for pattern MET_UNDER_MET", cnt);
4894 
4895   closeCapLogFile();
4896   return cnt;
4897 }
linesOverUnder(uint wireCnt,uint widthCnt,uint spaceCnt,uint dCnt,uint metLevel)4898 uint extRCModel::linesOverUnder(uint wireCnt, uint widthCnt, uint spaceCnt,
4899                                 uint dCnt, uint metLevel) {
4900   sprintf(_patternName, "OverUnder%d", wireCnt);
4901   openCapLogFile();
4902   uint cnt = 0;
4903 
4904   extMeasure measure;
4905   measure._wireCnt = wireCnt;
4906   for (uint met = 1; met < _layerCnt - 1; met++) {
4907     if (metLevel > 0 && met != metLevel)
4908       continue;
4909     measure._met = met;
4910     computeTables(&measure, wireCnt, widthCnt, spaceCnt, dCnt);
4911 
4912     allocOverUnderTable(&measure);
4913 
4914     for (uint underMet = 1; underMet < met; underMet++) {
4915       for (uint overMet = met + 1; overMet < _layerCnt; overMet++) {
4916         measure.setMets(met, underMet, overMet);
4917         measure._capTable = _capUnder;
4918 
4919         uint cnt1 = measureWithVar(&measure);
4920 
4921         logger_->info(
4922             RCX, 231,
4923             "Finished {} measurements for pattern M{}_over_M{}_under_M{}", cnt1,
4924             met, underMet, overMet);
4925 
4926         cnt += cnt1;
4927       }
4928     }
4929   }
4930   if (metLevel < 0)
4931     logger_->info(RCX, 230,
4932                   "Finished {} measurements for pattern MET_UNDER_MET", cnt);
4933 
4934   closeCapLogFile();
4935   return cnt;
4936 }
4937 
metRulesGen(const char * name,const char * topDir,const char * rulesFile,int pattern,bool writeFiles,bool readFiles,bool runSolver,bool keepFile,uint met)4938 uint extMain::metRulesGen(const char* name, const char* topDir,
4939                           const char* rulesFile, int pattern, bool writeFiles,
4940                           bool readFiles, bool runSolver, bool keepFile,
4941                           uint met) {
4942   extRCModel* m = _modelTable->get(0);
4943 
4944   m->setOptions(topDir, name, writeFiles, readFiles, runSolver, keepFile, met);
4945   if ((pattern > 0) && (pattern <= 9))
4946     m->linesOver(pattern, 20, 20, 20, met);
4947   else if ((pattern > 10) && (pattern <= 19))
4948     m->linesUnder(pattern - 10, 20, 20, 20, met);
4949   else if ((pattern > 20) && (pattern <= 29))
4950     m->linesOverUnder(pattern - 20, 20, 20, 20, met);
4951   else if ((pattern > 30) && (pattern <= 39)) {
4952     m->setDiagModel(1);
4953     m->linesDiagUnder(pattern - 30, 20, 20, 20, met);
4954   } else if ((pattern > 40) && (pattern <= 49)) {
4955     m->setDiagModel(2);
4956     m->linesDiagUnder(pattern - 40, 20, 20, 20, met);
4957   }
4958   m->closeFiles();
4959   return 0;
4960 }
writeRules(const char * name,const char * topDir,const char * rulesFile,int pattern,bool readDb,bool readFiles)4961 uint extMain::writeRules(const char* name, const char* topDir,
4962                          const char* rulesFile, int pattern, bool readDb,
4963                          bool readFiles) {
4964   if (readDb) {
4965     GenExtRules(rulesFile, pattern);
4966     return 0;
4967   }
4968 
4969   if (!readFiles) {
4970     extRCModel* m = _modelTable->get(0);
4971 
4972     m->setOptions(topDir, name, false, true, false, false);
4973     m->writeRules((char*)rulesFile, false);
4974     return 0;
4975   }
4976 
4977   if (pattern > 0)
4978     rulesGen(name, topDir, rulesFile, pattern, false, true, false, false);
4979   else
4980     rulesGen(name, topDir, rulesFile, 205, false, true, false, false);
4981   return 0;
4982 }
rulesGen(const char * name,const char * topDir,const char * rulesFile,int pattern,bool writeFiles,bool readFiles,bool runSolver,bool keepFile)4983 uint extMain::rulesGen(const char* name, const char* topDir,
4984                        const char* rulesFile, int pattern, bool writeFiles,
4985                        bool readFiles, bool runSolver, bool keepFile) {
4986   extRCModel* m = _modelTable->get(0);
4987 
4988   m->setOptions(topDir, name, writeFiles, readFiles, runSolver, keepFile);
4989 
4990   if ((pattern > 0) && (pattern <= 9))
4991     m->linesOver(pattern, 20, 20, 20);
4992   else if ((pattern > 10) && (pattern <= 19))
4993     m->linesUnder(pattern - 10, 20, 20, 20);
4994   else if ((pattern > 20) && (pattern <= 29))
4995     m->linesOverUnder(pattern - 20, 20, 20, 20);
4996   else if ((pattern > 30) && (pattern <= 39)) {
4997     m->setDiagModel(1);
4998     m->linesDiagUnder(pattern - 30, 20, 20, 20);
4999   } else if ((pattern > 40) && (pattern <= 49)) {
5000     m->setDiagModel(2);
5001     m->linesDiagUnder(pattern - 40, 20, 20, 20);
5002   } else if (pattern > 100) {
5003     m->linesOver(pattern % 10, 20, 20, 20);
5004     m->linesUnder(pattern % 10, 20, 20, 20);
5005     m->linesOverUnder(pattern % 10, 20, 20, 20);
5006     if (pattern > 200)
5007       m->setDiagModel(2);
5008     else
5009       m->setDiagModel(1);
5010     m->linesDiagUnder(pattern % 10, 20, 20, 20);
5011   }
5012   m->closeFiles();
5013 
5014   m->writeRules((char*)rulesFile, false);
5015   return 0;
5016 }
readProcess(const char * name,const char * filename)5017 uint extMain::readProcess(const char* name, const char* filename) {
5018   /** for testing OverUnderIndex
5019   uint mCnt= atoi(filename);
5020 
5021   for (uint ii= 2; ii<mCnt; ii++) {
5022           fprintf(stdout, "\n");
5023           for (uint u= ii-1; u>0; u--) {
5024                   for (uint o=  ii+1; o<mCnt; o++) {
5025                           uint metIndex= getMetIndexOverUnder(ii, u, o, mCnt,
5026   logger_);
5027 
5028                           fprintf(stdout, "%d  m= %d  %d  = %d\n", u,ii,o,
5029   metIndex);
5030                   }
5031           }
5032           uint maxIndex= getMaxMetIndexOverUnder(ii, mCnt, logger_);
5033           fprintf(stdout, "\nm= %d  maxIndex= %d\n\n", ii, maxIndex);
5034   }
5035   return 1;
5036   */
5037 
5038   extProcess* p = new extProcess(32, 32, logger_);
5039 
5040   p->readProcess(name, (char*)filename);
5041   p->writeProcess("process.out");
5042 
5043   // create rc model
5044 
5045   uint layerCnt = p->getConductorCnt();
5046   extRCModel* m = new extRCModel(layerCnt, (char*)name, logger_);
5047   _modelTable->add(m);
5048 
5049   m->setProcess(p);
5050   m->setDataRateTable(1);
5051 
5052   return 0;
5053 }
readExtRules(const char * name,const char * filename,int min,int typ,int max)5054 uint extMain::readExtRules(const char* name, const char* filename, int min,
5055                            int typ, int max) {
5056   //	extProcess *p= new extProcess(32, 32, logger_);
5057 
5058   //	p->readProcess(name, (char *) filename);
5059 
5060   // create rc model
5061 
5062   extRCModel* m = new extRCModel((char*)name, logger_);
5063   _modelTable->add(m);
5064 
5065   uint cornerTable[10];
5066   uint cornerCnt = 0;
5067   int dbunit = _block->getDbUnitsPerMicron();
5068   double dbFactor = 1;
5069   if (dbunit > 1000)
5070     dbFactor = dbunit * 0.001;
5071 
5072   _minModelIndex = 0;
5073   _maxModelIndex = 0;
5074   _typModelIndex = 0;
5075   if ((min >= 0) || (max >= 0)) {
5076     if ((min >= 0) && (max >= 0)) {
5077       _minModelIndex = min;
5078       _maxModelIndex = max;
5079       // ypModelIndex= (min+max)/2;
5080 
5081       cornerTable[cornerCnt++] = min;
5082       cornerTable[cornerCnt++] = max;
5083     } else if (min >= 0) {
5084       _minModelIndex = min;
5085       cornerTable[cornerCnt++] = min;
5086     } else if (max >= 0) {
5087       _maxModelIndex = max;
5088       cornerTable[cornerCnt++] = max;
5089     }
5090     m->readRules((char*)filename, false, true, true, true, true, cornerCnt,
5091                  cornerTable, dbFactor);
5092     //		int modelCnt= getRCmodel(0)->getModelCnt();
5093   } else {
5094     m->readRules((char*)filename, false, true, true, true, true, 0, cornerTable,
5095                  dbFactor);
5096     int modelCnt = getRCmodel(0)->getModelCnt();
5097     _minModelIndex = 0;
5098     _maxModelIndex = modelCnt - 1;
5099     _typModelIndex = (modelCnt - 1) / 2;
5100   }
5101 
5102   //	m->setProcess(p);
5103   //	m->setDataRateTable(1);
5104 
5105   return 0;
5106 }
5107 
findBiggestDatarateIndex(double d)5108 uint extRCModel::findBiggestDatarateIndex(double d) {
5109   return _dataRateTable->findNextBiggestIndex(d, 1);
5110 }
findDatarateIndex(double d)5111 int extRCModel::findDatarateIndex(double d) {
5112   for (uint ii = 0; ii < _modelCnt; ii++) {
5113     if (d == _dataRateTable->get(ii))
5114       return ii;
5115     else if (d > _dataRateTable->get(ii))
5116       return ii - 1;
5117   }
5118   return -1;
5119 }
findClosestDataRate(uint n,double diff)5120 int extRCModel::findClosestDataRate(uint n, double diff) {
5121   if (n == _modelCnt - 1)
5122     return n;
5123   if (n == 0)
5124     return n;
5125 
5126   double down = _dataRateTable->get(n);
5127   double down_dist = diff - down;
5128 
5129   double up = _dataRateTable->get(n + 1);
5130   double up_dist = up - diff;
5131 
5132   if (down_dist > up_dist)
5133     return n++;
5134 
5135   return n;
5136 }
findVariationZero(double d)5137 int extRCModel::findVariationZero(double d) {
5138   _noVariationIndex = _dataRateTable->findIndex(d);
5139   return _noVariationIndex;
5140 }
getWidthDistRCtable(uint met,int mUnder,int mOver,int & n,double dRate)5141 extDistWidthRCTable* extRCModel::getWidthDistRCtable(uint met, int mUnder,
5142                                                      int mOver, int& n,
5143                                                      double dRate) {
5144   int rIndex = 0;
5145   if (dRate > 0) {
5146     rIndex = findDatarateIndex(dRate);
5147     if (rIndex < 0)
5148       return NULL;
5149   }
5150   if ((mUnder > 0) && (mOver > 0)) {
5151     n = getMetIndexOverUnder(met, mUnder, mOver, _layerCnt,
5152                              _modelTable[rIndex]->_capOverUnder[met]->_metCnt);
5153     assert(n >= 0);
5154     return _modelTable[rIndex]->_capOverUnder[met];
5155   } else if (mOver) {
5156     n = mUnder;
5157     return _modelTable[rIndex]->_capOver[met];
5158   } else {
5159     n = mOver - met - 1;
5160     return _modelTable[rIndex]->_capUnder[met];
5161   }
5162 }
5163 /*
5164 void extRCModel::getRCtable(Ath__array1D<int> *sTable, Ath__array1D<double>
5165 *rcTable, uint valType, uint met, int mUnder, int mOver, int width, double
5166 dRate)
5167 {
5168         int n= 0;
5169         extDistWidthRCTable *capTable= getWidthDistRCtable(met, mUnder, mOver,
5170 n, dRate); if (valType==0) // coupling ;
5171 //_modelTable[rIndex]->_capOverUnder[met]->getFringeTable(n, width, sTable,
5172 rcTable, false); else if (valType==1) // fringe capTable->getFringeTable(n,
5173 width, sTable, rcTable, false); else if (valType==2) // res ;
5174 //_modelTable[rIndex]->_capOverUnder[met]->getFringeTable(n, width, sTable,
5175 rcTable, false); else // total ;
5176 //_modelTable[rIndex]->_capOverUnder[met]->getFringeTable(n, width, sTable,
5177 rcTable, false);
5178 }
5179 */
5180 }  // namespace rcx
5181