📄 oadefinvia.cpp
字号:
// *****************************************************************************// *****************************************************************************// DefInVia.cpp//// Functions to handle DEF VIAS construct for the 'def2oa' translator.// *****************************************************************************// 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/07/06 09:41:54 $// $State: Exp $// *****************************************************************************// *****************************************************************************#include "oaLefDef.h"BEGIN_LEFDEF_NAMESPACE// *****************************************************************************// DefInVia::DefInVia()// DefInVia::~DefInVia()//// This is the constructor for the DefInVia class.// *****************************************************************************DefInVia::DefInVia(DefIn &translator): defIn(translator){ translator.defInVia = this;}DefInVia::~DefInVia(){}// *****************************************************************************// DefInVia::init()//// This function initializes the DefInVia class. Any persistent data// will be reset.// *****************************************************************************voidDefInVia::init(){ turnViaTbl.clear();}// *****************************************************************************// DefInVia::parse()//// This function is called for each via found in the "VIAS" DEF construct.// It tries to decode patternName attribute, creates a stdVia and adds it// into the table of generated vias.// Turn Vias are recognized and stored in the turnViaNames list.// CustomViaDefs are created instead of stdVias for the following cases :// - vias without PATTERNNAME// - vias with invalid PATTERNNAME// - vias with an incorrect viaName// - vias for which there's no associated stdViaDef// *****************************************************************************voidDefInVia::parse(defiVia *data){ defVia = data; if (defVia->numLayers() == 1) { return parseTurnVia(); } if (defVia->hasViaRule()) { return parseRuleVia(); } if (defVia->hasPattern() && !defIn.getOptions()->doUseCustomVias()) { try { return parseGeometries(); } catch (oaException &err) { defIn.warn(cGeneric, (const char*) err.getMsg()); defIn.warn(cViaCreatingCustom, defVia->name()); } } parseCustomVia();}// *****************************************************************************// DefInVia::parseTurnVia()//// This function stores the name and dimension of this turnVia on the// translator object for use during parsing of special nets.// *****************************************************************************voidDefInVia::parseTurnVia(){ char *layName; int pxl; int pyl; int pxh; int pyh; defVia->layer(0, &layName, &pxl, &pyl, &pxh, &pyh); oaLayerNum layerNum = defIn.getLayerNum(layName); oaBox box(defIn.scaleToDBU(pxl), defIn.scaleToDBU(pyl), defIn.scaleToDBU(pxh), defIn.scaleToDBU(pyh)); turnViaTbl.insert(defVia->name(), box);} // *****************************************************************************// DefInVia::parseRuleVia()//// This function handles the viarule section in the current VIA construct.// It attempts to find a stdVia definition, and match the paramters in DEF.// *****************************************************************************voidDefInVia::parseRuleVia(){ char *ruleName; char *l1Name; char *cutName; char *l2Name; int cutX; int cutY; int cutSpaceX; int cutSpaceY; int l1EncX; int l1EncY; int l2EncX; int l2EncY; defVia->viaRule(&ruleName, &cutX, &cutY, &l1Name, &cutName, &l2Name, &cutSpaceX, &cutSpaceY, &l1EncX, &l1EncY, &l2EncX, &l2EncY); oaStdViaDef *stdViaDef = getViaDef(ruleName); if (!stdViaDef) { throw LefDefError(cViaNoViaRule, defVia->name()); } // Create and fill out the oaViaParam. oaViaParam stdViaParam; oaVector cutSpacing(defIn.scaleToDBU(cutSpaceX), defIn.scaleToDBU(cutSpaceY)); oaVector l1Enc(defIn.scaleToDBU(l1EncX), defIn.scaleToDBU(l1EncY)); oaVector l2Enc(defIn.scaleToDBU(l2EncX), defIn.scaleToDBU(l2EncY)); stdViaDef->getParams(stdViaParam); stdViaParam.setCutWidth(defIn.scaleToDBU(cutX)); stdViaParam.setCutHeight(defIn.scaleToDBU(cutY)); stdViaParam.setCutSpacing(cutSpacing); stdViaParam.setLayer1Enc(l1Enc); stdViaParam.setLayer2Enc(l2Enc); // Parse the via origin. if (defVia->hasOrigin()) { int originX; int originY; defVia->origin(&originX, &originY); oaVector originOffset(defIn.scaleToDBU(originX), defIn.scaleToDBU(originY)); stdViaParam.setOriginOffset(originOffset); } // Parse the metal layer offset. if (defVia->hasOffset()) { int l1OffsetX; int l1OffsetY; int l2OffsetX; int l2OffsetY; defVia->offset(&l1OffsetX, &l1OffsetY, &l2OffsetX, &l2OffsetY); oaVector l1Offset(defIn.scaleToDBU(l1OffsetX), defIn.scaleToDBU(l1OffsetY)); oaVector l2Offset(defIn.scaleToDBU(l2OffsetX), defIn.scaleToDBU(l2OffsetY)); stdViaParam.setLayer1Offset(l1Offset); stdViaParam.setLayer2Offset(l2Offset); } // Parse the number of rows & columns. int numCutsX = 1; int numCutsY = 1; if (defVia->hasRowCol()) { defVia->rowCol(&numCutsY, &numCutsX); } stdViaParam.setCutColumns(numCutsX); stdViaParam.setCutRows(numCutsY); // Parse the cut pattern - current default "all 1". if (defVia->hasCutPattern()) { defIn.setViaCutPattern(defVia->cutPattern(), stdViaParam, defVia->name()); } // Store the generated via params. defIn.addGenVia(defVia->name(), stdViaDef, stdViaParam);}// *****************************************************************************// DefInVia::parseGeometries()//// This function handles the geometries section in the current VIA construct.// It attempts to find a stdVia definition, and match the paramters to the// geometries in DEF.// *****************************************************************************voidDefInVia::parseGeometries(){ if (defVia->numPolygons() > 0) { throw LefDefError(cViaNonRectangular, defVia->name()); } int i; char *layName; oaPhysicalLayer *layer; int pxl; int pyl; int pxh; int pyh; oaInt4 xl; oaInt4 yl; oaInt4 xh; oaInt4 yh; // Find via size, cut size, total cut size, cut spacing & layers. oaBox bBox1; oaBox bBox2; oaInt4 cutWidth = 0; oaInt4 cutHeight = 0; oaVector cutSpacing(INT_MAX, INT_MAX); oaBox cutBox(INT_MAX, INT_MAX, -INT_MAX, -INT_MAX); oaPhysicalLayer *layer1 = NULL; oaPhysicalLayer *layer2 = NULL; oaPhysicalLayer *cutLayer = NULL; oaInt4 lastX = -INT_MAX; oaInt4 lastY = -INT_MAX; for (i = 0; i < defVia->numLayers(); i++) { defVia->layer(i, &layName, &pxl, &pyl, &pxh, &pyh); layer = defIn.getLayer(layName); xl = defIn.scaleToDBU(pxl); yl = defIn.scaleToDBU(pyl); xh = defIn.scaleToDBU(pxh); yh = defIn.scaleToDBU(pyh); if (layer->getMaterial() == oacCutMaterial) { if (cutLayer && layer != cutLayer) { throw LefDefError(cViaTooManyLayers, defVia->name()); } // Find bounding box for all cuts cutLayer = layer; if (xl < cutBox.left()) { cutBox.left() = xl; } if (yl < cutBox.bottom()) { cutBox.bottom() = yl; } if (xh > cutBox.right()) { cutBox.right() = xh; } if (yh > cutBox.top()) { cutBox.top() = yh; } if (!cutWidth) { // Find individual cut size. cutWidth = xh - xl; cutHeight = yh - yl; } // Find minimum cut spacing. oaInt4 spacing = (lastX != -INT_MAX) ? abs(xl - lastX) : 0; if (spacing && spacing < cutSpacing.x()) { cutSpacing.x() = spacing; } spacing = (lastY != -INT_MAX) ? abs(yl - lastY) : 0; if (spacing && spacing < cutSpacing.y()) { cutSpacing.y() = spacing; } lastX = xl; lastY = yl; } else if (!layer1) { layer1 = layer; bBox1.set(xl, yl, xh, yh); } else if (!layer2 && (layer != layer1)) { if (layer->getMaskNumber() < layer1->getMaskNumber()) { layer2 = layer1; bBox2 = bBox1; layer1 = layer; bBox1.set(xl, yl, xh, yh); } else { layer2 = layer; bBox2.set(xl, yl, xh, yh); } } else if ((layer != layer1) && (layer != layer2)) { throw LefDefError(cViaTooManyLayers, defVia->name()); } } if (!cutLayer || !layer1 || !layer2 || (layer1 == layer2)) { throw LefDefError(cViaMissingLayer, defVia->name()); } oaInt4 width1 = bBox1.right() - bBox1.left(); oaInt4 height1 = bBox1.top() - bBox1.bottom(); oaInt4 width2 = bBox2.right() - bBox2.left(); oaInt4 height2 = bBox2.top() - bBox2.bottom(); oaInt4 allCutWidth = cutBox.right() - cutBox.left(); oaInt4 allCutHeight = cutBox.top() - cutBox.bottom(); oaUInt4 numCutsX = 1; oaUInt4 numCutsY = 1; if (cutSpacing.x() != INT_MAX) { numCutsX += allCutWidth / cutSpacing.x(); cutSpacing.x() -= cutWidth; } if (cutSpacing.y() != INT_MAX) { numCutsY += allCutHeight / cutSpacing.y(); cutSpacing.y() -= cutHeight; } // Find matching viaRule. oaStdViaDef *stdViaDef = NULL; if (defVia->hasPattern()) { stdViaDef = getViaDef(defVia->pattern()); } if (!stdViaDef) { stdViaDef = getViaDef(cutLayer->getNumber(), cutHeight, cutWidth, cutSpacing); } if (!stdViaDef) { throw LefDefError(cViaNoViaRule, defVia->name());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -