1 /* Authors: Lutong Wang and Bangqi Xu */ 2 /* 3 * Copyright (c) 2019, The Regents of the University of California 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * * Neither the name of the University nor the 14 * names of its contributors may be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _FR_TECHOBJECT_H_ 30 #define _FR_TECHOBJECT_H_ 31 32 #include <iostream> 33 #include <map> 34 #include <memory> 35 #include <vector> 36 37 #include "db/obj/frVia.h" 38 #include "db/tech/frLayer.h" 39 #include "db/tech/frViaRuleGenerate.h" 40 #include "frBaseTypes.h" 41 #include "utl/Logger.h" 42 namespace fr { 43 namespace io { 44 class Parser; 45 } 46 class frTechObject 47 { 48 public: 49 // constructors frTechObject()50 frTechObject() : dbUnit(0), manufacturingGrid(0) {} 51 // getters getDBUPerUU()52 frUInt4 getDBUPerUU() const { return dbUnit; } getManufacturingGrid()53 frUInt4 getManufacturingGrid() const { return manufacturingGrid; } getLayer(const frString & name)54 frLayer* getLayer(const frString& name) const 55 { 56 if (name2layer.find(name) == name2layer.end()) { 57 // std::cout <<"Error: cannot find layer" <<std::endl; 58 // exit(1); 59 return nullptr; 60 } else { 61 return name2layer.at(name); 62 } 63 } getLayer(frLayerNum in)64 frLayer* getLayer(frLayerNum in) const 65 { 66 if ((int) in < 0 || in >= (int) layers.size()) { 67 std::cout << "Error: cannot find layer" << std::endl; 68 exit(1); 69 } else { 70 return layers.at(in).get(); 71 } 72 } getBottomLayerNum()73 frLayerNum getBottomLayerNum() const { return 0; } getTopLayerNum()74 frLayerNum getTopLayerNum() const 75 { 76 return (frLayerNum)((int) layers.size() - 1); 77 } getLayers()78 const std::vector<std::unique_ptr<frLayer>>& getLayers() const 79 { 80 return layers; 81 } 82 getVias()83 const std::vector<std::unique_ptr<frViaDef>>& getVias() const { return vias; } getViaRuleGenerates()84 const std::vector<std::unique_ptr<frViaRuleGenerate>>& getViaRuleGenerates() 85 const 86 { 87 return viaRuleGenerates; 88 } 89 const std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>>& getVia2ViaForbiddenLen()90 getVia2ViaForbiddenLen() const 91 { 92 return via2ViaForbiddenLen; 93 } 94 const std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>>& getViaForbiddenTurnLen()95 getViaForbiddenTurnLen() const 96 { 97 return viaForbiddenTurnLen; 98 } 99 const std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>>& getViaForbiddenPlanarLen()100 getViaForbiddenPlanarLen() const 101 { 102 return viaForbiddenPlanarLen; 103 } 104 105 // setters setDBUPerUU(frUInt4 uIn)106 void setDBUPerUU(frUInt4 uIn) { dbUnit = uIn; } setManufacturingGrid(frUInt4 in)107 void setManufacturingGrid(frUInt4 in) { manufacturingGrid = in; } addLayer(std::unique_ptr<frLayer> in)108 void addLayer(std::unique_ptr<frLayer> in) 109 { 110 name2layer[in->getName()] = in.get(); 111 layers.push_back(std::move(in)); 112 layer2Name2CutClass.push_back(std::map<std::string, frLef58CutClass*>()); 113 layerCutClass.push_back(std::vector<std::unique_ptr<frLef58CutClass>>()); 114 } addVia(std::unique_ptr<frViaDef> in)115 void addVia(std::unique_ptr<frViaDef> in) 116 { 117 if (name2via.find(in->getName()) != name2via.end()) { 118 std::cout << "Error: duplicated via definition for " << in->getName() 119 << "\n"; 120 } 121 name2via[in->getName()] = in.get(); 122 vias.push_back(std::move(in)); 123 } addCutClass(frLayerNum lNum,std::unique_ptr<frLef58CutClass> in)124 void addCutClass(frLayerNum lNum, std::unique_ptr<frLef58CutClass> in) 125 { 126 auto rptr = in.get(); 127 layer2Name2CutClass[lNum][in->getName()] = rptr; 128 layerCutClass[lNum].push_back(std::move(in)); 129 layers[lNum]->addCutClass(rptr); 130 } addViaRuleGenerate(std::unique_ptr<frViaRuleGenerate> in)131 void addViaRuleGenerate(std::unique_ptr<frViaRuleGenerate> in) 132 { 133 name2viaRuleGenerate[in->getName()] = in.get(); 134 viaRuleGenerates.push_back(std::move(in)); 135 } addConstraint(const std::shared_ptr<frConstraint> & constraintIn)136 void addConstraint(const std::shared_ptr<frConstraint>& constraintIn) 137 { 138 constraints.push_back(constraintIn); 139 } addUConstraint(std::unique_ptr<frConstraint> in)140 void addUConstraint(std::unique_ptr<frConstraint> in) 141 { 142 uConstraints.push_back(std::move(in)); 143 } 144 145 // forbidden length table related 146 bool isVia2ViaForbiddenLen(int tableLayerIdx, 147 bool isPrevDown, 148 bool isCurrDown, 149 bool isCurrDirX, 150 frCoord len, 151 frNonDefaultRule* ndr = nullptr, 152 bool isOverlap = false) 153 { 154 int tableEntryIdx = getTableEntryIdx(!isPrevDown, !isCurrDown, !isCurrDirX); 155 if (isOverlap) { 156 return isIncluded( 157 via2ViaForbiddenOverlapLen[tableLayerIdx][tableEntryIdx], len); 158 } else { 159 return isIncluded( 160 (ndr ? ndr->via2ViaForbiddenLen 161 : via2ViaForbiddenLen)[tableLayerIdx][tableEntryIdx], 162 len); 163 } 164 } 165 166 bool isViaForbiddenTurnLen(int tableLayerIdx, 167 bool isDown, 168 bool isCurrDirX, 169 frCoord len, 170 frNonDefaultRule* ndr = nullptr) 171 { 172 int tableEntryIdx = getTableEntryIdx(!isDown, !isCurrDirX); 173 return isIncluded((ndr ? ndr->viaForbiddenTurnLen 174 : viaForbiddenTurnLen)[tableLayerIdx][tableEntryIdx], 175 len); 176 } 177 isLine2LineForbiddenLen(int tableLayerIdx,bool isZShape,bool isCurrDirX,frCoord len)178 bool isLine2LineForbiddenLen(int tableLayerIdx, 179 bool isZShape, 180 bool isCurrDirX, 181 frCoord len) 182 { 183 int tableEntryIdx = getTableEntryIdx(!isZShape, !isCurrDirX); 184 return isIncluded(line2LineForbiddenLen[tableLayerIdx][tableEntryIdx], len); 185 } 186 isViaForbiddenThrough(int tableLayerIdx,bool isDown,bool isCurrDirX)187 bool isViaForbiddenThrough(int tableLayerIdx, bool isDown, bool isCurrDirX) 188 { 189 int tableEntryIdx = getTableEntryIdx(!isDown, !isCurrDirX); 190 return viaForbiddenThrough[tableLayerIdx][tableEntryIdx]; 191 } 192 getVia(frString name)193 frViaDef* getVia(frString name) const { return name2via.at(name); } 194 getViaRule(frString name)195 frViaRuleGenerate* getViaRule(frString name) const 196 { 197 return name2viaRuleGenerate.at(name); 198 } 199 addNDR(std::unique_ptr<frNonDefaultRule> n)200 void addNDR(std::unique_ptr<frNonDefaultRule> n) 201 { 202 nonDefaultRules.push_back(std::move(n)); 203 } 204 getNondefaultRules()205 const std::vector<std::unique_ptr<frNonDefaultRule>>& getNondefaultRules() 206 const 207 { 208 return nonDefaultRules; 209 } 210 getNondefaultRule(string name)211 frNonDefaultRule* getNondefaultRule(string name) 212 { 213 for (std::unique_ptr<frNonDefaultRule>& nd : nonDefaultRules) { 214 if (nd->getName() == name) 215 return nd.get(); 216 } 217 return nullptr; 218 } 219 getMaxNondefaultSpacing(int z)220 frCoord getMaxNondefaultSpacing(int z) 221 { 222 frCoord spc = 0; 223 for (std::unique_ptr<frNonDefaultRule>& nd : nonDefaultRules) { 224 if (nd->getSpacing(z) > spc) 225 spc = nd->getSpacing(z); 226 } 227 return spc; 228 } 229 getMaxNondefaultWidth(int z)230 frCoord getMaxNondefaultWidth(int z) 231 { 232 frCoord spc = 0; 233 for (std::unique_ptr<frNonDefaultRule>& nd : nonDefaultRules) { 234 if (nd->getWidth(z) > spc) 235 spc = nd->getWidth(z); 236 } 237 return spc; 238 } 239 hasNondefaultRules()240 bool hasNondefaultRules() { return !nonDefaultRules.empty(); } 241 242 // debug printAllConstraints(utl::Logger * logger)243 void printAllConstraints(utl::Logger* logger) 244 { 245 logger->report("Reporting Layer Properties"); 246 for (auto& layer : layers) { 247 auto type = layer->getType(); 248 if (type == frLayerTypeEnum::CUT) 249 logger->report("Cut Layer {}", layer->getName()); 250 else if (type == frLayerTypeEnum::ROUTING) 251 logger->report("Routing Layer {}", layer->getName()); 252 layer->printAllConstraints(logger); 253 } 254 } 255 printDefaultVias(Logger * logger)256 void printDefaultVias(Logger* logger) 257 { 258 logger->info(DRT, 167, "List of default vias:"); 259 for (auto& layer : layers) { 260 if (layer->getType() == frLayerTypeEnum::CUT 261 && layer->getLayerNum() >= 2 /*BOTTOM_ROUTING_LAYER*/) { 262 logger->report(" Layer {}", layer->getName()); 263 logger->report(" default via: {}", 264 layer->getDefaultViaDef()->getName()); 265 } 266 } 267 } 268 269 friend class io::Parser; 270 271 protected: 272 frUInt4 dbUnit; 273 frUInt4 manufacturingGrid; 274 275 std::map<frString, frLayer*> name2layer; 276 std::vector<std::unique_ptr<frLayer>> layers; 277 278 std::map<frString, frViaDef*> name2via; 279 std::vector<std::unique_ptr<frViaDef>> vias; 280 281 std::vector<std::map<frString, frLef58CutClass*>> layer2Name2CutClass; 282 std::vector<std::vector<std::unique_ptr<frLef58CutClass>>> layerCutClass; 283 284 std::map<frString, frViaRuleGenerate*> name2viaRuleGenerate; 285 std::vector<std::unique_ptr<frViaRuleGenerate>> viaRuleGenerates; 286 287 frCollection<std::shared_ptr<frConstraint>> constraints; 288 std::vector<std::unique_ptr<frConstraint>> uConstraints; 289 std::vector<std::unique_ptr<frNonDefaultRule>> nonDefaultRules; 290 291 // via2ViaForbiddenLen[z][0], prev via is down, curr via is down, forgidden x 292 // dist range (for non-shape-based rule) via2ViaForbiddenLen[z][1], prev via 293 // is down, curr via is down, forgidden y dist range (for non-shape-based 294 // rule) via2ViaForbiddenLen[z][2], prev via is down, curr via is up, 295 // forgidden x dist range (for non-shape-based rule) 296 // via2ViaForbiddenLen[z][3], prev via is down, curr via is up, forgidden y 297 // dist range (for non-shape-based rule) via2ViaForbiddenLen[z][4], prev via 298 // is up, curr via is down, forgidden x dist range (for non-shape-based 299 // rule) via2ViaForbiddenLen[z][5], prev via is up, curr via is down, 300 // forgidden y dist range (for non-shape-based rule) 301 // via2ViaForbiddenLen[z][6], prev via is up, curr via is up, forgidden x 302 // dist range (for non-shape-based rule) via2ViaForbiddenLen[z][7], prev via 303 // is up, curr via is up, forgidden y dist range (for non-shape-based 304 // rule) 305 std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>> 306 via2ViaForbiddenLen; 307 308 // via2ViaForbiddenOverlapLen[z][0], prev via is down, curr via is down, 309 // forgidden x dist range (for shape-based rule) 310 // via2ViaForbiddenOverlapLen[z][1], prev via is down, curr via is down, 311 // forgidden y dist range (for shape-based rule) 312 // via2ViaForbiddenOverlapLen[z][2], prev via is down, curr via is up, 313 // forgidden x dist range (for shape-based rule) 314 // via2ViaForbiddenOverlapLen[z][3], prev via is down, curr via is up, 315 // forgidden y dist range (for shape-based rule) 316 // via2ViaForbiddenOverlapLen[z][4], prev via is up, curr via is down, 317 // forgidden x dist range (for shape-based rule) 318 // via2ViaForbiddenOverlapLen[z][5], prev via is up, curr via is down, 319 // forgidden y dist range (for shape-based rule) 320 // via2ViaForbiddenOverlapLen[z][6], prev via is up, curr via is up, 321 // forgidden x dist range (for shape-based rule) 322 // via2ViaForbiddenOverlapLen[z][7], prev via is up, curr via is up, 323 // forgidden y dist range (for shape-based rule) 324 std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>> 325 via2ViaForbiddenOverlapLen; 326 327 // viaForbiddenTurnLen[z][0], last via is down, forbidden x dist range before 328 // turn viaForbiddenTurnLen[z][1], last via is down, forbidden y dist range 329 // before turn viaForbiddenTurnLen[z][2], last via is up, forbidden x dist 330 // range before turn viaForbiddenTurnLen[z][3], last via is up, forbidden y 331 // dist range before turn 332 std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>> 333 viaForbiddenTurnLen; 334 335 // viaForbiddenPlanarLen[z][0], last via is down, forbidden x dist range 336 // viaForbiddenPlanarLen[z][1], last via is down, forbidden y dist range 337 // viaForbiddenPlanarLen[z][2], last via is up, forbidden x dist range 338 // viaForbiddenPlanarLen[z][3], last via is up, forbidden y dist range 339 std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>> 340 viaForbiddenPlanarLen; 341 342 // line2LineForbiddenForbiddenLen[z][0], z shape, forbidden x dist range 343 // line2LineForbiddenForbiddenLen[z][1], z shape, forbidden y dist range 344 // line2LineForbiddenForbiddenLen[z][2], u shape, forbidden x dist range 345 // line2LineForbiddenForbiddenLen[z][3], u shape, forbidden y dist range 346 std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>> 347 line2LineForbiddenLen; 348 349 // viaForbiddenPlanarThrough[z][0], forbidden planar through along x direction 350 // for down via viaForbiddenPlanarThrough[z][1], forbidden planar through 351 // along y direction for down via viaForbiddenPlanarThrough[z][2], forbidden 352 // planar through along x direction for up via 353 // viaForbiddenPlanarThrough[z][3], forbidden planar through along y direction 354 // for up via 355 std::vector<std::vector<bool>> viaForbiddenThrough; 356 357 // forbidden length table related utilities getTableEntryIdx(bool in1,bool in2)358 int getTableEntryIdx(bool in1, bool in2) 359 { 360 int retIdx = 0; 361 if (in1) { 362 retIdx += 1; 363 } 364 retIdx <<= 1; 365 if (in2) { 366 retIdx += 1; 367 } 368 return retIdx; 369 } 370 getTableEntryIdx(bool in1,bool in2,bool in3)371 int getTableEntryIdx(bool in1, bool in2, bool in3) 372 { 373 int retIdx = 0; 374 if (in1) { 375 retIdx += 1; 376 } 377 retIdx <<= 1; 378 if (in2) { 379 retIdx += 1; 380 } 381 retIdx <<= 1; 382 if (in3) { 383 retIdx += 1; 384 } 385 return retIdx; 386 } 387 isIncluded(const std::vector<std::pair<frCoord,frCoord>> & intervals,const frCoord len)388 bool isIncluded(const std::vector<std::pair<frCoord, frCoord>>& intervals, 389 const frCoord len) 390 { 391 bool included = false; 392 for (auto& interval : intervals) { 393 if (interval.first <= len && interval.second >= len) { 394 included = true; 395 break; 396 } 397 } 398 return included; 399 } 400 401 friend class FlexRP; 402 }; 403 } // namespace fr 404 405 #endif 406