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