1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 //   list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 //   this list of conditions and the following disclaimer in the documentation
15 //   and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 //   contributors may be used to endorse or promote products derived from
19 //   this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 
33 #include "darr.h"
34 #include "db.h"
35 #include "rcx/extRCap.h"
36 #include "rcx/extSpef.h"
37 #include "rcx/exttree.h"
38 
39 namespace rcx {
40 
resetMinMaxRC(uint ii,uint jj)41 void extMain::resetMinMaxRC(uint ii, uint jj) {
42   _minCapTable[ii][jj] = 0;
43   _maxCapTable[ii][jj] = 0;
44   _minResTable[ii][jj] = 0;
45   _maxResTable[ii][jj] = 0;
46 }
setMinRC(uint ii,uint jj,extDistRC * rc)47 void extMain::setMinRC(uint ii, uint jj, extDistRC* rc) {
48   if (rc) {
49     _minCapTable[ii][jj] = 2 * rc->getTotalCap();
50     _minResTable[ii][jj] = 2 * rc->getRes();
51   } else {
52     _minCapTable[ii][jj] = 0;
53     _minResTable[ii][jj] = 0;
54   }
55 }
setMaxRC(uint ii,uint jj,extDistRC * rc)56 void extMain::setMaxRC(uint ii, uint jj, extDistRC* rc) {
57   if (rc) {
58     _maxCapTable[ii][jj] = 2 * rc->getTotalCap();
59     _maxResTable[ii][jj] = 2 * rc->getRes();
60   } else {
61     _maxCapTable[ii][jj] = 0;
62     _maxResTable[ii][jj] = 0;
63   }
64 }
getMinRC(int met,int width)65 extDistRC* extRCModel::getMinRC(int met, int width) {
66   if (met >= _layerCnt)
67     return NULL;
68 
69   extMeasure m;
70   m._met = met;
71   m._underMet = 0;
72   m._overMet = 0;
73   m._width = width;
74 
75   return getOverFringeRC(&m);
76 }
getMaxRC(int met,int width,int dist)77 extDistRC* extRCModel::getMaxRC(int met, int width, int dist) {
78   if (met >= _layerCnt)
79     return NULL;
80 
81   extMeasure m;
82   m._met = met;
83   m._width = width;
84   m._dist = dist;
85 
86   m._underMet = met - 1;
87   m._overMet = met + 1;
88 
89   extDistRC* rc = NULL;
90   if (met == _layerCnt - 1) {  // over
91     m._overMet = 0;
92     rc = getOverFringeRC(&m);
93   } else if (met == 1) {  // over
94     m._overMet = 2;
95     rc = getUnderRC(&m);
96   } else {
97     rc = getOverUnderRC(&m);
98   }
99   return rc;
100 }
debugRC(const char * debugWord,const char * from,int width,int level)101 void extDistRC::debugRC(const char* debugWord, const char* from, int width,
102                         int level) {
103   char tmp[32];
104   sprintf(tmp, " ");
105   if (level > 0)
106     sprintf(tmp, "%d", level);
107   if (width > 0)
108     sprintf(tmp, "%s %d", tmp, width);
109 
110   // debug(debugWord, "C", "%s: %s, tC %g  CC %g F %g D %g   R %g  Sep %d\n",
111   //		from, tmp, _coupling+_fringe+_diag, _coupling,  _fringe, _diag,
112   //_res, _sep);
113 }
calcMinMaxRC()114 uint extMain::calcMinMaxRC() {
115   uint cornerCnt = _modelTable->getCnt();
116   if (cornerCnt == 0)
117     cornerCnt = 1;
118 
119   _currentModel = getRCmodel(0);
120 
121   odb::dbSet<odb::dbTechLayer> layers = _tech->getLayers();
122   odb::dbSet<odb::dbTechLayer>::iterator itr;
123 
124   uint cnt = 0;
125 
126   for (itr = layers.begin(); itr != layers.end(); ++itr) {
127     odb::dbTechLayer* layer = *itr;
128     odb::dbTechLayerType type = layer->getType();
129 
130     if (type.getValue() != odb::dbTechLayerType::ROUTING)
131       continue;
132 
133     int met = layer->getRoutingLevel();
134     int width = layer->getWidth();
135     int dist = layer->getSpacing();
136     if (dist == 0)
137       dist = layer->getPitch() - layer->getWidth();
138 
139     for (uint jj = 0; jj < _modelMap.getCnt(); jj++) {
140       uint modelIndex = _modelMap.get(jj);
141       resetMinMaxRC(met, jj);
142 
143       extDistRC* rcMin = _currentModel->getMinRC(met, width);
144       extDistRC* rcMax = _currentModel->getMaxRC(met, width, dist);
145 
146       setMinRC(met, jj, rcMin);
147       setMaxRC(met, jj, rcMax);
148 
149       rcMin->debugRC("EXT_STATS", "MinRC", width, met);
150       rcMax->debugRC("EXT_STATS", "MaxRC", width, met);
151     }
152     cnt++;
153   }
154   return cnt;
155 }
getExtStats(odb::dbNet * net,uint corner,int & wlen,double & min_cap,double & max_cap,double & min_res,double & max_res,double & via_res,uint & via_cnt)156 uint extMain::getExtStats(odb::dbNet* net, uint corner, int& wlen,
157                           double& min_cap, double& max_cap, double& min_res,
158                           double& max_res, double& via_res, uint& via_cnt) {
159   min_cap = 0;
160   max_cap = 0;
161   min_res = 0;
162   max_res = 0;
163   via_cnt = 0;
164   via_res = 0;
165   wlen = 0;
166   uint cnt = 0;
167   sprintf(_tmpLenStats, "");
168 
169   odb::dbWire* wire = net->getWire();
170   if (wire == NULL)
171     return 0;
172 
173   odb::dbWireShapeItr shapes;
174   odb::dbShape s;
175   for (shapes.begin(wire); shapes.next(s);) {
176     //		uint level= 0;
177 
178     int shapeId = shapes.getShapeId();
179     if (s.isVia()) {
180       // if (!_skip_via_wires)
181       //    continue;
182       via_cnt++;
183 
184       odb::dbTechVia* tvia = s.getTechVia();
185       if (tvia != NULL) {
186         double res = tvia->getResistance();
187         via_res += res;
188       } else {
189         odb::dbVia* bvia = s.getVia();
190         if (bvia != NULL) {
191           double res = getViaResistance_b(bvia, net);
192           via_res += res;
193         }
194       }
195       continue;
196     }
197     cnt++;
198     uint met = s.getTechLayer()->getRoutingLevel();
199     int width = s.getTechLayer()->getWidth();
200 
201     odb::Rect r;
202     s.getBox(r);
203     int dx = r.xMax() - r.xMin();
204     int dy = r.yMax() - r.yMin();
205 
206     int len = 0;
207     if (width == dx)
208       len = dy;
209     else if (width == dy)
210       len = dx;
211     else {
212       len = dx;
213       if (dy > dx)
214         len = dy;
215     }
216     sprintf(_tmpLenStats, "%s,M%d:%d", _tmpLenStats, met, len);
217     wlen += len;
218 
219     min_res += len * _minResTable[met][corner];
220     max_res += len * _maxResTable[met][corner];
221 
222     min_cap += len * _minCapTable[met][corner];
223     max_cap += len * _maxCapTable[met][corner];
224   }
225   return cnt;
226 }
227 
228 }  // namespace rcx
229