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

📄 oalefinlayer.cpp

📁 openaccess读def,lef文件所用的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if (lefLayer->spacingRangeMin(i) <= lefLayer->width()) {	    continue;	}	oaInt4	spacing = lefIn.uuToDBU(lefLayer->spacing(i));	oaInt4	width   = lefIn.uuToDBU(lefLayer->spacingRangeMin(i));	oaUInt4 w       = getRowIndex(table, width);	for (oaUInt4 j = 0; j < table.getNumCols(); j++) {	    table.setValue(w, j, spacing);	}    }        // Set the correct spacing rule type based on the values in the table.    // simple spacing values are reduced to an oaIntValue, and width-based-only    // spacing values are reduced to a 1D lookup table.    oaValue *value = NULL;        if (table.getNumRows() == 1 && table.getNumCols() == 1) {	value = oaIntValue::create(lefIn.tech(), table.getValue(0, 0));    } else if (table.getNumCols() == 1) {	oa1DLookupTbl<oaInt4, oaInt4> table1D(table.getNumRows(), "width", 0,					      oacSnapDownInterpolateType);	table1D.setDefaultValue(table.getDefaultValue());	for (oaUInt4 j = 0; j < table.getNumRows(); j++) {	    table1D.setHeader(j, table.getRowHeader(j));	    table1D.setValue(j, table.getValue(j, 0));	}		value = oaInt1DTblValue::create(lefIn.tech(), table1D);    } else if (table.getNumRows() && table.getNumCols()) {	value = oaInt2DTblValue::create(lefIn.tech(), table);    }    if (value) {	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinSpacing,			    layer->getNumber(), value);    }}voidLefInLayer::parseSpacingInfluence(){    if (lefLayer->hasSpacingNumber()) {	oa2DLookupTbl<oaInt4, oaInt4, oaInt4> table(0, 0, "width", "distance", 0,						    oacSnapDownInterpolateType,						    oacInclusiveSnapDownInterpolateType);	for (oaInt4 i = 0; i < lefLayer->numSpacing(); i++) {	    if (!lefLayer->hasSpacingRange(i)		|| !lefLayer->hasSpacingRangeInfluence(i)) {		continue;	    }	    oaUInt4 width  = lefIn.uuToDBU(lefLayer->spacingRangeMin(i));	    oaUInt4 length = lefIn.uuToDBU(lefLayer->spacingRangeInfluence(i));	    oaUInt4 w = getRowIndex(table, width);	    oaUInt4 l = getColIndex(table, length);	    table.setValue(w, l, lefIn.uuToDBU(lefLayer->spacing(i)));	}	if (table.getNumRows() && table.getNumCols()) {	    oaValue *value = oaInt2DTblValue::create(lefIn.tech(), table);	    	    lefIn.setConstraint(lefIn.getFoundryRules(),				oacMinProtrudedProximitySpacing, 				layer->getNumber(), value);	}    }}// *****************************************************************************// LefInLayer::parseSpacingTable()// LefInLayer::parseSpacingTableInfluence()//// These functions handle the Spacing Tables (5.5) for this layer.//// Syntax://     [SPACINGTABLE//         PARALLELRUNLENGTH {length} ...//         {WIDTH width {spacing} ...} ... ;//         [SPACINGTABLE//             INFLUENCE {WIDTH width WITHIN distance SPACING spacing} ... ;//	   ]//     ]// // The SPACINGTABLE is stored in OA using an oaInt2DTblValue for the// oacMinSpacing constraint in the foundry rules constraint group.//// The SPACINGTABLE INFLUENCE is stored in OA using an oaInt2DTblValue for the// oacMinProximitySpacing constraint in the foundry rules constraint group.// *****************************************************************************voidLefInLayer::parseSpacingTable(){    for (oaInt4 i = 0; i < lefLayer->numSpacingTable(); i++) {	lefiSpacingTable *lefSpacing = lefLayer->spacingTable(i);	if (lefSpacing->isInfluence()) {	    continue;	}		lefiParallel *parallel = lefSpacing->parallel();	oa2DLookupTbl<oaInt4, oaInt4, oaInt4>	table(parallel->numWidth(),						      parallel->numLength(),						      "width", "length", 0,						      oacSnapDownInterpolateType,						      oacInclusiveSnapDownInterpolateType);	for (oaInt4 w = 0; w < parallel->numWidth(); w++) {	    oaUInt4 width = lefIn.uuToDBU(parallel->width(w));	    table.setRowHeader(w, width ? width + 1 : 0);	    for (oaInt4 l = 0; l < parallel->numLength(); l++) {		table.setColHeader(l, lefIn.uuToDBU(parallel->length(l)));		table.setValue(w, l,                               lefIn.uuToDBU(parallel->widthSpacing(w, l)));	    }	}	oaValue	*value = oaInt2DTblValue::create(lefIn.tech(), table);	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinSpacing, 			    layer->getNumber(), value);    }}voidLefInLayer::parseSpacingTableInfluence(){    for (oaInt4 i = 0; i < lefLayer->numSpacingTable(); i++) {	lefiSpacingTable *lefSpacing = lefLayer->spacingTable(i);	if (!lefSpacing->isInfluence()) {	    continue;	}	lefiInfluence *influence = lefSpacing->influence();	oa2DLookupTbl<oaInt4, oaInt4, oaInt4>	table(0, 0, "width", "distance", 0,						      oacInclusiveSnapDownInterpolateType,						      oacInclusiveSnapDownInterpolateType);	for (oaInt4 j = 0; j < influence->numInfluenceEntry(); j++) {	    oaUInt4 w = getRowIndex(table, lefIn.uuToDBU(influence->width(j)));	    oaUInt4 d = getColIndex(table, lefIn.uuToDBU(influence->distance(j)));	    table.setValue(w, d, lefIn.uuToDBU(influence->spacing(j)));	}	if (table.getNumRows()) {	    oaValue *value = oaInt2DTblValue::create(lefIn.tech(), table);	    	    lefIn.setConstraint(lefIn.getFoundryRules(), oacMinProximitySpacing, 				layer->getNumber(), value);	}    }    }// *****************************************************************************// LefInLayer::parseWireExt()// // This function handles the WIREEXTENSION attribute for the current layer.//// Syntax://     [WIREEXTENSION value ; ]// // The WIREEXTENSION value is stored in OA using an oaIntValue for the// oacMinWireExtension constraint in the LEFDefaultRouteSpec constraint group.// *****************************************************************************voidLefInLayer::parseWireExt(){    if (lefLayer->hasWireExtension()) {	oaValue *v = oaIntValue::create(lefIn.tech(),					lefIn.uuToDBU(lefLayer->wireExtension()));		lefIn.setConstraint(lefIn.getDefaultRules(), oacMinWireExtension,			    layer->getNumber(), v);    }}// *****************************************************************************// LefInLayer::parseMinCut()// // This function handles the minimumCut attributes for the specified layer.// Since minimumcut rules are stored on CUT layers in OA, we store them// on metal layers temporarily in LefInLayer::parseMinCutMetal, and this// function moves it onto the current CUT layer...// *****************************************************************************voidLefInLayer::parseMinCut(){    oaPhysicalLayer *layerBelow = layer->getLayerBelow(oacMetalMaterial);        if (!layerBelow) {        return;    }    oaLayerConstraintDef    *def = oaLayerConstraintDef::get(oacMinNumCut);    oaConstraint	    *c = oaLayerConstraint::find(lefIn.getFoundryRules(), 							 layerBelow->getNumber(),							 def);    if (c) {        lefIn.setConstraint(lefIn.getFoundryRules(), oacMinNumCut, 			    layer->getNumber(), c->getValue()->copy());	c->destroy();    }        def = oaLayerConstraintDef::get(oacMinProtrusionNumCut);    c = oaLayerConstraint::find(lefIn.getFoundryRules(), layerBelow->getNumber(), 				def);    if (c) {	oaConstraintParamArray params;	c->getParams(params);		oaConstraintParamArray params2(3);	params2.append(params[0]->copy());	params2.append(params[1]->copy());	params2.append(params[2]->copy());	lefIn.setConstraint(lefIn.getFoundryRules(), oacMinProtrusionNumCut,			    layer->getNumber(), c->getValue()->copy(), true, 			    &params2);	c->destroy();    }}// *****************************************************************************// LefInLayer::parseMinCutMetal()// // This function handles the minimumCut attributes for the specified layer.// MinCut rules are stored only on the cut layers in OA.// Rules for the cut layer above are temporarily stored on the current// metal layer, since the cut layer above does not exist yet.// They are moved to the cut layer by LefInLayer::parseMinCut.//// MINIMUMCUT <numCuts> WIDTH <width> [FROMABOVE | FROMBELOW]// The oacMinNumCut constraint should be set on the cut layer.// (Determined using FROMABOVE, FROMLBEOW).// Because there can be several of these statements the value should be an// oa1DLookupTbl with the lookup (width) value (numcuts).// *****************************************************************************voidLefInLayer::parseMinCutMetal(){    if (!lefLayer->numMinimumcut()) {        return;    }        oaLayer *layerBelow = layer->getLayerBelow(oacCutMaterial);    oa1DLookupTbl<oaInt4, oaInt4> tableBelow(0, "width", 1,					     oacSnapDownInterpolateType,					     oacSnapDownExtrapolateType,					     oacSnapDownExtrapolateType);    oa1DLookupTbl<oaInt4, oaInt4> tableAbove(0, "width", 1,					     oacSnapDownInterpolateType,					     oacSnapDownExtrapolateType,					     oacSnapDownExtrapolateType);        oaConstraint    *c;    for (oaInt4 i = 0; i < lefLayer->numMinimumcut(); i++) {	// Handle the oacMinProtrusionNumCut constraint        if (lefLayer->hasMinimumcutNumCuts(i)) {	    continue;        }        	// Fill the minCut tables        oaInt4 width = lefIn.uuToDBU(lefLayer->minimumcutWidth(i));        if (!lefLayer->hasMinimumcutConnection(i)            || !strcmp(lefLayer->minimumcutConnection(i), "FROMBELOW")) {            for (oaUInt4 j(0); j < tableBelow.getNumItems(); j++) {                if ((tableBelow.getValue(j) == lefLayer->minimumcut(i))                    && (tableBelow.getHeader(j) < width)) {		    lefIn.warn(cLayerMinCutRedundant, lefLayer->name(),			       lefLayer->minimumcut(i),			       lefLayer->minimumcutWidth(i));                    width = tableBelow.getHeader(j);                }            }            tableBelow.setValue(getIndex(tableBelow, width),                                lefLayer->minimumcut(i));        }                if (!lefLayer->hasMinimumcutConnection(i)            || !strcmp(lefLayer->minimumcutConnection(i), "FROMABOVE")) {            for (oaUInt4 j(0); j < tableAbove.getNumItems(); j++) {                if ((tableAbove.getValue(j) == lefLayer->minimumcut(i))                    && (tableAbove.getHeader(j) < width)) {                    lefIn.warn(cLayerMinCutRedundant, lefLayer->name(),			       lefLayer->minimumcut(i),			       lefLayer->minimumcutWidth(i));                    width = tableAbove.getHeader(j);                }            }            tableAbove.setValue(getIndex(tableAbove, width),                                lefLayer->minimumcut(i));        }    }    oaLayerConstraintDef    *def = oaLayerConstraintDef::get(oacMinNumCut);        if (layerBelow && tableBelow.getNumItems()) {	c = oaLayerConstraint::find(lefIn.getFoundryRules(),				    layerBelow->getNumber(), def);        	if (c && c->getValue()->getType() == oacInt1DTblValueType) {            oa1DLookupTbl<oaInt4, oaInt4> tablePrev(0, "width", 1);            ((oaInt1DTblValue *) c->getValue())->get(tablePrev);            for (oaUInt4 j(0); j < tablePrev.getNumItems(); j++) {                for (oaUInt4 k(0); k < tableBelow.getNumItems(); k++) {                    if (tablePrev.getValue(j) == tableBelow.getValue(k)) {                        if (tablePrev.getHeader(j) < tableBelow.getHeader(k)) {                            tableBelow.setHeader(j, tablePrev.getHeader(k));                        }                        break;                    } else if (k = tableBelow.getNumItems() - 1) {                        tableBelow.setValue(getIndex(tableBelow,                                                     tablePrev.getHeader(j)),                                            tablePrev.getValue(j));                    }                }            }	    c->setValue(oaInt1DTblValue::create(lefIn.tech(), tableBelow));	} else {	    oaValue *v = oaInt1DTblValue::create(lefIn.tech(), tableBelow);	    c = oaLayerConstraint::create(layerBelow->getNumber(), def, v);	    oaConstraintGroupMem::create(lefIn.getFoundryRules(), c);	}    }    if (tableAbove.getNumItems()) {	oaValue *v = oaInt1DTblValue::create(lefIn.tech(), tableAbove);	c = oaLayerConstraint::create(layer->getNumber(), def, v);	oaConstraintGroupMem::create(lefIn.getFoundryRules(), c);    }}// *****************************************************************************// LefInLayer::parseMinProtrusionCut()// // This function handles the minimumCut attributes for the specified layer.// MinCut rules are stored only on the cut layers in OA.// Rules for the cut layer above are temporarily stored on the current// metal layer, since the cut layer above does not exist yet.// They are moved to the cut layer by LefInLayer::parseMinCut.//// MINIMUMCUT <numCuts> WIDTH <width> [FROMABOVE | FROMBELOW]//                                        LENGTH <length> WITHIN <distance>// The oacMinProtrusionNumCut constraint should be set on the cut layer.// (Determined using FROMABOVE, FROMBELOW).// // OA allows only be one of these per layer. It should be represented as an// oaIntParam constraint with parameters (distance, length, width) and// value (numcuts). If multiple such rules are found in LEF, the most// conservative combination is taken.// *****************************************************************************voidLefInLayer::parseMinProtrusionCut(){    oaLayer *layerBelow = layer->getLayerBelow(oacCutMaterial);    for (oaInt4 i = 0; i < lefLayer->numMinimumcut(); i++) {        if (!lefLayer->hasMinimumcutNumCuts(i)) {	    continue;        }	oaInt4	dist = lefIn.uuToDBU(lefLayer->minimumcutDistance(i));        oaInt4	length = lefIn.uuToDBU(lefLayer->minimumcutLength(i));	oaInt4	width = lefIn.uuToDBU(lefLayer->minimumcutWidth(i));	oaInt4	numCut = lefLayer->minimumcut(i);	if (layerBelow	    && (!lefLayer->hasMinimumcutConnection(i)	    || !strcmp(lefLayer->minimumcutConnection(i), "FROMBELOW"))) {	    setMinCutConstraint(layerBelow->getNumber(), dist, length, width, numCut);	}	if (!lefLayer->hasMinimumcutConnection(i)	    || !strcmp(lefLayer->minimumcutConnection(i), "FROMABOVE")) {	    setMinCutConstraint(layer->getNumber(), dist, length, width, numCut);	    	}    }}// *****************************************************************************// LefInLayer::parseCutRes()

⌨️ 快捷键说明

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