📄 oalefinvia.cpp
字号:
// *****************************************************************************// *****************************************************************************// LefInVia.cpp//// Functions to handle LEF VIA constructs.//// *****************************************************************************// Except as specified in the OpenAccess terms of use of Cadence or Silicon// Integration Initiative, this material may not be copied, modified,// re-published, uploaded, executed, or distributed in any way, in any medium,// in whole or in part, without prior written permission from Cadence.//// Copyright 2002-2005 Cadence Design Systems, Inc.// All Rights Reserved.//// $Author: nitters $// $Revision: 1.84 $// $Date: 2005/05/25 09:42:52 $// $State: Exp $// *****************************************************************************// *****************************************************************************#include "oaLefDef.h"BEGIN_LEFDEF_NAMESPACE// *****************************************************************************// LefInVia::LefInVia()// LefInVia::~LefInVia()//// This is the constructor for the LefInVia class. // *****************************************************************************LefInVia::LefInVia(LefIn &translator): lefIn(translator){ translator.lefInVia = this;}LefInVia::~LefInVia(){}// *****************************************************************************// LefInVia::parse//// This function creates a new via definition from the LEF datastructure.// *****************************************************************************voidLefInVia::parse(lefiVia *data, oaBoolean fromNDR){ lefVia = data; numCuts = 0; layer1 = NULL; cutLayer = NULL; layer2 = NULL; if (lefVia->hasViaRule()) { return parseRuleVia(); } parseLayers(); createVia(); parseDefault(); parseTopOfStack(); parseResistance(); parseProperties();}// *****************************************************************************// LefInVia::parseLayers//// This function determines cut, bottom and top layers from the LEF via.// *****************************************************************************voidLefInVia::parseLayers(){ for (int i = 0; i < lefVia->numLayers(); i++) { oaPhysicalLayer *layer = lefIn.getLayer(lefVia->layerName(i)); if (layer->getMaterial() == oacCutMaterial) { if (cutLayer) { throw LefDefError(cViaMultipleCutLayers, lefVia->name()); } cutLayer = layer; continue; } if (!layer1) { layer1 = layer; continue; } if (layer->getMaskNumber() < layer1->getMaskNumber()) { layer2 = layer1; layer1 = layer; continue; } layer2 = layer; } if (!cutLayer) { throw LefDefError(cViaNoCutLayer, lefVia->name()); } if (!layer1 || !layer2) { throw LefDefError(cViaMissingRoutingLayers, lefVia->name()); }}// *****************************************************************************// LefInVia::parseDefault()//// This function handles the DEFAULT attribute for the current via.// *****************************************************************************voidLefInVia::parseDefault(){ if (lefVia->hasDefault()) { lefIn.addViaDef(via); }}// *****************************************************************************// LefInVia::parseTopOfStack()//// This function handles the via topofstack attribute.// *****************************************************************************voidLefInVia::parseTopOfStack(){ if (lefVia->hasTopOfStack()) { lefIn.setBooleanProp(via, cLefViaTopOfStack, true); }}// *****************************************************************************// LefInVia::parseResistance()//// This function handles the via resistance attribute.// *****************************************************************************voidLefInVia::parseResistance(){ if (lefVia->hasResistance()) { via->setResistancePerCut(oaFloat(lefVia->resistance()) * numCuts); }}// *****************************************************************************// LefInVia::parseProperties()// // This function handles the PROPERTY attributes for the specified via.// *****************************************************************************voidLefInVia::parseProperties(){ LefDefProp *propDef; for (int i = 0; i < lefVia->numProperties(); i++) { propDef = lefIn.getProp(lefVia->propName(i), cLefDefVia); lefIn.createProp(propDef, via, lefVia->propValue(i)); }}// *****************************************************************************// LefInVia::createVia//// This function creates a new OA custom via from the LEF parser datastructure.// A via consists of its viaDef and associated design.// The via's layers can be in any order, so we search for the cut layer// first, and then find the bottom & top layers.// This function is also called to create the vias from the NONDEFAULTRULE// construct.//// Note:// Some vias with fewer than 3 layers can exist: cut only.// DEFAULT vias must have 3 layers.// *****************************************************************************voidLefInVia::createVia(){ oaString viaName(lefVia->name()); via = oaViaDef::find(lefIn.tech(), viaName); if (via && via->getType() == oacStdViaDefType) { viaName += "_"; viaName += cLefViaDesignName; via = oaViaDef::find(lefIn.tech(), viaName); } oaDesign *design; oaScalarName libN; oaScalarName cellN(lefIn.getNS(), viaName); oaScalarName viewN(lefIn.getNS(), cLefViaDesignName); lefIn.tech()->getLibName(libN); if (via) { ((oaCustomViaDef*) via)->getLibName(libN); ((oaCustomViaDef*) via)->getCellName(cellN); ((oaCustomViaDef*) via)->getViewName(viewN); if (!lefIn.getOptions()->overwriteMode()) { design = oaDesign::open(libN, cellN, viewN, 'r'); if (!verifyGeometries(design)) { design->close(); throw LefDefError(cViaExists, (const char*) viaName); } design->close(); return; } } design = oaDesign::open(libN, cellN, viewN, oaViewType::get(oacMaskLayout), 'w'); if (!design->getTopBlock()) { oaBlock::create(design, oacExcludeFromModuleDomain); } try { createGeom(design); } catch (oaException &err) { design->close(); oaDesign::destroy(libN, cellN, viewN); throw err; } design->setCellType(oacViaCellType); design->save(); design->close(); if (!via) { via = oaCustomViaDef::create(lefIn.tech(), viaName, libN, cellN, viewN, layer1, layer2); }}// *****************************************************************************// LefInVia::createGeom()//// This function creates the shapes in the via cellview.// Inverted bboxes are corrected usin min & max functions below.// *****************************************************************************voidLefInVia::createGeom(oaDesign *design){ oaPhysicalLayer *layer; oaBlock *blk = design->getTopBlock(); for (int i = 0; i < lefVia->numLayers(); i++) { layer = lefIn.getLayer(lefVia->layerName(i)); for (oaInt4 j = 0 ; j < lefVia->numRects(i); j++) { oaInt4 xlDbu = lefIn.uuToDBU(lefVia->xl(i, j)); oaInt4 ylDbu = lefIn.uuToDBU(lefVia->yl(i, j)); oaInt4 xhDbu = lefIn.uuToDBU(lefVia->xh(i, j)); oaInt4 yhDbu = lefIn.uuToDBU(lefVia->yh(i, j)); if ((xlDbu == xhDbu) || (ylDbu == yhDbu)) { lefIn.warn(cGeomZeroSizedRect); continue; } oaBox box(oaMin(xlDbu, xhDbu), oaMin(ylDbu, yhDbu), oaMax(xlDbu, xhDbu), oaMax(ylDbu, yhDbu)); oaRect::create(blk, layer->getNumber(), oavPurposeNumberDrawing, box); if (layer->getMaterial() == oacCutMaterial) { numCuts++; } } for (oaInt4 j = 0 ; j < lefVia->numPolygons(i); j++) { const lefiGeomPolygon &polygon = lefVia->getPolygon(i, j); oaPointArray pointArray; for (int k = 0; k < polygon.numPoints; k++) { oaInt4 x = lefIn.uuToDBU(polygon.x[k]); oaInt4 y = lefIn.uuToDBU(polygon.y[k]); pointArray.append(oaPoint(x, y)); } oaPolygon::create(blk, layer->getNumber(), oavPurposeNumberDrawing, pointArray); if (layer->getMaterial() == oacCutMaterial) { numCuts++; } } }}// *****************************************************************************// LefInVia::verifyGeometries()// LefInVia::verifyGeom()//// These functions compare the geometries section with the patternName in the// current VIA construct.// *****************************************************************************oaBooleanLefInVia::verifyGeometries(oaDesign *master){ oaIter<oaShape> shapeIter(master->getTopBlock()->getShapes()); while (oaShape *shape = shapeIter.getNext()) { oaBox bBox; shape->getBBox(bBox); if (bBox.hasNoArea()) { continue; } oaLayer *layer = lefIn.getLayer(shape->getLayerNum()); if (layer->getType() == oacPhysicalLayerType && ((oaPhysicalLayer*) layer)->getMaterial() == oacCutMaterial) { numCuts++; } if (!verifyGeom(shape->getLayerNum(), bBox.left(), bBox.bottom(), bBox.right(), bBox.top())) { return false; } } return true;} oaBooleanLefInVia::verifyGeom(oaLayerNum layerNum, oaInt4 llx, oaInt4 lly, oaInt4 urx, oaInt4 ury){ for (int i = 0; i < lefVia->numLayers(); i++) { oaLayer *layer = lefIn.getLayer(lefVia->layerName(i)); if (layer->getNumber() == layerNum) { for (oaInt4 j = 0 ; j < lefVia->numRects(i); j++) { if ((llx == lefIn.uuToDBU(lefVia->xl(i, j))) && (lly == lefIn.uuToDBU(lefVia->yl(i, j))) && (urx == lefIn.uuToDBU(lefVia->xh(i, j))) && (ury == lefIn.uuToDBU(lefVia->yh(i, j)))) { return true; } } } } return false;} // *****************************************************************************// LefInVia::parseRuleVia()//// This function handles the viarule section in the current VIA construct.// It attempts to find a stdVia definition, and match the paramters in LEF.// *****************************************************************************voidLefInVia::parseRuleVia(){ oaViaDef *stdViaDef = oaStdViaDef::find(lefIn.tech(), lefVia->viaRuleName()); if (!stdViaDef) { throw LefDefError(cViaNoViaRule, lefVia->name()); } // Create and fill out the oaViaParam. oaViaParam stdViaParam; oaVector cutSpacing(lefIn.uuToDBU(lefVia->xCutSpacing()), lefIn.uuToDBU(lefVia->yCutSpacing())); oaVector l1Enc(lefIn.uuToDBU(lefVia->xBotEnc()), lefIn.uuToDBU(lefVia->yBotEnc())); oaVector l2Enc(lefIn.uuToDBU(lefVia->xTopEnc()), lefIn.uuToDBU(lefVia->yTopEnc())); ((oaStdViaDef*) stdViaDef)->getParams(stdViaParam); stdViaParam.setCutWidth(lefIn.uuToDBU(lefVia->xCutSize())); stdViaParam.setCutHeight(lefIn.uuToDBU(lefVia->yCutSize())); stdViaParam.setCutSpacing(cutSpacing); stdViaParam.setLayer1Enc(l1Enc); stdViaParam.setLayer2Enc(l2Enc); // Parse the via origin. if (lefVia->hasOrigin()) { oaVector originOffset(lefIn.uuToDBU(lefVia->xOffset()), lefIn.uuToDBU(lefVia->yOffset())); stdViaParam.setOriginOffset(originOffset); } // Parse the metal layer offset. if (lefVia->hasOffset()) { oaVector l1Offset(lefIn.uuToDBU(lefVia->xBotOffset()), lefIn.uuToDBU(lefVia->yBotOffset())); oaVector l2Offset(lefIn.uuToDBU(lefVia->xTopOffset()), lefIn.uuToDBU(lefVia->yTopOffset())); stdViaParam.setLayer1Offset(l1Offset); stdViaParam.setLayer2Offset(l2Offset); } // Parse the number of rows & columns. int numCutsX = 1; int numCutsY = 1; if (lefVia->hasRowCol()) { numCutsX = lefVia->numCutCols(); numCutsY = lefVia->numCutRows(); } stdViaParam.setCutColumns(numCutsX); stdViaParam.setCutRows(numCutsY); // Parse the cut pattern - current default "all 1". if (lefVia->hasCutPattern()) { lefIn.setViaCutPattern(lefVia->cutPattern(), stdViaParam, lefVia->name()); } // Store the generated via params. lefIn.addGenVia(lefVia->name(), stdViaDef, stdViaParam);}END_LEFDEF_NAMESPACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -