📄 oalefoutlayer.cpp
字号:
&& table.getRowInterpolateType() == oacSnapDownInterpolateType) { width -= 1; } lefOut.outNoIndent("\n"); lefOut.output("WIDTH %.11g ", lefOut.dbuToUU(width)); for (oaUInt4 l(0); l < table.getNumCols(); l++) { lefOut.outNoIndent("%.11g ", lefOut.dbuToUU(table.getValue(w, l))); } } lefOut.outNoIndent(";\n"); lefOut.decIndent();}// *****************************************************************************// LefOutLayer::writeSpacingInfluence()// // This function outputs the spacing influence attribute for this layer.// *****************************************************************************voidLefOutLayer::writeSpacingInfluence(){ oaValue *value = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinProtrudedProximitySpacing, layer->getNumber()); if (value && value->getType() == oacInt2DTblValueType) { oa2DLookupTbl<oaInt4, oaInt4, oaInt4> table; ((oaInt2DTblValue *) value)->get(table); for (oaUInt4 w(0); w < table.getNumRows(); w++) { for (oaUInt4 l(0); l < table.getNumCols(); l++) { oaUInt4 width = table.getRowHeader(w); oaUInt4 length = table.getColHeader(l); oaUInt4 spacing = table.getValue(w, l); if ((w && table.getValue(w - 1, l) == spacing) || (l && table.getValue(w, l - 1) == spacing)) { continue; } lefOut.output("SPACING %.11g RANGE %.11g 1000 INFLUENCE %.11g ;\n", lefOut.dbuToUU(spacing), lefOut.dbuToUU(width), lefOut.dbuToUU(length)); } } }}// *****************************************************************************// LefOutLayer::writeSpacingInfluenceTable()// // This function outputs the spacing influence attribute for this layer.// *****************************************************************************voidLefOutLayer::writeSpacingInfluenceTable(){ if (lefOut.getOptions()->getVersion() < cLefDefVersion55) { return; } oaValue *value = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinProximitySpacing, layer->getNumber()); if (value && value->getType() == oacInt2DTblValueType) { lefOut.output("SPACINGTABLE INFLUENCE"); lefOut.incIndent(); oa2DLookupTbl<oaInt4, oaInt4, oaInt4> table; oaUInt4 spacing = 0; ((oaInt2DTblValue *) value)->get(table); for (oaUInt4 w = 0; w < table.getNumRows(); w++) { oaUInt4 width = table.getRowHeader(w); if (width > 0 && table.getRowInterpolateType() == oacSnapDownInterpolateType) { width -= 1; } lefOut.outNoIndent("\n"); lefOut.output("WIDTH %.11g ", lefOut.dbuToUU(width)); for (oaUInt4 d = 0; d < table.getNumCols(); d++) { if (table.getValue(w, d) > oaInt4(spacing)) { oaUInt4 distance = table.getColHeader(d); if (distance > 0 && table.getColInterpolateType() == oacSnapDownInterpolateType) { distance -= 1; } spacing = table.getValue(w, d); lefOut.outNoIndent("WITHIN %.11g SPACING %.11g", lefOut.dbuToUU(distance), lefOut.dbuToUU(spacing)); break; } } } lefOut.outNoIndent(" ;\n"); lefOut.decIndent(); }}// *****************************************************************************// LefOutLayer::writeCutSpacing()// // This function outputs the cut-spacing for this layer, syntax:// [SPACING minSpacing [LAYER 2ndLayerName] ;]...// *****************************************************************************voidLefOutLayer::writeCutSpacing(){ oaValue *value = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinSpacing, layer->getNumber()); if (value && value->getType() == oacIntValueType) { lefOut.output("SPACING %.11g ;\n", lefOut.dbuToUU(((oaIntValue *)value)->get())); } value = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinCenterToCenterSpacing, layer->getNumber()); if (value && value->getType() == oacIntValueType) { lefOut.output("SPACING %.11g CENTERTOCENTER ;\n", lefOut.dbuToUU(((oaIntValue *)value)->get())); } oaIter<oaLayer> otherLayerIter(lefOut.tech()->getLayers()); while (oaLayer *otherLayer = otherLayerIter.getNext()) { if (otherLayer->getType() == oacPhysicalLayerType && (((oaPhysicalLayer *) otherLayer)->getMaskNumber() < layer->getMaskNumber())) { value = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinClearance, layer->getNumber(), otherLayer->getNumber()); if (value && value->getType() == oacIntValueType) { oaString otherLayerName; otherLayer->getName(otherLayerName); lefOut.output("SPACING %.11g LAYER %s ;\n", lefOut.dbuToUU(((oaIntValue *)value)->get()), (const char *) otherLayerName); } } } if (lefOut.getOptions()->getVersion() > cLefDefVersion54) { oaLayerConstraintDef *def = oaLayerConstraintDef::get(oacMinAdjacentViaSpacing); oaConstraintParamDef *numCutsDef = oaConstraintParamDef::get(oacNumCutsConstraintParamType); oaConstraintParamDef *distDef = oaConstraintParamDef::get(oacDistanceConstraintParamType); oaConstraint *c = oaLayerConstraint::find(lefOut.getFoundryRules(), layer->getNumber(), def); if (c) { oaConstraintParamArray params; c->getParams(params); oaConstraintParam *numCutsParam = params.findParam(numCutsDef); oaConstraintParam *distParam = params.findParam(distDef); if (!numCutsParam || !distParam) { return; } oaValue *value = c->getValue(); oaValue *numCutsValue = numCutsParam->getValue(); oaValue *distValue = distParam->getValue(); if (value && value->getType() == oacIntValueType && numCutsValue && numCutsValue->getType() == oacIntValueType && distValue && distValue->getType() == oacIntValueType) { lefOut.output("SPACING %.11g ADJACENTCUTS %d WITHIN %.11g ;\n", lefOut.dbuToUU(((oaIntValue*) value)->get()), ((oaIntValue*) numCutsValue)->get(), lefOut.dbuToUU(((oaIntValue*) distValue)->get())); } } }}// *****************************************************************************// LefOutLayer::writeEnclosure()// // This function outputs the enclosure for this layer.// *****************************************************************************voidLefOutLayer::writeEnclosure(){ oa1DLookupTbl<oaInt4, oaInt4> firstTableBelow; oa1DLookupTbl<oaInt4, oaInt4> secondTableBelow; oaValue *vBelow = NULL; oaPhysicalLayer *layerBelow = layer->getLayerBelow(oacMetalMaterial); if (layerBelow) { vBelow = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinDualExtension, layerBelow->getNumber(), layer->getNumber(), NULL, true, true); if (vBelow && vBelow->getType() == oacDualInt1DTblValueType) { ((oaDualInt1DTblValue*) vBelow)->getFirst(firstTableBelow); ((oaDualInt1DTblValue*) vBelow)->getSecond(secondTableBelow); } else if (vBelow && vBelow->getType() == oacDualIntValueType) { firstTableBelow.setNumItems(1); secondTableBelow.setNumItems(1); firstTableBelow.setHeader(0, 0); secondTableBelow.setHeader(0, 0); firstTableBelow.setValue(0, ((oaDualIntValue*) vBelow)->getFirst()); secondTableBelow.setValue(0, ((oaDualIntValue*) vBelow)->getSecond()); } } oa1DLookupTbl<oaInt4, oaInt4> firstTableAbove; oa1DLookupTbl<oaInt4, oaInt4> secondTableAbove; oaValue *vAbove = NULL; oaPhysicalLayer *layerAbove = layer->getLayerAbove(oacMetalMaterial); if (layerAbove) { vAbove = lefOut.getConstraint(lefOut.getFoundryRules(), oacMinDualExtension, layerAbove->getNumber(), layer->getNumber(), NULL, true, true); if (vAbove && vAbove->getType() == oacDualInt1DTblValueType) { ((oaDualInt1DTblValue*) vAbove)->getFirst(firstTableAbove); ((oaDualInt1DTblValue*) vAbove)->getSecond(secondTableAbove); } else if (vAbove && vAbove->getType() == oacDualIntValueType) { firstTableAbove.setNumItems(1); secondTableAbove.setNumItems(1); firstTableAbove.setHeader(0, 0); secondTableAbove.setHeader(0, 0); firstTableAbove.setValue(0, ((oaDualIntValue*) vAbove)->getFirst()); secondTableAbove.setValue(0, ((oaDualIntValue*) vAbove)->getSecond()); } } for (oaUInt4 i = 0; i < firstTableBelow.getNumItems(); i++) { lefOut.output("ENCLOSURE BELOW %.11g %.11g", lefOut.dbuToUU(firstTableBelow.getValue(i)), lefOut.dbuToUU(secondTableBelow.getValue(i))); oaUInt4 width = firstTableBelow.getHeader(i); if (width > 0) { lefOut.outNoIndent(" WIDTH %.11g", lefOut.dbuToUU(width)); } lefOut.outNoIndent(" ;\n"); } for (oaUInt4 i = 0; i < firstTableAbove.getNumItems(); i++) { lefOut.output("ENCLOSURE ABOVE %.11g %.11g", lefOut.dbuToUU(firstTableAbove.getValue(i)), lefOut.dbuToUU(secondTableAbove.getValue(i))); oaUInt4 width = firstTableAbove.getHeader(i); if (width > 0) { lefOut.outNoIndent(" WIDTH %.11g", lefOut.dbuToUU(width)); } lefOut.outNoIndent(" ;\n"); }}// *****************************************************************************// LefOutLayer::writePreferredEnclosure()// // This function outputs the preferred enclosure for this layer. Note that// we still search the DefaultRules for backwards compatability with 2.2.2.// *****************************************************************************voidLefOutLayer::writePreferredEnclosure(){ oa1DLookupTbl<oaInt4, oaInt4> firstTableBelow; oa1DLookupTbl<oaInt4, oaInt4> secondTableBelow; oaValue *vBelow = NULL; oaPhysicalLayer *layerBelow = layer->getLayerBelow(oacMetalMaterial); if (layerBelow) { vBelow = lefOut.getConstraint(lefOut.getDefaultRules(), oacMinDualExtension, layerBelow->getNumber(), layer->getNumber(), NULL, true, false); if (vBelow && vBelow->getType() == oacDualInt1DTblValueType) { ((oaDualInt1DTblValue*) vBelow)->getFirst(firstTableBelow); ((oaDualInt1DTblValue*) vBelow)->getSecond(secondTableBelow); } else if (vBelow && vBelow->getType() == oacDualIntValueType) { firstTableBelow.setNumItems(1); secondTableBelow.setNumItems(1); firstTableBelow.setHeader(0, 0); secondTableBelow.setHeader(0, 0); firstTableBelow.setValue(0, ((oaDualIntValue*) vBelow)->getFirst()); secondTableBelow.setValue(0, ((oaDualIntValue*) vBelow)->getSecond()); } } oa1DLookupTbl<oaInt4, oaInt4> firstTableAbove; oa1DLookupTbl<oaInt4, oaInt4> secondTableAbove; oaValue *vAbove = NULL; oaPhysicalLayer *layerAbove = layer->getLayerAbove(oacMetalMaterial); if (layerAbove) { vAbove = lefOut.getConstraint(lefOut.getDefaultRules(), oacMinDualExtension, layerAbove->getNumber(), layer->getNumber(), NULL, true, false); if (vAbove && vAbove->getType() == oacDualInt1DTblValueType) { ((oaDualInt1DTblValue*) vAbove)->getFirst(firstTableAbove); ((oaDualInt1DTblValue*) vAbove)->getSecond(secondTableAbove); } else if (vAbove && vAbove->getType() == oacDualIntValueType) { firstTableAbove.setNumItems(1); secondTableAbove.setNumItems(1); firstTableAbove.setHeader(0, 0); secondTableAbove.setHeader(0, 0); firstTableAbove.setValue(0, ((oaDualIntValue*) vAbove)->getFirst()); secondTableAbove.setValue(0, ((oaDualIntValue*) vAbove)->getSecond()); } } for (oaUInt4 i = 0; i < firstTableBelow.getNumItems(); i++) { lefOut.output("PREFERENCLOSURE BELOW %.11g %.11g", lefOut.dbuToUU(firstTableBelow.getValue(i)), lefOut.dbuToUU(secondTableBelow.getValue(i))); oaUInt4 width = firstTableBelow.getHeader(i); if (width > 0) { lefOut.outNoIndent(" WIDTH %.11g", lefOut.dbuToUU(width)); } lefOut.outNoIndent(" ;\n"); } for (oaUInt4 i = 0; i < firstTableAbove.getNumItems(); i++) { lefOut.output("PREFERENCLOSURE ABOVE %.11g %.11g", lefOut.dbuToUU(firstTableAbove.getValue(i)), lefOut.dbuToUU(secondTableAbove.getValue(i))); oaUInt4 width = firstTableAbove.getHeader(i); if (width > 0) { lefOut.outNoIndent(" WIDTH %.11g", lefOut.dbuToUU(width)); } lefOut.outNoIndent(" ;\n"); }}// *****************************************************************************// LefOutLayer::writeDirection()// // This function outputs the direction for this layer, syntax:// DIRECTION {HORIZONTAL | VERTICAL} ;// *****************************************************************************voidLefOutLayer::writeDirection(){ switch (layer->getPrefRoutingDir()) { case oacHorzPrefRoutingDir: lefOut.output("DIRECTION HORIZONTAL ;\n"); break; case oacVertPrefRoutingDir: lefOut.output("DIRECTION VERTICAL ;\n"); break; case oacLeftDiagPrefRoutingDir: lefOut.output("DIRECTION DIAG45 ;\n"); break; case oacRightDiagPrefRoutingDir: lefOut.output("DIRECTION DIAG135 ;\n"); break; case oacNonePrefRoutingDir: default: { oaString layerName; layer->getName(layerName); lefOut.warn(cLayerDirectionUnknown, (const char*) layerName); } lefOut.output("DIRECTION HORIZONTAL ;\n"); }}// *****************************************************************************// LefOutLayer::writeWireExt()// // This function outputs the wire-extension value for this layer, syntax:// [WIREEXTENSION value ; ]// When value is half the width value, we don't output it since it's the// default.// *****************************************************************************voidLefOutLayer::writeWireExt(){ oaUInt4 ext = lefOut.getLayerExt(lefOut.getDefaultRules(), layer->getNumber()); oaUInt4 width = lefOut.getLayerWidth(lefOut.getDefaultRules(), layer->getNumber()); if (ext && ext != (width / 2)) { lefOut.output("WIREEXTENSION %.11g ;\n", lefOut.dbuToUU(ext)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -