📄 mtdrclayouttool.java
字号:
if (ret) { if (reportInfo.errorTypeSearch == DRC.DRCCheckMode.ERROR_CHECK_CELL) return true; errorsFound = true; } // Check select over transistor poly// ret = checkSelectOverPolysilicon(ai, layer, poly, ai.getParent()); ret = checkExtensionRules(ai, layer, poly, ai.getParent()); if (ret) { if (reportInfo.errorTypeSearch == DRC.DRCCheckMode.ERROR_CHECK_CELL) return true; errorsFound = true; } if (validLayers.isABadLayer(tech, layerNum))// if (tech == layersValidTech && !layersValid[layerNum]) { DRC.createDRCErrorLogger(reportInfo, DRC.DRCErrorType.BADLAYERERROR, null, ai.getParent(), 0, 0, null, (tot == 1) ? null : poly, ai, layer, null, null, null); if (reportInfo.errorTypeSearch == DRC.DRCCheckMode.ERROR_CHECK_CELL) return true; errorsFound = true; } } return errorsFound; } /** * Method to check the design rules about cell instance "ni". Only check other * instances, and only check the parts of each that are within striking range. * Returns true if an error was found. */ private boolean checkCellInst(NodeInst ni, int globalIndex) { Cell thisCell = (Cell)ni.getProto(); if (!thisCell.isLayout()) return false; // skips non-layout cells. // get transformation out of the instance AffineTransform upTrans = ni.translateOut(ni.rotateOut()); // get network numbering for the instance CheckInst ci = checkInsts.get(ni); int localIndex = globalIndex * ci.multiplier + ci.localIndex + ci.offset; boolean errorFound = false; // look for other instances surrounding this one Rectangle2D nodeBounds = ni.getBounds(); double worstInteractionDistance = reportInfo.worstInteractionDistance; Rectangle2D searchBounds = new Rectangle2D.Double( nodeBounds.getMinX() - worstInteractionDistance, nodeBounds.getMinY() - worstInteractionDistance, nodeBounds.getWidth() + worstInteractionDistance * 2, nodeBounds.getHeight() + worstInteractionDistance * 2); instanceInteractionList.clear(); // part3 for (Iterator<RTBounds> it = ni.getParent().searchIterator(searchBounds); it.hasNext();) { RTBounds geom = it.next(); if (geom == ni) continue; // covered by checkInteraction? if (!(geom instanceof NodeInst)) continue; NodeInst oNi = (NodeInst) geom; // only check other nodes that are numerically higher (so each pair is only checked once) if (oNi.getNodeIndex() <= ni.getNodeIndex()) continue; if (!oNi.isCellInstance()) continue; // see if this configuration of instances has already been done if (checkInteraction(ni, null, oNi, null, null)) continue; // found other instance "oNi", look for everything in "ni" that is near it Rectangle2D nearNodeBounds = oNi.getBounds(); Rectangle2D subBounds = new Rectangle2D.Double( nearNodeBounds.getMinX() - worstInteractionDistance, nearNodeBounds.getMinY() - worstInteractionDistance, nearNodeBounds.getWidth() + worstInteractionDistance * 2, nearNodeBounds.getHeight() + worstInteractionDistance * 2); // recursively search instance "ni" in the vicinity of "oNi" boolean ret = checkCellInstContents(subBounds, ni, upTrans, localIndex, oNi, null, globalIndex, null); if (ret) errorFound = true; } return errorFound; } /** * Method to recursively examine the area "bounds" in cell "cell" with global index "globalIndex". * The objects that are found are transformed by "uptrans" to be in the space of a top-level cell. * They are then compared with objects in "oNi" (which is in that top-level cell), * which has global index "topGlobalIndex". */ private boolean checkCellInstContents(Rectangle2D bounds, NodeInst thisNi, AffineTransform upTrans, int globalIndex, NodeInst oNi, NodeInst oNiParent, int topGlobalIndex, NodeInst triggerNi) { // Job aborted or scheduled for abort if (checkAbort()) return true; Cell cell = (Cell) thisNi.getProto(); boolean logsFound = false; Netlist netlist = getCheckProto(cell).netlist; Technology cellTech = cell.getTechnology(); // Need to transform bounds coordinates first otherwise it won't // never overlap Rectangle2D bb = (Rectangle2D) bounds.clone(); AffineTransform downTrans = thisNi.transformIn(); DBMath.transformRect(bb, downTrans); for (Iterator<RTBounds> it = cell.searchIterator(bb); it.hasNext();) { RTBounds geom = it.next(); // Checking if element is covered by exclusion region// if (coverByExclusion(geom))// continue; // skips this element if (geom instanceof NodeInst) { NodeInst ni = (NodeInst) geom; NodeProto np = ni.getProto(); if (NodeInst.isSpecialNode(ni)) continue; // Oct 5'04 if (ni.isCellInstance()) { // see if this configuration of instances has already been done if (checkInteraction(ni, thisNi, oNi, oNiParent, triggerNi)) continue; // Jan 27'05. Removed on May'05 // You can't discard by interaction becuase two cells could be visited many times // during this type of checking AffineTransform subUpTrans = ni.translateOut(ni.rotateOut()); subUpTrans.preConcatenate(upTrans); CheckInst ci = checkInsts.get(ni); int localIndex = globalIndex * ci.multiplier + ci.localIndex + ci.offset; // changes Sept04: subBound by bb boolean ret = checkCellInstContents(bb, ni, subUpTrans, localIndex, oNi, oNiParent, topGlobalIndex, (triggerNi == null) ? ni : triggerNi); if (ret) { if (reportInfo.errorTypeSearch == DRC.DRCCheckMode.ERROR_CHECK_CELL) return true; logsFound = true; } } else { AffineTransform rTrans = ni.rotateOut(); rTrans.preConcatenate(upTrans); Technology tech = np.getTechnology(); Poly[] primPolyList = tech.getShapeOfNode(ni, true, reportInfo.ignoreCenterCuts, thisLayerFunction); convertPseudoLayers(ni, primPolyList); int tot = primPolyList.length; Technology.MultiCutData multiCutData = tech.getMultiCutData(ni); for (int j = 0; j < tot; j++) { Poly poly = primPolyList[j]; Layer layer = poly.getLayer(); if (layer == null) { assert (false); if (Job.LOCALDEBUGFLAG) System.out.println("When is this case?"); continue; } poly.transform(rTrans); // determine network for this polygon int net = getDRCNetNumber(netlist, poly.getPort(), ni, globalIndex); boolean ret = badSubBox(poly, layer, net, tech, ni, rTrans, globalIndex, oNi, topGlobalIndex, multiCutData); if (ret) { if (reportInfo.errorTypeSearch == DRC.DRCCheckMode.ERROR_CHECK_CELL) return true; logsFound = true; } } } } else { ArcInst ai = (ArcInst) geom; Technology tech = ai.getProto().getTechnology(); if (tech != cellTech) { DRC.createDRCErrorLogger(reportInfo, DRC.DRCErrorType.TECHMIXWARN, " belongs to " + tech.getTechName(), cell, 0, 0, null, null, ai, null, null, null, null); continue; } Poly[] arcPolyList = tech.getShapeOfArc(ai, thisLayerFunction); int tot = arcPolyList.length; for (int j = 0; j < tot; j++) arcPolyList[j].transform(upTrans); cropActiveArc(ai, arcPolyList); for (int j = 0; j < tot; j++) { Poly poly = arcPolyList[j]; Layer layer = poly.getLayer(); if (layer == null) continue; if (layer.isNonElectrical()) continue; Network jNet = netlist.getNetwork(ai, 0); int net = -1; if (jNet != null) { Integer[] netList = networkLists.get(jNet); net = netList[globalIndex].intValue(); } boolean ret = badSubBox(poly, layer, net, tech, ai, upTrans, globalIndex, oNi, topGlobalIndex, null); if (ret) { if (reportInfo.errorTypeSearch == DRC.DRCCheckMode.ERROR_CHECK_CELL) return true; logsFound = true; } } } } return logsFound; } /** * Method to examine polygon "poly" layer "layer" network "net" technology "tech" geometry "geom" * which is in cell "cell" and has global index "globalIndex". * The polygon is compared against things inside node "oNi", and that node's parent has global index "topGlobalIndex". */ private boolean badSubBox(Poly poly, Layer layer, int net, Technology tech, Geometric geom, AffineTransform trans, int globalIndex, NodeInst oNi, int topGlobalIndex, Technology.MultiCutData multiCutData) { // see how far around the box it is necessary to search double maxSize = poly.getMaxSize(); double bound = currentRules.getMaxSurround(layer, maxSize); if (bound < 0) return false; // get bounds Rectangle2D bounds = new Rectangle2D.Double(); bounds.setRect(poly.getBounds2D()); AffineTransform downTrans = oNi.rotateIn(); AffineTransform tTransI = oNi.translateIn(); downTrans.preConcatenate(tTransI); DBMath.transformRect(bounds, downTrans); AffineTransform upTrans = oNi.translateOut(oNi.rotateOut()); CheckInst ci = checkInsts.get(oNi); int localIndex = topGlobalIndex * ci.multiplier + ci.localIndex + ci.offset; // determine if original object has multiple contact cuts// boolean baseMulti = false;// if (geom instanceof NodeInst)// {// baseMulti = tech.isMultiCutCase((NodeInst) geom);// } // search in the area surrounding the box bounds.setRect(bounds.getMinX() - bound, bounds.getMinY() - bound, bounds.getWidth() + bound * 2, bounds.getHeight() + bound * 2); return (badBoxInArea(poly, layer, tech, net, geom, trans, globalIndex, bounds, (Cell) oNi.getProto(), localIndex, oNi.getParent(), topGlobalIndex, upTrans, multiCutData, false)); // true in this case you don't want to check Geometric.objectsTouch(nGeom, geom) if nGeom and geom are in the // same cell because they could come from different cell instances. } /** * Method to examine a polygon to see if it has any errors with its surrounding area. * The polygon is "poly" on layer "layer" on network "net" from technology "tech" from object "geom". * Checking looks in cell "cell" global index "globalIndex". * Object "geom" can be transformed to the space of this cell with "trans". * Returns TRUE if a spacing error is found relative to anything surrounding it at or below * this hierarchical level. */ private boolean badBox(Poly poly, Layer layer, int net, Technology tech, Geometric geom, AffineTransform trans, Cell cell, int globalIndex, Technology.MultiCutData multiCutData) { // see how far around the box it is necessary to search double maxSize = poly.getMaxSize(); double bound = this.currentRules.getMaxSurround(layer, maxSize); if (bound < 0) return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -