📄 oalefinmacro.cpp
字号:
// 0 0 0 none // 0 0 1 all// 0 1 0 Y // 0 1 1 all // 1 0 0 X // 1 0 1 all // 1 1 0 XandY // 1 1 1 all// *****************************************************************************voidLefInMacro::parseSymmetry(){ if (lefMacro->has90Symmetry() || lefMacro->hasXSymmetry() || lefMacro->hasYSymmetry()) { oaSymmetryEnum symmetry(oacNoSymmetry); if (lefMacro->has90Symmetry()) { symmetry = oacAnySymmetry; } else if (lefMacro->hasXSymmetry() && lefMacro->hasYSymmetry()) { symmetry = oacXYSymmetry; } else if (lefMacro->hasXSymmetry()) { symmetry = oacXSymmetry; } else if (lefMacro->hasYSymmetry()) { symmetry = oacYSymmetry; } lefIn.topBlock()->setSymmetry(symmetry); }}// *****************************************************************************// LefInMacro::parseSite()//// This function handles the SITE attribute of the current LEF macro.// *****************************************************************************voidLefInMacro::parseSite(){ oaSitePattern sitePattern; oaSiteRef siteRef; // Parse the simple site name if any. if (lefMacro->hasSiteName()) { siteRef.siteName() = lefMacro->siteName(); sitePattern.append(siteRef); } // Parse the sitePatterns if any. for (int i = 0; i < lefMacro->numSitePattern(); i++) { lefiSitePattern *lefPattern = lefMacro->sitePattern(i); siteRef.siteName() = lefPattern->name(); siteRef.transform().orient() = lefIn.getOrient(lefPattern->orient()); double x = lefPattern->x(); double y = lefPattern->y(); if (lefPattern->hasStepPattern()) { for (int j = 0; j < lefPattern->xStart(); j++) { for (int k = 0; k < lefPattern->yStart(); k++) { siteRef.transform().xOffset() = lefIn.uuToDBU(x); siteRef.transform().yOffset() = lefIn.uuToDBU(y); sitePattern.append(siteRef); y += lefPattern->yStep(); } x += lefPattern->xStep(); } } else { siteRef.transform().xOffset() = lefIn.uuToDBU(x); siteRef.transform().yOffset() = lefIn.uuToDBU(y); sitePattern.append(siteRef); } } // Set the sitePattern if any siteRefs were found. if (sitePattern.getNumElements()) { lefIn.topBlock()->setSitePattern(sitePattern); }}// *****************************************************************************// LefInMacro::parseProperties()// // This function handles the PROPERTY attributes for the specified macro.// *****************************************************************************voidLefInMacro::parseProperties(){ LefDefProp *propDef; for (int i = 0; i < lefMacro->numProperties(); i++) { propDef = lefIn.getProp(oaString(lefMacro->propName(i)), cLefDefMacro); lefIn.createProp(propDef, lefIn.design(), lefMacro->propValue(i)); }}// *****************************************************************************// LefInMacro::shiftGeometry()// // This function shifts all the geometry in the cellview by the specified// vector.// *****************************************************************************voidLefInMacro::shiftGeometry(const oaTransform &xForm){ oaIter<oaShape> shapeIter(lefIn.topBlock()->getShapes()); while (oaShape *shape = shapeIter.getNext()) { shape->move(xForm); } oaIter<oaVia> viaIter(lefIn.topBlock()->getVias()); while (oaVia *via = viaIter.getNext()) { via->move(xForm); } oaIter<oaBlockage> blockageIter(lefIn.topBlock()->getBlockages()); while (oaBlockage *blockage = blockageIter.getNext()) { blockage->move(xForm); } oaIter<oaBoundary> boundIter(lefIn.topBlock()->getBoundaries()); while (oaBoundary *boundary = boundIter.getNext()) { boundary->move(xForm); } oaSnapBoundary *snapB = oaSnapBoundary::find(lefIn.topBlock()); if (snapB) { snapB->move(xForm); } oaPRBoundary *prB = oaPRBoundary::find(lefIn.topBlock()); if (prB) { prB->move(xForm); }}// *****************************************************************************// LefIn::addOverlapPoints()// LefIn::deleteOverlapPoints()// // These functions add/delete a pointarray to/from the overlap array.// *****************************************************************************voidLefInMacro::addOverlapPoints(const oaPointArray &points){ oaBox box; points.getBBox(box); for (oaUInt4 i = 0; i < overlapPoints.getNumElements(); i++) { if (overlapPoints[i].contains(box)) { return; } overlapPoints[i].getBBox(box); if (points.contains(box)) { deleteOverlapPoints(i--); } } overlapPoints.append(points);}voidLefInMacro::deleteOverlapPoints(oaUInt4 i){ oaUInt4 overlapNumUsed = overlapPoints.getNumElements(); if (overlapNumUsed) { overlapPoints[i] = overlapPoints[overlapNumUsed - 1]; } overlapPoints.setNumElements(overlapNumUsed - 1);}// *****************************************************************************// LefInMacro::mergePointArray()//// This function adds the new points from the second pointArray to the// original pointArray. If the point arrays do not overlap false is returned.// *****************************************************************************voidLefInMacro::mergePointArray(oaPointArray &origPoints, const oaPointArray &newPoints){ // Add all non-contained points and intersectionsto a set of points. oaArray<oaPoint> pointSet; oaPoint point; oaSegment seg; oaUInt4 numPoints = origPoints.getNumElements(); for (oaUInt4 i = 0; i < numPoints; i++) { point = origPoints[i]; if (!newPoints.contains(point, false)) { if (pointSet.find(point) == oacNullIndex) { pointSet.append(point); } } seg.tail() = point; seg.head() = origPoints[(i < numPoints - 1) ? i + 1 : 0]; if (getIntersectPoint(newPoints, seg, point)) { if (pointSet.find(point) == oacNullIndex) { pointSet.append(point); } } } numPoints = newPoints.getNumElements(); for (oaUInt4 i = 0; i < numPoints; i++) { point = newPoints[i]; if (!origPoints.contains(point, false)) { if (pointSet.find(point) == oacNullIndex) { pointSet.append(point); } } } // Start with left most - lower point, and trace outline oaUInt4 next = 0; oaUInt4 start = 0; oaUInt4 end = pointSet.getNumElements() - 1; point = oaPoint(INT_MAX, INT_MAX); while(next < pointSet.getNumElements()) { if (pointSet[next].x() <= point.x()) { point = pointSet[next]; start = next; } next++; } oaPointArray points; oaBoolean found; oaPoint nextPoint; points.append(point); if (start < end) { pointSet[start] = pointSet[end]; } pointSet.setNumElements(end); while (pointSet.getNumElements()) { found = false; next = 0; while (next < pointSet.getNumElements()) { if (pointSet[next].x() == point.x() && pointSet[next].y() > point.y()) { if (!found || pointSet[next].y() < nextPoint.y()) { nextPoint = pointSet[next]; start = next; } found = true; } next++; } if (!found) { next = 0; while (next < pointSet.getNumElements()) { if (pointSet[next].y() == point.y() && pointSet[next].x() > point.x()) { if (!found || pointSet[next].x() < nextPoint.x()) { nextPoint = pointSet[next]; start = next; } found = true; } next++; } } if (!found) { next = 0; while (next < pointSet.getNumElements()) { if (pointSet[next].x() == point.x() && pointSet[next].y() < point.y()) { if (!found || pointSet[next].y() > nextPoint.y()) { nextPoint = pointSet[next]; start = next; } found = true; } next++; } } if (!found) { next = 0; while (next < pointSet.getNumElements()) { if (pointSet[next].y() == point.y() && pointSet[next].x() < point.x()) { if (!found || pointSet[next].x() > nextPoint.x()) { nextPoint = pointSet[next]; start = next; } found = true; } next++; } } point = nextPoint; end = pointSet.getNumElements() - 1; points.append(point); if (start < end) { pointSet[start] = pointSet[end]; } pointSet.setNumElements(end); } points.compress(); origPoints = points;}// *****************************************************************************// LefInMacro::getIntersectPoint()//// This function finds the intersection point between the given pointArray,// and the segment. If there is multiple intersection points, the one closest// to the tail of the segment is returned.// *****************************************************************************oaBooleanLefInMacro::getIntersectPoint(const oaPointArray &points, const oaSegment &seg, oaPoint &intersect){ oaBoolean res(false); oaPoint tmp; oaSegment seg1; for (oaUInt4 i = 0; i < points.getNumElements(); i++) { seg1.tail() = points[i]; seg1.head() = points[(i < points.getNumElements() - 1) ? i + 1 : 0]; if (seg1.intersects(seg, tmp)) { if (!res || (tmp.distanceFrom2(seg.tail()) < intersect.distanceFrom2(seg.tail()))) { intersect = tmp; res = true; } } } return res;}END_LEFDEF_NAMESPACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -