📄 oalefoutmacro.cpp
字号:
foreignView = oaDesign::open(libName, cellName, viewName, oaViewType::get(oacMaskLayout), 'r'); } catch (oaException &err) { oaString macroName; design->getCellName(lefOut.getNS(), macroName); lefOut.error(cMacroCannotFindForeign, (const char*) macroName, (const char *) err.getMsg()); return; } oaIter<oaInst> instIter(foreignView->getTopBlock()->getInsts()); while(oaInst *inst = instIter.getNext()) { oaString foreignName; oaTransform xForm; inst->getCellName(lefOut.getNS(), foreignName); inst->getTransform(xForm); lefOut.output("FOREIGN %s %.11g %.11g ;\n", (const char *) foreignName, lefOut.dbuToUU(xForm.offset().x()), lefOut.dbuToUU(xForm.offset().y())); } foreignView->close(); return; } if (!bBox.hasNoArea()) { oaString foreignName; design->getCellName(lefOut.getNS(), foreignName); lefOut.output("FOREIGN %s %.11g %.11g ;\n", (const char *) foreignName, lefOut.dbuToUU(bBox.left()), lefOut.dbuToUU(bBox.bottom())); }}// *****************************************************************************// LefOutMacro::writeOrigin()//// This function outputs the macro origin, taken from the difference between// the snapBoundary and the coordinates of the lower-left point, syntax:// [ORIGIN pt ;]// *****************************************************************************voidLefOutMacro::writeOrigin(){ if (!bBox.hasNoArea()) { lefOut.output("ORIGIN %.11g %.11g ;\n", lefOut.dbuToUU(-bBox.left()), lefOut.dbuToUU(-bBox.bottom())); }}// *****************************************************************************// LefOutMacro::writeEEQ()//// This function outputs the Electrical EQuivalent of this macro, syntax:// [EEQ macroName ;]// *****************************************************************************voidLefOutMacro::writeEEQ(){ oaString EEQ; block->getEEQMaster(EEQ); if (EEQ != "") { lefOut.output("EEQ %s ;\n", (const char *) EEQ); }}// *****************************************************************************// LefOutMacro::writeSize()//// Taken from the snapBoundary, as inverse of lef2gn, syntax:// SIZE width BY height ;// *****************************************************************************voidLefOutMacro::writeSize(){ if (!bBox.hasNoArea()) { lefOut.output("SIZE %.11g BY %.11g ;\n", lefOut.dbuToUU(oaInt4(bBox.getWidth())), lefOut.dbuToUU(oaInt4(bBox.getHeight()))); }}// *****************************************************************************// LefOutMacro::writeSymmetry()//// This function outputs the symmetry for this macro, syntax:// [SYMMETRY {X | Y | R90}... ;]// *****************************************************************************voidLefOutMacro::writeSymmetry(){ switch (block->getSymmetry()) { case oacAnySymmetry: lefOut.output("SYMMETRY X Y R90 ;\n"); break; case oacXYSymmetry: lefOut.output("SYMMETRY X Y ;\n"); break; case oacXSymmetry: lefOut.output("SYMMETRY X ;\n"); break; case oacYSymmetry: lefOut.output("SYMMETRY Y ;\n"); }}// *****************************************************************************// LefOutMacro::writeSite()//// This function outputs the site definition for this macro, syntax:// [SITE siteName ;]// *****************************************************************************voidLefOutMacro::writeSite(){ oaSitePattern sitePattern; block->getSitePattern(sitePattern); for (oaUInt4 i = 0; i < sitePattern.getNumElements(); i++) { lefOut.output("SITE %s", (const char *) sitePattern[i].siteName()); oaTransform &xform = sitePattern[i].transform(); if (xform != oaTransform(0, 0)) { lefOut.outNoIndent(" %.11g %.11g %s", lefOut.dbuToUU(xform.offset().x()), lefOut.dbuToUU(xform.offset().y()), (const char *) "N"); } lefOut.outNoIndent(" ;\n"); }}// *****************************************************************************// LefOutMacro::writePins()//// This function outputs the MACRO PINS (OA terminals) for this macro.// *****************************************************************************voidLefOutMacro::writePins(){ oaBitTerm *term; oaIter<oaTerm> termIt(block->getTerms(oacTermIterSingleBit | oacTermIterEquivNets)); while (term = (oaBitTerm*) termIt.getNext()) { writePin(term); }}// *****************************************************************************// LefOutMacro::writePin()//// This function outputs the MACRO PIN information for specified terminal.// *****************************************************************************voidLefOutMacro::writePin(oaBitTerm *term){ lefOut.getLefOutPin()->write(term);}// *****************************************************************************// LefOutMacro::writeObs()//// This function outputs the OBStruction definitions for this macro// *****************************************************************************voidLefOutMacro::writeObs(){ oaBoolean hasBlockages = false; oaBlockage *blockage; oaIter<oaBlockage> blockageIter(block->getBlockages()); while (!hasBlockages && (blockage = blockageIter.getNext())) { if (blockage->getBlockageType() == oacRoutingBlockageType) { hasBlockages = true; } } oaBoolean hasOverlap = false; oaPRBoundary *prBoundary = oaPRBoundary::find(block); oaPointArray prPoints; if (prBoundary) { oaPointArray snapPoints(4); prBoundary->getPoints(prPoints); snapPoints[0].x() = bBox.left(); snapPoints[0].y() = bBox.bottom(); snapPoints[1].x() = bBox.left(); snapPoints[1].y() = bBox.top(); snapPoints[2].x() = bBox.right(); snapPoints[2].y() = bBox.top(); snapPoints[3].x() = bBox.right(); snapPoints[3].y() = bBox.bottom(); snapPoints.setNumElements(4); if (snapPoints != prPoints) { hasOverlap = true; } } if (!hasBlockages && !hasOverlap) { return; } lefOut.output("OBS\n"); lefOut.incIndent(); lefOut.getLefOutGeom()->reset(); blockageIter.reset(); while (oaBlockage *blockage = blockageIter.getNext()) { if (blockage->getType() == oacLayerBlockageType && blockage->getBlockageType() == oacRoutingBlockageType) { lefOut.getLefOutGeom()->writeFig(blockage); } } if (hasOverlap) { lefOut.output("LAYER %s ;\n", (const char *) lefOut.getOverlapName()); lefOut.incIndent(); lefOut.output("POLYGON"); for (oaUInt4 i = 0; i < prPoints.getNumElements(); i++) { lefOut.outNoIndent(" %.11g %.11g", lefOut.dbuToUU(prPoints[i].x()), lefOut.dbuToUU(prPoints[i].y())); } lefOut.outNoIndent(" ;\n"); lefOut.decIndent(); } lefOut.decIndent(); lefOut.output("END\n");}// *****************************************************************************// LefOutMacro::writeDensity()//// This function outputs the density definitions for this macro// *****************************************************************************voidLefOutMacro::writeDensity(){ if (lefOut.getOptions()->getVersion() < cLefDefVersion56) { return; } oaBoolean hasBlockages(false); oaBlockage *blockage; oaIter<oaBlockage> blockageIter(block->getBlockages()); while (!hasBlockages && (blockage = blockageIter.getNext())) { if (blockage->getBlockageType() == oacFillBlockageType) { hasBlockages = true; } } if (!hasBlockages) { return; } lefOut.output("DENSITY\n"); lefOut.incIndent(); oaLayerNum layerNum(oacNullIndex); blockageIter.reset(); while (oaBlockage *blockage = blockageIter.getNext()) { if (blockage->getType() == oacLayerBlockageType && blockage->getBlockageType() == oacFillBlockageType) { if (((oaLayerBlockage*) blockage)->getLayerNum() != layerNum) { layerNum = ((oaLayerBlockage*) blockage)->getLayerNum(); oaString layerName; oaLayer *layer = lefOut.getLayer(layerNum); layer->getName(layerName); lefOut.output("LAYER %s ;\n", (const char *) layerName); } lefOut.incIndent(); oaBox box; blockage->getBBox(box); lefOut.output("RECT %.11g %.11g %.11g %.11g %.2f ;\n", lefOut.dbuToUU(box.left()), lefOut.dbuToUU(box.bottom()), lefOut.dbuToUU(box.right()), lefOut.dbuToUU(box.top()), blockage->getDensity()); lefOut.decIndent(); } } lefOut.decIndent(); lefOut.output("END\n");}END_LEFDEF_NAMESPACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -