📄 mtdrclayouttool.java
字号:
// get bounds Rectangle2D bounds = new Rectangle2D.Double(); bounds.setRect(poly.getBounds2D()); // 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, 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. * <p/> * 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; } } } int multiInt = (multi) ? 1 : 0; for (int j = 0; j < tot; j++) { Poly npoly = subPolyList[j]; Layer nLayer = npoly.getLayer(); if (nLayer == null) continue; if (coverByExclusion(npoly, nGeom.getParent())) continue; //npoly.transform(rTrans); Rectangle2D nPolyRect = npoly.getBounds2D(); // can't do this because "lxbound..." is local but the poly bounds are global // On the corners? if (DBMath.isGreaterThan(nPolyRect.getMinX(), rBound.getMaxX()) || DBMath.isGreaterThan(rBound.getMinX(), nPolyRect.getMaxX()) || DBMath.isGreaterThan(nPolyRect.getMinY(), rBound.getMaxY()) || DBMath.isGreaterThan(rBound.getMinY(), nPolyRect.getMaxY())) continue; // determine network for this polygon int nNet = getDRCNetNumber(netlist, npoly.getPort(), ni, cellGlobalIndex); // see whether the two objects are electrically connected boolean con = false; if (nNet >= 0 && nNet == net) con = true; // Checking extension, it could be slow boolean ret = checkExtensionGateRule(geom, layer, poly, nLayer, npoly, netlist); if (ret) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } // check if both polys are cut and if the combine area doesn't excess cut sizes // regardless if they are connected or not ret = checkCutSizes(np, geom, layer, poly, nGeom, nLayer, npoly, topCell); if (ret) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } // if they connect electrically and adjoin, don't check if (con && touch) { // Check if there are minimum size defects boolean maytouch = DRC.mayTouch(tech, con, layer, nLayer); Rectangle2D trueBox1 = poly.getBox(); if (trueBox1 == null) trueBox1 = poly.getBounds2D(); Rectangle2D trueBox2 = npoly.getBox(); if (trueBox2 == null) trueBox1 = npoly.getBounds2D(); ret = checkMinDefects(cell, maytouch, geom, poly, trueBox1, layer, nGeom, npoly, trueBox2, nLayer, topCell); if (ret) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } continue; } boolean edge = false; // @TODO check if previous spacing rule was composed of same layers! DRCTemplate theRule = getSpacingRule(layer, poly, geom, nLayer, npoly, ni, con, multiInt); // Try edge rules if (theRule == null) { theRule = this.currentRules.getEdgeRule(layer, nLayer); edge = true; } if (theRule == null) continue; ret = checkDist(tech, topCell, topGlobalIndex, poly, layer, net, geom, trans, globalIndex, npoly, nLayer, nNet, nGeom, rTrans, cellGlobalIndex, con, theRule, edge); if (ret) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } } } } else { ArcInst ai = (ArcInst) nGeom; ArcProto ap = ai.getProto(); // don't check between technologies if (ap.getTechnology() != tech) continue; // see if this type of arc can interact with this layer if (!validLayers.checkLayerWithArc(layer, ap)) continue; // see if the objects directly touch boolean touch = sameInstance && nGeom.isConnected(geom); // see whether the two objects are electrically connected Network jNet = netlist.getNetwork(ai, 0); Integer[] netNumbers = networkLists.get(jNet); int nNet = netNumbers[cellGlobalIndex].intValue(); boolean con = false; if (net >= 0 && nNet == net) con = true; // if they connect electrically and adjoin, don't check// if (con && touch) continue; // get the shape of each arcinst layer Poly[] subPolyList = tech.getShapeOfArc(ai); int tot = subPolyList.length; for (int i = 0; i < tot; i++) subPolyList[i].transform(upTrans); cropActiveArc(ai, subPolyList); boolean multi = baseMulti; int multiInt = (multi) ? 1 : 0; for (int j = 0; j < tot; j++) { Poly nPoly = subPolyList[j]; Layer nLayer = nPoly.getLayer(); if (nLayer == null) continue; if (coverByExclusion(nPoly, nGeom.getParent())) continue; Rectangle2D nPolyRect = nPoly.getBounds2D(); // can't do this because "lxbound..." is local but the poly bounds are global if (nPolyRect.getMinX() > rBound.getMaxX() || nPolyRect.getMaxX() < rBound.getMinX() ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -