📄 quick.java
字号:
// 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, null); 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) { 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); int tot = arcPolyList.length; for(int j=0; j<tot; j++) arcPolyList[j].transform(upTrans); DRC.cropActiveArc(ai, reportInfo.ignoreCenterCuts, 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 = DRC.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// Technology.MultiCutData multiCutData = null;// if (geom instanceof NodeInst)// {// multiCutData = tech.getMultiCutData((NodeInst)geom);// }// boolean baseMulti = tech.isMultiCutInTechnology(multiCutData); // 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 = DRC.getMaxSurround(layer, maxSize); if (bound < 0) return false; // get bounds Rectangle2D bounds = new Rectangle2D.Double(); bounds.setRect(poly.getBounds2D()); // determine if original object has multiple contact cuts// Technology.MultiCutData multiCutData = null;// if (geom instanceof NodeInst)// {// multiCutData = tech.getMultiCutData((NodeInst)geom);// }// boolean baseMulti = tech.isMultiCutInTechnology(multiCutData); // 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, globalIndex, cell, globalIndex, DBMath.MATID, multiCutData, true); } /** * Method to recursively examine a polygon to see if it has any errors with its surrounding area. * The polygon is "poly" on layer "layer" from technology "tech" on network "net" from object "geom" * which is associated with global index "globalIndex". * Checking looks in the area (lxbound-hxbound, lybound-hybound) in cell "cell" global index "cellGlobalIndex". * The polygon coordinates are in the space of cell "topCell", global index "topGlobalIndex", * and objects in "cell" can be transformed by "upTrans" to get to this space. * The base object, in "geom" can be transformed by "trans" to get to this space. * The minimum size of this polygon is "minSize" and "baseMulti" is TRUE if it comes from a multicut contact. * If the two objects are in the same cell instance (nonhierarchical DRC), then "sameInstance" is TRUE. * If they are from different instances, then "sameInstance" is FALSE. * * Returns TRUE if errors are found. */ private boolean badBoxInArea(Poly poly, Layer layer, Technology tech, int net, Geometric geom, AffineTransform trans, int globalIndex, Rectangle2D bounds, Cell cell, int cellGlobalIndex, Cell topCell, int topGlobalIndex, AffineTransform upTrans, Technology.MultiCutData multiCutData, boolean sameInstance) { Rectangle2D rBound = new Rectangle2D.Double(); rBound.setRect(bounds); DBMath.transformRect(rBound, upTrans); // Step 1 Netlist netlist = getCheckProto(cell).netlist; Rectangle2D subBound = new Rectangle2D.Double(); //Sept 30 boolean foundError = false; boolean isLayerAContact = layer.getFunction().isContact(); boolean baseMulti = tech.isMultiCutInTechnology(multiCutData); // These nodes won't generate any DRC errors. Most of them are pins if (geom instanceof NodeInst && NodeInst.isSpecialNode(((NodeInst)geom))) return false; // Sept04 changes: bounds by rBound for(Iterator<RTBounds> it = cell.searchIterator(bounds); it.hasNext(); ) { Geometric nGeom = (Geometric)it.next(); // I have to check if they are the same instance otherwise I check geometry against itself if (nGeom == geom && (sameInstance))// || nGeom.getParent() == cell)) continue; // Checking if element is covered by exclusion region if (coverByExclusion(nGeom)) continue; // skips this element if (nGeom instanceof NodeInst) { NodeInst ni = (NodeInst)nGeom; NodeProto np = ni.getProto(); if (NodeInst.isSpecialNode(ni)) continue; // Oct 5; // ignore nodes that are not primitive if (ni.isCellInstance()) { // instance found: look inside it for offending geometry AffineTransform rTransI = ni.rotateIn(); AffineTransform tTransI = ni.translateIn(); rTransI.preConcatenate(tTransI); subBound.setRect(bounds); DBMath.transformRect(subBound, rTransI); CheckInst ci = checkInsts.get(ni); int localIndex = cellGlobalIndex * ci.multiplier + ci.localIndex + ci.offset; AffineTransform subTrans = ni.translateOut(ni.rotateOut()); subTrans.preConcatenate(upTrans); //Sept 15 04 // compute localIndex if (badBoxInArea(poly, layer, tech, net, geom, trans, globalIndex, subBound, (Cell)np, localIndex, topCell, topGlobalIndex, subTrans, multiCutData, sameInstance)) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } } else { // don't check between technologies if (np.getTechnology() != tech) continue; // see if this type of node can interact with this layer if (!validLayers.checkLayerWithNode(layer, np)) continue; // see if the objects directly touch but they are not // coming from different NodeInst (not from checkCellInstContents // because they might below to the same cell but in different instances boolean touch = sameInstance && nGeom.isConnected(geom); // prepare to examine every layer in this nodeinst AffineTransform rTrans = ni.rotateOut(); rTrans.preConcatenate(upTrans); // get the shape of each nodeinst layer Poly [] subPolyList = tech.getShapeOfNode(ni, true, reportInfo.ignoreCenterCuts, null); convertPseudoLayers(ni, subPolyList); int tot = subPolyList.length; for(int i=0; i<tot; i++) subPolyList[i].transform(rTrans); /* Step 1 */ boolean multi = baseMulti; Technology.MultiCutData niMCD = tech.getMultiCutData(ni); // in case it is one via against many from another contact (3-contact configuration) if (!multi && isLayerAContact && niMCD != null) { multi = tech.isMultiCutInTechnology(niMCD); if (!multi) { // geom must be NodeInst NodeInst gNi = (NodeInst)geom; // in this case, both possible contacts are either 1xn or mx1 with n,m>=1 if (multiCutData.numCutsX() == 1) // it is 1xn { // Checking if they match at the Y axis. If yes, they are considered as a long 1xn array // so multi=false. The other element must be 1xM if (niMCD.numCutsY() != 1 && ni.getAnchorCenterX() != gNi.getAnchorCenterX()) multi = true; } else { // Checking if they match at the Y axis. If yes, they are considered as a long 1xn array // so multi=false if (niMCD.numCutsX() != 1 && ni.getAnchorCenterY() != gNi.getAnchorCenterY()) multi = true; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -