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

📄 oalefinlayer.cpp

📁 openaccess读def,lef文件所用的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				    oacMinAdjacentViaSpacing, layer->getNumber(),				    v, true, &params);	    } else {		oaLayerConstraintType	type = oacMinSpacing;		if (lefLayer->hasSpacingCenterToCenter(i)) {		    type = oacMinCenterToCenterSpacing;		}		oaValue *v = oaIntValue::create(lefIn.tech(),						lefIn.uuToDBU(lefLayer->spacing(i)));		lefIn.setConstraint(lefIn.getFoundryRules(), type,				    layer->getNumber(), v);	    }	}    }}// *****************************************************************************// LefInLayer::parseEnclosure()// LefInLayer::parsePreferredEnclosure()// LefInLayer::parseEnclosureMetal()// // These functions handle the ENCLOSURE attributes for the specified layer.//// Syntax://     [ENCLOSURE [ABOVE | BELOW] overhang1 overhang2 [WIDTH minWidth] ;] ...//     [PREFERENCLOSURE [ABOVE | BELOW overhang1 overhang2 [WIDTH minWidth] ;] ...// // The ENCLOSURE for cut layers is stored in OA using oaDualIntValue for the// oacMinDualExtension constraint in the foundryRules constraint group, on the// metal layers above and below the cut layer.//// If multiple, width based, rules are present they are grouped together in an// oaoaDualInt1DTblValue, which is indexed by WIDTH.//// Normal ENCLOSURE attributes are mapped to hard constraints, and PREFERRED// ENCLOSURE attributes are mapped to soft constraints in the FoundryRules.// *****************************************************************************voidLefInLayer::parseEnclosure(){    oa1DLookupTbl<oaInt4, oaInt4>   firstTableBelow;    oa1DLookupTbl<oaInt4, oaInt4>   secondTableBelow;    oa1DLookupTbl<oaInt4, oaInt4>   firstTableAbove;    oa1DLookupTbl<oaInt4, oaInt4>   secondTableAbove;    oaPhysicalLayer *layerBelow = layer->getLayerBelow(oacMetalMaterial);    // Retrieve any values already on the layer below.    if (layerBelow) {	oaValue *v = lefIn.getConstraint(lefIn.getFoundryRules(),					 oacMinDualExtension,					 layerBelow->getNumber(),					 layer->getNumber(), NULL, true, true);	if (v && v->getType() == oacDualInt1DTblValueType) {	    ((oaDualInt1DTblValue*) v)->getFirst(firstTableBelow);	    ((oaDualInt1DTblValue*) v)->getSecond(secondTableBelow);	}    }    // Add the new values to the tables.    for (int i = 0; i < lefLayer->numEnclosure(); i++) {	oaUInt4	ext1 = lefIn.uuToDBU(lefLayer->enclosureOverhang1(i));	oaUInt4	ext2 = lefIn.uuToDBU(lefLayer->enclosureOverhang2(i));	oaUInt4	width = 0;		if (lefLayer->hasEnclosureWidth(i)) {	    width = lefIn.uuToDBU(lefLayer->enclosureMinWidth(i));	}	if (!lefLayer->hasEnclosureRule(i)	    || !strcmp(lefLayer->enclosureRule(i), "BELOW")) {	    oaUInt4 firstIndex = getIndex(firstTableBelow, width);	    oaUInt4 secondIndex = getIndex(secondTableBelow, width);		    firstTableBelow.setValue(firstIndex, ext1);	    secondTableBelow.setValue(secondIndex, ext2);	}	if (!lefLayer->hasEnclosureRule(i)	    || !strcmp(lefLayer->enclosureRule(i), "ABOVE")) {	    oaUInt4 firstIndex = getIndex(firstTableAbove, width);	    oaUInt4 secondIndex = getIndex(secondTableAbove, width);		    firstTableAbove.setValue(firstIndex, ext1);	    secondTableAbove.setValue(secondIndex, ext2);	}    }    // Set the constraint for the layer below    if (firstTableBelow.getNumItems() > 0 && layerBelow) {	oaValue  *value;		if (firstTableBelow.getNumItems() == 1) {	    value = oaDualIntValue::create(lefIn.tech(),					   firstTableBelow.getValue(0),					   secondTableBelow.getValue(0));	} else {	    value = oaDualInt1DTblValue::create(lefIn.tech(),						      firstTableBelow,						      secondTableBelow);	}	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinDualExtension,			    layerBelow->getNumber(), layer->getNumber(),			    value);    }    // Temporarily store the constraint for layerAbove on the first tech layer.    oaIter<oaLayer> layerIt(lefIn.tech()->getLayers());    oaLayer *otherLayer = layerIt.getNext();    if (firstTableAbove.getNumItems() > 0 && otherLayer) {	oaValue  *value;		if (firstTableAbove.getNumItems() == 1) {	    value = oaDualIntValue::create(lefIn.tech(),					   firstTableAbove.getValue(0),					   secondTableAbove.getValue(0));	} else {	    value = oaDualInt1DTblValue::create(lefIn.tech(),						      firstTableAbove,						      secondTableAbove);	}	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinDualExtension,			    layer->getNumber(), otherLayer->getNumber(),			    value);    }}voidLefInLayer::parsePreferredEnclosure(){    oa1DLookupTbl<oaInt4, oaInt4>   firstTableBelow;    oa1DLookupTbl<oaInt4, oaInt4>   secondTableBelow;    oa1DLookupTbl<oaInt4, oaInt4>   firstTableAbove;    oa1DLookupTbl<oaInt4, oaInt4>   secondTableAbove;    oaPhysicalLayer *layerBelow = layer->getLayerBelow(oacMetalMaterial);    // Retrieve any values already on the layer below.    if (layerBelow) {	oaValue *v = lefIn.getConstraint(lefIn.getFoundryRules(),					 oacMinDualExtension,					 layerBelow->getNumber(),					 layer->getNumber(), NULL, false, false);	if (v && v->getType() == oacDualInt1DTblValueType) {	    ((oaDualInt1DTblValue*) v)->getFirst(firstTableBelow);	    ((oaDualInt1DTblValue*) v)->getSecond(secondTableBelow);	}    }    // Add the new values to the tables.    for (int i = 0; i < lefLayer->numPreferEnclosure(); i++) {	oaUInt4	ext1 = lefIn.uuToDBU(lefLayer->preferEnclosureOverhang1(i));	oaUInt4	ext2 = lefIn.uuToDBU(lefLayer->preferEnclosureOverhang2(i));	oaUInt4	width = 0;		if (lefLayer->hasPreferEnclosureWidth(i)) {	    width = lefIn.uuToDBU(lefLayer->preferEnclosureMinWidth(i));	}	if (!lefLayer->hasPreferEnclosureRule(i)	    || !strcmp(lefLayer->preferEnclosureRule(i), "BELOW")) {	    oaUInt4 firstIndex = getIndex(firstTableBelow, width);	    oaUInt4 secondIndex = getIndex(secondTableBelow, width);		    firstTableBelow.setValue(firstIndex, ext1);	    secondTableBelow.setValue(secondIndex, ext2);	}	if (!lefLayer->hasPreferEnclosureRule(i)	    || !strcmp(lefLayer->preferEnclosureRule(i), "ABOVE")) {	    oaUInt4 firstIndex = getIndex(firstTableAbove, width);	    oaUInt4 secondIndex = getIndex(secondTableAbove, width);		    firstTableAbove.setValue(firstIndex, ext1);	    secondTableAbove.setValue(secondIndex, ext2);	}    }    // Set the soft constraint for the layer below    if (firstTableBelow.getNumItems() > 0 && layerBelow) {	oaValue  *value;		if (firstTableBelow.getNumItems() == 1) {	    value = oaDualIntValue::create(lefIn.tech(),					   firstTableBelow.getValue(0),					   secondTableBelow.getValue(0));	} else {	    value = oaDualInt1DTblValue::create(lefIn.tech(),						firstTableBelow,						secondTableBelow);	}	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinDualExtension,			    layerBelow->getNumber(), layer->getNumber(),			    value, false);    }    // Temporarily store the constraint for layerAbove on the first tech layer.    oaIter<oaLayer> layerIt(lefIn.tech()->getLayers());    oaLayer *otherLayer = layerIt.getNext();    if (firstTableAbove.getNumItems() > 0 && otherLayer) {	oaValue  *value;		if (firstTableAbove.getNumItems() == 1) {	    value = oaDualIntValue::create(lefIn.tech(),					   firstTableAbove.getValue(0),					   secondTableAbove.getValue(0));	} else {	    value = oaDualInt1DTblValue::create(lefIn.tech(),						      firstTableAbove,						      secondTableAbove);	}	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinDualExtension,			    layer->getNumber(), otherLayer->getNumber(),			    value, false);    }}voidLefInLayer::parseEnclosureMetal(){    oaPhysicalLayer *cutBelow = layer->getLayerBelow(oacCutMaterial);        if (!cutBelow) {	return;    }    oaIter<oaLayer> layerIt(lefIn.tech()->getLayers());    oaLayer	    *otherLayer = layerIt.getNext();        if (!otherLayer) {	return;    }    oaLayerPairConstraintDef	*def	= oaLayerPairConstraintDef::get(oacMinDualExtension);    oaLayerPairConstraint	*c;    while (c = oaLayerPairConstraint::find(lefIn.getFoundryRules(),					   cutBelow->getNumber(),					   otherLayer->getNumber(), def)) {	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinDualExtension,			    layer->getNumber(), cutBelow->getNumber(),			    c->getValue()->copy(), c->isHard());	c->destroy();    }    while (c = oaLayerPairConstraint::find(lefIn.getDefaultRules(),					   cutBelow->getNumber(),					   otherLayer->getNumber(), def)) {	lefIn.setConstraint(lefIn.getDefaultRules(), oacMinDualExtension,			    layer->getNumber(), cutBelow->getNumber(),			    c->getValue()->copy(), c->isHard());	c->destroy();    }}// *****************************************************************************// LefInLayer::parseSpacing()// LefInLayer::parseSpacingInfluence()// // These functions handle the Spacing attributes for the specified layer.//// Syntax://     [SPACING minSpacing//         [ RANGE minWidth maxWidth//            [ USELENGTHTHRESHOLD//            | INFLUENCE value [RANGE stubMinWidth stubMaxWidth]//            | RANGE minWidth maxWidth]//         | LENGTHTHRESHOLD maxLength [RANGE minWidth maxWidth]//         ]//     ;] ...//// SPACING rules are stored in OA as an oaIntValue for the oacMinSpacing// constraint in the foundry rules, and the generic (no range)// spacing is also set as the spacing value on the LEFDefaultRouteSpec// constraint group.//// If multiple RANGE (width) based rules are present, the values are grouped// together in an oaInt1DTblValue, which is indexed by width.//// If LENGTHTHRESHOLD spacing rules are present, all SPACING rules are grouped// together in an oaInt2DTblValue, indexed by width and length.// *****************************************************************************voidLefInLayer::parseSpacing(){    if (!lefLayer->hasSpacingNumber()) {	return;    }    oa2DLookupTbl<oaInt4, oaInt4, oaInt4> table(0, 0, "width", "length", 0,						oacSnapDownInterpolateType,						oacInclusiveSnapDownInterpolateType);        // First process the generic spacing value, then all spacing ranges, and    // then process the length-threshold values so that the table will inherit    // the right spacing values for ranges to which the length-threshold does    // not apply.    // Simple spacing rules.        oaInt4 width = lefIn.getLayerWidth(lefIn.getFoundryRules(),				       layer->getNumber());    for (oaInt4 i = 0; i < lefLayer->numSpacing(); i++) {	if (lefLayer->hasSpacingRangeInfluence(i)	    || lefLayer->hasSpacingLengthThreshold(i)) {	    continue;	}		// This could be an "implicit" generic spacing if the lower limit is	// less or equal to the minimum width.	if (lefLayer->hasSpacingRange(i)	    && lefIn.uuToDBU(lefLayer->spacingRangeMin(i)) > width) {	    continue;	}	// Store the generic spacing in location 0, 0 of the table, and in the	// table's default value.	oaInt4	spacing = lefIn.uuToDBU(lefLayer->spacing(i));	oaUInt4 w = getRowIndex(table, 0);	oaUInt4 l = getColIndex(table, 0);	table.setValue(w, l, spacing);	table.setDefaultValue(spacing);    }    // LENGTHTHRESHOLD spacing rules    for (oaInt4 i = 0; i < lefLayer->numSpacing(); i++) {	if (lefLayer->hasSpacingLengthThreshold(i)) {	    oaInt4  spacing = lefIn.uuToDBU(lefLayer->spacing(i));	    oaInt4  width   = 0;	    oaUInt4 wm      = table.getNumRows();	    oaInt4  length  = lefIn.uuToDBU(lefLayer->spacingLengthThreshold(i));	    // Determine the applicable width range for this spacing value.	    // We add an extra column for the start of the next range.	    if (lefLayer->hasSpacingLengthThresholdRange(i)) {		width = lefIn.uuToDBU(lefLayer->spacingLengthThresholdRangeMin(i));		oaInt4 widthMax = lefIn.uuToDBU(lefLayer->spacingLengthThresholdRangeMax(i)) + 1;		wm = getRowIndex(table, widthMax);	    }	    // Store the spacing value in all width entries between the column	    // for the minimum width (inclusive) and the column for the start	    // of the next range.	    oaUInt4 w = getRowIndex(table, width);	    oaUInt4 l = getColIndex(table, length);	    for (oaUInt4 j = w; j < wm; j++) {		if (l) {		    table.setValue(j, l - 1, spacing);		} else {		    table.setValue(j, l, spacing);		}	    }	}    }        // RANGE spacing rules with USELENGHTTHRESHOLD    // (note: upper limit ignored)    for (oaInt4 i = 0; i < lefLayer->numSpacing(); i++) {	if (lefLayer->hasSpacingRangeInfluence(i)	    || lefLayer->hasSpacingLengthThreshold(i)	    || !lefLayer->hasSpacingRange(i)	    || !lefLayer->hasSpacingRangeUseLengthThreshold(i)) {	    continue;	}		oaInt4	spacing = lefIn.uuToDBU(lefLayer->spacing(i));	oaInt4	width = lefIn.uuToDBU(lefLayer->spacingRangeMin(i));	oaUInt4 w = getRowIndex(table, width);	oaUInt4 l = table.getNumCols() - 1;	table.setValue(w, l, spacing);    }        // RANGE spacing rules without USELENGTHTHRESHOLD    // (note: upper limit ignored)    for (oaInt4 i = 0; i < lefLayer->numSpacing(); i++) {	if (lefLayer->hasSpacingRangeInfluence(i)	    || lefLayer->hasSpacingLengthThreshold(i)	    || !lefLayer->hasSpacingRange(i)	    || lefLayer->hasSpacingRangeUseLengthThreshold(i)) {	    continue;	}		// Skip implicit default spacing rules here.

⌨️ 快捷键说明

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