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

📄 oalefinviarule.cpp

📁 openaccess读def,lef文件所用的源代码
💻 CPP
字号:
// *****************************************************************************// *****************************************************************************// LefInViaRule.cpp//// Functions to handle LEF VIARULE and LEF VIARULE GENERATE constructs for the// 'lef2oa' 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.62 $//  $Date: 2005/04/19 14:58:52 $//  $State: Exp $// *****************************************************************************// *****************************************************************************#include "oaLefDef.h"BEGIN_LEFDEF_NAMESPACE// *****************************************************************************// LefInViaRule::LefInViaRule()// LefInViaRule::~LefInViaRule()//// This is the constructor for the LefInViaRule class. // *****************************************************************************LefInViaRule::LefInViaRule(LefIn    &translator):   lefIn(translator),    viaTable(0, 0, "layer1Width", "layer2Width", NULL){    translator.lefInViaRule = this;}LefInViaRule::~LefInViaRule(){}// *****************************************************************************// LefInViaRule::parse()//// This function creates a new OA viaSpec from the LEF parser datastructure.// *****************************************************************************voidLefInViaRule::parse(lefiViaRule	*data){    lefViaRule	= data;    lefLayer1	= NULL;    lefLayer2   = NULL;    lefCutLayer	= NULL;    viaRule	= NULL;    layer1	= NULL;    layer2	= NULL;    cutLayer	= NULL;    colMin	= oacNullIndex;    colMax	= oacNullIndex;    rowMin	= oacNullIndex;    rowMax	= oacNullIndex;    viaTable.setNumRows(0);    viaTable.setNumCols(0);    viaTable.setDefaultValue(NULL);    parseLayers();        // Find any existing viaDef table    viaRule = oaViaSpec::find(layer1, layer2);    if (viaRule) {	oaViaDef2DTblValue  *value = viaRule->getValue();	if (value) {	    value->get(viaTable);	}    }    oaViaDefArray   newArray;        parseWidthRanges();    if (lefViaRule->hasGenerate()) {	parseGenerate(newArray);    } else {	parseVias(newArray);    }    if (!newArray.getNumElements()) {	return;    }	    oaViaDefArrayValue	*arrayValue = NULL;    if (rowMin == oacNullIndex || colMin == oacNullIndex) {	// Default (non-width based) value	if (viaRule) {	    arrayValue = viaRule->getDefaultValue();	}	oaViaDefArray   array;	if (arrayValue) {	    arrayValue->get(array);	}	for (oaUInt4 i = 0; i < newArray.getNumElements(); i++) {	    if (array.find(newArray[i]) == oacNullIndex) {		array.append(newArray[i]);	    }	}	if (arrayValue) {	    arrayValue->set(array);	} else {	    arrayValue = oaViaDefArrayValue::create(lefIn.tech(), array);	    if (viaRule) {		viaRule->setDefaultValue(arrayValue);	    } else {		viaRule = oaViaSpec::create(layer1, layer2, arrayValue);	    }		}    } else {	// Add the vias to each row & column in between the min and max ranges	for (oaUInt4 row = rowMin; row < rowMax; row++) {	    for (oaUInt4 col = colMin; col < colMax; col++) {		arrayValue = (oaViaDefArrayValue*) viaTable.getValue(row, col);		oaViaDefArray   array;		if (arrayValue) {		    arrayValue->get(array);		}		for (oaUInt4 i = 0; i < newArray.getNumElements(); i++) {		    if (array.find(newArray[i]) == oacNullIndex) {			array.append(newArray[i]);		    }		}		if (arrayValue) {		    arrayValue->set(array);		} else {		    arrayValue = oaViaDefArrayValue::create(lefIn.tech(), array);		    viaTable.setValue(row, col, arrayValue);		}	    }	}		if (!viaRule || !viaRule->getValue()) {	    oaViaDef2DTblValue  *value = oaViaDef2DTblValue::create(lefIn.tech(),								    viaTable);	    if (!viaRule) {		viaRule = oaViaSpec::create(layer1, layer2, value);	    } else {		viaRule->setValue(value);	    }	} else {	    viaRule->getValue()->set(viaTable);	}    }        if (!lefViaRule->hasGenerate()) {	parseProperties();    }}// *****************************************************************************// LefInViaRule::parseLayers()//// This function finds the via rule layers in the techDB.// *****************************************************************************voidLefInViaRule::parseLayers(){    layer1 = lefIn.getLayer(lefViaRule->layer(0)->name());    layer2 = lefIn.getLayer(lefViaRule->layer(1)->name());         if (layer2->getMaskNumber() < layer1->getMaskNumber()) {	layer1 = layer2;	layer2 = lefIn.getLayer(lefViaRule->layer(0)->name());		lefLayer1 = lefViaRule->layer(1);	lefLayer2 = lefViaRule->layer(0);    } else {	lefLayer1 = lefViaRule->layer(0);	lefLayer2 = lefViaRule->layer(1);    }    if (lefViaRule->numLayers() > 2) {	lefCutLayer = lefViaRule->layer(2);	cutLayer = lefIn.getLayer(lefCutLayer->name());    }}// *****************************************************************************// LefInViaRule::parseGenerate()//// This function creates an OA stdViaDef with the via from the LEF parser// datastructure.// *****************************************************************************voidLefInViaRule::parseGenerate(oaViaDefArray   &array){    if(!cutLayer) {	if (layer1 == layer2) {	    // Ignore turn vias	    return;	} else {	    throw LefDefError(cViaRuleNoCutLayer, lefViaRule->name());	}    }        oaViaParam	viaParams;    if (lefLayer1->hasEnclosure()	|| lefLayer2->hasEnclosure()) {	parseEnclosure(viaParams);    } else {	parseOverhang(viaParams);    }        viaParams.setCutLayer(cutLayer->getNumber());    parseCutSize(viaParams);    parseCutSpacing(viaParams);        oaString	viaRuleName = lefViaRule->name();    oaViaDef	*viaDef = oaViaDef::find(lefIn.tech(), viaRuleName);    if (viaDef && viaDef->getType() == oacCustomViaDefType) {	viaRuleName += "_rule";	viaDef = NULL;    }    if (!viaDef) {	viaDef = oaStdViaDef::create(lefIn.tech(), viaRuleName,				     layer1, layer2, viaParams);    } else {	((oaStdViaDef*) viaDef)->setParams(viaParams);    }    parseCutResistance((oaStdViaDef*) viaDef);        if (array.find(viaDef) == oacNullIndex) {	array.append(viaDef);    }    if (lefViaRule->hasDefault()) {	lefIn.addViaDef(viaDef);    }}// *****************************************************************************// LefInViaRule::parseCutResistance()//// This function handles the RESISTANCE attribute for the current viaRule.// It sets the resistancePerCut attribute on the associated viaDef.// Prerequisite : the viaDef has already been created successfully.// *****************************************************************************voidLefInViaRule::parseCutResistance(oaStdViaDef *viaDef){    if (lefCutLayer->hasResistance()) {	viaDef->setResistancePerCut(oaFloat(lefCutLayer->resistance()));    }}// *****************************************************************************// LefInViaRule::parseOverhang()//// This function handles the OVERHANG attribute for the current viaRule.// It sets the layer2 and layer1 enclosures parameters from the OVERHANG// and DIRECTION attributes.// Note that in LEF both routing layers will have the same enclosure values.// *****************************************************************************voidLefInViaRule::parseOverhang(oaViaParam	&viaParams){    oaInt4  enclosureX = 0;    oaInt4  enclosureY = 0;    if (lefLayer1->hasOverhang() || lefLayer2->hasOverhang()) {	if (lefLayer1->hasOverhang()) {	    if (lefLayer1->isHorizontal()) {		enclosureY = lefIn.uuToDBU(lefLayer1->overhang());	    } else {		enclosureX = lefIn.uuToDBU(lefLayer1->overhang());	    }	}	if (lefLayer2->hasOverhang()) {	    if (lefLayer2->isHorizontal()) {		enclosureY = lefIn.uuToDBU(lefLayer2->overhang());	    } else {		enclosureX = lefIn.uuToDBU(lefLayer2->overhang());	    }	}	viaParams.setLayer1Enc(oaVector(enclosureX, enclosureY));	viaParams.setLayer2Enc(oaVector(enclosureX, enclosureY));    }}// *****************************************************************************// LefInViaRule::parseEnclosure()//// This function handles the ENCLOSURE attribute for the current viaRule.// *****************************************************************************voidLefInViaRule::parseEnclosure(oaViaParam	&viaParams){    if (lefLayer1->hasEnclosure()) {	oaInt4  enclosureX(lefIn.uuToDBU(lefLayer1->enclosureOverhang1()));	oaInt4  enclosureY(lefIn.uuToDBU(lefLayer1->enclosureOverhang2()));	viaParams.setLayer1Enc(oaVector(enclosureX, enclosureY));    }    if (lefLayer2->hasEnclosure()) {	oaInt4  enclosureX(lefIn.uuToDBU(lefLayer2->enclosureOverhang1()));	oaInt4  enclosureY(lefIn.uuToDBU(lefLayer2->enclosureOverhang2()));	viaParams.setLayer2Enc(oaVector(enclosureX, enclosureY));    }}// *****************************************************************************// LefInViaRule::parseCutSize()//// This function handles the RECT attribute for the current viaRule.// It sets the cutSize parameter of the specified viaParams.// *****************************************************************************voidLefInViaRule::parseCutSize(oaViaParam	&viaParams){    oaInt4  xl = lefIn.uuToDBU(lefCutLayer->xl());    oaInt4  yl = lefIn.uuToDBU(lefCutLayer->yl());    oaInt4  xh = lefIn.uuToDBU(lefCutLayer->xh());    oaInt4  yh = lefIn.uuToDBU(lefCutLayer->yh());    oaInt4  sizeX = abs(xh - xl);    oaInt4  sizeY = abs(yh - yl);    viaParams.setCutWidth(sizeX);    viaParams.setCutHeight(sizeY);}// *****************************************************************************// LefInViaRule::parseCutSpacing()//// This function handles the SPACING attribute for the current viaRule.// It sets the cutSpacing parameter of the specified viaParams.// OA Cut Spacing is edge to edge while LEF spacing is center to center.// *****************************************************************************voidLefInViaRule::parseCutSpacing(oaViaParam    &viaParams){    oaInt4  lefSpacingX = lefIn.uuToDBU(lefCutLayer->spacingStepX());    oaInt4  lefSpacingY = lefIn.uuToDBU(lefCutLayer->spacingStepY());    oaInt4  spacingX = lefSpacingX - viaParams.getCutWidth();    oaInt4  spacingY = lefSpacingY - viaParams.getCutHeight();        viaParams.setCutSpacing(oaVector(spacingX, spacingY));}// *****************************************************************************// LefInViaRule::parseWidthRanges()//// This function handles the WIDTH ranges attributes for the current viaRule.// *****************************************************************************voidLefInViaRule::parseWidthRanges(){    if (lefLayer1->hasWidth() && lefLayer2->hasWidth()) {	rowMin = getRowIndex(lefIn.uuToDBU(lefLayer1->widthMin()));	colMin = getColIndex(lefIn.uuToDBU(lefLayer2->widthMin()));	rowMax = getRowIndex(lefIn.uuToDBU(lefLayer1->widthMax()) + 1);	colMax = getColIndex(lefIn.uuToDBU(lefLayer2->widthMax()) + 1);    }}// *****************************************************************************// LefInViaRule::parseVias()// // This function handles the VIA attributes for the current via rule// *****************************************************************************voidLefInViaRule::parseVias(oaViaDefArray &array){    for (oaInt4 i = 0; i != lefViaRule->numVias(); i++) {	oaString viaName(lefViaRule->viaName(i));	oaViaDef *viaDef = oaViaDef::find(lefIn.tech(), viaName);		if (!viaDef ||	    (viaDef->getType() == oacStdViaDefType	     && !lefIn.getOptions()->doUseDefaultStdVias())) {	    viaName += "_";	    viaName += cLefViaDesignName;	    viaDef = oaViaDef::find(lefIn.tech(), viaName);	    if (!viaDef) {		throw LefDefError(cViaRuleViaNotFound, lefViaRule->name(),				  (const char*) viaName);	    }	}	if (array.find(viaDef) == oacNullIndex) {	    array.append(viaDef);	}    }}// *****************************************************************************// LefInViaRule::parseProperties()// // This function handles the PROPERTY attributes for the current via rule// *****************************************************************************voidLefInViaRule::parseProperties(){    LefDefProp *propDef;    for (int i = 0; i < lefViaRule->numProps(); i++) {	propDef = lefIn.getProp(lefViaRule->propName(i), cLefDefViaRule);	lefIn.createProp(propDef, viaRule, lefViaRule->propValue(i));    }}// *****************************************************************************// LefInViaRule::getRowIndex()// LefInViaRule::getColumnIndex()// // This function returns the table index for the specified header/row/column.// If an entry does not exist, it is inserted at the appropriate place, and// all existing data is moved up.// *****************************************************************************oaUInt4LefInViaRule::getRowIndex(oaInt4    row){    oaUInt4 numRows = viaTable.getNumRows();    oaUInt4 index = 0;    for (; index < numRows; index++) {	if (viaTable.getRowHeader(index) == row) {	    return index;	}	if (viaTable.getRowHeader(index) > row) {	    break;	}    }    viaTable.setNumRows(numRows + 1);    for (oaUInt4 i = numRows; i >= index && i > 0; i--) {        viaTable.setRowHeader(i, viaTable.getRowHeader(i - 1));        for (oaUInt4 j = 0; j < viaTable.getNumCols(); j++) {            viaTable.setValue(i, j, viaTable.getValue(i - 1, j));        }    }    viaTable.setRowHeader(index, row);    for (oaUInt4 i = 0; i < viaTable.getNumCols(); i++) {	oaValue	*v = index > 0 ? viaTable.getValue(index - 1, i) : NULL;		viaTable.setValue(index, i, v ? (oaViaDefArrayValue*) v->copy() : NULL);    }    return index;}oaUInt4LefInViaRule::getColIndex(oaInt4    column){    oaUInt4 numCols = viaTable.getNumCols();    oaUInt4 index = 0;    for (; index < numCols; index++) {	if (viaTable.getColHeader(index) == column) {	    return index;	}	if (viaTable.getColHeader(index) > column) {	    break;	}    }    viaTable.setNumCols(numCols + 1);    for (oaUInt4 i = numCols; i >= index && i > 0; i--) {        viaTable.setColHeader(i, viaTable.getColHeader(i - 1));        for (oaUInt4 j = 0; j < viaTable.getNumRows(); j++) {	    viaTable.setValue(j, i, viaTable.getValue(j, i - 1));        }    }    viaTable.setColHeader(index, column);    for (oaUInt4 i = 0; i < viaTable.getNumRows(); i++) {	oaValue	*v = index > 0 ? viaTable.getValue(i, index - 1) : NULL;		viaTable.setValue(i, index, v ? (oaViaDefArrayValue*) v->copy() : NULL);    }    return index;}END_LEFDEF_NAMESPACE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -