📄 mtdrcareatool.java
字号:
Cell cell = info.getCell(); Set<String> set = cellLayersCon.getLayersSet(cell); // The cell doesn't contain the layer if (set != null && !set.contains(theLayer.getName())) { return false; } GeometryHandlerLayerBucket bucket = cellsMap.get(cell); if (bucket == null) { bucket = new GeometryHandlerLayerBucket(mode); cellsMap.put(cell, bucket); } else { assert(bucket.merged); return false; // done with this cell } for(Iterator<ArcInst> it = info.getCell().getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); Network aNet = info.getNetlist().getNetwork(ai, 0); // aNet is null if ArcProto is Artwork if (aNet == null) continue; ArcProto ap = ai.getProto(); boolean notFound = !arcsList.contains(ap); if (notFound) continue; // primitive doesn't contain this layer Technology tech = ap.getTechnology(); Poly[] arcInstPolyList = tech.getShapeOfArc(ai, thisLayerFunction); int tot = arcInstPolyList.length; for(int i=0; i<tot; i++) { Poly poly = arcInstPolyList[i]; bucket.addElementLocal(poly, theLayer); } } return true; } public void exitCell(HierarchyEnumerator.CellInfo info) { Cell cell = info.getCell(); boolean isTopCell = cell == topCell; GeometryHandlerLayerBucket bucket = cellsMap.get(cell); bucket.mergeGeometry(cell, cellsMap); if (isTopCell) { for (Layer layer : bucket.local.getKeySet()) {// int oldV = checkMinAreaLayerWithTree(bucket.local, topCell, layer); checkMinAreaLayerWithLoops(bucket.local, topCell, layer); } } } public boolean visitNodeInst(Nodable no, HierarchyEnumerator.CellInfo info) { // Checking if the job was aborted if (job.checkAbort()) return false; // Facet or special elements NodeInst ni = no.getNodeInst(); if (NodeInst.isSpecialNode(ni)) return (false); // Cells if (ni.isCellInstance()) return (true); NodeProto np = ni.getProto(); if (!np.getTechnology().isLayout()) return (false); // only layout nodes GeometryHandlerLayerBucket bucket = cellsMap.get(info.getCell()); AffineTransform trans = ni.rotateOut(); PrimitiveNode pNp = (PrimitiveNode)np; boolean notFound = !nodesList.contains(pNp); if (notFound) return false; // pNp doesn't have the layer Technology tech = pNp.getTechnology(); // Don't get electric layers in case of transistors otherwise it is hard to detect ports Poly [] nodeInstPolyList = tech.getShapeOfNode(ni, false, true, thisLayerFunction); int tot = nodeInstPolyList.length; for(int i=0; i<tot; i++) { Poly poly = nodeInstPolyList[i]; poly.roundPoints(); // Trying to avoid mismatches while joining areas. poly.transform(trans); bucket.addElementLocal(poly, theLayer); } return true; } private int checkMinAreaLayerWithLoops(GeometryHandler merge, Cell cell, Layer layer) { // Layer doesn't have min area if (minAreaRule == null && enclosedAreaRule == null && spacingRule == null) return 0; PolySweepMerge m = (PolySweepMerge)merge; // easier to implement for now. List<Area> areas = m.getAreas(layer); GenMath.MutableInteger errorFound = new GenMath.MutableInteger(0); // It could be multi-threaded per area for (Area area : areas) { List<PolyBase> list = PolyBase.getLoopsFromArea(area, layer); boolean minPass = true; for (PolyBase p : list) { double a = p.getArea(); minPass = (minAreaEnclosedRule == null) ? true : a >= minAreaEnclosedRule.getValue(0); if (!minPass) break; // go for full checking if (spacingRule != null) { Rectangle2D bnd = p.getBounds2D(); minPass = bnd.getWidth() >= spacingRule.getValue(0); if (minPass) minPass = bnd.getHeight() >= spacingRule.getValue(1); } if (!minPass) break; // go for full checking } // Must run the real checking if (!minPass) { List<PolyBase.PolyBaseTree> roots = PolyBase.getTreesFromLoops(list); for (PolyBase.PolyBaseTree obj : roots) { traversePolyTree(layer, obj, 0, cell, errorFound); } } } return errorFound.intValue(); }// private int checkMinAreaLayerWithTree(GeometryHandler merge, Cell cell, Layer layer)// {// // Layer doesn't have min area// if (minAreaRule == null && enclosedAreaRule == null && spacingRule == null) return 0;//// Collection<PolyBase.PolyBaseTree> trees = merge.getTreeObjects(layer);// GenMath.MutableInteger errorFound = new GenMath.MutableInteger(0);//// for (PolyBase.PolyBaseTree obj : trees)// {// traversePolyTree(layer, obj, 0, cell, errorFound);// }// return errorFound.intValue();// } private void traversePolyTree(Layer layer, PolyBase.PolyBaseTree obj, int level, Cell cell, GenMath.MutableInteger count) { List<PolyBase.PolyBaseTree> sons = obj.getSons(); for (PolyBase.PolyBaseTree son : sons) { traversePolyTree(layer, son, level+1, cell, count); } boolean minAreaCheck = level%2 == 0; boolean checkMin = false, checkNotch = false; DRC.DRCErrorType errorType = DRC.DRCErrorType.MINAREAERROR; double minVal = 0; String ruleName = ""; if (minAreaCheck) { if (minAreaRule == null) return; // no rule minVal = minAreaRule.getValue(0); ruleName = minAreaRule.ruleName; checkMin = true; } else { // odd level checks enclose area and holes (spacing rule) errorType = DRC.DRCErrorType.ENCLOSEDAREAERROR; if (enclosedAreaRule != null) { minVal = enclosedAreaRule.getValue(0); ruleName = enclosedAreaRule.ruleName; checkMin = true; } checkNotch = (spacingRule != null); } PolyBase poly = obj.getPoly(); if (checkMin) { double area = poly.getArea(); // isGreaterThan doesn't consider equals condition therefore negate condition is used if (!DBMath.isGreaterThan(minVal, area)) return; // larger than the min value count.increment(); DRC.createDRCErrorLogger(reportInfo, errorType, null, cell, minVal, area, ruleName, poly, null, layer, null, null, null); } if (checkNotch) { // Notches are calculated using the bounding box of the polygon -> this is an approximation Rectangle2D bnd = poly.getBounds2D(); if (bnd.getWidth() < spacingRule.getValue(0)) { count.increment(); DRC.createDRCErrorLogger(reportInfo, DRC.DRCErrorType.NOTCHERROR, "(X axis)", cell, spacingRule.getValue(0), bnd.getWidth(), spacingRule.ruleName, poly, null, layer, null, null, layer); } if (bnd.getHeight() < spacingRule.getValue(1)) { count.increment(); DRC.createDRCErrorLogger(reportInfo, DRC.DRCErrorType.NOTCHERROR, "(Y axis)", cell, spacingRule.getValue(1), bnd.getHeight(), spacingRule.ruleName, poly, null, layer, null, null, layer); } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -