📄 oadefinvia.cpp
字号:
} // Create and fill out the oaViaParam. oaVector enclosure1((width1 - allCutWidth ) / 2, (height1 - allCutHeight) / 2); oaVector enclosure2((width2 - allCutWidth ) / 2, (height2 - allCutHeight) / 2); oaVector originOffset(cutBox.left() + allCutWidth / 2 , cutBox.bottom() + allCutHeight / 2); oaVector offset1(bBox1.left() + width1 / 2 - originOffset.x(), bBox1.bottom() + height1 / 2 - originOffset.y()); oaVector offset2(bBox2.left() + width2 / 2 - originOffset.x(), bBox2.bottom() + height2 / 2 - originOffset.y()); oaViaParam stdViaParam; stdViaDef->getParams(stdViaParam); // Store cutSpacing if any if (cutSpacing.x() == INT_MAX) { cutSpacing.x() = stdViaParam.getCutSpacing().x(); } if (cutSpacing.y() == INT_MAX) { cutSpacing.y() = stdViaParam.getCutSpacing().y(); } stdViaParam.setLayer1Enc(enclosure1); stdViaParam.setLayer2Enc(enclosure2); stdViaParam.setCutSpacing(cutSpacing); stdViaParam.setOriginOffset(originOffset); stdViaParam.setLayer1Offset(offset1); stdViaParam.setLayer2Offset(offset2); stdViaParam.setCutColumns(numCutsX); stdViaParam.setCutRows(numCutsY); for (oaUInt4 r = 0; r < numCutsY; r++) { for (oaUInt4 c = 0; c < numCutsX; c++) { stdViaParam.setCutPatternVal(r, c, false); } } // Determine cut pattern oaUInt4 cutCol; oaUInt4 cutRow; for (i = 0; i < defVia->numLayers(); i++) { defVia->layer(i, &layName, &pxl, &pyl, &pxh, &pyh); layer = defIn.getLayer(layName); if (layer->getMaterial() == oacCutMaterial) { xl = defIn.scaleToDBU(pxl); yl = defIn.scaleToDBU(pyl); xh = defIn.scaleToDBU(pxh); yh = defIn.scaleToDBU(pyh); cutCol = (xl - cutBox.left()) / (cutSpacing.x() + cutWidth); cutRow = (yl - cutBox.bottom()) / (cutSpacing.y() + cutHeight); stdViaParam.setCutPatternVal(cutRow, cutCol, true); } } // Store the generated via params. defIn.addGenVia(defVia->name(), stdViaDef, stdViaParam);}// *****************************************************************************// DefInVia::parseCustomVia()//// This function tries to create a customViaDef and its associated design// in the technology database for the current via.// It tries to re-open the technology database in append mode the first time// it's called.// *****************************************************************************voidDefInVia::parseCustomVia(){ if (!defVia->numLayers()) { throw LefDefError(cViaNoGeom, defVia->name()); } oaString viaName(defVia->name()); oaViaDef *viaDef = oaViaDef::find(defIn.tech(), viaName); // Check for existing stdViaDef and rename this via if so. if (viaDef && viaDef->getType() == oacStdViaDefType) { viaName += "_"; viaName += cLefViaDesignName; viaDef = oaViaDef::find(defIn.tech(), viaName); } // Check for existing customViaDef and verify if it corresponds. if (viaDef && viaDef->getType() == oacCustomViaDefType) { oaScalarName libName; oaScalarName cellName; oaScalarName viewName; ((oaCustomViaDef *) viaDef)->getLibName(libName); ((oaCustomViaDef *) viaDef)->getCellName(cellName); ((oaCustomViaDef *) viaDef)->getViewName(viewName); oaLib *lib = oaLib::find(libName); lib->getAccess(oacReadLibAccess); oaDesign *master = oaDesign::open(libName, cellName, viewName, 'r'); if (!verifyGeometries(master)) { master->close(); lib->releaseAccess(); throw LefDefError(cViaExists, defVia->name()); } master->close(); lib->releaseAccess(); return; } // Need to create a new customViaDef. if (defIn.tech()->getMode() != 'a') { defIn.tech()->reopen('a'); } // Create via design. static oaScalarName viewName(defIn.getNS(), cLefViaDesignName); oaScalarName libName; oaScalarName cellName(defIn.getNS(), defVia->name()); defIn.tech()->getLibName(libName); oaLib *lib = oaLib::find(libName); lib->getAccess(oacWriteLibAccess); oaDesign *design = oaDesign::open(libName, cellName, viewName, oaViewType::get(oacMaskLayout), 'w'); design->setCellType(oacViaCellType); if (!design->getTopBlock()) { oaBlock::create(design); } oaPhysicalLayer *layer1 = NULL; oaPhysicalLayer *layer2 = NULL; parseGeometries(design, layer1, layer2); // Create the customViaDef. oaCustomViaDef::create(defIn.tech(), viaName, libName, cellName, viewName, layer1, layer2); design->save(); design->close(); lib->releaseAccess();}// *****************************************************************************// DefInVia::parseGeometries()//// This function handles the geometries section in the current VIA construct.// It stores the shapes in a design.// *****************************************************************************voidDefInVia::parseGeometries(oaDesign *viaDesign, oaPhysicalLayer *&layer1, oaPhysicalLayer *&layer2){ oaBlock *blk = viaDesign->getTopBlock(); char *layName; oaPhysicalLayer *layer; oaPhysicalLayer *cutLayer = NULL; int pxl; int pyl; int pxh; int pyh; oaInt4 xl; oaInt4 yl; oaInt4 xh; oaInt4 yh; int numShapes = defVia->numLayers() + defVia->numPolygons(); int numRects = defVia->numLayers(); // Parse any rectangles for (int i = 0; i < numShapes; i++) { if (i < defVia->numLayers()) { defVia->layer(i, &layName, &pxl, &pyl, &pxh, &pyh); layer = defIn.getLayer(layName); } else { layer = defIn.getLayer(defVia->polygonName(i - numRects)); } // Find metal and cut layers. if (layer->getMaterial() == oacCutMaterial) { if (cutLayer && layer != cutLayer) { throw LefDefError(cViaTooManyLayers, defVia->name()); } cutLayer = layer; } else if (!layer1) { layer1 = layer; } else if (!layer2 && (layer != layer1)) { if (layer->getMaskNumber() < layer1->getMaskNumber()) { layer2 = layer1; layer1 = layer; } else { layer2 = layer; } } else if ((layer != layer1) && (layer != layer2)) { throw LefDefError(cViaTooManyLayers, defVia->name()); } if (i < numRects) { xl = defIn.scaleToDBU(pxl); yl = defIn.scaleToDBU(pyl); xh = defIn.scaleToDBU(pxh); yh = defIn.scaleToDBU(pyh); oaRect::create(blk, layer->getNumber(), oavPurposeNumberDrawing, oaBox(oaMin(xl, xh), oaMin(yl, yh), oaMax(xl, xh), oaMax(yl, yh))); continue; } defiPoints points = defVia->getPolygon(i - numRects); oaUInt4 numPoints = points.numPoints; oaPointArray pointArray(numPoints); for (oaUInt4 j = 0; j < numPoints; j++) { pointArray[j].x() = defIn.scaleToDBU(points.x[j]); pointArray[j].y() = defIn.scaleToDBU(points.y[j]); } pointArray.setNumElements(numPoints); pointArray.compress(); oaPolygon::create(blk, layer->getNumber(), oavPurposeNumberDrawing, pointArray); } // Check layers if (!cutLayer || !layer1 || !layer2 || (layer1 == layer2)) { throw LefDefError(cViaMissingLayer, defVia->name()); }}// *****************************************************************************// DefInVia::verifyGeometries()// DefInVia::verifyGeom()//// These functions compare the geometries section with the patternName in the// current VIA construct.// *****************************************************************************oaBooleanDefInVia::verifyGeometries(oaDesign *master){ oaIter<oaShape> shapeIter(master->getTopBlock()->getShapes()); while (oaShape *shape = shapeIter.getNext()) { if (shape->getType() == oacRectType) { oaBox bBox; shape->getBBox(bBox); if (!verifyGeom(shape->getLayerNum(), bBox.left(), bBox.bottom(), bBox.right(), bBox.top())) { return false; } } } return true;} oaBooleanDefInVia::verifyGeom(oaLayerNum layerNum, oaInt4 llx, oaInt4 lly, oaInt4 urx, oaInt4 ury){ char *layerName; int left; int right; int top; int bottom; for (int i = 0; i < defVia->numLayers(); i++) { defVia->layer(i, &layerName, &left, &bottom, &right, &top); if ((llx == defIn.scaleToDBU(left)) && (lly == defIn.scaleToDBU(bottom)) && (urx == defIn.scaleToDBU(right)) && (ury == defIn.scaleToDBU(top))) { return true; } } return false;} // *****************************************************************************// DefInVia::getViaDef()//// These functions try to find a matching stdViaDef.// The first version searches by name, from the patternName.// The second version searches by parametes.// *****************************************************************************oaStdViaDef*DefInVia::getViaDef(const oaString &patternName){ oaStdViaDef *stdViaDef = NULL; oaString viaDefName; oaIter<oaViaDef> viaDefIt(defIn.tech()->getViaDefs()); while (oaViaDef *viaDef = viaDefIt.getNext()) { if (viaDef->getType() == oacStdViaDefType) { oaString s; viaDef->getName(s); if ((patternName.substr(s) == 0) && (s.getLength() > viaDefName.getLength())) { stdViaDef = (oaStdViaDef *) viaDef; viaDefName = s; } } } return stdViaDef;}oaStdViaDef*DefInVia::getViaDef(oaLayerNum layerNum, oaUInt4 cutHeight, oaUInt4 cutWidth, oaVector cutSpacing){ oaStdViaDef *stdViaDef = NULL; oaIter<oaViaDef> viaDefIter(defIn.tech()->getViaDefs()); while (oaViaDef *viaDef = viaDefIter.getNext()) { if (viaDef->getType() == oacStdViaDefType) { oaViaParam param; ((oaStdViaDef *) viaDef)->getParams(param); if (param.getCutLayer() == layerNum && param.getCutHeight() == cutHeight && param.getCutWidth() == cutWidth) { stdViaDef = (oaStdViaDef *) viaDef; if (param.getCutSpacing() == cutSpacing) { break; } } } } return stdViaDef;}END_LEFDEF_NAMESPACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -