⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oalefinvia.cpp

📁 openaccess读def,lef文件所用的源代码
💻 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 + -