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