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