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 #include <dbRtTree.h>
33
34 #include "dbUtil.h"
35 #include "rcx/extRCap.h"
36 #include "utl/Logger.h"
37
38 #ifdef HI_ACC_1
39 #define FRINGE_UP_DOWN
40 #endif
41 // #define CHECK_SAME_NET
42 //#define DEBUG_NET 208091
43 //#define MIN_FOR_LOOPS
44
45 namespace rcx {
46
47 using utl::RCX;
48
49 using odb::dbBlock;
50 using odb::dbBox;
51 using odb::dbBTerm;
52 using odb::dbCapNode;
53 using odb::dbCCSeg;
54 using odb::dbChip;
55 using odb::dbDatabase;
56 using odb::dbNet;
57 using odb::dbRSeg;
58 using odb::dbRtTree;
59 using odb::dbSet;
60 using odb::dbShape;
61 using odb::dbSigType;
62 using odb::dbTech;
63 using odb::dbTechLayer;
64 using odb::dbTechLayerDir;
65 using odb::dbTechLayerType;
66 using odb::dbWire;
67 using odb::dbWirePath;
68 using odb::dbWirePathItr;
69 using odb::dbWirePathShape;
70 using odb::gs;
71 using odb::Rect;
72 using odb::SEQ;
73
getFirstShape(dbNet * net,dbShape & s)74 bool extMeasure::getFirstShape(dbNet* net, dbShape& s) {
75 dbWirePath path;
76 dbWirePathShape pshape;
77
78 dbWirePathItr pitr;
79 dbWire* wire = net->getWire();
80
81 bool status = false;
82 for (pitr.begin(wire); pitr.getNextPath(path);) {
83 pitr.getNextShape(pshape);
84 s = pshape.shape;
85 status = true;
86 break;
87 }
88 return status;
89 }
parse_setLayer(Ath__parser * parser1,uint & layerNum,bool print)90 bool extMeasure::parse_setLayer(Ath__parser* parser1, uint& layerNum,
91 bool print) {
92 if (parser1->isKeyword(0, "(setLayer")) {
93 if (print)
94 parser1->printWords(stdout);
95
96 layerNum = parser1->getInt(1);
97 return true;
98 } else if (parser1->isKeyword(0, "setLayer")) {
99 if (print)
100 parser1->printWords(stdout);
101
102 layerNum = parser1->getInt(1);
103 return true;
104 }
105 return false;
106 }
107 #ifdef OLD_READ_QCAP
108
readQcap(extMain * extMain,const char * filename,const char * design,const char * capFile,bool skipBterms,dbDatabase * db)109 int extMeasure::readQcap(extMain* extMain, const char* filename,
110 const char* design, const char* capFile,
111 bool skipBterms, dbDatabase* db) {
112 bool debug = false;
113
114 uint nm = 1000;
115
116 dbChip* chip = dbChip::create(db);
117 assert(chip);
118 _block = dbBlock::create(chip, design, '/');
119 assert(_block);
120 _block->setBusDelimeters('[', ']');
121 _block->setDefUnits(nm);
122
123 _extMain = extMain;
124 _extMain->_block = _block;
125 _create_net_util.setBlock(_block);
126
127 dbTech* tech = db->getTech();
128
129 uint netCnt = 0;
130 uint totWireCnt = 0;
131 bool layerSectionFlag = false;
132
133 Ath__parser parser1;
134 parser1.addSeparator("\r");
135 parser1.openFile((char*)filename);
136
137 Ath__parser parserWord;
138 parserWord.resetSeparator("=");
139
140 Ath__parser parserParen;
141 parserParen.resetSeparator("()");
142
143 Ath__parser ambersandParser;
144 ambersandParser.resetSeparator("&");
145
146 while (parser1.parseNextLine() > 0) {
147 if (parser1.isKeyword(0, "layer")) {
148 if (!layerSectionFlag) {
149 logger_->info(RCX, 481, "Reading layer section of file {}", filename);
150 layerSectionFlag = true;
151 }
152 char* layerName = parser1.get(1);
153
154 char* typeWord = parser1.get(4, "type=");
155 if (typeWord == NULL)
156 continue;
157 parserWord.mkWords(typeWord);
158 if (!parserWord.isKeyword(1, "interconnect"))
159 continue;
160
161 // parserWord.mkWords(parser1.get(4));
162 // uint s= parserWord.getDouble(1);
163
164 char* layerNumWord = parser1.get(4, "ID=");
165 if (layerNumWord == NULL)
166 continue;
167 parserWord.mkWords(layerNumWord);
168 uint layerNum = parserWord.getInt(1);
169
170 _idTable[layerNum] = 0; // reset mapping
171
172 if (debug)
173 parser1.printWords(stdout);
174
175 dbTechLayer* techLayer = tech->findLayer(layerName);
176 if (techLayer == NULL) {
177 logger_->warn(
178 RCX, 370, "Layer {} in line number {} in file {} has not beed defined in LEF file, will skip all attached geometries!",
179 layerName, parser1.getLineNum(), filename);
180 continue;
181 }
182
183 dbTechLayerType type = techLayer->getType();
184
185 if (type.getValue() != dbTechLayerType::ROUTING)
186 continue;
187
188 _idTable[layerNum] = techLayer->getRoutingLevel();
189
190 logger_->info(RCX, 368, "Read layer name {} with number {} that corresponds to routing level {}.",
191 layerName, layerNum, _idTable[layerNum]);
192
193 continue;
194 }
195 if (parser1.isKeyword(0, "net")) {
196 char netName[256];
197 strcpy(netName, parser1.get(1));
198
199 char mainNetName[256];
200 bool subNetFlag = false;
201 ambersandParser.mkWords(netName);
202 if (ambersandParser.getWordCnt() == 2) {
203 subNetFlag = true;
204 strcpy(mainNetName, ambersandParser.get(0));
205 }
206
207 if (debug)
208 parser1.printWords(stdout);
209
210 netCnt++;
211
212 if (parser1.parseNextLine() > 0) {
213 uint layerNum = 0;
214 if (!parse_setLayer(&parser1, layerNum, debug))
215 continue; // empty nets, TODO warning
216
217 dbRtTree rtTree;
218 dbNet* net = NULL;
219
220 uint wireCnt = 0;
221 while (parser1.parseNextLine() > 0) {
222 if (parse_setLayer(&parser1, layerNum, debug))
223 continue;
224
225 _ll[0] = Ath__double2int(parser1.getDouble(0) * nm);
226 _ll[1] = Ath__double2int(parser1.getDouble(1) * nm);
227 _ur[0] = Ath__double2int(parser1.getDouble(2) * nm);
228
229 char* w3 = parser1.get(3);
230 parserParen.mkWords(w3);
231 _ur[1] = Ath__double2int(parserParen.getDouble(0) * nm);
232
233 if (debug)
234 parser1.printWords(stdout);
235
236 uint level = _idTable[layerNum];
237 if (level == 0) {
238 logger_->info(RCX, 366,
239 "Skipping net {}, layer num {} not defined in LEF",
240 netName, layerNum);
241 } else if (wireCnt == 0) {
242 dbNet* mainNet = NULL;
243 if (!subNetFlag) {
244 net = _create_net_util.createNetSingleWire(
245 netName, _ll[0], _ll[1], _ur[0], _ur[1], level);
246 } else {
247 mainNet = _block->findNet(mainNetName);
248 if (mainNet == NULL)
249 net = _create_net_util.createNetSingleWire(
250 mainNetName, _ll[0], _ll[1], _ur[0], _ur[1], level);
251 else
252 net = _create_net_util.createNetSingleWire(
253 netName, _ll[0], _ll[1], _ur[0], _ur[1], level,
254 true /*skipBterms*/);
255 }
256 dbShape s;
257 if ((net != NULL) && getFirstShape(net, s)) {
258 if (debug) {
259 logger_->info(RCX, 363, "\t\tCreated net {} : {} {} {} {}",
260 net->getConstName(), s.xMin(), s.yMin(), s.xMax(),
261 s.yMax());
262 }
263 if (!subNetFlag) {
264 dbWire* w1 = net->getWire();
265 rtTree.decode(w1);
266 } else {
267 if (mainNet != NULL) {
268 dbRtTree m;
269 m.decode(mainNet->getWire());
270 dbRtTree s;
271 s.decode(net->getWire());
272 m.move(&s);
273 m.encode(mainNet->getWire());
274 dbNet::destroy(net);
275 } else {
276 dbRtTree s;
277 s.decode(net->getWire());
278 s.encode(net->getWire());
279 }
280 }
281 }
282 } else if (wireCnt > 0) {
283 char buff[1024];
284 sprintf(buff, "%s__w%d_line%d", netName, wireCnt + 1,
285 parser1.getLineNum());
286
287 dbNet* net1 = _create_net_util.createNetSingleWire(
288 buff, _ll[0], _ll[1], _ur[0], _ur[1], level,
289 true /*skipBterms*/);
290
291 dbShape s;
292 if ((net1 != NULL) && getFirstShape(net1, s)) {
293 if (debug) {
294 logger_->info(RCX, 256, "\t\tCreated net {} : {} {} {} {}",
295 net1->getConstName(), s.xMin(), s.yMin(),
296 s.xMax(), s.yMax());
297 }
298
299 dbWire* wire = net1->getWire();
300 dbRtTree T;
301 T.decode(wire);
302 rtTree.move(&T);
303 dbNet::destroy(net1);
304 }
305 }
306 uint n = strlen(w3);
307 if (w3[n - 1] == ')') {
308 if ((wireCnt > 0) && !subNetFlag) {
309 rtTree.encode(net->getWire());
310 }
311 totWireCnt += wireCnt + 1;
312 if (netCnt % 1000 == 0)
313 logger_->info(RCX, 361, "Have read {} nets and {} wires", netCnt,
314 totWireCnt);
315
316 break;
317 }
318
319 wireCnt++;
320 }
321 continue;
322 }
323 }
324 }
325 if (netCnt > 0) {
326 dbBox* bb = _block->getBBox();
327 Rect r(bb->xMin(), bb->yMin(), bb->xMax(), bb->yMax());
328 _block->setDieArea(r);
329
330 logger_->info(RCX, 51, "Have read {} nets from file {}", netCnt, filename);
331 } else {
332 logger_->warn(RCX, 70, "No nets were read from file {}", filename);
333 }
334 uint ccCnt = 0;
335 int gndCnt = 0;
336 if (capFile != NULL) {
337 _extMain->_noModelRC = true;
338 _extMain->_cornerCnt = 1;
339 _extMain->_extDbCnt = 1;
340 _block->setCornerCount(_extMain->_cornerCnt);
341 _extMain->setupMapping(0);
342
343 dbSet<dbNet> nets = _block->getNets();
344 dbSet<dbNet>::iterator net_itr;
345 dbNet* net;
346 for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
347 net = *net_itr;
348 _extMain->makeNetRCsegs(net);
349 }
350 gndCnt = readCapFile(capFile, ccCnt);
351 }
352 logger_->info(RCX, 360, "Have created {} gnd caps and {} cc caps", gndCnt,
353 ccCnt);
354
355 return netCnt;
356 }
357 #endif
createSingleWireNet(char * name,uint level,bool viaFlag,bool debug,bool skipVias,bool skipBterms)358 dbNet* extMeasure::createSingleWireNet(char* name, uint level, bool viaFlag,
359 bool debug, bool skipVias,
360 bool skipBterms) {
361 if (viaFlag) {
362 if (skipVias)
363 return NULL;
364 return NULL;
365 }
366 // wire
367
368 dbNet* net = _create_net_util.createNetSingleWire(
369 name, _ll[0], _ll[1], _ur[0], _ur[1], level, skipBterms);
370
371 dbShape s;
372 if ((net == NULL) || !getFirstShape(net, s)) {
373 logger_->warn(RCX, 462, "\t\tCannot create wire: {} {} {} {} for name {}",
374 s.xMin(), s.yMin(), s.xMax(), s.yMax(), name);
375 return NULL;
376 }
377 if (debug) {
378 logger_->info(RCX, 371, "\t\tCreated net {} : {} {} {} {}",
379 net->getConstName(), s.xMin(), s.yMin(), s.xMax(), s.yMax());
380 }
381 return net;
382 }
383
readQcap(extMain * extMain,const char * filename,const char * design,const char * capFile,bool skipBterms,dbDatabase * db)384 int extMeasure::readQcap(extMain* extMain, const char* filename,
385 const char* design, const char* capFile,
386 bool skipBterms, dbDatabase* db) {
387 bool skipVias = true;
388 bool debug = false;
389
390 uint nm = 1000;
391
392 dbChip* chip = dbChip::create(db);
393 assert(chip);
394 _block = dbBlock::create(chip, design, '/');
395 assert(_block);
396 _block->setBusDelimeters('[', ']');
397 _block->setDefUnits(nm);
398
399 _extMain = extMain;
400 _extMain->_block = _block;
401 _create_net_util.setBlock(_block);
402
403 dbTech* tech = db->getTech();
404
405 bool viaTable[1000];
406 int loHeightTable[1000];
407 int hiHeightTable[1000];
408 for (uint ii = 0; ii < 1000; ii++) {
409 loHeightTable[ii] = 0;
410 hiHeightTable[ii] = 0;
411 viaTable[ii] = false;
412 }
413
414 uint netCnt = 0;
415 uint totWireCnt = 0;
416 bool layerSectionFlag = false;
417
418 Ath__parser parser1;
419 parser1.addSeparator("\r");
420 parser1.openFile((char*)filename);
421
422 Ath__parser parserWord;
423 parserWord.resetSeparator("=");
424
425 Ath__parser parserParen;
426 parserParen.resetSeparator("()");
427
428 Ath__parser ambersandParser;
429 ambersandParser.resetSeparator("&");
430
431 while (parser1.parseNextLine() > 0) {
432 if (parser1.isKeyword(0, "layer")) {
433 if (!layerSectionFlag) {
434 logger_->info(RCX, 63, "Reading layer section of file {}", filename);
435 layerSectionFlag = true;
436 }
437 char* layerName = parser1.get(1);
438
439 char* typeWord = parser1.get(4, "type=");
440 if (typeWord == NULL)
441 continue;
442
443 bool viaFlag = false;
444 bool intercoonetFlag = false;
445
446 parserWord.mkWords(typeWord);
447 if (parserWord.isKeyword(1, "interconnect")) {
448 intercoonetFlag = true;
449 } else if (parserWord.isKeyword(1, "via")) {
450 viaFlag = true;
451 }
452 char* layerNumWord = parser1.get(4, "ID=");
453
454 if (layerNumWord == NULL) {
455 logger_->warn(RCX, 461,
456 "Cannot read layer number for layer name {} at line: {}",
457 layerName, parser1.getLineNum());
458 continue;
459 }
460 parserWord.mkWords(layerNumWord);
461 uint layerNum = parserWord.getInt(1);
462
463 _idTable[layerNum] = 0; // reset mapping
464
465 if (debug)
466 parser1.printWords(stdout);
467
468 int n1 = parser1.getInt(2, 1);
469 int n2 = parser1.getInt(3, 1);
470
471 if (intercoonetFlag) {
472 dbTechLayer* techLayer = tech->findLayer(layerName);
473 if (techLayer == NULL) {
474 logger_->warn(
475 RCX, 372,
476 "Layer {} in line number {} in file {} has not beed defined in "
477 "LEF file, will skip all attached geometries",
478 layerName, parser1.getLineNum(), filename);
479 continue;
480 }
481
482 dbTechLayerType type = techLayer->getType();
483
484 if (type.getValue() != dbTechLayerType::ROUTING)
485 continue;
486
487 _idTable[layerNum] = techLayer->getRoutingLevel();
488
489 logger_->info(RCX, 367,
490 "Read layer name {} with number {} that corresponds to "
491 "routing level {}",
492 layerName, layerNum, _idTable[layerNum]);
493
494 loHeightTable[n1] = layerNum;
495 hiHeightTable[n2] = layerNum;
496 } else if (viaFlag) {
497 int topLayer = loHeightTable[n2];
498 int level1 = _idTable[topLayer];
499
500 if (level1 > 0) {
501 int botLayer = hiHeightTable[n1];
502 int level2 = _idTable[botLayer];
503
504 if (level2 > 0) {
505 _idTable[layerNum] = level2;
506 viaTable[layerNum] = true;
507 }
508 }
509 }
510 continue;
511 }
512 if (parser1.isKeyword(0, "net")) {
513 char netName[256];
514 strcpy(netName, parser1.get(1));
515
516 char mainNetName[256];
517 bool subNetFlag = false;
518 ambersandParser.mkWords(netName);
519 if (ambersandParser.getWordCnt() == 2) {
520 subNetFlag = true;
521 strcpy(mainNetName, ambersandParser.get(0));
522 }
523
524 if (debug)
525 parser1.printWords(stdout);
526
527 netCnt++;
528
529 if (parser1.parseNextLine() > 0) {
530 uint layerNum = 0;
531 if (!parse_setLayer(&parser1, layerNum, debug))
532 continue; // empty nets, TODO warning
533
534 dbRtTree rtTree;
535 dbNet* net = NULL;
536
537 uint wireCnt = 0;
538 while (parser1.parseNextLine() > 0) {
539 if (parse_setLayer(&parser1, layerNum, debug))
540 continue;
541
542 _ll[0] = Ath__double2int(parser1.getDouble(0) * nm);
543 _ll[1] = Ath__double2int(parser1.getDouble(1) * nm);
544 _ur[0] = Ath__double2int(parser1.getDouble(2) * nm);
545
546 char* w3 = parser1.get(3);
547 parserParen.mkWords(w3);
548 _ur[1] = Ath__double2int(parserParen.getDouble(0) * nm);
549
550 if (debug)
551 parser1.printWords(stdout);
552
553 uint level = _idTable[layerNum];
554 if (level == 0) {
555 logger_->info(RCX, 365,
556 "Skipping net {}, layer num {} not defined in LEF",
557 netName, layerNum);
558 } else if (wireCnt == 0) {
559 dbNet* mainNet = NULL;
560
561 if (!subNetFlag) {
562 // net= _create_net_util.createNetSingleWire(netName, _ll[0],
563 // _ll[1], _ur[0], _ur[1], level);
564 net = createSingleWireNet(netName, level, viaTable[layerNum],
565 debug, skipVias);
566 if (net != NULL) {
567 dbWire* w1 = net->getWire();
568 rtTree.decode(w1);
569 }
570 } else {
571 mainNet = _block->findNet(mainNetName);
572 if (mainNet == NULL) {
573 // net= _create_net_util.createNetSingleWire(mainNetName,
574 // _ll[0], _ll[1], _ur[0], _ur[1], level);
575 net = createSingleWireNet(mainNetName, level,
576 viaTable[layerNum], debug, skipVias);
577
578 if (net != NULL) {
579 dbRtTree s;
580 s.decode(net->getWire());
581 s.encode(net->getWire());
582 }
583 } else {
584 // net= _create_net_util.createNetSingleWire(netName, _ll[0],
585 // _ll[1], _ur[0], _ur[1], level, true/*skipBterms*/);
586 net = createSingleWireNet(netName, level, viaTable[layerNum],
587 debug, skipVias, true /*skipBterms*/);
588 if (net != NULL) {
589 dbRtTree m;
590 m.decode(mainNet->getWire());
591 dbRtTree s;
592 s.decode(net->getWire());
593 m.move(&s);
594 m.encode(mainNet->getWire());
595 dbNet::destroy(net);
596 }
597 }
598 }
599 /*
600 if (net!=NULL) {
601 if (!subNetFlag) {
602 dbWire *w1= net->getWire();
603 rtTree.decode(w1);
604 }
605 else {
606 if (mainNet!=NULL) {
607 dbRtTree m;
608 m.decode(mainNet->getWire());
609 dbRtTree s;
610 s.decode(net->getWire());
611 m.move(&s);
612 m.encode(mainNet->getWire());
613 dbNet::destroy(net);
614 }
615 else {
616 dbRtTree s;
617 s.decode(net->getWire());
618 s.encode(net->getWire());
619 }
620 }
621 }
622 */
623 } else if (wireCnt > 0) {
624 char buff[1024];
625 sprintf(buff, "%s__w%d_line%d", netName, wireCnt + 1,
626 parser1.getLineNum());
627
628 dbNet* net1 =
629 createSingleWireNet(buff, level, viaTable[layerNum], debug,
630 skipVias, true /*skipBterms*/);
631 // dbNet *net1= _create_net_util.createNetSingleWire(buff,
632 // _ll[0], _ll[1], _ur[0], _ur[1], level, true/*skipBterms*/);
633
634 if (net1 != NULL) {
635 dbWire* wire = net1->getWire();
636 dbRtTree T;
637 T.decode(wire);
638 rtTree.move(&T);
639 dbNet::destroy(net1);
640 }
641 }
642 uint n = strlen(w3);
643 if (w3[n - 1] == ')') {
644 if ((wireCnt > 0) && !subNetFlag) {
645 rtTree.encode(net->getWire());
646 }
647 totWireCnt += wireCnt + 1;
648 if (netCnt % 1000 == 0)
649 logger_->info(RCX, 362, "Have read {} nets and {} wires", netCnt,
650 totWireCnt);
651
652 break;
653 }
654
655 wireCnt++;
656 }
657 continue;
658 }
659 }
660 }
661 if (netCnt > 0) {
662 dbBox* bb = _block->getBBox();
663 Rect r(bb->xMin(), bb->yMin(), bb->xMax(), bb->yMax());
664 _block->setDieArea(r);
665
666 logger_->info(RCX, 53, "Have read {} nets from file {}", netCnt, filename);
667 } else {
668 logger_->warn(RCX, 56, "No nets were read from file {}", filename);
669 }
670 uint ccCnt = 0;
671 int gndCnt = 0;
672 if (capFile != NULL) {
673 _extMain->_noModelRC = true;
674 _extMain->_cornerCnt = 1;
675 _extMain->_extDbCnt = 1;
676 _block->setCornerCount(_extMain->_cornerCnt);
677 _extMain->setupMapping(0);
678
679 dbSet<dbNet> nets = _block->getNets();
680 dbSet<dbNet>::iterator net_itr;
681 dbNet* net;
682 for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
683 net = *net_itr;
684 _extMain->makeNetRCsegs(net);
685 }
686 gndCnt = readCapFile(capFile, ccCnt);
687 }
688 logger_->info(RCX, 71, "Have created {} gnd caps and {} cc caps", gndCnt,
689 ccCnt);
690
691 return netCnt;
692 }
readAB(extMain * extMain,const char * filename,const char * design,const char * capFile,bool skipBterms,dbDatabase * db)693 int extMeasure::readAB(extMain* extMain, const char* filename,
694 const char* design, const char* capFile, bool skipBterms,
695 dbDatabase* db) {
696 bool skipVias = true;
697 bool debug = false;
698
699 uint nm = 1000;
700
701 dbChip* chip = dbChip::create(db);
702 assert(chip);
703 _block = dbBlock::create(chip, design, '/');
704 assert(_block);
705 _block->setBusDelimeters('[', ']');
706 _block->setDefUnits(nm);
707
708 _extMain = extMain;
709 _extMain->_block = _block;
710 _create_net_util.setBlock(_block);
711
712 dbTech* tech = db->getTech();
713
714 uint netCnt = 0;
715
716 Ath__parser parser1;
717 parser1.openFile((char*)filename);
718 while (parser1.parseNextLine() > 0) {
719 netCnt++;
720 char* layerName = parser1.get(1);
721 dbTechLayer* techLayer = tech->findLayer(layerName);
722 if (techLayer == NULL) {
723 logger_->warn(
724 RCX, 369,
725 "Layer {} in line number {} in file {} has not beed defined "
726 "in LEF file, will skip all attached geometries",
727 layerName, parser1.getLineNum(), filename);
728 continue;
729 }
730 dbTechLayerType type = techLayer->getType();
731 if (type.getValue() != dbTechLayerType::ROUTING)
732 continue;
733
734 char netName[256];
735 strcpy(netName, parser1.get(0));
736
737 _ll[0] = Ath__double2int(parser1.getDouble(2) * nm);
738 _ll[1] = Ath__double2int(parser1.getDouble(3) * nm);
739 _ur[0] = Ath__double2int(parser1.getDouble(4) * nm);
740 _ur[1] = Ath__double2int(parser1.getDouble(5) * nm);
741
742 uint level = techLayer->getRoutingLevel();
743 dbNet* net =
744 createSingleWireNet(netName, level, false, debug, skipVias, true);
745
746 if (parser1.getWordCnt() > 6)
747 net->setSigType(dbSigType::ANALOG);
748
749 if (netCnt % 10000 == 0)
750 logger_->info(RCX, 68, "Have read {} nets ", netCnt);
751 }
752 if (netCnt > 0) {
753 dbBox* bb = _block->getBBox();
754 Rect r(bb->xMin(), bb->yMin(), bb->xMax(), bb->yMax());
755 _block->setDieArea(r);
756
757 logger_->info(RCX, 54, "Have read {} nets from file {}", netCnt, filename);
758 } else {
759 logger_->warn(RCX, 482, "No nets were read from file {}", filename);
760 }
761 uint ccCnt = 0;
762 int gndCnt = 0;
763 if (capFile != NULL) {
764 _extMain->_noModelRC = true;
765 _extMain->_cornerCnt = 1;
766 _extMain->_extDbCnt = 1;
767 _block->setCornerCount(_extMain->_cornerCnt);
768 _extMain->setupMapping(0);
769
770 dbSet<dbNet> nets = _block->getNets();
771 dbSet<dbNet>::iterator net_itr;
772 dbNet* net;
773 for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
774 net = *net_itr;
775 _extMain->makeNetRCsegs(net);
776 }
777 gndCnt = readCapFile(capFile, ccCnt);
778 }
779 logger_->info(RCX, 359, "Have created {} gnd caps and {} cc caps", gndCnt,
780 ccCnt);
781
782 return netCnt;
783 }
784
getRseg(const char * netname,const char * capMsg,const char * tableEntryName)785 dbRSeg* extMeasure::getRseg(const char* netname, const char* capMsg,
786 const char* tableEntryName) {
787 dbNet* net = _block->findNet(netname);
788 if (net == NULL) {
789 logger_->warn(RCX, 74, "Cannot find net {} from the {} table entry {}",
790 netname, capMsg, tableEntryName);
791 return NULL;
792 }
793 dbRSeg* r = getFirstDbRseg(net->getId());
794 if (r == NULL) {
795 logger_->warn(RCX, 460,
796 "Cannot find dbRseg for net {} from the {} table entry {}",
797 netname, capMsg, tableEntryName);
798 }
799 return r;
800 }
readCapFile(const char * filename,uint & ccCnt)801 int extMeasure::readCapFile(const char* filename, uint& ccCnt) {
802 uint totCnt = 0;
803 double units = 1.0;
804 Ath__parser parser;
805 parser.openFile((char*)filename);
806 parser.resetSeparator(" \t\n\r");
807
808 Ath__parser parserWord;
809 parserWord.resetSeparator("-");
810
811 bool totalFlag = false;
812 bool ccFlag = false;
813 while (parser.parseNextLine() > 0) {
814 parser.printWords(stdout);
815 if (parser.isKeyword(0, "[pF]")) {
816 units = 1000.0;
817 continue;
818 }
819 if ((parser.isKeyword(0, "Cross-coupled")) ||
820 (parser.isKeyword(0, "Cross-Coupled"))) {
821 totalFlag = false;
822 ccFlag = true;
823 continue;
824 }
825 if (parser.isKeyword(0, "Total") || parser.isKeyword(1, "total")) {
826 totalFlag = true;
827 ccFlag = false;
828 continue;
829 }
830 if (!((totalFlag || ccFlag) && (parser.getWordCnt() >= 4)))
831 continue;
832
833 uint indexCapword = 1;
834 if (parser.getWordCnt() > 4)
835 indexCapword = 2;
836 double cap = parser.getDouble(indexCapword) * units;
837
838 char* netname = parser.get(0);
839 char bufNetName[512];
840 strcpy(bufNetName, netname);
841
842 if (ccFlag) { // coupling cap
843 parserWord.mkWords(netname);
844 char* netname1 = parserWord.get(0);
845 char* netname2 = parserWord.get(1);
846
847 dbRSeg* rseg1 = getRseg(netname1, "Cross-Coupled", bufNetName);
848 if (rseg1 == NULL)
849 continue;
850 dbRSeg* rseg2 = getRseg(netname2, "Cross-Coupled", bufNetName);
851 if (rseg2 == NULL)
852 continue;
853
854 dbCCSeg* ccap = dbCCSeg::create(
855 dbCapNode::getCapNode(_block, rseg1->getTargetNode()),
856 dbCapNode::getCapNode(_block, rseg2->getTargetNode()), true);
857 ccap->addCapacitance(cap);
858
859 logger_->info(RCX, 453, "Created coupling Cap {} for nets {} and {}", cap,
860 netname1, netname2);
861
862 ccCnt++;
863 } else if (totalFlag) { // total cap
864 dbRSeg* rseg1 = getRseg(netname, "Total", netname);
865 if (rseg1 == NULL)
866 continue;
867
868 rseg1->setCapacitance(cap);
869
870 logger_->info(RCX, 257, "Created gnd Cap {} for net {}", cap, netname);
871
872 totCnt++;
873 }
874 continue;
875 }
876 dbSet<dbNet> nets = _block->getNets();
877 dbSet<dbNet>::iterator net_itr;
878 dbNet* net;
879 for (net_itr = nets.begin(); net_itr != nets.end(); ++net_itr) {
880 net = *net_itr;
881
882 dbRSeg* r = getFirstDbRseg(net->getId());
883 if (r == NULL)
884 continue;
885
886 double totCap = r->getCapacitance();
887 double totCC = net->getTotalCouplingCap();
888 r->setCapacitance(totCap - totCC);
889 }
890
891 return totCnt;
892 }
getMinWidth(dbTech * tech)893 void extMeasure::getMinWidth(dbTech* tech) {
894 dbSet<dbTechLayer> layers = tech->getLayers();
895 dbSet<dbTechLayer>::iterator litr;
896 dbTechLayer* layer;
897 for (litr = layers.begin(); litr != layers.end(); ++litr) {
898 layer = *litr;
899 if (layer->getType() != dbTechLayerType::ROUTING)
900 continue;
901
902 uint level = layer->getRoutingLevel();
903 uint pitch = layer->getPitch();
904 uint minWidth = layer->getWidth();
905 // uint minSpacing= layer->getSpacing();
906 //_minSpaceTable[level]= minSpacing;
907 _minSpaceTable[level] = pitch - minWidth;
908 }
909 }
updateBox(uint w_layout,uint s_layout,int dir)910 void extMeasure::updateBox(uint w_layout, uint s_layout, int dir) {
911 uint d = _dir;
912 if (dir >= 0)
913 d = dir;
914
915 _ll[d] = _ur[d] + s_layout;
916 _ur[d] = _ll[d] + w_layout;
917
918 // printBox(stdout);
919 }
createNetSingleWire(char * dirName,uint idCnt,uint w_layout,uint s_layout,int dir)920 uint extMeasure::createNetSingleWire(char* dirName, uint idCnt, uint w_layout,
921 uint s_layout, int dir) {
922 if (w_layout == 0) {
923 dbTechLayer* layer = _create_net_util.getRoutingLayer()[_met];
924 w_layout = layer->getWidth();
925 }
926 if (s_layout == 0) {
927 uint d = _dir;
928 if (dir >= 0)
929 d = dir;
930 _ur[d] = _ll[d] + w_layout;
931 } else {
932 updateBox(w_layout, s_layout, dir);
933 }
934
935 // uint w2= w_layout/2;
936 int ll[2];
937 int ur[2];
938 ll[0] = _ll[0];
939 ll[1] = _ll[1];
940 ur[0] = _ur[0];
941 ur[1] = _ur[1];
942
943 /*
944 if (_dir)
945 ll[0] -=w2;
946 else
947 ll[1] -=w2;
948 */
949
950 // ur[!_dir] = ur[!_dir] + _minWidth - w_layout;
951 ur[!_dir] = ur[!_dir] - w_layout / 2;
952 ll[!_dir] = ll[!_dir] + w_layout / 2;
953
954 // updateBox(w_layout, s_layout, dir);
955 char left, right;
956 _block->getBusDelimeters(left, right);
957
958 char netName[1024];
959 sprintf(netName, "%s%c%d%c", dirName, left, idCnt, right);
960 if (_skip_delims)
961 sprintf(netName, "%s_%d", dirName, idCnt);
962
963 assert(_create_net_util.getBlock() == _block);
964 dbNet* net = _create_net_util.createNetSingleWire(netName, ll[0], ll[1],
965 ur[0], ur[1], _met);
966
967 dbBTerm* in1 = net->get1stBTerm();
968 if (in1 != NULL) {
969 in1->rename(net->getConstName());
970 // fprintf(stdout, "M%d %8d %8d %8d %8d DX=%d DY=%d %s\n",
971 // _met, ll[0], ll[1], ur[0], ur[1], ur[0]-ll[0], ur[1]-ll[1], netName);
972 }
973
974 uint netId = net->getId();
975 addNew2dBox(net, ll, ur, _met, _dir, netId, false);
976
977 _extMain->makeNetRCsegs(net);
978
979 return netId;
980 }
createNetSingleWire_cntx(int met,char * dirName,uint idCnt,int d,int ll[2],int ur[2],int s_layout)981 uint extMeasure::createNetSingleWire_cntx(int met, char* dirName, uint idCnt,
982 int d, int ll[2], int ur[2],
983 int s_layout) {
984 char netName[1024];
985
986 sprintf(netName, "%s_cntxM%d_%d", dirName, met, idCnt);
987
988 assert(_create_net_util.getBlock() == _block);
989 dbNet* net = _create_net_util.createNetSingleWire(netName, ll[0], ll[1],
990 ur[0], ur[1], met);
991 dbBTerm* in1 = net->get1stBTerm();
992 if (in1 != NULL) {
993 in1->rename(net->getConstName());
994 }
995 _extMain->makeNetRCsegs(net);
996
997 return net->getId();
998 }
createDiagNetSingleWire(char * dirName,uint idCnt,int begin,int w_layout,int s_layout,int dir)999 uint extMeasure::createDiagNetSingleWire(char* dirName, uint idCnt, int begin,
1000 int w_layout, int s_layout, int dir) {
1001 int ll[2], ur[2];
1002 ll[!_dir] = _ll[!_dir];
1003 ll[_dir] = begin;
1004 ur[!_dir] = _ur[!_dir];
1005 ur[_dir] = begin + w_layout;
1006
1007 int met;
1008 if (_overMet > 0)
1009 met = _overMet;
1010 else if (_underMet > 0)
1011 met = _underMet;
1012
1013 char left, right;
1014 _block->getBusDelimeters(left, right);
1015
1016 char netName[1024];
1017 sprintf(netName, "%s%c%d%c", dirName, left, idCnt, right);
1018 if (_skip_delims)
1019 sprintf(netName, "%s_%d", dirName, idCnt);
1020
1021 assert(_create_net_util.getBlock() == _block);
1022 dbNet* net = _create_net_util.createNetSingleWire(netName, ll[0], ll[1],
1023 ur[0], ur[1], met);
1024 addNew2dBox(net, ll, ur, met, _dir, net->getId(), false);
1025
1026 _extMain->makeNetRCsegs(net);
1027
1028 return net->getId();
1029 }
addNew2dBox(dbNet * net,int * ll,int * ur,uint m,uint d,uint id,bool cntx)1030 ext2dBox* extMeasure::addNew2dBox(dbNet* net, int* ll, int* ur, uint m, uint d,
1031 uint id, bool cntx) {
1032 ext2dBox* bb = _2dBoxPool->alloc();
1033
1034 dbShape s;
1035 if ((net != NULL) && _extMain->getFirstShape(net, s)) {
1036 bb->_ll[0] = s.xMin();
1037 bb->_ll[1] = s.yMin();
1038 bb->_ur[0] = s.xMax();
1039 bb->_ur[1] = s.yMax();
1040 } else {
1041 bb->_ll[0] = ll[0];
1042 bb->_ll[1] = ll[1];
1043 bb->_ur[0] = ur[0];
1044 bb->_ur[1] = ur[1];
1045 }
1046
1047 bb->_met = m;
1048 bb->_dir = d;
1049 bb->_id = id;
1050 bb->_map = 0;
1051
1052 if (cntx) // context net
1053 _2dBoxTable[1][m].add(bb);
1054 else // main net
1055 _2dBoxTable[0][m].add(bb);
1056
1057 return bb;
1058 }
rotate()1059 void ext2dBox::rotate() {
1060 int x = _ur[0];
1061 _ur[0] = _ur[1];
1062 _ur[1] = x;
1063
1064 x = _ll[0];
1065 _ll[0] = _ll[1];
1066 _ll[1] = x;
1067 _dir = !_dir;
1068 }
length()1069 uint ext2dBox::length() {
1070 return _ur[_dir] - _ll[_dir]; // TEST !_dir
1071 // return _ur[!_dir] - _ll[!dir];
1072 }
width()1073 uint ext2dBox::width() {
1074 return _ur[!_dir] - _ll[!_dir]; // TEST _dir
1075 // return _ur[_dir] - _ll[_dir];
1076 }
loX()1077 int ext2dBox::loX() { return _ll[0]; }
loY()1078 int ext2dBox::loY() { return _ll[1]; }
id()1079 uint ext2dBox::id() { return _id; }
printGeoms3D(FILE * fp,double h,double t,int * orig)1080 void ext2dBox::printGeoms3D(FILE* fp, double h, double t, int* orig) {
1081 fprintf(fp,
1082 "%3d %8d -- M%d D%d %g %g %g %g L= %g W= %g H= %g TH= %g ORIG "
1083 "%g %g\n",
1084 _id, _map, _met, _dir, 0.001 * _ll[0], 0.001 * _ll[1], 0.001 * _ur[0],
1085 0.001 * _ur[1], 0.001 * length(), 0.001 * width(), h, t,
1086 0.001 * (_ll[0] - orig[0]), 0.001 * (_ll[1] - orig[1]));
1087 }
clean2dBoxTable(int met,bool cntx)1088 void extMeasure::clean2dBoxTable(int met, bool cntx) {
1089 if (met <= 0)
1090 return;
1091 for (uint ii = 0; ii < _2dBoxTable[cntx][met].getCnt(); ii++) {
1092 ext2dBox* bb = _2dBoxTable[cntx][met].get(ii);
1093 _2dBoxPool->free(bb);
1094 }
1095 _2dBoxTable[cntx][met].resetCnt();
1096 }
getBoxLength(uint ii,int met,bool cntx)1097 uint extMeasure::getBoxLength(uint ii, int met, bool cntx) {
1098 if (met <= 0)
1099 return 0;
1100
1101 int cnt = _2dBoxTable[cntx][met].getCnt();
1102 if (cnt <= 0)
1103 return 0;
1104
1105 ext2dBox* bb = _2dBoxTable[cntx][met].get(ii);
1106
1107 // return bb->length();
1108 return bb->width();
1109 }
getBox(int met,bool cntx,int & xlo,int & ylo,int & xhi,int & yhi)1110 void extMeasure::getBox(int met, bool cntx, int& xlo, int& ylo, int& xhi,
1111 int& yhi) {
1112 if (met <= 0)
1113 return;
1114
1115 int cnt = _2dBoxTable[cntx][met].getCnt();
1116 if (cnt <= 0)
1117 return;
1118
1119 ext2dBox* bbLo = _2dBoxTable[cntx][met].get(0);
1120 ext2dBox* bbHi = _2dBoxTable[cntx][met].get(cnt - 1);
1121
1122 xlo = MIN(bbLo->loX(), bbHi->loX());
1123 ylo = MIN(bbLo->loY(), bbHi->loY());
1124
1125 xhi = MAX(bbLo->_ur[0], bbHi->_ur[0]);
1126 yhi = MAX(bbLo->_ur[1], bbHi->_ur[1]);
1127 }
writeRaphaelPointXY(FILE * fp,double X,double Y)1128 void extMeasure::writeRaphaelPointXY(FILE* fp, double X, double Y) {
1129 fprintf(fp, " %6.3f,%6.3f ; ", X, Y);
1130 }
1131
writeBoxRaphael3D(FILE * fp,ext2dBox * bb,int * base_ll,int * base_ur,double y1,double th,double volt)1132 void extMeasure::writeBoxRaphael3D(FILE* fp, ext2dBox* bb, int* base_ll,
1133 int* base_ur, double y1, double th,
1134 double volt) {
1135 /* this function assumes the boxes bb, base_ll, and base_ur, are generated
1136 * from a vertical wire. Any box that is generated from a horizontal wire must
1137 * be rotat before passing into this function.
1138 */
1139
1140 double len = ((double)bb->length()) / 1000;
1141 double width = ((double)bb->width()) / 1000;
1142
1143 double middle = 0.001 * (base_ur[0] + base_ll[0]) * 0.5;
1144 double x;
1145 if (!bb->_dir) {
1146 x = len;
1147 len = width;
1148 width = x;
1149 }
1150 // double x=len*0.5;
1151 x = 0.001 * bb->_ll[0] - middle;
1152
1153 double l = 0.001 * (bb->_ll[1] - base_ll[1]);
1154
1155 /*
1156 if (!bb->_dir)
1157 l = ((double)(bb->loX() - x1))/1000;
1158 else
1159 l = ((double)(bb->loY() - x1))/1000;
1160 */
1161 fprintf(fp, "POLY3D NAME= M%d_RC_%d_w%d; ", bb->_met, bb->_map, bb->_id);
1162 fprintf(fp, " COORD= ");
1163 writeRaphaelPointXY(fp, x, y1);
1164 writeRaphaelPointXY(fp, x + width, y1);
1165 writeRaphaelPointXY(fp, x + width, y1 + th);
1166 writeRaphaelPointXY(fp, x, y1 + th);
1167
1168 fprintf(fp, " V1=0,0,%g; HEIGHT=%g;", l, len);
1169 fprintf(fp, " VOLT=%g ;\n", volt);
1170 }
writeRaphael3D(FILE * fp,int met,bool cntx,double x1,double y1,double th)1171 uint extMeasure::writeRaphael3D(FILE* fp, int met, bool cntx, double x1,
1172 double y1, double th) {
1173 if (met <= 0 || !_3dFlag)
1174 return 0;
1175
1176 uint cnt = 0;
1177 double l, width, len, x;
1178 for (uint ii = 0; ii < _2dBoxTable[cntx][met].getCnt(); ii++) {
1179 ext2dBox* bb = _2dBoxTable[cntx][met].get(ii);
1180 len = ((double)bb->length()) / 1000;
1181 width = ((double)bb->width()) / 1000;
1182 double tt;
1183 tt = len;
1184 len = width;
1185 width = tt;
1186 x = len * 0.5;
1187 if (!bb->_dir)
1188 l = ((double)(bb->loX() - x1)) / 1000;
1189 else
1190 l = ((double)(bb->loY() - x1)) / 1000;
1191
1192 fprintf(fp, "POLY3D NAME= M%d__w0; ", met);
1193 fprintf(fp, " COORD= ");
1194 writeRaphaelPointXY(fp, -x, y1);
1195 writeRaphaelPointXY(fp, x, y1);
1196 writeRaphaelPointXY(fp, x, y1 + th);
1197 writeRaphaelPointXY(fp, -x, y1 + th);
1198
1199 fprintf(fp, " V1=0,0,%g; HEIGHT=%g;", l, width);
1200 fprintf(fp, " VOLT=0 ;\n");
1201 cnt++;
1202 }
1203 return cnt;
1204 }
writeDiagRaphael3D(FILE * fp,int met,bool cntx,double x1,double y1,double th)1205 uint extMeasure::writeDiagRaphael3D(FILE* fp, int met, bool cntx, double x1,
1206 double y1, double th) {
1207 if (met <= 0 || !_3dFlag)
1208 return 0;
1209
1210 uint cnt = 0;
1211 double l, width, len;
1212 for (uint ii = 0; ii < _2dBoxTable[cntx][met].getCnt(); ii++) {
1213 ext2dBox* bb = _2dBoxTable[cntx][met].get(ii);
1214 width = ((double)bb->length()) / 1000;
1215 len = ((double)bb->width()) / 1000;
1216 if (!bb->_dir)
1217 l = ((double)(bb->loX() - x1)) / 1000;
1218 else
1219 l = ((double)(bb->loY() - x1)) / 1000;
1220
1221 fprintf(fp, "POLY3D NAME= M%d__w%d; ", met, bb->id());
1222 fprintf(fp, " COORD= ");
1223 writeRaphaelPointXY(fp, l, y1);
1224 writeRaphaelPointXY(fp, l + width, y1);
1225 writeRaphaelPointXY(fp, l + width, y1 + th);
1226 writeRaphaelPointXY(fp, l, y1 + th);
1227
1228 fprintf(fp, " V1=0,0,0; HEIGHT=%g;", len);
1229 fprintf(fp, " VOLT=0 ;\n");
1230 cnt++;
1231 }
1232 return cnt;
1233 }
createContextNets(char * dirName,int bboxLL[2],int bboxUR[2],int met,double pitchMult)1234 uint extMeasure::createContextNets(char* dirName, int bboxLL[2], int bboxUR[2],
1235 int met, double pitchMult) {
1236 if (met <= 0)
1237 return 0;
1238
1239 // char left, right;
1240 // _block->getBusDelimeters(left, right);
1241
1242 dbTechLayer* layer = _tech->findRoutingLayer(met);
1243 dbTechLayer* mlayer = _tech->findRoutingLayer(_met);
1244 uint minWidth = layer->getWidth();
1245 uint minSpace = layer->getSpacing();
1246 int pitch =
1247 Ath__double2int(1000 * ((minWidth + minSpace) * pitchMult) / 1000);
1248
1249 int ll[2];
1250 int ur[2];
1251
1252 uint offset = 0;
1253 /*
1254 if (met > _met)
1255 offset= _minWidth+_minSpace;
1256 else
1257 offset= 2*(minWidth+minSpace);
1258 */
1259 ll[_dir] = bboxLL[_dir] - offset;
1260 ur[_dir] = bboxUR[_dir] + offset;
1261
1262 _ur[_dir] = ur[_dir];
1263
1264 uint cnt = 1;
1265
1266 uint not_dir = !_dir;
1267 int start = bboxLL[not_dir] + offset;
1268 // int end= bboxUR[not_dir]-offset;
1269 int end = bboxUR[not_dir];
1270 for (int lenXY = (int)(start + minWidth); (int)(lenXY + minWidth) <= end;
1271 lenXY += pitch) {
1272 ll[not_dir] = lenXY;
1273 ur[not_dir] = lenXY + minWidth;
1274
1275 char netName[1024];
1276 // sprintf(netName, "%s_m%d_cntxt%c%d%c", dirName, met, left, cnt++, right);
1277 sprintf(netName, "%s_m%d_cntxt_%d", dirName, met, cnt++);
1278 dbNet* net;
1279 assert(_create_net_util.getBlock() == _block);
1280 if (mlayer->getDirection() != dbTechLayerDir::HORIZONTAL)
1281 net = _create_net_util.createNetSingleWire(
1282 netName, ll[0], ll[1], ur[0], ur[1], met, dbTechLayerDir::HORIZONTAL,
1283 false);
1284 else
1285 net = _create_net_util.createNetSingleWire(netName, ll[0], ll[1], ur[0],
1286 ur[1], met,
1287 mlayer->getDirection(), false);
1288 // net= _create_net_util.createNetSingleWire(netName, ll[0], ll[1],
1289 // ur[0], ur[1], met);
1290
1291 addNew2dBox(net, ll, ur, met, not_dir, net->getId(), true); // TEST not_dir
1292 }
1293 return cnt - 1;
1294 }
getFirstDbRseg(uint netId)1295 dbRSeg* extMeasure::getFirstDbRseg(uint netId) {
1296 dbNet* net = dbNet::getNet(_block, netId);
1297
1298 dbSet<dbRSeg> rSet = net->getRSegs();
1299 dbSet<dbRSeg>::iterator rc_itr;
1300
1301 // double cap= 0.0;
1302
1303 dbRSeg* rseg = NULL;
1304 for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
1305 rseg = *rc_itr;
1306 break;
1307 }
1308 // rseg->setCapacitance(tot);
1309
1310 return rseg;
1311 }
getCCfringe(uint lastNode,uint n,uint start,uint end)1312 double extMeasure::getCCfringe(uint lastNode, uint n, uint start, uint end) {
1313 double ccFr = 0.0;
1314 for (uint ii = start; ii <= end; ii++) {
1315 int d = n - ii;
1316 int u = n + ii;
1317
1318 if (n + ii > lastNode)
1319 break;
1320
1321 if (d > 0)
1322 ccFr += _capMatrix[d][n];
1323
1324 ccFr += _capMatrix[n][u];
1325 }
1326 return ccFr;
1327 }
getCCfringe3D(uint lastNode,uint n,uint start,uint end)1328 double extMeasure::getCCfringe3D(uint lastNode, uint n, uint start, uint end) {
1329 double ccFr = 0.0;
1330 uint End;
1331 if (_diag)
1332 End = lastNode - n;
1333 else
1334 End = end;
1335 for (uint ii = start; ii <= End; ii++) {
1336 int d = n - ii;
1337 uint u = n + ii;
1338 /*
1339 if (n+ii>lastNode)
1340 break;
1341 */
1342 if (d > 0)
1343 ccFr += _capMatrix[1][d];
1344 if (u <= lastNode)
1345 ccFr += _capMatrix[1][u];
1346 }
1347 return ccFr;
1348 }
printBox(FILE * fp)1349 void extMeasure::printBox(FILE* fp) {
1350 fprintf(fp, "( %8d %8d ) ( %8d %8d )\n", _ll[0], _ll[1], _ur[0], _ur[1]);
1351 }
initWS_box(extMainOptions * opt,uint gridCnt)1352 uint extMeasure::initWS_box(extMainOptions* opt, uint gridCnt) {
1353 dbTechLayer* layer = opt->_tech->findRoutingLayer(_met);
1354 _minWidth = layer->getWidth();
1355 _pitch = layer->getPitch();
1356 _minSpace = _pitch - _minWidth;
1357 _dir = layer->getDirection() == dbTechLayerDir::HORIZONTAL ? 1 : 0;
1358
1359 uint patternSep = gridCnt * (_minWidth + _minSpace);
1360
1361 _ll[0] = opt->_ur[0] + patternSep;
1362 _ll[1] = 0;
1363
1364 _ur[_dir] = _ll[_dir];
1365 // _ur[! _dir] = _ll[!_dir] + (opt->_len-_minWidth); // to agree with width
1366 // extension
1367 // DF 620 _ur[! _dir] = _ll[!_dir] + opt->_len;
1368 _ur[!_dir] =
1369 _ll[!_dir] + opt->_len * _minWidth / 1000; // _len is in nm per ext.ti
1370
1371 return patternSep;
1372 }
updateForBench(extMainOptions * opt,extMain * extMain)1373 void extMeasure::updateForBench(extMainOptions* opt, extMain* extMain) {
1374 _benchFlag = true;
1375 _len = opt->_len;
1376 _wireCnt = opt->_wireCnt;
1377 _block = opt->_block;
1378 _tech = opt->_tech;
1379 _extMain = extMain;
1380 _3dFlag = opt->_3dFlag;
1381 _create_net_util.setBlock(_block, false);
1382 _dbunit = _block->getDbUnitsPerMicron();
1383 }
defineBox(CoupleOptions & options)1384 uint extMeasure::defineBox(CoupleOptions& options) {
1385 _no_debug = false;
1386 _met = options[0];
1387
1388 _len = options[3];
1389 _dist = options[4];
1390 _s_nm = options[4];
1391
1392 int xy = options[5];
1393 _dir = options[6];
1394
1395 _width = options[7];
1396 _w_nm = options[7];
1397 /*
1398 if (_dist>0) {
1399 if (options[8]>_width) {
1400 _width= options[8];
1401 _w_nm= options[8];
1402 }
1403 // _width= (options[7]+options[8])/2;
1404 // _w_nm= (options[7]+options[8])/2;rm O
1405 }
1406 */
1407 int base = options[9];
1408 // _dir= 1 horizontal
1409 // _dir= 0 vertical
1410
1411 if (_dir == 0) {
1412 _ll[1] = xy;
1413 _ll[0] = base;
1414 _ur[1] = xy + _len;
1415 _ur[0] = base + _width;
1416 } else {
1417 _ll[0] = xy;
1418 _ll[1] = base;
1419 _ur[0] = xy + _len;
1420 _ur[1] = base + _width;
1421 }
1422 for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
1423 _rc[ii]->_coupling = 0.0;
1424 _rc[ii]->_fringe = 0.0;
1425 _rc[ii]->_diag = 0.0;
1426 _rc[ii]->_res = 0.0;
1427 _rc[ii]->_sep = 0;
1428 }
1429 dbTechLayer* layer = _extMain->_tech->findRoutingLayer(_met);
1430 _minWidth = layer->getWidth();
1431 #ifdef HI_ACC_1
1432 _toHi = (options[11] > 0) ? true : false;
1433 #else
1434 _toHi = true;
1435 #endif
1436
1437 return _len;
1438 }
tableCopyP(Ath__array1D<int> * src,Ath__array1D<int> * dst)1439 void extMeasure::tableCopyP(Ath__array1D<int>* src, Ath__array1D<int>* dst) {
1440 for (uint ii = 0; ii < src->getCnt(); ii++)
1441 dst->add(src->get(ii));
1442 }
1443
tableCopyP(Ath__array1D<SEQ * > * src,Ath__array1D<SEQ * > * dst)1444 void extMeasure::tableCopyP(Ath__array1D<SEQ*>* src, Ath__array1D<SEQ*>* dst) {
1445 for (uint ii = 0; ii < src->getCnt(); ii++)
1446 dst->add(src->get(ii));
1447 }
tableCopy(Ath__array1D<SEQ * > * src,Ath__array1D<SEQ * > * dst,gs * pixelTable)1448 void extMeasure::tableCopy(Ath__array1D<SEQ*>* src, Ath__array1D<SEQ*>* dst,
1449 gs* pixelTable) {
1450 for (uint ii = 0; ii < src->getCnt(); ii++)
1451 copySeq(src->get(ii), dst, pixelTable);
1452 }
release(Ath__array1D<SEQ * > * seqTable,gs * pixelTable)1453 void extMeasure::release(Ath__array1D<SEQ*>* seqTable, gs* pixelTable) {
1454 if (pixelTable == NULL)
1455 pixelTable = _pixelTable;
1456
1457 for (uint ii = 0; ii < seqTable->getCnt(); ii++)
1458 pixelTable->release(seqTable->get(ii));
1459
1460 seqTable->resetCnt();
1461 }
1462 /* DF 720
1463 int extMeasure::calcDist(int *ll, int *ur)
1464 {
1465 int d= ((_ur[_dir]+_ll[_dir]) - (ur[_dir]+ll[_dir]))/2;
1466 return d>=0 ? d : -d;
1467 } */
calcDist(int * ll,int * ur)1468 int extMeasure::calcDist(int* ll, int* ur) {
1469 int d = ll[_dir] - _ur[_dir];
1470 if (d >= 0)
1471 return d;
1472
1473 d = _ll[_dir] - ur[_dir];
1474 if (d >= 0)
1475 return d;
1476 /*
1477 d= ll[_dir] - _ll[_dir];
1478 if (d>0)
1479 return d;
1480
1481 d = _ll[_dir] - ll[_dir];
1482 if (d>0)
1483 return d;
1484 */
1485 return 0;
1486 }
addSeq(int * ll,int * ur)1487 SEQ* extMeasure::addSeq(int* ll, int* ur) {
1488 SEQ* s = _pixelTable->salloc();
1489 for (uint ii = 0; ii < 2; ii++) {
1490 s->_ll[ii] = ll[ii];
1491 s->_ur[ii] = ur[ii];
1492 }
1493 s->type = 0;
1494 return s;
1495 }
addSeq(int * ll,int * ur,Ath__array1D<SEQ * > * seqTable,gs * pixelTable)1496 void extMeasure::addSeq(int* ll, int* ur, Ath__array1D<SEQ*>* seqTable,
1497 gs* pixelTable) {
1498 if (pixelTable == NULL)
1499 pixelTable = _pixelTable;
1500
1501 SEQ* s = pixelTable->salloc();
1502 for (uint ii = 0; ii < 2; ii++) {
1503 s->_ll[ii] = ll[ii];
1504 s->_ur[ii] = ur[ii];
1505 }
1506 s->type = 0;
1507 if (seqTable != NULL)
1508 seqTable->add(s);
1509 }
addSeq(Ath__array1D<SEQ * > * seqTable,gs * pixelTable)1510 void extMeasure::addSeq(Ath__array1D<SEQ*>* seqTable, gs* pixelTable) {
1511 SEQ* s = pixelTable->salloc();
1512 for (uint ii = 0; ii < 2; ii++) {
1513 s->_ll[ii] = _ll[ii];
1514 s->_ur[ii] = _ur[ii];
1515 }
1516 s->type = 0;
1517
1518 seqTable->add(s);
1519 }
1520
copySeq(SEQ * t,Ath__array1D<SEQ * > * seqTable,gs * pixelTable)1521 void extMeasure::copySeq(SEQ* t, Ath__array1D<SEQ*>* seqTable, gs* pixelTable) {
1522 SEQ* s = pixelTable->salloc();
1523 for (uint ii = 0; ii < 2; ii++) {
1524 s->_ll[ii] = t->_ll[ii];
1525 s->_ur[ii] = t->_ur[ii];
1526 }
1527 s->type = t->type;
1528
1529 seqTable->add(s);
1530 }
copySeqUsingPool(SEQ * t,Ath__array1D<SEQ * > * seqTable)1531 void extMeasure::copySeqUsingPool(SEQ* t, Ath__array1D<SEQ*>* seqTable) {
1532 SEQ* s = _seqPool->alloc();
1533 for (uint ii = 0; ii < 2; ii++) {
1534 s->_ll[ii] = t->_ll[ii];
1535 s->_ur[ii] = t->_ur[ii];
1536 }
1537 s->type = t->type;
1538
1539 seqTable->add(s);
1540 }
1541
getOverUnderIndex()1542 uint extMeasure::getOverUnderIndex() // TO_TEST
1543 {
1544 int n = _layerCnt - _met - 1;
1545 n *= _underMet - 1;
1546 n += _overMet - _met - 1;
1547
1548 if ((n < 0) || (n >= (int)_layerCnt + 1)) {
1549 /*
1550 fprintf(stdout, "getOverUnderIndex: out of range n= %d m=%d
1551 u= %d o= %d\n", n, _met, _underMet, _overMet);
1552 */
1553 logger_->info(RCX, 459,
1554 "getOverUnderIndex: out of range n= {} m={} u= {} o= {}", n,
1555 _met, _underMet, _overMet);
1556 }
1557
1558 return n;
1559 }
getFringe(uint len,double * valTable)1560 extDistRC* extMeasure::getFringe(uint len, double* valTable) {
1561 // m._met= met;
1562 // m._width= width;
1563 // m._underMet= 0;
1564
1565 extDistRC* rcUnit = NULL;
1566
1567 for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
1568 extMetRCTable* rcModel = _metRCTable.get(ii);
1569
1570 rcUnit = rcModel->getOverFringeRC(this);
1571
1572 if (rcUnit == NULL)
1573 continue;
1574
1575 valTable[ii] = rcUnit->getFringe() * len;
1576 }
1577 return rcUnit;
1578 }
addOverOrUnderLen(int met,bool over,uint len)1579 void extLenOU::addOverOrUnderLen(int met, bool over, uint len) {
1580 _overUnder = false;
1581 _under = false;
1582 if (over) {
1583 _overMet = -1;
1584 _underMet = met;
1585 _over = true;
1586 } else {
1587 _overMet = met;
1588 _underMet = -1;
1589 _over = false;
1590 _under = true;
1591 }
1592 _len = len;
1593 }
addOULen(int underMet,int overMet,uint len)1594 void extLenOU::addOULen(int underMet, int overMet, uint len) {
1595 _overUnder = true;
1596 _under = false;
1597 _over = false;
1598
1599 _overMet = overMet;
1600 _underMet = underMet;
1601
1602 _len = len;
1603 }
getLength(SEQ * s,int dir)1604 uint extMeasure::getLength(SEQ* s, int dir) {
1605 return s->_ur[dir] - s->_ll[dir];
1606 }
1607
blackCount(uint start,Ath__array1D<SEQ * > * resTable)1608 uint extMeasure::blackCount(uint start, Ath__array1D<SEQ*>* resTable) {
1609 uint cnt = 0;
1610 for (uint jj = start; jj < resTable->getCnt(); jj++) {
1611 SEQ* s = resTable->get(jj);
1612
1613 // pixelTable->show_seq(s);
1614
1615 if (s->type > 0) // Black
1616 cnt++;
1617 }
1618 return cnt;
1619 }
computeOverFringe(uint overMet,uint overWidth,uint len,uint dist)1620 extDistRC* extMeasure::computeOverFringe(uint overMet, uint overWidth, uint len,
1621 uint dist) {
1622 extDistRC* rcUnit = NULL;
1623
1624 for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
1625 extMetRCTable* rcModel = _metRCTable.get(ii);
1626
1627 rcUnit = rcModel->_capOver[overMet]->getRC(_met, overWidth, dist);
1628
1629 if (IsDebugNet())
1630 rcUnit->printDebugRC(_met, overMet, 0, _width, dist, len, logger_);
1631
1632 if (rcUnit != NULL) {
1633 _rc[ii]->_fringe += rcUnit->_fringe * len;
1634 _rc[ii]->_res += rcUnit->_res * len;
1635 }
1636 }
1637 return rcUnit;
1638 }
computeUnderFringe(uint underMet,uint underWidth,uint len,uint dist)1639 extDistRC* extMeasure::computeUnderFringe(uint underMet, uint underWidth,
1640 uint len, uint dist) {
1641 extDistRC* rcUnit = NULL;
1642
1643 uint n = _met - underMet - 1;
1644
1645 for (uint ii = 0; ii < _metRCTable.getCnt(); ii++) {
1646 extMetRCTable* rcModel = _metRCTable.get(ii);
1647 if (rcModel->_capUnder[underMet] == NULL)
1648 continue;
1649
1650 rcUnit = rcModel->_capUnder[underMet]->getRC(n, underWidth, dist);
1651 if (IsDebugNet())
1652 rcUnit->printDebugRC(_met, 0, underMet, _width, dist, len, logger_);
1653
1654 if (rcUnit != NULL) {
1655 _rc[ii]->_fringe += rcUnit->_fringe * len;
1656 _rc[ii]->_res += rcUnit->_res * len;
1657 }
1658 }
1659 return rcUnit;
1660 }
swap_coords(SEQ * s)1661 void extMeasure::swap_coords(SEQ* s) {
1662 int xy = s->_ll[1];
1663 s->_ll[1] = s->_ll[0];
1664 s->_ll[0] = xy;
1665
1666 xy = s->_ur[1];
1667 s->_ur[1] = s->_ur[0];
1668 s->_ur[0] = xy;
1669 }
swap_coords(uint initCnt,uint endCnt,Ath__array1D<SEQ * > * resTable)1670 uint extMeasure::swap_coords(uint initCnt, uint endCnt,
1671 Ath__array1D<SEQ*>* resTable) {
1672 for (uint ii = initCnt; ii < endCnt; ii++)
1673 swap_coords(resTable->get(ii));
1674
1675 return endCnt - initCnt;
1676 }
1677
getOverlapSeq(uint met,SEQ * s,Ath__array1D<SEQ * > * resTable)1678 uint extMeasure::getOverlapSeq(uint met, SEQ* s, Ath__array1D<SEQ*>* resTable) {
1679 uint len1 = 0;
1680
1681 if (!_rotatedGs) {
1682 len1 = _pixelTable->get_seq(s->_ll, s->_ur, _dir, met, resTable);
1683 } else {
1684 if (_dir > 0) { // extracting horizontal segments
1685 len1 = _pixelTable->get_seq(s->_ll, s->_ur, _dir, met, resTable);
1686 } else {
1687 int sll[2];
1688 int sur[2];
1689
1690 sll[0] = s->_ll[1];
1691 sll[1] = s->_ll[0];
1692 sur[0] = s->_ur[1];
1693 sur[1] = s->_ur[0];
1694
1695 uint initCnt = resTable->getCnt();
1696
1697 len1 = _pixelTable->get_seq(sll, sur, !_dir, met, resTable);
1698
1699 swap_coords(initCnt, resTable->getCnt(), resTable);
1700 }
1701 }
1702
1703 if ((len1 >= 0) && (len1 <= _len)) {
1704 return len1;
1705 } else {
1706 #ifdef DEBUG_gs
1707 logger_->info(RCX, 454, "pixelTable gave len {}, bigger than expected {}",
1708 len1, _len);
1709 #endif
1710 return 0;
1711 }
1712 }
getOverlapSeq(uint met,int * ll,int * ur,Ath__array1D<SEQ * > * resTable)1713 uint extMeasure::getOverlapSeq(uint met, int* ll, int* ur,
1714 Ath__array1D<SEQ*>* resTable) {
1715 uint len1 = 0;
1716
1717 if (!_rotatedGs) {
1718 len1 = _pixelTable->get_seq(ll, ur, _dir, met, resTable);
1719 } else {
1720 if (_dir > 0) { // extracting horizontal segments
1721 len1 = _pixelTable->get_seq(ll, ur, _dir, met, resTable);
1722 } else {
1723 int sll[2];
1724 int sur[2];
1725
1726 sll[0] = ll[1];
1727 sll[1] = ll[0];
1728 sur[0] = ur[1];
1729 sur[1] = ur[0];
1730
1731 uint initCnt = resTable->getCnt();
1732
1733 len1 = _pixelTable->get_seq(sll, sur, !_dir, met, resTable);
1734
1735 swap_coords(initCnt, resTable->getCnt(), resTable);
1736 }
1737 }
1738
1739 if ((len1 >= 0) && (len1 <= _len)) {
1740 return len1;
1741 } else {
1742 #ifdef DEBUG_gs
1743 logger_->info(RCX, 455, "pixelTable gave len {}, bigger than expected {}",
1744 len1, _len);
1745 #endif
1746 return 0;
1747 }
1748 }
1749
computeOverOrUnderSeq(Ath__array1D<SEQ * > * seqTable,uint met,Ath__array1D<SEQ * > * resTable,bool over)1750 uint extMeasure::computeOverOrUnderSeq(Ath__array1D<SEQ*>* seqTable, uint met,
1751 Ath__array1D<SEQ*>* resTable,
1752 bool over) {
1753 uint len = 0;
1754 for (uint ii = 0; ii < seqTable->getCnt(); ii++) {
1755 SEQ* s = seqTable->get(ii);
1756
1757 // pixelTable->show_seq(s);
1758
1759 if (s->type > 0) { // Black
1760 continue;
1761 }
1762 if ((s->_ll[0] < _ll[0]) || (s->_ll[1] < _ll[1]) || (s->_ur[0] > _ur[0]) ||
1763 (s->_ur[1] > _ur[1])) {
1764 // fprintf(stdout, "Out of Range result from gs for box (%d %d) (%d
1765 // %d)\n", _ll[0], _ll[1], _ur[0], _ur[1]);
1766 continue;
1767 }
1768 len += getOverlapSeq(met, s, resTable);
1769
1770 #ifdef FRINGE_UP_DOWN
1771 uint startIndex = resTable->getCnt();
1772 int maxDist = 1000; // TO_TEST
1773
1774 if (blackCount(startIndex, resTable) > 0) {
1775 for (uint jj = startIndex; jj < resTable->getCnt(); jj++) {
1776 SEQ* q = resTable->get(jj);
1777
1778 if (q->type > 0) // Black
1779 continue;
1780
1781 int dist = getLength(q, !_dir);
1782
1783 if (dist < 0)
1784 continue; // TO_TEST
1785 if (dist > maxDist)
1786 continue;
1787
1788 if (over)
1789 computeUnderFringe(met, _width, _width, dist);
1790 else
1791 computeOverFringe(met, _width, _width, dist);
1792 }
1793 }
1794 #endif
1795 }
1796 if (len > _len)
1797 return 0;
1798
1799 if (len <= 0)
1800 return 0;
1801
1802 #ifdef MIN_FOR_LOOPS
1803 extLenOU* ouLen = _lenOUPool->alloc();
1804 ouLen->addOverOrUnderLen(met, over, len);
1805 _lenOUtable->add(ouLen);
1806 #else
1807 if (over)
1808 computeOverRC(len);
1809 else
1810 computeUnderRC(len);
1811 #endif
1812
1813 return len;
1814 }
computeOUwith2planes(int * ll,int * ur,Ath__array1D<SEQ * > * resTable)1815 uint extMeasure::computeOUwith2planes(int* ll, int* ur,
1816 Ath__array1D<SEQ*>* resTable) {
1817 Ath__array1D<SEQ*> met1Table(16);
1818
1819 bool over = true;
1820 uint met1 = _underMet;
1821 uint met2 = _overMet;
1822 if (_met - _underMet > _overMet - _met) {
1823 met2 = _underMet;
1824 met1 = _overMet;
1825 over = false;
1826 }
1827 getOverlapSeq(met1, ll, ur, &met1Table);
1828
1829 uint len = 0;
1830 for (uint ii = 0; ii < met1Table.getCnt(); ii++) {
1831 SEQ* s = met1Table.get(ii);
1832
1833 // pixelTable->show_seq(s);
1834
1835 if (s->type == 0) { // white
1836 resTable->add(s);
1837 continue;
1838 }
1839 /*
1840 if
1841 ((s->_ll[0]<_ll[0])||(s->_ll[1]<_ll[1])||(s->_ur[0]>_ur[0])||(s->_ur[1]>_ur[1]))
1842 {
1843 //fprintf(stdout, "Out of Range result from gs for box (%d %d) (%d
1844 %d)\n",
1845 // _ll[0], _ll[1], _ur[0], _ur[1]);
1846 continue;
1847 }
1848 */
1849 len += getOverlapSeq(met2, s, resTable);
1850 _pixelTable->release(s);
1851 }
1852 return len;
1853 }
calcOU(uint len)1854 void extMeasure::calcOU(uint len) {
1855 #ifdef MIN_FOR_LOOPS
1856 extLenOU* ou = _lenOUPool->alloc();
1857 ou->addOULen(_underMet, _overMet, len);
1858 _lenOUtable->add(ou);
1859 #else
1860 computeOverUnderRC(len);
1861 #endif
1862 }
1863
computeOverUnder(int * ll,int * ur,Ath__array1D<SEQ * > * resTable)1864 uint extMeasure::computeOverUnder(int* ll, int* ur,
1865 Ath__array1D<SEQ*>* resTable) {
1866 uint ouLen = 0;
1867
1868 if (_ouPixelTableIndexMap != NULL) {
1869 uint ou_plane = _ouPixelTableIndexMap[_underMet][_overMet];
1870 ouLen = _pixelTable->get_seq(ll, ur, _dir, ou_plane, resTable);
1871 } else {
1872 ouLen = computeOUwith2planes(ll, ur, resTable);
1873 }
1874
1875 if ((ouLen < 0) || (ouLen > _len)) {
1876 // fprintf(stdout, "pixelTable gave len %d, bigger than expected
1877 //%d\n", ouLen, _len);
1878 logger_->info(RCX, 456, "pixelTable gave len {}, bigger than expected {}",
1879 ouLen, _len);
1880 return 0;
1881 }
1882 if (ouLen > 0)
1883 calcOU(ouLen);
1884
1885 return ouLen;
1886 }
1887
computeOverOrUnderSeq(Ath__array1D<int> * seqTable,uint met,Ath__array1D<int> * resTable,bool over)1888 uint extMeasure::computeOverOrUnderSeq(Ath__array1D<int>* seqTable, uint met,
1889 Ath__array1D<int>* resTable, bool over) {
1890 if (seqTable->getCnt() <= 0)
1891 return 0;
1892
1893 uint len = 0;
1894
1895 bool black = true;
1896 for (uint ii = 0; ii < seqTable->getCnt() - 1; ii++) {
1897 int xy1 = seqTable->get(ii);
1898 int xy2 = seqTable->get(ii + 1);
1899
1900 black = !black;
1901
1902 if (black)
1903 continue;
1904
1905 if (xy1 == xy2)
1906 continue;
1907
1908 uint len1 = mergeContextArray(_ccContextArray[met], _minSpaceTable[met],
1909 xy1, xy2, resTable);
1910
1911 // if ((len1>=0)&&(len1<=_len))
1912 if (len1 >= 0)
1913 len += len1;
1914 #ifdef DEBUG_gs
1915 else
1916 // fprintf(stdout, "pixelTable gave len %d, bigger
1917 // than expected %d\n", len1, _len);
1918 logger_->info(RCX, 457, "pixelTable gave len {}, bigger than expected {}",
1919 len1, _len);
1920 #endif
1921 }
1922 if (len > _len)
1923 return 0;
1924
1925 if (len <= 0)
1926 return 0;
1927
1928 if (over)
1929 computeOverRC(len);
1930 else
1931 computeUnderRC(len);
1932
1933 return len;
1934 }
1935
computeOverUnder(int xy1,int xy2,Ath__array1D<int> * resTable)1936 uint extMeasure::computeOverUnder(int xy1, int xy2,
1937 Ath__array1D<int>* resTable) {
1938 uint ouLen = intersectContextArray(xy1, xy2, _underMet, _overMet, resTable);
1939
1940 if ((ouLen < 0) || (ouLen > _len)) {
1941 // fprintf(stdout, "pixelTable gave len %d, bigger than expected
1942 //%d\n", ouLen, _len);
1943 logger_->info(RCX, 458, "pixelTable gave len {}, bigger than expected {}",
1944 ouLen, _len);
1945 return 0;
1946 }
1947 if (ouLen > 0)
1948 computeOverUnderRC(ouLen);
1949
1950 return ouLen;
1951 }
1952
mergeContextArray(Ath__array1D<int> * srcContext,int minS,Ath__array1D<int> * tgtContext)1953 uint extMeasure::mergeContextArray(Ath__array1D<int>* srcContext, int minS,
1954 Ath__array1D<int>* tgtContext) {
1955 tgtContext->resetCnt(0);
1956 uint ssize = srcContext->getCnt();
1957 if (ssize < 4)
1958 return 0;
1959 uint contextLength = 0;
1960 tgtContext->add(srcContext->get(0));
1961 int p1 = srcContext->get(1);
1962 int p2 = srcContext->get(2);
1963 int n1, n2;
1964 uint jj = 3;
1965 while (jj < ssize - 2) {
1966 n1 = srcContext->get(jj++);
1967 n2 = srcContext->get(jj++);
1968 if (n1 - p2 <= minS)
1969 p2 = n2;
1970 else {
1971 tgtContext->add(p1);
1972 tgtContext->add(p2);
1973 contextLength += p2 - p1;
1974 p1 = n1;
1975 p2 = n2;
1976 }
1977 }
1978 tgtContext->add(p1);
1979 tgtContext->add(p2);
1980 tgtContext->add(srcContext->get(ssize - 1));
1981 contextLength += p2 - p1;
1982 return contextLength;
1983 }
1984
mergeContextArray(Ath__array1D<int> * srcContext,int minS,int pmin,int pmax,Ath__array1D<int> * tgtContext)1985 uint extMeasure::mergeContextArray(Ath__array1D<int>* srcContext, int minS,
1986 int pmin, int pmax,
1987 Ath__array1D<int>* tgtContext) {
1988 tgtContext->resetCnt(0);
1989 uint ssize = srcContext->getCnt();
1990 if (ssize < 4)
1991 return 0;
1992 tgtContext->add(pmin);
1993 uint contextLength = 0;
1994 int p1, p2, n1, n2;
1995 uint jj;
1996 for (jj = 2; jj < ssize - 1; jj += 2)
1997 if (srcContext->get(jj) > pmin)
1998 break;
1999 if (jj >= ssize - 1) {
2000 tgtContext->add(pmax);
2001 return 0;
2002 }
2003 p1 = srcContext->get(jj - 1);
2004 if (p1 < pmin)
2005 p1 = pmin;
2006 p2 = srcContext->get(jj++);
2007 if (p2 > pmax)
2008 p2 = pmax;
2009 while (jj < ssize - 2) {
2010 n1 = srcContext->get(jj++);
2011 if (n1 >= pmax)
2012 break;
2013 n2 = srcContext->get(jj++);
2014 if (n2 > pmax)
2015 n2 = pmax;
2016 if (n1 - p2 <= minS)
2017 p2 = n2;
2018 else {
2019 tgtContext->add(p1);
2020 tgtContext->add(p2);
2021 contextLength += p2 - p1;
2022 p1 = n1;
2023 p2 = n2;
2024 }
2025 }
2026 tgtContext->add(p1);
2027 tgtContext->add(p2);
2028 contextLength += p2 - p1;
2029 tgtContext->add(pmax);
2030 return contextLength;
2031 }
2032
makeMergedContextArray(uint met,int minS)2033 uint extMeasure::makeMergedContextArray(uint met, int minS) {
2034 return mergeContextArray(_ccContextArray[met], minS,
2035 _ccMergedContextArray[met]);
2036 }
2037
makeMergedContextArray(uint met)2038 uint extMeasure::makeMergedContextArray(uint met) {
2039 return mergeContextArray(_ccContextArray[met], _minSpaceTable[met],
2040 _ccMergedContextArray[met]);
2041 }
2042
makeMergedContextArray(int pmin,int pmax,uint met,int minS)2043 uint extMeasure::makeMergedContextArray(int pmin, int pmax, uint met,
2044 int minS) {
2045 return mergeContextArray(_ccContextArray[met], minS, pmin, pmax,
2046 _ccMergedContextArray[met]);
2047 }
2048
makeMergedContextArray(int pmin,int pmax,uint met)2049 uint extMeasure::makeMergedContextArray(int pmin, int pmax, uint met) {
2050 return mergeContextArray(_ccContextArray[met], _minSpaceTable[met], pmin,
2051 pmax, _ccMergedContextArray[met]);
2052 }
2053
intersectContextArray(int pmin,int pmax,uint met1,uint met2,Ath__array1D<int> * tgtContext)2054 uint extMeasure::intersectContextArray(int pmin, int pmax, uint met1, uint met2,
2055 Ath__array1D<int>* tgtContext) {
2056 int minS1 = _minSpaceTable[met1];
2057 int minS2 = _minSpaceTable[met2];
2058
2059 Ath__array1D<int> t1Context(1024);
2060 mergeContextArray(_ccContextArray[met1], minS1, pmin, pmax, &t1Context);
2061 Ath__array1D<int> t2Context(1024);
2062 mergeContextArray(_ccContextArray[met2], minS2, pmin, pmax, &t2Context);
2063
2064 tgtContext->resetCnt(0);
2065 tgtContext->add(pmin);
2066 uint tsize1 = t1Context.getCnt();
2067 uint tsize2 = t2Context.getCnt();
2068 if (!tsize1 || !tsize2) {
2069 tgtContext->add(pmax);
2070 return 0;
2071 }
2072 uint readc1 = 1;
2073 uint readc2 = 1;
2074 uint jj1 = 1;
2075 uint jj2 = 1;
2076 uint icontextLength = 0;
2077 int p1min, p1max, p2min, p2max, ptmin, ptmax;
2078 while (1) {
2079 if (readc1) {
2080 if (jj1 + 2 >= tsize1)
2081 break;
2082 p1min = t1Context.get(jj1++);
2083 p1max = t1Context.get(jj1++);
2084 readc1 = 0;
2085 }
2086 if (readc2) {
2087 if (jj2 + 2 >= tsize2)
2088 break;
2089 p2min = t2Context.get(jj2++);
2090 p2max = t2Context.get(jj2++);
2091 readc2 = 0;
2092 }
2093 if (p1min >= p2max) {
2094 readc2 = 1;
2095 continue;
2096 }
2097 if (p2min >= p1max) {
2098 readc1 = 1;
2099 continue;
2100 }
2101 ptmin = p1min > p2min ? p1min : p2min;
2102 ptmax = p1max < p2max ? p1max : p2max;
2103 tgtContext->add(ptmin);
2104 tgtContext->add(ptmax);
2105 icontextLength += ptmax - ptmin;
2106 if (p1max > p2max)
2107 readc2 = 1;
2108 else if (p1max < p2max)
2109 readc1 = 1;
2110 else
2111 readc1 = readc2 = 1;
2112 }
2113 tgtContext->add(pmax);
2114 return icontextLength;
2115 }
2116
measureOverUnderCap()2117 uint extMeasure::measureOverUnderCap() {
2118 int ll[2] = {_ll[0], _ll[1]};
2119 int ur[2] = {_ur[0], _ur[1]};
2120 ur[_dir] = ll[_dir];
2121
2122 _tmpTable->resetCnt();
2123 _ouTable->resetCnt();
2124 _overTable->resetCnt();
2125 _underTable->resetCnt();
2126
2127 uint ouLen = 0;
2128 uint underLen = 0;
2129 uint overLen = 0;
2130
2131 if ((_met > 1) && (_met < (int)_layerCnt - 1)) {
2132 _underMet = _met - 1;
2133 _overMet = _met + 1;
2134
2135 ouLen = computeOverUnder(ll, ur, _tmpTable);
2136 } else {
2137 addSeq(_tmpTable, _pixelTable);
2138 _underMet = _met;
2139 _overMet = _met;
2140 }
2141 uint totUnderLen = underLen;
2142 uint totOverLen = overLen;
2143
2144 _underMet = _met;
2145 _overMet = _met;
2146
2147 int remainderLength = _len - ouLen;
2148
2149 while (remainderLength > 0) {
2150 _underMet--;
2151 _overMet++;
2152
2153 underLen = 0;
2154 overLen = 0;
2155 if (_underMet > 0) {
2156 // cap over _underMet
2157 underLen = computeOverOrUnderSeq(_tmpTable, _underMet, _underTable, true);
2158 release(_tmpTable);
2159
2160 if (_overMet < (int)_layerCnt) {
2161 // cap under _overMet
2162 overLen =
2163 computeOverOrUnderSeq(_underTable, _overMet, _overTable, false);
2164 release(_underTable);
2165
2166 tableCopyP(_overTable, _tmpTable);
2167 _overTable->resetCnt();
2168 totOverLen += overLen;
2169 } else {
2170 tableCopyP(_underTable, _tmpTable);
2171 _underTable->resetCnt();
2172 }
2173 totUnderLen += underLen;
2174 } else if (_overMet < (int)_layerCnt) {
2175 overLen = computeOverOrUnderSeq(_tmpTable, _overMet, _overTable, false);
2176 release(_tmpTable);
2177 tableCopyP(_overTable, _tmpTable);
2178 _overTable->resetCnt();
2179
2180 totOverLen += overLen;
2181 } else
2182 break;
2183
2184 remainderLength -= (underLen + overLen);
2185 }
2186 release(_tmpTable);
2187 uint totLen = ouLen + totOverLen + totUnderLen;
2188
2189 return totLen;
2190 }
updateLengthAndExit(int & remainder,int & totCovered,int len)2191 bool extMeasure::updateLengthAndExit(int& remainder, int& totCovered, int len) {
2192 if (len <= 0)
2193 return false;
2194
2195 totCovered += len;
2196 remainder -= len;
2197
2198 if (remainder <= 0)
2199 return true;
2200
2201 return false;
2202 }
getDgPlaneAndTrackIndex(uint tgt_met,int trackDist,int & loTrack,int & hiTrack)2203 int extMeasure::getDgPlaneAndTrackIndex(uint tgt_met, int trackDist,
2204 int& loTrack, int& hiTrack) {
2205 int n = tgt_met - *_dgContextBaseLvl + *_dgContextDepth;
2206 assert(n >= 0);
2207 if (n >= (int)*_dgContextPlanes)
2208 return -1;
2209
2210 loTrack =
2211 _dgContextLowTrack[n] < -trackDist ? -trackDist : _dgContextLowTrack[n];
2212 hiTrack = _dgContextHiTrack[n] > trackDist ? trackDist : _dgContextHiTrack[n];
2213
2214 return n;
2215 }
2216
2217 // CJ doc notes
2218 // suppose we do "ext ectract -cc_model 3", then
2219 // *_dgContextTracks is 7 (3*2 + 1), and *_dgContextTracks/2 is 3
2220 // _dgContextLowTrack[planeIndex] can be -3 ~ 0
2221 // _dgContextHiTrack[planeIndex] can be 0 ~ 3
2222 // if we want to handle all Dg tracks in the plane, we can say:
2223 // int lowTrack = _dgContextLowTrack[planeIndex];
2224 // int hiTrack = _dgContextHiTrack[planeIndex];
2225 // or if we want only from the lower 2 tracks to the higher 2, we can say:
2226 // int lowTrack = _dgContextLowTrack[planeIndex] < -2 ? -2 :
2227 // _dgContextLowTrack[planeIndex]; int hiTrack = _dgContextHiTrack[planeIndex]
2228 // > 2 ? 2 : _dgContextHiTrack[planeIndex];
2229 //
seq_release(Ath__array1D<SEQ * > * table)2230 void extMeasure::seq_release(Ath__array1D<SEQ*>* table) {
2231 for (uint jj = 0; jj < table->getCnt(); jj++) {
2232 SEQ* s = table->get(jj);
2233 _seqPool->free(s);
2234 }
2235 table->resetCnt();
2236 }
2237
computeDiag(SEQ * s,uint targetMet,uint dir,uint planeIndex,uint trackn,Ath__array1D<SEQ * > * residueSeq)2238 uint extMeasure::computeDiag(SEQ* s, uint targetMet, uint dir, uint planeIndex,
2239 uint trackn, Ath__array1D<SEQ*>* residueSeq) {
2240 Ath__array1D<SEQ*>* dgContext = _dgContextArray[planeIndex][trackn];
2241 if (dgContext->getCnt() <= 1)
2242 return 0;
2243
2244 Ath__array1D<SEQ*> overlapSeq(16);
2245 getDgOverlap(s, _dir, dgContext, &overlapSeq, residueSeq);
2246
2247 uint len = 0;
2248 for (uint jj = 0; jj < overlapSeq.getCnt(); jj++) {
2249 SEQ* tgt = overlapSeq.get(jj);
2250 uint diagDist = calcDist(tgt->_ll, tgt->_ur);
2251 uint tgWidth = tgt->_ur[_dir] - tgt->_ll[_dir];
2252 uint len1 = getLength(tgt, !_dir);
2253
2254 DebugDiagCoords(_met, targetMet, len1, diagDist, tgt->_ll, tgt->_ur);
2255 len += len1;
2256 bool skip_high_acc = true;
2257 #ifdef HI_ACC_1
2258 bool verticalOverlap = false;
2259 if (_dist < 0 && !skip_high_acc) {
2260 if (diagDist <= _width && diagDist >= 0 && (int)_width < 10 * _minWidth &&
2261 _verticalDiag) {
2262 verticalCap(_rsegSrcId, tgt->type, len1, tgWidth, diagDist, targetMet);
2263 verticalOverlap = true;
2264 } else if (((int)tgWidth > 10 * _minWidth) &&
2265 ((int)_width > 10 * _minWidth) && (tgWidth >= 2 * diagDist)) {
2266 areaCap(_rsegSrcId, tgt->type, len1, targetMet);
2267 verticalOverlap = true;
2268 } else if ((int)tgWidth > 2 * _minWidth && tgWidth >= 2 * diagDist) {
2269 calcDiagRC(_rsegSrcId, tgt->type, len1, 1000000, targetMet);
2270 }
2271 // TO_OPTIMIZE
2272 else if (_diagModel == 2) {
2273 if (_verticalDiag)
2274 verticalCap(_rsegSrcId, tgt->type, len1, tgWidth, diagDist,
2275 targetMet);
2276 else
2277 calcDiagRC(_rsegSrcId, tgt->type, len1, tgWidth, diagDist, targetMet);
2278 }
2279 // if (!verticalOverlap) {
2280 if (!verticalOverlap && _overMet > _met + 1) {
2281 addSeq(tgt->_ll, tgt->_ur, residueSeq);
2282 }
2283
2284 continue;
2285 }
2286 #endif
2287 if (_diagModel == 2)
2288 calcDiagRC(_rsegSrcId, tgt->type, len1, tgWidth, diagDist, targetMet);
2289 if (_diagModel == 1)
2290 calcDiagRC(_rsegSrcId, tgt->type, len1, diagDist, targetMet);
2291 }
2292 seq_release(&overlapSeq);
2293 return len;
2294 }
2295
computeDiagOU(SEQ * s,uint trackMin,uint trackMax,uint targetMet,Ath__array1D<SEQ * > * diagTable)2296 int extMeasure::computeDiagOU(SEQ* s, uint trackMin, uint trackMax,
2297 uint targetMet, Ath__array1D<SEQ*>* diagTable) {
2298 #ifdef HI_ACC_1
2299 // int trackDist = _extMain->_couplingFlag;
2300 int trackDist = 2;
2301 #else
2302 int trackDist = 3;
2303 #endif
2304 int loTrack;
2305 int hiTrack;
2306 int planeIndex =
2307 getDgPlaneAndTrackIndex(targetMet, trackDist, loTrack, hiTrack);
2308 if (planeIndex < 0)
2309 return 0;
2310
2311 uint len = 0;
2312
2313 Ath__array1D<SEQ*> tmpTable(16);
2314 copySeqUsingPool(s, &tmpTable);
2315
2316 Ath__array1D<SEQ*> residueTable(16);
2317
2318 int trackTable[200];
2319 uint cnt = 0;
2320 for (int kk = (int)trackMin; kk <= (int)trackMax;
2321 kk++) // skip overlapping track
2322 {
2323 #ifdef HI_ACC_1
2324 if (kk <= _dgContextHiTrack[planeIndex])
2325 #else
2326 if (kk < _dgContextHiTrack[planeIndex])
2327 #endif
2328 trackTable[cnt++] = *_dgContextTracks / 2 + kk;
2329
2330 if (!kk)
2331 continue;
2332 if (-kk >= _dgContextLowTrack[planeIndex])
2333 trackTable[cnt++] = *_dgContextTracks / 2 - kk;
2334 }
2335 // DIMITRIS -- MENTOR pattern 06
2336 if (cnt == 0)
2337 trackTable[cnt++] = *_dgContextTracks / 2;
2338 // DIMITRIS -- END
2339
2340 for (uint ii = 0; ii < cnt; ii++) {
2341 int trackn = trackTable[ii];
2342
2343 #ifdef HI_ACC_1
2344 if (_dgContextArray[planeIndex][trackn]->getCnt() <= 1)
2345 continue;
2346 #endif
2347 bool add_all_diag = false;
2348 if (!add_all_diag) {
2349 for (uint jj = 0; jj < tmpTable.getCnt(); jj++)
2350 len += computeDiag(tmpTable.get(jj), targetMet, _dir, planeIndex,
2351 trackn, &residueTable);
2352 } else {
2353 len += computeDiag(s, targetMet, _dir, planeIndex, trackn, &residueTable);
2354 }
2355
2356 seq_release(&tmpTable);
2357 tableCopyP(&residueTable, &tmpTable);
2358 residueTable.resetCnt();
2359 }
2360 // seq_release(&tmpTable);
2361 if (diagTable != NULL)
2362 tableCopyP(&tmpTable, diagTable);
2363 else
2364 seq_release(&tmpTable);
2365 return len;
2366 }
2367
compute_Diag_Over_Under(Ath__array1D<SEQ * > * seqTable,Ath__array1D<SEQ * > * resTable)2368 int extMeasure::compute_Diag_Over_Under(Ath__array1D<SEQ*>* seqTable,
2369 Ath__array1D<SEQ*>* resTable) {
2370 bool overUnder = true;
2371 int met1 = _underMet;
2372 int met2 = _overMet;
2373
2374 if (_met - _underMet > _overMet - _met) {
2375 met2 = _underMet;
2376 met1 = _overMet;
2377 overUnder = false;
2378 }
2379
2380 int totCovered = 0;
2381 for (uint ii = 0; ii < seqTable->getCnt(); ii++) {
2382 SEQ* s = seqTable->get(ii);
2383
2384 if (s->type > 0) // Black
2385 continue;
2386
2387 uint len = s->_ur[!_dir] - s->_ll[!_dir];
2388 int remainder = len;
2389
2390 if (_diagFlow) {
2391 if (_overMet < (int)_layerCnt)
2392 computeDiagOU(s, 0, 3, _overMet, NULL);
2393 // computeDiagOU(s, 0, 3, _overMet, _diagTable); // only diagonal, not
2394 // coupling
2395 // is additive to over/under
2396 // trying to capture single diagonal lines
2397 }
2398
2399 addSeq(s->_ll, s->_ur, _diagTable);
2400
2401 // uint diagLen= 0;
2402 // if (updateLengthAndExit(remainder, totCovered, diagLen))
2403 // break;
2404
2405 uint len1 = computeOverOrUnderSeq(_diagTable, met1, _underTable, overUnder);
2406
2407 if (updateLengthAndExit(remainder, totCovered, len1))
2408 break;
2409
2410 uint len2 = computeOverOrUnderSeq(_underTable, met2, resTable, !overUnder);
2411
2412 if (updateLengthAndExit(remainder, totCovered, len2))
2413 break;
2414
2415 release(_diagTable, _pixelTable);
2416 release(_underTable, _pixelTable);
2417 }
2418 release(_diagTable, _pixelTable);
2419 release(_underTable, _pixelTable);
2420
2421 return totCovered;
2422 }
compute_Diag_OverOrUnder(Ath__array1D<SEQ * > * seqTable,bool over,uint met,Ath__array1D<SEQ * > * resTable)2423 int extMeasure::compute_Diag_OverOrUnder(Ath__array1D<SEQ*>* seqTable,
2424 bool over, uint met,
2425 Ath__array1D<SEQ*>* resTable) {
2426 int totCovered = 0;
2427 int diagTotLen = 0;
2428 for (uint ii = 0; ii < seqTable->getCnt(); ii++) {
2429 SEQ* s = seqTable->get(ii);
2430
2431 if (s->type > 0) // Black
2432 continue;
2433
2434 uint len = s->_ur[!_dir] - s->_ll[!_dir];
2435 int remainder = len;
2436
2437 // uint diagLen= 0;
2438
2439 if (_diagFlow) {
2440 if (!over) {
2441 computeDiagOU(s, 0, 3, met, NULL);
2442 // computeDiagOU(s, 0, 3, met, _diagTable); // only diagonal, not
2443 // coupling
2444 // is additive to over/under
2445 // trying to capture single diagonal lines
2446
2447 // if (updateLengthAndExit(remainder, totCovered,
2448 // diagLen)) break;
2449 }
2450 }
2451 addSeq(s->_ll, s->_ur, _diagTable);
2452
2453 uint len1 = computeOverOrUnderSeq(_diagTable, met, resTable, over);
2454
2455 if (updateLengthAndExit(remainder, totCovered, len1))
2456 break;
2457
2458 release(_diagTable);
2459 }
2460 release(_diagTable);
2461 release(_underTable);
2462
2463 return totCovered - diagTotLen;
2464 }
measureUnderOnly(bool diagFlag)2465 uint extMeasure::measureUnderOnly(bool diagFlag) {
2466 int totCovered = 0;
2467 int remainderLen = _len;
2468
2469 uint overLen = 0;
2470 _underMet = 0;
2471 for (_overMet = _met + 1; _overMet < (int)_layerCnt; _overMet++) {
2472 overLen =
2473 compute_Diag_OverOrUnder(_tmpSrcTable, false, _overMet, _tmpDstTable);
2474
2475 if (updateLengthAndExit(remainderLen, totCovered, overLen))
2476 break;
2477
2478 release(_tmpSrcTable);
2479 tableCopyP(_tmpDstTable, _tmpSrcTable);
2480 _tmpDstTable->resetCnt();
2481 }
2482 release(_tmpSrcTable);
2483 release(_tmpDstTable);
2484
2485 return totCovered;
2486 }
measureOverOnly(bool diagFlag)2487 uint extMeasure::measureOverOnly(bool diagFlag) {
2488 int totCovered = 0;
2489 int remainder = _len;
2490
2491 _overMet = -1;
2492 for (_underMet = _met - 1; _underMet > 0; _underMet--) {
2493 uint underLen =
2494 compute_Diag_OverOrUnder(_tmpSrcTable, true, _underMet, _tmpDstTable);
2495
2496 if (updateLengthAndExit(remainder, totCovered, underLen))
2497 break;
2498
2499 release(_tmpSrcTable);
2500 tableCopyP(_tmpDstTable, _tmpSrcTable);
2501 _tmpDstTable->resetCnt();
2502 }
2503 release(_tmpSrcTable);
2504 release(_tmpDstTable);
2505
2506 return totCovered;
2507 }
ouFlowStep(Ath__array1D<SEQ * > * overTable)2508 uint extMeasure::ouFlowStep(Ath__array1D<SEQ*>* overTable) {
2509 Ath__array1D<SEQ*> tmpTable(32);
2510 uint len = 0;
2511 for (uint ii = 0; ii < overTable->getCnt(); ii++) {
2512 SEQ* s = overTable->get(ii);
2513
2514 /* if (s->type==0) {
2515 continue;
2516 }
2517 */
2518 uint ouLen = getOverlapSeq(_underMet, s, &tmpTable);
2519
2520 if (ouLen > 0) {
2521 calcOU(ouLen);
2522 len += ouLen;
2523 }
2524 }
2525 release(overTable);
2526
2527 for (uint jj = 0; jj < tmpTable.getCnt(); jj++) {
2528 SEQ* s = tmpTable.get(jj);
2529 if (s->type == 0) {
2530 overTable->add(s);
2531 // s->type= 1;
2532 continue;
2533 }
2534 _pixelTable->release(s);
2535 }
2536 return len;
2537 }
2538 #ifdef DIAG_FIRST
underFlowStep(Ath__array1D<SEQ * > * srcTable,Ath__array1D<SEQ * > * overTable)2539 int extMeasure::underFlowStep(Ath__array1D<SEQ*>* srcTable,
2540 Ath__array1D<SEQ*>* overTable) {
2541 int totLen = 0;
2542
2543 Ath__array1D<SEQ*> whiteTable(32);
2544 Ath__array1D<SEQ*> table1(32);
2545 Ath__array1D<SEQ*> diagTable(32);
2546
2547 uint diagTotBeforeUnder = 0;
2548 for (uint ii = 0; ii < srcTable->getCnt(); ii++) {
2549 SEQ* s1 = srcTable->get(ii);
2550
2551 #ifdef HI_ACC_1
2552 if ((_overMet < _met + 3) && _diagFlow && _toHi) {
2553 #else
2554 if ((_overMet < _met + 5) && _diagFlow && _toHi) {
2555 #endif
2556 int diagLen = computeDiagOU(s1, 0, 1, _overMet, &diagTable);
2557 if (diagLen > 0) {
2558 diagTotBeforeUnder += diagLen;
2559 for (uint jj = 0; jj < diagTable.getCnt(); jj++) {
2560 SEQ* s2 = diagTable.get(jj);
2561 int oLen = getOverlapSeq(_overMet, s2, &table1);
2562 if (oLen > 0)
2563 totLen += oLen;
2564 }
2565 release(&diagTable);
2566 diagTable.resetCnt();
2567 //#ifndef HI_ACC_1
2568 continue;
2569 //#endif
2570 } else {
2571 release(&diagTable);
2572 diagTable.resetCnt();
2573 }
2574 }
2575 #ifdef HI_ACC_1
2576 else if ((_overMet < _met + 5) && _diagFlow && _toHi) {
2577 computeDiagOU(s1, 0, 1, _overMet, NULL);
2578 }
2579 #endif
2580 int oLen = getOverlapSeq(_overMet, s1, &table1);
2581 if (oLen > 0)
2582 totLen += oLen;
2583 }
2584 bool moreDiag =
2585 (_overMet < _met + 5) && _diagFlow && (diagTotBeforeUnder == 0) && _toHi;
2586 #ifdef HI_ACC_1
2587 int trackDist = _extMain->_couplingFlag;
2588 #else
2589 int trackDist = 3;
2590 #endif
2591 for (uint jj = 0; jj < table1.getCnt(); jj++) {
2592 SEQ* s2 = table1.get(jj);
2593
2594 if (s2->type == 0) {
2595 if (moreDiag)
2596 computeDiagOU(s2, 2, trackDist, _overMet, NULL);
2597 whiteTable.add(s2);
2598 continue;
2599 }
2600 overTable->add(s2);
2601 s2->type = 0;
2602 }
2603 release(srcTable);
2604 tableCopyP(&whiteTable, srcTable);
2605
2606 return totLen;
2607 }
2608 #else
2609 int extMeasure::underFlowStep(Ath__array1D<SEQ*>* srcTable,
2610 Ath__array1D<SEQ*>* overTable) {
2611 int totLen = 0;
2612
2613 Ath__array1D<SEQ*> whiteTable(32);
2614 Ath__array1D<SEQ*> table1(32);
2615 Ath__array1D<SEQ*> diagTable(32);
2616
2617 for (uint ii = 0; ii < srcTable->getCnt(); ii++) {
2618 SEQ* s1 = srcTable->get(ii);
2619 int oLen = getOverlapSeq(_overMet, s1, &table1);
2620 if (oLen > 0)
2621 totLen += oLen;
2622 }
2623 for (uint jj = 0; jj < table1.getCnt(); jj++) {
2624 SEQ* s2 = table1.get(jj);
2625
2626 if (s2->type == 0) {
2627 if (_diagFlow)
2628 _diagLen += computeDiagOU(s2, 0, 3, _overMet, NULL);
2629 whiteTable.add(s2);
2630 continue;
2631 }
2632 overTable->add(s2);
2633 s2->type = 0;
2634 }
2635 release(srcTable);
2636 tableCopyP(&whiteTable, srcTable);
2637
2638 return totLen;
2639 }
2640 #endif
2641 uint extMeasure::measureDiagFullOU() {
2642 // DEBUG_HERE
2643
2644 _tmpSrcTable->resetCnt();
2645 _tmpDstTable->resetCnt();
2646
2647 int ll[2] = {_ll[0], _ll[1]};
2648 int ur[2] = {_ur[0], _ur[1]};
2649 ur[_dir] = ll[_dir];
2650 // ur[_dir]= (ll[_dir]+ur[_dir])/2;
2651 // ll[_dir]= ur[_dir];
2652
2653 addSeq(ll, ur, _tmpSrcTable);
2654
2655 #ifndef HI_ACC_1
2656 if (_met == 1)
2657 return measureUnderOnly(true);
2658 #endif
2659
2660 if (_met == (int)_layerCnt - 1)
2661 return measureOverOnly(false);
2662
2663 _tmpTable->resetCnt();
2664 _ouTable->resetCnt();
2665 _overTable->resetCnt();
2666 _underTable->resetCnt();
2667 _diagTable->resetCnt();
2668
2669 int totCovered = 0;
2670 int remainder = _len;
2671
2672 // uint maxDist = 10;
2673 uint maxDist = _extMain->_ccContextDepth;
2674 int upperLimit = _met + maxDist >= _layerCnt ? _layerCnt : _met + maxDist;
2675 int lowerLimit = _met - maxDist;
2676 if (lowerLimit < 0)
2677 lowerLimit = 0;
2678
2679 // uint totLen= 0;
2680 for (_overMet = _met + 1; _overMet < upperLimit; _overMet++) {
2681 int totUnderLen = underFlowStep(_tmpSrcTable, _overTable);
2682 if (totUnderLen <= 0) {
2683 release(_overTable);
2684 continue;
2685 }
2686
2687 int underLen = totUnderLen;
2688 int totOUCovered = 0;
2689 bool skipUnderMetOverSub = false;
2690 for (_underMet = _met - 1; _underMet > lowerLimit; _underMet--) {
2691 uint overLen = ouFlowStep(_overTable);
2692
2693 if (updateLengthAndExit(underLen, totOUCovered, overLen)) {
2694 skipUnderMetOverSub = true;
2695 release(_overTable);
2696 break;
2697 }
2698 }
2699 if (!skipUnderMetOverSub) {
2700 computeOverOrUnderSeq(_overTable, _overMet, _underTable, false);
2701 release(_underTable);
2702 }
2703 release(_overTable);
2704 if (updateLengthAndExit(remainder, totCovered, totUnderLen)) {
2705 release(_overTable);
2706 break;
2707 }
2708 }
2709
2710 _overMet = -1;
2711 for (_underMet = _met - 1; _underMet > 0; _underMet--) {
2712 uint overLen =
2713 computeOverOrUnderSeq(_tmpSrcTable, _underMet, _tmpDstTable, true);
2714
2715 if (updateLengthAndExit(remainder, totCovered, overLen))
2716 break;
2717
2718 release(_tmpSrcTable);
2719 tableCopyP(_tmpDstTable, _tmpSrcTable);
2720 _tmpDstTable->resetCnt();
2721 }
2722 release(_tmpSrcTable);
2723 release(_tmpDstTable);
2724
2725 return totCovered;
2726 }
2727
2728 uint extMeasure::measureDiagOU(uint ouLevelLimit, uint diagLevelLimit) {
2729 return measureDiagFullOU();
2730
2731 _tmpSrcTable->resetCnt();
2732 _tmpDstTable->resetCnt();
2733
2734 int ll[2] = {_ll[0], _ll[1]};
2735 int ur[2] = {_ur[0], _ur[1]};
2736 ur[_dir] = ll[_dir];
2737
2738 addSeq(ll, ur, _tmpSrcTable);
2739
2740 if (_met == 1)
2741 return measureUnderOnly(true);
2742
2743 if (_met == (int)_layerCnt - 1)
2744 return measureOverOnly(false);
2745
2746 _tmpTable->resetCnt();
2747 _ouTable->resetCnt();
2748 _overTable->resetCnt();
2749 _underTable->resetCnt();
2750 _diagTable->resetCnt();
2751
2752 int totCovered = 0;
2753 int remainder = _len;
2754
2755 uint downDist = 1;
2756 uint upDist = 1;
2757
2758 _underMet = _met;
2759 downDist = 0;
2760 _overMet = _met;
2761 upDist = 0;
2762 // bool upDownFlag= false;
2763 while (true) {
2764 if (_underMet > 0) {
2765 _underMet--;
2766 downDist++;
2767 }
2768
2769 if (_overMet < (int)_layerCnt) {
2770 _overMet++;
2771 upDist++;
2772 }
2773 if ((_underMet == 0) && (_overMet == (int)_layerCnt))
2774 break;
2775
2776 if ((_underMet > 0) && (downDist <= ouLevelLimit) &&
2777 (upDist <= ouLevelLimit)) {
2778 uint ouLen = 0;
2779
2780 for (uint ii = 0; ii < _tmpSrcTable->getCnt();
2781 ii++) { // keep on adding inside loop
2782 SEQ* s = _tmpSrcTable->get(ii);
2783
2784 if (s->type > 0) // Black
2785 continue;
2786
2787 ouLen += computeOverUnder(s->_ll, s->_ur, _ouTable);
2788 }
2789 release(_tmpSrcTable);
2790 if (updateLengthAndExit(remainder, totCovered, ouLen))
2791 break;
2792 } else {
2793 tableCopyP(_tmpSrcTable, _ouTable);
2794 _tmpSrcTable->resetCnt();
2795 }
2796
2797 uint underLen = 0;
2798 uint overUnderLen = 0;
2799
2800 if (_underMet > 0)
2801 overUnderLen = compute_Diag_Over_Under(_ouTable, _tmpDstTable);
2802 else
2803 underLen =
2804 compute_Diag_OverOrUnder(_ouTable, false, _overMet, _tmpDstTable);
2805
2806 release(_ouTable);
2807 release(_tmpSrcTable);
2808 tableCopyP(_tmpDstTable, _tmpSrcTable);
2809 _tmpDstTable->resetCnt();
2810
2811 if (updateLengthAndExit(remainder, totCovered, underLen + overUnderLen))
2812 break;
2813 }
2814 release(_tmpSrcTable);
2815 return totCovered;
2816 }
2817
2818 void extMeasure::ccReportProgress() {
2819 uint repChunk = 1000000;
2820 if ((_totCCcnt > 0) && (_totCCcnt % repChunk == 0))
2821 logger_->info(RCX, 79, "Have processed {} CC caps, and stored {} CC caps",
2822 _totCCcnt, _totBigCCcnt);
2823 }
2824 void extMeasure::printNet(dbRSeg* rseg, uint netId) {
2825 if (rseg == NULL)
2826 return;
2827
2828 dbNet* net = rseg->getNet();
2829
2830 if (netId == net->getId()) {
2831 _netId = netId;
2832 dbCapNode* cap2 = dbCapNode::getCapNode(_block, rseg->getTargetNode());
2833 uint node2 = cap2->getNode();
2834 uint shapeId2 = cap2->getShapeId();
2835 }
2836 }
2837 bool extMain::updateCoupCap(dbRSeg* rseg1, dbRSeg* rseg2, int jj, double v) {
2838 if (rseg1 != NULL && rseg2 != NULL) {
2839 dbCCSeg* ccap = dbCCSeg::create(
2840 dbCapNode::getCapNode(_block, rseg1->getTargetNode()),
2841 dbCapNode::getCapNode(_block, rseg2->getTargetNode()), true);
2842 ccap->addCapacitance(v, jj);
2843 return true;
2844 }
2845 if (rseg1 != NULL)
2846 updateTotalCap(rseg1, v, jj);
2847 if (rseg2 != NULL)
2848 updateTotalCap(rseg2, v, jj);
2849
2850 return false;
2851 }
2852 double extMain::calcFringe(extDistRC* rc, double deltaFr,
2853 bool includeCoupling) {
2854 double ccCap = 0.0;
2855 if (includeCoupling)
2856 ccCap = rc->_coupling;
2857
2858 double cap = rc->_fringe + ccCap - deltaFr;
2859
2860 if (_gndcModify)
2861 cap *= _gndcFactor;
2862
2863 return cap;
2864 }
2865 double extMain::updateTotalCap(dbRSeg* rseg, double cap, uint modelIndex) {
2866 if (rseg == NULL)
2867 return 0;
2868
2869 int extDbIndex, sci, scDbIndex;
2870 extDbIndex = getProcessCornerDbIndex(modelIndex);
2871 double tot = rseg->getCapacitance(extDbIndex);
2872 tot += cap;
2873 if (_updateTotalCcnt >= 0) {
2874 if (_printFile == NULL)
2875 _printFile = fopen("updateCap.1", "w");
2876 _updateTotalCcnt++;
2877 fprintf(_printFile, "%d %d %g %g\n", _updateTotalCcnt, rseg->getId(), tot,
2878 cap);
2879 }
2880
2881 rseg->setCapacitance(tot, extDbIndex);
2882 // return rseg->getCapacitance(extDbIndex);
2883 getScaledCornerDbIndex(modelIndex, sci, scDbIndex);
2884 if (sci == -1)
2885 return tot;
2886 getScaledGndC(sci, cap);
2887 double tots = rseg->getCapacitance(scDbIndex);
2888 tots += cap;
2889 rseg->setCapacitance(tots, scDbIndex);
2890 return tot;
2891 }
2892
2893 void extDistRC::addRC(extDistRC* rcUnit, uint len, bool addCC) {
2894 if (rcUnit == NULL)
2895 return;
2896
2897 _fringe += rcUnit->_fringe * len;
2898
2899 if (addCC) // dist based
2900 _coupling += rcUnit->_coupling * len;
2901 }
2902 double extMain::updateRes(dbRSeg* rseg, double res, uint model) {
2903 if (rseg == NULL)
2904 return 0;
2905
2906 if (_eco && !rseg->getNet()->isWireAltered())
2907 return 0.0;
2908
2909 if (_resModify)
2910 res *= _resFactor;
2911
2912 if (_eco && !rseg->getNet()->isWireAltered())
2913 return 0.0;
2914
2915 double tot = rseg->getResistance(model);
2916 tot += res;
2917
2918 rseg->setResistance(tot, model);
2919 return rseg->getResistance(model);
2920 }
2921 bool extMeasure::isConnectedToBterm(dbRSeg* rseg1) {
2922 if (rseg1 == NULL)
2923 return false;
2924
2925 dbCapNode* node1 = rseg1->getTargetCapNode();
2926 if (node1->isBTerm())
2927 return true;
2928 dbCapNode* node2 = rseg1->getSourceCapNode();
2929 if (node2->isBTerm())
2930 return true;
2931
2932 return false;
2933 }
2934 bool extMeasure::isBtermConnection(dbRSeg* rseg1, dbRSeg* rseg2) {
2935 return _btermThreshold &&
2936 (isConnectedToBterm(rseg1) || isConnectedToBterm(rseg2)) &&
2937 (rseg1 != rseg2);
2938 }
2939
2940 dbCCSeg* extMeasure::makeCcap(dbRSeg* rseg1, dbRSeg* rseg2, double ccCap) {
2941 if ((rseg1 != NULL) && (rseg2 != NULL) &&
2942 rseg1->getNet() != rseg2->getNet()) { // signal nets
2943
2944 _totCCcnt++; // TO_TEST
2945
2946 bool btermConnection = isBtermConnection(rseg1, rseg2);
2947
2948 if ((ccCap >= _extMain->_coupleThreshold) || btermConnection) {
2949 _totBigCCcnt++;
2950
2951 dbCapNode* node1 = rseg1->getTargetCapNode();
2952 dbCapNode* node2 = rseg2->getTargetCapNode();
2953
2954 return dbCCSeg::create(node1, node2, true);
2955 } else {
2956 _totSmallCCcnt++;
2957 return NULL;
2958 }
2959 } else {
2960 return NULL;
2961 }
2962 }
2963 void extMeasure::addCCcap(dbCCSeg* ccap, double v, uint model) {
2964 double coupling = _ccModify ? v * _ccFactor : v;
2965 ccap->addCapacitance(coupling, model);
2966 }
2967 void extMeasure::addFringe(dbRSeg* rseg1, dbRSeg* rseg2, double frCap,
2968 uint model) {
2969 if (_gndcModify)
2970 frCap *= _gndcFactor;
2971
2972 if (rseg1 != NULL)
2973 _extMain->updateTotalCap(rseg1, frCap, model);
2974
2975 if (rseg2 != NULL)
2976 _extMain->updateTotalCap(rseg2, frCap, model);
2977 }
2978
2979 void extMeasure::calcDiagRC(int rsegId1, uint rsegId2, uint len, uint diagWidth,
2980 uint diagDist, uint tgtMet) {
2981 double capTable[10];
2982 uint modelCnt = _metRCTable.getCnt();
2983 for (uint ii = 0; ii < modelCnt; ii++) {
2984 extMetRCTable* rcModel = _metRCTable.get(ii);
2985
2986 capTable[ii] = len * getDiagUnderCC(rcModel, diagWidth, diagDist, tgtMet);
2987 #ifdef DAVID_ACC_08_02
2988 _rc[ii]->_diag += capTable[ii];
2989 double ccTable[10];
2990 if (_dist > 0) {
2991 extDistRC* rc = getDiagUnderCC2(rcModel, diagWidth, diagDist, tgtMet);
2992 if (rc)
2993 ccTable[ii] = len * rc->_coupling;
2994
2995 rc = rcModel->_capOver[_met]->getRC(0, _width, _dist);
2996 if (rc) {
2997 ccTable[ii] -= len * rc->_coupling;
2998 _rc[ii]->_coupling += ccTable[ii];
2999 }
3000 }
3001 #endif
3002 }
3003 dbRSeg* rseg1 = NULL;
3004 dbRSeg* rseg2 = NULL;
3005 if (rsegId1 > 0)
3006 rseg1 = dbRSeg::getRSeg(_block, rsegId1);
3007 if (rsegId2 > 0)
3008 rseg2 = dbRSeg::getRSeg(_block, rsegId2);
3009
3010 dbCCSeg* ccCap = makeCcap(rseg1, rseg2, capTable[_minModelIndex]);
3011
3012 for (uint model = 0; model < modelCnt; model++) {
3013 // extMetRCTable* rcModel= _metRCTable.get(model);
3014
3015 if (ccCap != NULL)
3016 addCCcap(ccCap, capTable[model], model);
3017 else
3018 #ifdef HI_ACC_1
3019 addFringe(NULL, rseg2, capTable[model], model);
3020 #else
3021 addFringe(rseg1, rseg2, capTable[model], model);
3022 #endif
3023 }
3024 }
3025 void extMeasure::createCap(int rsegId1, uint rsegId2, double* capTable) {
3026 dbRSeg* rseg1 = NULL;
3027 dbRSeg* rseg2 = NULL;
3028 if (rsegId1 > 0)
3029 rseg1 = dbRSeg::getRSeg(_block, rsegId1);
3030 if (rsegId2 > 0)
3031 rseg2 = dbRSeg::getRSeg(_block, rsegId2);
3032
3033 dbCCSeg* ccCap = makeCcap(rseg1, rseg2, capTable[_minModelIndex]);
3034
3035 uint modelCnt = _metRCTable.getCnt();
3036 for (uint model = 0; model < modelCnt; model++) {
3037 // extMetRCTable* rcModel= _metRCTable.get(model);
3038 if (ccCap != NULL)
3039 addCCcap(ccCap, capTable[model], model);
3040 else
3041 #ifdef HI_ACC_1
3042 {
3043 _rc[model]->_diag += capTable[model];
3044 addFringe(NULL, rseg2, capTable[model], model);
3045 }
3046 #else
3047 addFringe(rseg1, rseg2, capTable[model], model);
3048 #endif
3049 }
3050 }
3051 void extMeasure::areaCap(int rsegId1, uint rsegId2, uint len, uint tgtMet) {
3052 double capTable[10];
3053 uint modelCnt = _metRCTable.getCnt();
3054 for (uint ii = 0; ii < modelCnt; ii++) {
3055 extMetRCTable* rcModel = _metRCTable.get(ii);
3056 double area = 1.0 * _width;
3057 area *= len;
3058 extDistRC* rc = getUnderLastWidthDistRC(rcModel, tgtMet);
3059 capTable[ii] = 2 * area * rc->_fringe; //_fringe always 1/2 of rulesGen
3060
3061 #ifdef HI_ACC_1
3062 dbRSeg* rseg2 = NULL;
3063 if (rsegId2 > 0)
3064 rseg2 = dbRSeg::getRSeg(_block, rsegId2);
3065
3066 if (rseg2 != NULL) {
3067 uint met = _met;
3068 _met = tgtMet;
3069 extDistRC* area_rc = areaCapOverSub(ii, rcModel);
3070 _met = met;
3071 double areaCapOverSub = 2 * area * area_rc->_fringe;
3072 _extMain->updateTotalCap(rseg2, 0.0, 0.0, areaCapOverSub, ii);
3073 }
3074 #endif
3075
3076 // old way capTable[ii]= 2*area*getUnderRC(rcModel)->_fringe; //_fringe
3077 // always 1/2 of rulesGen
3078 }
3079 createCap(rsegId1, rsegId2, capTable);
3080 }
3081 extDistRC* extMeasure::areaCapOverSub(uint modelNum, extMetRCTable* rcModel) {
3082 if (rcModel == NULL)
3083 rcModel = _metRCTable.get(modelNum);
3084
3085 extDistRC* rc = rcModel->getOverFringeRC(this);
3086
3087 return rc;
3088 }
3089 bool extMeasure::verticalCap(int rsegId1, uint rsegId2, uint len, uint tgtWidth,
3090 uint diagDist, uint tgtMet) {
3091 dbRSeg* rseg2 = NULL;
3092 if (rsegId2 > 0)
3093 rseg2 = dbRSeg::getRSeg(_block, rsegId2);
3094 dbRSeg* rseg1 = NULL;
3095 if (rsegId1 > 0)
3096 rseg1 = dbRSeg::getRSeg(_block, rsegId1);
3097
3098 double capTable[10];
3099 uint modelCnt = _metRCTable.getCnt();
3100 for (uint ii = 0; ii < modelCnt; ii++) {
3101 extMetRCTable* rcModel = _metRCTable.get(ii);
3102
3103 extDistRC* rc = getVerticalUnderRC(rcModel, diagDist, tgtWidth, tgtMet);
3104 if (rc == NULL)
3105 return false;
3106
3107 // double scale= 0.5*diagDist/tgtWidth;
3108
3109 capTable[ii] = len * rc->_fringe;
3110
3111 if ((rseg2 == NULL) && (rseg1 == NULL))
3112 continue;
3113
3114 // extDistRC *overSubFringe=
3115 //_metRCTable.get(ii)->_capOver[tgtMet]->getFringeRC(0, _width);
3116 extDistRC* overSubFringe =
3117 _metRCTable.get(ii)->_capOver[tgtMet]->getFringeRC(0, tgtWidth);
3118 if (overSubFringe == NULL)
3119 continue;
3120 double frCap = len * overSubFringe->_fringe; // 02
3121
3122 if (diagDist > tgtWidth) {
3123 // double scale= 0.25*diagDist/_width;
3124 double scale = 0.25 * diagDist / tgtWidth;
3125 scale = 1.0 / scale;
3126 if (scale > 0.5)
3127 scale = 0.5;
3128 // if (tgtMet==_layerCnt-1)
3129 // scale *= 0.5;
3130
3131 frCap *= scale;
3132 }
3133 if (rseg2 != NULL)
3134 _extMain->updateTotalCap(rseg2, 0.0, 0.0, frCap, ii);
3135 if (rseg1 != NULL)
3136 _extMain->updateTotalCap(rseg1, 0.0, 0.0, 0.5 * frCap, ii);
3137 }
3138 createCap(rsegId1, rsegId2, capTable);
3139 return true;
3140 }
3141
3142 void extMeasure::calcDiagRC(int rsegId1, uint rsegId2, uint len, uint dist,
3143 uint tgtMet) {
3144 int DOUBLE_DIAG = 1;
3145 double capTable[10];
3146 uint modelCnt = _metRCTable.getCnt();
3147 for (uint ii = 0; ii < modelCnt; ii++) {
3148 extMetRCTable* rcModel = _metRCTable.get(ii);
3149
3150 #ifdef HI_ACC_1
3151 if (dist != 1000000) {
3152 double cap = getDiagUnderCC(rcModel, dist, tgtMet);
3153 double diagCap = DOUBLE_DIAG * len * cap;
3154 capTable[ii] = diagCap;
3155 _rc[ii]->_diag += diagCap;
3156
3157 const char* msg = "calcDiagRC";
3158 Debug_DiagValues(0.0, diagCap, msg);
3159 } else
3160 capTable[ii] = 2 * len * getUnderRC(rcModel)->_fringe;
3161 #else
3162 capTable[ii] = len * getDiagUnderCC(rcModel, dist, tgtMet);
3163 #endif
3164 }
3165 createCap(rsegId1, rsegId2, capTable);
3166 }
3167
3168 void extMeasure::calcRC(dbRSeg* rseg1, dbRSeg* rseg2, uint totLenCovered) {
3169 bool btermConnection = isBtermConnection(rseg1, rseg2);
3170
3171 int lenOverSub = _len - totLenCovered;
3172 // int mUnder= _underMet; // will be replaced
3173
3174 uint modelCnt = _metRCTable.getCnt();
3175
3176 for (uint model = 0; model < modelCnt; model++) {
3177 extMetRCTable* rcModel = _metRCTable.get(model);
3178
3179 if (totLenCovered > 0) {
3180 for (uint ii = 0; ii < _lenOUtable->getCnt(); ii++) {
3181 extLenOU* ou = _lenOUtable->get(ii);
3182
3183 _overMet = ou->_overMet;
3184 _underMet = ou->_underMet;
3185
3186 extDistRC* ouRC = NULL;
3187
3188 if (ou->_over)
3189 ouRC = getOverRC(rcModel);
3190 else if (ou->_under)
3191 ouRC = getUnderRC(rcModel);
3192 else if (ou->_overUnder)
3193 ouRC = getOverUnderRC(rcModel);
3194
3195 _rc[model]->addRC(ouRC, ou->_len, _dist > 0);
3196 }
3197 }
3198
3199 if (_dist < 0) { // dist is infinit
3200 ; /*
3201 extDistRC *rc1= _metRCTable.get(jj)->getOverFringeRC(this);
3202 if (rc1!=NULL)
3203 deltaFr[jj]= rc1->getFringe() * totLenCovered;
3204 */
3205 } else { // dist based
3206
3207 _underMet = 0;
3208
3209 extDistRC* rcOverSub = getOverRC(rcModel);
3210 if (lenOverSub > 0) {
3211 _rc[model]->addRC(rcOverSub, lenOverSub, _dist > 0);
3212 }
3213 double res = 0.0;
3214 if (rcOverSub != NULL)
3215 res = rcOverSub->_res * _len;
3216
3217 double deltaFr = 0.0;
3218 double deltaRes = 0.0;
3219 extDistRC* rcMaxDist = rcModel->getOverFringeRC(this);
3220
3221 if (rcMaxDist != NULL) {
3222 deltaFr = rcMaxDist->getFringe() * _len;
3223 deltaRes = rcMaxDist->_res * _len;
3224 res -= deltaRes;
3225 }
3226
3227 if (rseg1 != NULL)
3228 _extMain->updateRes(rseg1, res, model);
3229
3230 if (rseg2 != NULL)
3231 _extMain->updateRes(rseg2, res, model);
3232
3233 dbCCSeg* ccap = NULL;
3234 bool includeCoupling = true;
3235 if ((rseg1 != NULL) && (rseg2 != NULL)) { // signal nets
3236
3237 _totCCcnt++; // TO_TEST
3238
3239 if ((_rc[_minModelIndex]->_coupling >= _extMain->_coupleThreshold) ||
3240 btermConnection) {
3241 // dbNet* srcNet=
3242 // rseg1->getNet(); dbNet* tgtNet=
3243 // rseg2->getNet();
3244
3245 // ccap= dbCCSeg::create(srcNet, rseg1->getTargetNode(),
3246 // tgtNet, rseg2->getTargetNode(), true);
3247
3248 ccap = dbCCSeg::create(
3249 dbCapNode::getCapNode(_block, rseg1->getTargetNode()),
3250 dbCapNode::getCapNode(_block, rseg2->getTargetNode()), true);
3251
3252 includeCoupling = false;
3253 _totBigCCcnt++;
3254 } else
3255 _totSmallCCcnt++;
3256 }
3257 extDistRC* finalRC = _rc[model];
3258 if (ccap != NULL) {
3259 double coupling =
3260 _ccModify ? finalRC->_coupling * _ccFactor : finalRC->_coupling;
3261 ccap->addCapacitance(coupling, model);
3262 }
3263
3264 double frCap = _extMain->calcFringe(finalRC, deltaFr, includeCoupling);
3265
3266 if (rseg1 != NULL)
3267 _extMain->updateTotalCap(rseg1, frCap, model);
3268
3269 if (rseg2 != NULL)
3270 _extMain->updateTotalCap(rseg2, frCap, model);
3271 }
3272 }
3273 for (uint ii = 0; ii < _lenOUtable->getCnt(); ii++)
3274 _lenOUPool->free(_lenOUtable->get(ii));
3275
3276 _lenOUtable->resetCnt();
3277 }
3278
3279 void extMeasure::OverSubRC(dbRSeg* rseg1, dbRSeg* rseg2, int ouCovered,
3280 int diagCovered, int srcCovered) {
3281 int res_lenOverSub = _len - ouCovered; // 0228
3282 res_lenOverSub = 0; // 0315 -- new calc
3283 bool SCALING_RES = false;
3284
3285 int DIAG_SUB_DIVIDER = 1;
3286
3287 double SUB_MULT_CAP =
3288 1.0; // Open ended resitance should account by 1/4 -- 11/15
3289
3290 double SUB_MULT_RES = 1.0;
3291 if (SCALING_RES) {
3292 double dist_track = 0.0;
3293 SUB_MULT_RES = ScaleResbyTrack(true, dist_track);
3294 res_lenOverSub = _len;
3295 }
3296 int lenOverSub = _len - ouCovered;
3297 if (lenOverSub < 0)
3298 lenOverSub = 0;
3299
3300 bool rvia1 = rseg1 != NULL && isVia(rseg1->getId());
3301
3302 if (!((lenOverSub > 0) || (res_lenOverSub > 0))) {
3303 return;
3304 }
3305
3306 _underMet = 0;
3307 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3308 extDistRC* rc = _metRCTable.get(jj)->getOverFringeRC(this);
3309 if (rc == NULL)
3310 continue;
3311 double cap = 0;
3312 double tot = 0;
3313 if (lenOverSub > 0) {
3314 cap = SUB_MULT_CAP * rc->getFringe() * lenOverSub;
3315 tot = _extMain->updateTotalCap(rseg1, cap, jj);
3316 }
3317 double res = 0;
3318 if (!_extMain->_lef_res && !rvia1) {
3319 if (res_lenOverSub > 0) {
3320 extDistRC* rc0 = _metRCTable.get(jj)->getOverFringeRC(this, 0);
3321 extDistRC* rc_last =
3322 _metRCTable.get(jj)->getOverFringeRC_last(_met, _width);
3323 double delta0 = rc0->_res - rc_last->_res;
3324 if (delta0 < 0)
3325 delta0 = -delta0;
3326 if (delta0 < 0.000001)
3327 SUB_MULT_RES = 1.0;
3328 // if (lenOverSub>0) {
3329 res = rc->getRes() * res_lenOverSub;
3330 res *= SUB_MULT_RES;
3331 _extMain->updateRes(rseg1, res, jj);
3332 }
3333 }
3334 const char* msg = "OverSubRC (No Neighbor)";
3335 OverSubDebug(rc, lenOverSub, res_lenOverSub, res, cap, msg);
3336 }
3337 }
3338
3339 /**
3340 * ScaleResbyTrack scales the original calculation by
3341 * a coefficient depending on how many track(s) away the
3342 * nearest neighbors to the wire of interest.
3343 *
3344 * To scale the calculated resistance to be closer to
3345 * golden resistance from commercial tool.
3346 *
3347 * @return the scaling coefficient for the resistance.
3348 * @currently not used
3349 */
3350 double extMeasure::ScaleResbyTrack(bool openEnded, double& dist_track) {
3351 dist_track = 0.0;
3352
3353 bool SKIP_SCALING = false;
3354 if (SKIP_SCALING)
3355 return 1;
3356
3357 // Dividers: 1, 1.2, 2, 3 respectively for tracks: 1, 2, >=3 --- assumption:
3358 // extRules is 1/2 of total res
3359 double SUB_MULT_RES = 1;
3360 if (openEnded) {
3361 SUB_MULT_RES = 0.4;
3362 return SUB_MULT_RES;
3363 }
3364 if (_extMain->_minDistTable[_met] > 0 && !SKIP_SCALING) {
3365 dist_track = _dist / _extMain->_minDistTable[_met];
3366 if (dist_track >= 3)
3367 SUB_MULT_RES = 2.0 / (1 + 4);
3368 else if (dist_track > 1 && dist_track <= 2)
3369 SUB_MULT_RES = 1;
3370 else if (dist_track > 2 && dist_track <= 4)
3371 SUB_MULT_RES = 2.0 / (1 + 3);
3372 }
3373 return SUB_MULT_RES;
3374 }
3375
3376 void extMeasure::OverSubRC_dist(dbRSeg* rseg1, dbRSeg* rseg2, int ouCovered,
3377 int diagCovered, int srcCovered) {
3378 double SUB_MULT = 1.0;
3379 double dist_track = 0.0;
3380 double SUB_MULT_RES = ScaleResbyTrack(false, dist_track);
3381 double res_lenOverSub = _len;
3382 res_lenOverSub = 0; // 0315 -- new calc
3383 // ----------------------------------------- DF Scaling - 022821
3384 int lenOverSub = _len - ouCovered;
3385
3386 int lenOverSub_bot = _len - srcCovered;
3387 if (lenOverSub_bot > 0)
3388 lenOverSub += lenOverSub_bot;
3389
3390 // bool rvia1= rseg1!=NULL && extMain::getShapeProperty_rc(rseg1->getNet(),
3391 // rseg1->getId())>0; bool rvia2= rseg2!=NULL &&
3392 // extMain::getShapeProperty_rc(rseg2->getNet(), rseg2->getId())>0;
3393 bool rvia1 = rseg1 != NULL && isVia(rseg1->getId());
3394 bool rvia2 = rseg2 != NULL && isVia(rseg2->getId());
3395
3396 if (!((lenOverSub > 0) || (res_lenOverSub > 0))) {
3397 return;
3398 }
3399 _underMet = 0;
3400 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3401 extMetRCTable* rcModel = _metRCTable.get(jj);
3402 extDistRC* rc = getOverRC(rcModel);
3403
3404 extDistRC* rc_last = rcModel->getOverFringeRC_last(_met, _width);
3405 double delta = rc->_res - rc_last->_res;
3406 if (delta < 0)
3407 delta = -delta;
3408
3409 extDistRC* rc0 = rcModel->getOverFringeRC(this, 0);
3410 double delta0 = rc0->_res - rc_last->_res;
3411 if (delta0 < 0)
3412 delta0 = -delta0;
3413
3414 SUB_MULT_RES = 1.0;
3415
3416 if (rc == NULL)
3417 continue;
3418
3419 double res = rc->getRes() * res_lenOverSub;
3420 res *= SUB_MULT_RES;
3421
3422 if (!_extMain->_lef_res) {
3423 if (!rvia1)
3424 _extMain->updateRes(rseg1, res, jj);
3425 if (!rvia2)
3426 _extMain->updateRes(rseg2, res, jj);
3427 }
3428
3429 double tot = 0;
3430 double fr = 0;
3431 double cc = 0;
3432 if (lenOverSub > 0) {
3433 if (_sameNetFlag) { // TO OPTIMIZE
3434 fr = SUB_MULT * rc->getFringe() * lenOverSub;
3435 tot = _extMain->updateTotalCap(rseg1, fr, jj);
3436 } else {
3437 double fr = SUB_MULT * rc->getFringe() * lenOverSub;
3438 tot = _extMain->updateTotalCap(rseg1, fr, jj);
3439 _extMain->updateTotalCap(rseg2, fr, jj);
3440
3441 if (_dist > 0) { // dist based
3442 cc = SUB_MULT * rc->getCoupling() * lenOverSub;
3443 _extMain->updateCoupCap(rseg1, rseg2, jj, cc);
3444 tot += cc;
3445 }
3446 }
3447 }
3448 const char* msg = "OverSubRC_dist (With Neighbor)";
3449 OverSubDebug(rc, lenOverSub, lenOverSub, res, fr + cc, msg);
3450 }
3451 }
3452
3453 int extMeasure::computeAndStoreRC(dbRSeg* rseg1, dbRSeg* rseg2,
3454 int srcCovered) {
3455 bool DEBUG1 = false;
3456 if (DEBUG1) {
3457 segInfo("SRC", _netSrcId, _rsegSrcId);
3458 segInfo("DST", _netTgtId, _rsegTgtId);
3459 }
3460 // Copy from computeAndStoreRC_720
3461 bool SUBTRACT_DIAG = false;
3462 bool no_ou = true;
3463 bool USE_DB_UBITS = false;
3464 if (rseg1 == NULL && rseg2 == NULL)
3465 return 0;
3466
3467 bool traceFlag = false;
3468 bool watchFlag = IsDebugNet();
3469
3470 rcSegInfo();
3471 if (IsDebugNet())
3472 debugPrint(logger_, RCX, "debug_net", 1,
3473 "measureRC:"
3474 "C"
3475 "\t[BEGIN-OUD] ----- OverUnder/Diagonal RC ----- BEGIN");
3476
3477 uint modelCnt = _metRCTable.getCnt();
3478 int totLenCovered = 0;
3479 _lenOUtable->resetCnt();
3480 if (_extMain->_usingMetalPlanes && (_extMain->_geoThickTable == NULL)) {
3481 _diagLen = 0;
3482 if (_extMain->_ccContextDepth > 0) {
3483 if (!_diagFlow)
3484 totLenCovered = measureOverUnderCap();
3485 else {
3486 totLenCovered = measureDiagOU(1, 2);
3487 }
3488 }
3489 }
3490 ouCovered_debug(totLenCovered);
3491
3492 if (USE_DB_UBITS) {
3493 totLenCovered = _extMain->GetDBcoords2(totLenCovered);
3494 _len = _extMain->GetDBcoords2(_len);
3495 _diagLen = _extMain->GetDBcoords2(_diagLen);
3496 }
3497 int lenOverSub = _len - totLenCovered;
3498
3499 if (_diagLen > 0 && SUBTRACT_DIAG)
3500 lenOverSub -= _diagLen;
3501
3502 if (lenOverSub < 0)
3503 lenOverSub = 0;
3504
3505 double deltaFr[10];
3506 double deltaRes[10];
3507 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3508 deltaFr[jj] = 0.0;
3509 deltaRes[jj] = 0.0;
3510 }
3511 double SUB_MULT = 1.0;
3512 bool COMPUTE_OVER_SUB = true;
3513
3514 // Case where the geometric search returns no neighbor found
3515 // _dist is infinit
3516 if (_dist < 0) {
3517 if (totLenCovered < 0)
3518 totLenCovered = 0;
3519
3520 _underMet = 0;
3521
3522 _no_debug = true;
3523 _no_debug = false;
3524
3525 bool rvia1 = isVia(rseg1->getId());
3526 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3527 bool ou = false;
3528 _rc[jj]->_res = 0; // DF 022821 : Res non context based
3529
3530 if (_rc[jj]->_fringe > 0) {
3531 ou = true;
3532 double tot = _extMain->updateTotalCap(rseg1, _rc[jj]->_fringe, jj);
3533 }
3534 if (ou && IsDebugNet())
3535 _rc[jj]->printDebugRC_values("OverUnder Total Open");
3536 }
3537 if (IsDebugNet())
3538 debugPrint(logger_, RCX, "debug_net", 1,
3539 "measureRC:"
3540 "C",
3541 "\t[END-OUD] ----- OverUnder/Diagonal ----- END");
3542 rcSegInfo();
3543
3544 if (COMPUTE_OVER_SUB) {
3545 OverSubRC(rseg1, NULL, totLenCovered, _diagLen, _len);
3546 return totLenCovered;
3547 }
3548 } else { // dist based
3549
3550 _underMet = 0;
3551
3552 // getFringe(_len, deltaFr);
3553 // _no_debug= true;
3554 // computeR(_len, deltaRes);
3555 // _no_debug= false;
3556 // _extMain->updateTotalRes(rseg1, rseg2, this, deltaRes, modelCnt);
3557
3558 bool rvia1 = rseg1 != NULL && isVia(rseg1->getId());
3559 bool rvia2 = rseg2 != NULL && isVia(rseg2->getId());
3560
3561 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3562 bool ou = false;
3563 double totR1 = 0;
3564 double totR2 = 0;
3565 /* Res NOT context dependent DF: 022821
3566 if (!_extMain->_lef_res && _rc[jj]->_res > 0) {
3567 if (!rvia1) {
3568 ou = true;
3569 totR1 = _extMain->updateRes(rseg1, _rc[jj]->_res, jj);
3570 }
3571 if (!rvia2) {
3572 ou = true;
3573 totR2 = _extMain->updateRes(rseg2, _rc[jj]->_res, jj);
3574 }
3575 } */
3576 double tot1 = 0;
3577 double tot2 = 0;
3578 if (_rc[jj]->_fringe > 0) {
3579 ou = true;
3580 tot1 = _extMain->updateTotalCap(rseg1, _rc[jj]->_fringe, jj);
3581 tot2 = _extMain->updateTotalCap(rseg2, _rc[jj]->_fringe, jj);
3582 }
3583 if (_rc[jj]->_coupling > 0) {
3584 ou = true;
3585 _extMain->updateCoupCap(rseg1, rseg2, jj, _rc[jj]->_coupling);
3586 }
3587 tot1 += _rc[jj]->_coupling;
3588 tot2 += _rc[jj]->_coupling;
3589 if (ou && IsDebugNet())
3590 _rc[jj]->printDebugRC_values("OverUnder Total Dist");
3591 }
3592 rcSegInfo();
3593 if (IsDebugNet())
3594 debugPrint(logger_, RCX, "debug_net", 1,
3595 "measureRC:"
3596 "C"
3597 "\t[END-OUD] ------ OverUnder/Diagonal RC ------ END");
3598
3599 if (COMPUTE_OVER_SUB) {
3600 // OverSubRC(rseg1, NULL, totLenCovered, _diagLen, srcCovered);
3601 OverSubRC_dist(rseg1, rseg2, totLenCovered, _diagLen, _len);
3602 return totLenCovered;
3603 }
3604 }
3605 return totLenCovered;
3606 }
3607
3608 void extMeasure::measureRC(CoupleOptions& options) {
3609 // return;
3610
3611 _totSegCnt++;
3612
3613 int rsegId1 = options[1]; // dbRSeg id for SRC segment
3614 int rsegId2 = options[2]; // dbRSeg id for Target segment
3615
3616 // if ((rsegId1<0)&&(rsegId2<0)) // power nets
3617 // return;
3618
3619 _rsegSrcId = rsegId1;
3620 _rsegTgtId = rsegId2;
3621
3622 defineBox(options);
3623
3624 if (_extMain->_lefRC)
3625 return;
3626
3627 //_netId= 0;
3628 #ifdef DEBUG_NET
3629 uint debugNetId = DEBUG_NET;
3630 #endif
3631
3632 dbRSeg* rseg1 = NULL;
3633 dbNet* srcNet = NULL;
3634 uint netId1 = 0;
3635 if (rsegId1 > 0) {
3636 rseg1 = dbRSeg::getRSeg(_block, rsegId1);
3637 srcNet = rseg1->getNet();
3638 netId1 = srcNet->getId();
3639 #ifdef DEBUG_NET
3640 printNet(rseg1, debugNetId);
3641 #endif
3642 }
3643 // fprintf(stdout, "net: %d %s\n", netId1, srcNet->getConstName());
3644 _netSrcId = netId1;
3645
3646 dbRSeg* rseg2 = NULL;
3647 dbNet* tgtNet = NULL;
3648 uint netId2 = 0;
3649 if (rsegId2 > 0) {
3650 rseg2 = dbRSeg::getRSeg(_block, rsegId2);
3651 tgtNet = rseg2->getNet();
3652 netId2 = tgtNet->getId();
3653 #ifdef DEBUG_NET
3654 printNet(rseg2, debugNetId);
3655 #endif
3656 }
3657 #ifdef HI_ACC_1
3658 _sameNetFlag = (srcNet == tgtNet);
3659 #endif
3660
3661 _netTgtId = netId2;
3662
3663 _totSignalSegCnt++;
3664
3665 if (_met >= (int)_layerCnt) // TO_TEST
3666 return;
3667 // if (netId1==netId2)
3668 // return;
3669
3670 if (_extMain->_measureRcCnt >= 0) {
3671 if (_extMain->_printFile == NULL)
3672 _extMain->_printFile = fopen("measureRC.1", "w");
3673 fprintf(_extMain->_printFile,
3674 "%d met= %d len= %d dist= %d r1= %d r2= %d\n", _totSignalSegCnt,
3675 _met, _len, _dist, rsegId1, rsegId2);
3676 }
3677 if (_extMain->_geoThickTable != NULL) {
3678 double diff = 0.0;
3679
3680 if ((_extMain->_geoThickTable[_met] != NULL) &&
3681 !_extMain->_geoThickTable[_met]
3682 ->getThicknessDiff(_ll[0], _ll[1], _width, diff)) {
3683 _metRCTable.set(0, _extMain->getRCmodel(0)->getMetRCTable(0));
3684 } else {
3685 uint n = _extMain->getRCmodel(0)->findBiggestDatarateIndex(diff);
3686 n = _extMain->getRCmodel(0)->findClosestDataRate(n, diff);
3687 _metRCTable.set(0, _extMain->getRCmodel(0)->getMetRCTable(n));
3688 }
3689
3690 /*
3691 double thRef= 0.5;
3692 double nomThick= 0.0;
3693 double thickDiff=
3694 _extMain->_geoThickTable[_met]->getThicknessDiff(_ll[0], _ll[1], _width,
3695 nomThick);
3696
3697 double th= 0.001*nomThick*(1+thickDiff);
3698
3699 double diff= (th-thRef)/thRef;
3700 if (diff==0.0) {
3701 _metRCTable.set(1,
3702 _extMain->getRCmodel(0)->getMetRCTable(0));
3703 }
3704 else {
3705 uint n=
3706 _extMain->getRCmodel(0)->findBiggestDatarateIndex(diff);
3707 _metRCTable.set(1,
3708 _extMain->getRCmodel(0)->getMetRCTable(n));
3709 }
3710 // set 2nd model with
3711 */
3712 }
3713 // uint modelCnt= _metRCTable.getCnt();
3714 _verticalDiag = _currentModel->getVerticalDiagFlag();
3715 int prevCovered = options[20];
3716 prevCovered = 0;
3717
3718 // -------------------------------- db units -------------
3719 bool USE_DB_UNITS = false;
3720 if (USE_DB_UNITS) {
3721 if (_dist > 0)
3722 _dist = _extMain->GetDBcoords2(_dist);
3723 _width = _extMain->GetDBcoords2(_width);
3724 }
3725 // if (_dist>0)
3726 // _dist= 64;
3727
3728 _netId = _extMain->_debug_net_id;
3729
3730 DebugStart();
3731
3732 int totCovered = computeAndStoreRC(rseg1, rseg2, prevCovered);
3733
3734 bool rvia1 = rseg1 != NULL && isVia(rseg1->getId());
3735 if (!rvia1 && rseg1 != NULL) {
3736 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3737 _rc[jj]->_res = 0;
3738 }
3739 bool DEBUG1 = _netId == 604801;
3740 if (IsDebugNet()) {
3741 const char* netName = "";
3742 if (_netId > 0) {
3743 dbNet* net = dbNet::getNet(_block, _netId);
3744 netName = net->getConstName();
3745 }
3746 fprintf(stdout,
3747 " ---------------------------------------------------------------"
3748 "------------------\n");
3749 fprintf(stdout, " %7d %7d %7d %7d M%d D%d L%d N%d N%d %s\n",
3750 _ll[0], _ur[0], _ll[1], _ur[1], _met, _dist, _len, _netSrcId,
3751 _netTgtId, netName);
3752 fprintf(stdout,
3753 " ---------------------------------------------------------------"
3754 "------------------\n");
3755 }
3756 uint track_num = options[18];
3757 double deltaRes[10];
3758 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3759 deltaRes[jj] = 0.0;
3760 }
3761 // if (_dist>0)
3762
3763 SEQ* s = addSeq(_ll, _ur);
3764 int len_covered = computeResDist(s, 1, 4, _met, NULL);
3765 int len_down_not_coupled = _len - len_covered;
3766
3767 int maxDist = getMaxDist(_met, 0);
3768 if (_dist > 0 && len_down_not_coupled > 0) {
3769 calcRes(rseg1->getId(), len_down_not_coupled, 0, _dist, _met);
3770 len_covered += len_down_not_coupled;
3771 }
3772 if (len_covered > 0) {
3773 calcRes0(deltaRes, _met, len_covered);
3774 }
3775 // calcRes(_rsegSrcId, len_down_not_coupled, _dist, 0, _met);
3776
3777 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3778 double totR1 = _rc[jj]->_res;
3779 if (totR1 > 0) {
3780 totR1 -= deltaRes[jj];
3781 double totalSegCap = 0;
3782 if (totR1 != 0.0)
3783 totalSegCap = _extMain->updateRes(rseg1, totR1, jj);
3784 }
3785 }
3786 }
3787 if (IsDebugNet())
3788 debugPrint(logger_, RCX, "debug_net", 1,
3789 "[END-DistRC:C]"
3790 "\tDistRC:C"
3791 " ----- measureRC: ----- END\n");
3792 options[20] = totCovered;
3793
3794 // ccReportProgress();
3795 }
3796
3797 int extMeasure::computeAndStoreRC_720(dbRSeg* rseg1, dbRSeg* rseg2,
3798 int srcCovered) {
3799 bool SUBTRACT_DIAG = false;
3800 bool no_ou = true;
3801 bool USE_DB_UBITS = false;
3802 if (rseg1 == NULL && rseg2 == NULL)
3803 return 0;
3804
3805 bool traceFlag = false;
3806 bool watchFlag = IsDebugNet();
3807 _netId = _extMain->_debug_net_id;
3808 if (_netId > 0)
3809 traceFlag = printTraceNet("\nBEGIN", true, NULL, 0, 0);
3810
3811 uint modelCnt = _metRCTable.getCnt();
3812 int totLenCovered = 0;
3813 _lenOUtable->resetCnt();
3814 if (_extMain->_usingMetalPlanes && (_extMain->_geoThickTable == NULL)) {
3815 _diagLen = 0;
3816 if (_extMain->_ccContextDepth > 0) {
3817 if (!_diagFlow)
3818 totLenCovered = measureOverUnderCap();
3819 else
3820 totLenCovered = measureDiagOU(1, 2);
3821 }
3822 }
3823 totLenCovered += srcCovered;
3824
3825 #ifdef MIN_FOR_LOOPS
3826
3827 calcRC(rseg1, rseg2, totLenCovered);
3828 return;
3829 #endif
3830
3831 double deltaFr[10];
3832 double deltaRes[10];
3833 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3834 deltaFr[jj] = 0.0;
3835 deltaRes[jj] = 0.0;
3836 }
3837 if (USE_DB_UBITS) {
3838 totLenCovered = _extMain->GetDBcoords2(totLenCovered);
3839 _len = _extMain->GetDBcoords2(_len);
3840 _diagLen = _extMain->GetDBcoords2(_diagLen);
3841 }
3842 int lenOverSub = _len - totLenCovered;
3843
3844 if (_diagLen > 0 && SUBTRACT_DIAG)
3845 lenOverSub -= _diagLen;
3846
3847 if (lenOverSub < 0)
3848 lenOverSub = 0;
3849
3850 if (traceFlag) {
3851 debugPrint(logger_, RCX, "debug_net", 2,
3852 "Trace:"
3853 "C"
3854 " OU {} SUB {} DIAG {} PREV_COVERED {}",
3855 totLenCovered, lenOverSub, _diagLen, srcCovered);
3856 printNetCaps();
3857 }
3858 // printTraceNet("OU", false, NULL, lenOverSub, totLenCovered);
3859
3860 // int mUnder= _underMet; // will be replaced
3861
3862 double SUB_MULT = 1.0;
3863 bool COMPUTE_OVER_SUB = true;
3864 if (_dist < 0) { // dist is infinit
3865 if (totLenCovered < 0)
3866 totLenCovered = 0;
3867
3868 computeR(_len, deltaRes);
3869 _extMain->updateTotalRes(rseg1, rseg2, this, deltaRes, modelCnt);
3870
3871 if (totLenCovered > 0) {
3872 _underMet = 0;
3873 for (uint jj = 0; jj < _metRCTable.getCnt(); jj++) {
3874 extDistRC* rc = _metRCTable.get(jj)->getOverFringeRC(this);
3875 if (rc != NULL) {
3876 deltaFr[jj] = SUB_MULT * rc->getFringe() * totLenCovered;
3877 deltaRes[jj] = rc->getRes() * totLenCovered;
3878 }
3879 }
3880 // computeR(_len, deltaRes);
3881 // _extMain->updateTotalRes(rseg1, rseg2, this, deltaRes, modelCnt);
3882
3883 if (rseg1 != NULL)
3884 #ifdef HI_ACC_1
3885 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, false, false);
3886 #else
3887 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, false);
3888 #endif
3889 if (rseg2 != NULL)
3890 _extMain->updateTotalCap(rseg2, this, deltaFr, modelCnt, false);
3891
3892 if (traceFlag)
3893 printTraceNet("0D", false, NULL, lenOverSub, totLenCovered);
3894 }
3895 } else { // dist based
3896
3897 if (lenOverSub > 0) {
3898 _underMet = 0;
3899 computeOverRC(lenOverSub);
3900 }
3901
3902 // deltaFr[jj]= getFringe(m._met, m._width, jj) * m._len; TO_TEST
3903 // ---------------------------------- TO DEBUG ------------
3904 getFringe(_len, deltaFr);
3905 // ---------------------------------- TO DEBUG ------------
3906
3907 computeR(_len, deltaRes);
3908 _extMain->updateTotalRes(rseg1, rseg2, this, deltaRes, modelCnt);
3909
3910 if ((rseg1 != NULL) && (rseg2 != NULL)) { // signal nets
3911
3912 bool btermConnection = isBtermConnection(rseg1, rseg2);
3913
3914 _totCCcnt++; // TO_TEST
3915 #ifdef HI_ACC_2
3916 if (rseg1->getNet() == rseg2->getNet()) { // same signal net
3917 #ifdef HI_ACC_1
3918 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, false, true);
3919 #else
3920 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, false);
3921 #endif
3922 _extMain->updateTotalCap(rseg2, this, deltaFr, modelCnt, false);
3923
3924 if (traceFlag)
3925 printTraceNet("AC2", false, NULL, 0, 0);
3926
3927 return totLenCovered;
3928 }
3929 #endif
3930
3931 if ((_rc[_minModelIndex]->_coupling < _extMain->_coupleThreshold) &&
3932 !btermConnection) { // TO_TEST
3933
3934 #ifdef HI_ACC_1
3935 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, true, true);
3936 #else
3937 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, true);
3938 #endif
3939 _extMain->updateTotalCap(rseg2, this, deltaFr, modelCnt, true);
3940
3941 if (traceFlag)
3942 printTraceNet("cC", false);
3943
3944 _totSmallCCcnt++;
3945
3946 return totLenCovered;
3947 }
3948 _totBigCCcnt++;
3949
3950 // dbNet* srcNet= rseg1->getNet();
3951 // dbNet* tgtNet= rseg2->getNet();
3952
3953 dbCCSeg* ccap = dbCCSeg::create(
3954 dbCapNode::getCapNode(_block, rseg1->getTargetNode()),
3955 dbCapNode::getCapNode(_block, rseg2->getTargetNode()), true);
3956
3957 double cap;
3958 int extDbIndex, sci, scDbIndex;
3959 for (uint jj = 0; jj < modelCnt; jj++) {
3960 cap = _ccModify ? _rc[jj]->_coupling * _ccFactor : _rc[jj]->_coupling;
3961 extDbIndex = _extMain->getProcessCornerDbIndex(jj);
3962 ccap->addCapacitance(cap, extDbIndex);
3963 _extMain->getScaledCornerDbIndex(jj, sci, scDbIndex);
3964 if (sci != -1) {
3965 _extMain->getScaledCC(sci, cap);
3966 ccap->addCapacitance(cap, scDbIndex);
3967 }
3968 int net1 = rseg1->getNet()->getId();
3969 int net2 = rseg2->getNet()->getId();
3970 if (_netId == net1 || _netId == net2) {
3971 debugPrint(logger_, RCX, "debug_net", 2,
3972 "Trace:"
3973 "C"
3974 "\taddCapacitance-CC: {}-{} {}-{} {}",
3975 net1, rseg1->getId(), net2, rseg2->getId(), cap);
3976 }
3977 }
3978 // --------------------------- to test it was include_coupling= false
3979 bool include_coupling = false;
3980 // updateCCCap(rseg1, rseg2, m._rc->_coupling);
3981 #ifdef HI_ACC_1
3982 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, include_coupling,
3983 true);
3984 #else
3985 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, false);
3986 #endif
3987 _extMain->updateTotalCap(rseg2, this, deltaFr, modelCnt, false);
3988
3989 if (traceFlag)
3990 printTraceNet("CC", false, ccap);
3991
3992 } else if (rseg1 != NULL) {
3993 #ifdef HI_ACC_1
3994 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, true, true);
3995 #else
3996 _extMain->updateTotalCap(rseg1, this, deltaFr, modelCnt, true);
3997 #endif
3998 if (traceFlag)
3999 printTraceNet("GN", false);
4000 } else if (rseg2 != NULL) {
4001 _extMain->updateTotalCap(rseg2, this, deltaFr, modelCnt, true);
4002 if (traceFlag)
4003 printTraceNet("GN", false);
4004 }
4005 }
4006 return totLenCovered;
4007 }
4008
4009 void extMeasure::getDgOverlap(SEQ* sseq, uint dir,
4010 Ath__array1D<SEQ*>* dgContext,
4011 Ath__array1D<SEQ*>* overlapSeq,
4012 Ath__array1D<SEQ*>* residueSeq) {
4013 int idx = dgContext->get(0)->_ll[0];
4014 uint lp = dir ? 0 : 1; // x : y
4015 uint wp = dir ? 1 : 0; // y : x
4016 SEQ* rseq;
4017 SEQ* tseq;
4018 SEQ* wseq;
4019 int covered = sseq->_ll[lp];
4020
4021 #ifdef HI_ACC_1
4022 if (idx == dgContext->getCnt()) {
4023 rseq = _seqPool->alloc();
4024 rseq->_ll[wp] = sseq->_ll[wp];
4025 rseq->_ur[wp] = sseq->_ur[wp];
4026 rseq->_ll[lp] = sseq->_ll[lp];
4027 rseq->_ur[lp] = sseq->_ur[lp];
4028 residueSeq->add(rseq);
4029 return;
4030 }
4031 #endif
4032
4033 dbRSeg* srseg = NULL;
4034 if (_rsegSrcId > 0)
4035 srseg = dbRSeg::getRSeg(_block, _rsegSrcId);
4036 for (; idx < (int)dgContext->getCnt(); idx++) {
4037 tseq = dgContext->get(idx);
4038 if (tseq->_ur[lp] <= covered)
4039 continue;
4040
4041 if (tseq->_ll[lp] >= sseq->_ur[lp]) {
4042 rseq = _seqPool->alloc();
4043 rseq->_ll[wp] = sseq->_ll[wp];
4044 rseq->_ur[wp] = sseq->_ur[wp];
4045 rseq->_ll[lp] = covered;
4046 rseq->_ur[lp] = sseq->_ur[lp];
4047 assert(rseq->_ur[lp] >= rseq->_ll[lp]);
4048 residueSeq->add(rseq);
4049 break;
4050 }
4051 #ifdef CHECK_SAME_NET
4052 dbRSeg* trseg = NULL;
4053 if (tseq->type > 0)
4054 trseg = dbRSeg::getRSeg(_block, tseq->type);
4055 if ((trseg != NULL) && (srseg != NULL) &&
4056 (trseg->getNet() == srseg->getNet())) {
4057 if ((tseq->_ur[lp] >= sseq->_ur[lp]) ||
4058 (idx == (int)dgContext->getCnt() - 1)) {
4059 rseq = _seqPool->alloc();
4060 rseq->_ll[wp] = sseq->_ll[wp];
4061 rseq->_ur[wp] = sseq->_ur[wp];
4062 rseq->_ll[lp] = covered;
4063 rseq->_ur[lp] = sseq->_ur[lp];
4064 assert(rseq->_ur[lp] >= rseq->_ll[lp]);
4065 residueSeq->add(rseq);
4066 break;
4067 } else
4068 continue;
4069 }
4070 #endif
4071 wseq = _seqPool->alloc();
4072 wseq->type = tseq->type;
4073 wseq->_ll[wp] = tseq->_ll[wp];
4074 wseq->_ur[wp] = tseq->_ur[wp];
4075 if (tseq->_ur[lp] <= sseq->_ur[lp])
4076 wseq->_ur[lp] = tseq->_ur[lp];
4077 else
4078 wseq->_ur[lp] = sseq->_ur[lp];
4079 if (tseq->_ll[lp] <= covered)
4080 wseq->_ll[lp] = covered;
4081 else {
4082 wseq->_ll[lp] = tseq->_ll[lp];
4083 rseq = _seqPool->alloc();
4084 rseq->_ll[wp] = sseq->_ll[wp];
4085 rseq->_ur[wp] = sseq->_ur[wp];
4086 rseq->_ll[lp] = covered;
4087 rseq->_ur[lp] = tseq->_ll[lp];
4088 assert(rseq->_ur[lp] >= rseq->_ll[lp]);
4089 residueSeq->add(rseq);
4090 }
4091 assert(wseq->_ur[lp] >= wseq->_ll[lp]);
4092 overlapSeq->add(wseq);
4093 covered = wseq->_ur[lp];
4094 if (tseq->_ur[lp] >= sseq->_ur[lp])
4095 break;
4096 if (idx == (int)dgContext->getCnt() - 1 && covered < sseq->_ur[lp]) {
4097 rseq = _seqPool->alloc();
4098 rseq->_ll[wp] = sseq->_ll[wp];
4099 rseq->_ur[wp] = sseq->_ur[wp];
4100 rseq->_ll[lp] = covered;
4101 rseq->_ur[lp] = sseq->_ur[lp];
4102 assert(rseq->_ur[lp] >= rseq->_ll[lp]);
4103 residueSeq->add(rseq);
4104 }
4105 }
4106 dgContext->get(0)->_ll[0] = idx;
4107 }
4108
4109 void extMeasure::getDgOverlap(CoupleOptions& options) {
4110 int ttttprintOverlap = 1;
4111 int srcseqcnt = 0;
4112 if (ttttprintOverlap && !_dgContextFile) {
4113 _dgContextFile = fopen("overlapSeq.1", "w");
4114 fprintf(_dgContextFile, "wire overlapping context:\n");
4115 srcseqcnt = 0;
4116 }
4117 uint met = -options[0];
4118 srcseqcnt++;
4119 SEQ* seq = _seqPool->alloc();
4120 SEQ* pseq;
4121 int dir = options[6];
4122 uint xidx = 0;
4123 uint yidx = 1;
4124 uint lidx, bidx;
4125 lidx = dir == 1 ? xidx : yidx;
4126 bidx = dir == 1 ? yidx : xidx;
4127 seq->_ll[lidx] = options[1];
4128 seq->_ll[bidx] = options[3];
4129 seq->_ur[lidx] = options[2];
4130 seq->_ur[bidx] = options[4];
4131 if (ttttprintOverlap)
4132 fprintf(_dgContextFile,
4133 "\nSource Seq %d:ll_0=%d ll_1=%d ur_0=%d ur_1=%d met=%d dir=%d\n",
4134 srcseqcnt, seq->_ll[0], seq->_ll[1], seq->_ur[0], seq->_ur[1], met,
4135 dir);
4136 Ath__array1D<SEQ*> overlapSeq(16);
4137 Ath__array1D<SEQ*> residueSeq(16);
4138 Ath__array1D<SEQ*>* dgContext = NULL;
4139 for (int jj = 1; jj <= *_dgContextHiLvl; jj++) {
4140 int gridn = *_dgContextDepth + jj;
4141 for (int kk = 0; kk <= _dgContextHiTrack[gridn]; kk++) {
4142 int trackn = *_dgContextTracks / 2 + kk;
4143 dgContext = _dgContextArray[gridn][trackn];
4144 overlapSeq.resetCnt();
4145 residueSeq.resetCnt();
4146 getDgOverlap(seq, dir, dgContext, &overlapSeq, &residueSeq);
4147 if (!ttttprintOverlap)
4148 continue;
4149
4150 for (uint ss = 0; ss < overlapSeq.getCnt(); ss++) {
4151 pseq = overlapSeq.get(ss);
4152 fprintf(
4153 _dgContextFile,
4154 "\n overlap %d:ll_0=%d ll_1=%d ur_0=%d ur_1=%d met=%d trk=%d\n",
4155 ss, pseq->_ll[0], pseq->_ll[1], pseq->_ur[0], pseq->_ur[1],
4156 jj + met, kk + _dgContextBaseTrack[gridn]);
4157 }
4158 for (uint ss1 = 0; ss1 < residueSeq.getCnt(); ss1++) {
4159 if (ss1 == 0 && overlapSeq.getCnt() == 0)
4160 fprintf(_dgContextFile, "\n");
4161 pseq = residueSeq.get(ss1);
4162 fprintf(
4163 _dgContextFile,
4164 " residue %d:ll_0=%d ll_1=%d ur_0=%d ur_1=%d met=%d trk=%d\n",
4165 ss1, pseq->_ll[0], pseq->_ll[1], pseq->_ur[0], pseq->_ur[1],
4166 jj + met, kk + _dgContextBaseTrack[gridn]);
4167 }
4168 }
4169 }
4170 }
4171
4172 void extMeasure::initTargetSeq() {
4173 Ath__array1D<SEQ*>* dgContext = NULL;
4174 SEQ* seq;
4175 for (int jj = 1; jj <= *_dgContextHiLvl; jj++) {
4176 int gridn = *_dgContextDepth + jj;
4177 for (int kk = _dgContextLowTrack[gridn]; kk <= _dgContextHiTrack[gridn];
4178 kk++) {
4179 int trackn = *_dgContextTracks / 2 + kk;
4180 dgContext = _dgContextArray[gridn][trackn];
4181 seq = dgContext->get(0);
4182 seq->_ll[0] = 1;
4183 }
4184 }
4185 }
4186
4187 void extMeasure::printDgContext() {
4188 if (_dgContextFile == NULL)
4189 //_dgContextFile=stdout;
4190 return;
4191
4192 _dgContextCnt++;
4193 fprintf(_dgContextFile, "diagonalContext %d: baseLevel %d\n", _dgContextCnt,
4194 *_dgContextBaseLvl);
4195 Ath__array1D<SEQ*>* dgContext = NULL;
4196 SEQ* seq = NULL;
4197 for (int jj = *_dgContextLowLvl; jj <= *_dgContextHiLvl; jj++) {
4198 int gridn = *_dgContextDepth + jj;
4199 fprintf(_dgContextFile, " level %d, plane %d, baseTrack %d\n",
4200 *_dgContextBaseLvl + jj, gridn, _dgContextBaseTrack[gridn]);
4201 int lowTrack = _dgContextLowTrack[gridn];
4202 int hiTrack = _dgContextHiTrack[gridn];
4203 for (int kk = lowTrack; kk <= hiTrack; kk++) {
4204 int trackn = *_dgContextTracks / 2 + kk;
4205 dgContext = _dgContextArray[gridn][trackn];
4206 fprintf(_dgContextFile, " track %d (%d), %d seqs\n",
4207 _dgContextBaseTrack[gridn] + kk, trackn, dgContext->getCnt());
4208 for (uint ii = 0; ii < dgContext->getCnt(); ii++) {
4209 seq = dgContext->get(ii);
4210 fprintf(_dgContextFile,
4211 " seq %d: ll_0=%d ll_1=%d ur_0=%d ur_1=%d rseg=%d\n", ii,
4212 seq->_ll[0], seq->_ll[1], seq->_ur[0], seq->_ur[1], seq->type);
4213 }
4214 }
4215 }
4216 }
4217
4218 } // namespace rcx
4219