📄 quick.java
字号:
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 = DRC.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); DRC.cropActiveArc(ai, reportInfo.ignoreCenterCuts, subPolyList); boolean multi = baseMulti; // this condition is not very relevant for arcs because no cut/via is used in arcs 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() || nPolyRect.getMinY() > rBound.getMaxY() || nPolyRect.getMaxY() < rBound.getMinY()) continue; boolean ret = false; // if they connect electrically and adjoin, don't check // We must check if there are minor defects if they overlap regardless if they are connected or not 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; } // see how close they can get boolean edge = false; DRCTemplate theRule = getSpacingRule(layer, poly, geom, nLayer, nPoly, ai, con, multiInt); if (theRule == null) { theRule = DRC.getEdgeRule(layer, nLayer); edge = true; } if (theRule == null) continue; // check the distance ret = checkDist(tech, topCell, topGlobalIndex, poly, layer, net, geom, trans, globalIndex, nPoly, nLayer, nNet, nGeom, upTrans, cellGlobalIndex, con, theRule, edge); if (ret) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } // Checking extension, it could be slow ret = checkExtensionGateRule(geom, layer, poly, nLayer, nPoly, netlist); if (ret) { foundError = true; if (reportInfo.errorTypeSearch != DRC.DRCCheckMode.ERROR_CHECK_EXHAUSTIVE) return true; } } } } return foundError; } /** * Function to detect small edges due to overlapping polygons of the same material. It is valid only * for manhattan shapes * @return true if error was found */ private boolean checkMinDefects(Cell cell, boolean maytouch, Geometric geom1, Poly poly1, Rectangle2D trueBox1, Layer layer1, Geometric geom2, Poly poly2, Rectangle2D trueBox2, Layer layer2, Cell topCell) { if (trueBox1 == null || trueBox2 == null) return false; if (!maytouch) return false; // manhattan double pdx = DBMath.round(Math.max(trueBox2.getMinX()-trueBox1.getMaxX(), trueBox1.getMinX()-trueBox2.getMaxX())); double pdy = DBMath.round(Math.max(trueBox2.getMinY()-trueBox1.getMaxY(), trueBox1.getMinY()-trueBox2.getMaxY())); double pd = Math.max(pdx, pdy); if (DBMath.areEquals(pdx, 0) && DBMath.areEquals(pdy, 0)) pd = 0; // touching boolean foundError = false; // They have to overlap if (DBMath.isGreaterThan(pd, 0)) return false; // they are electrically connected and they overlap: look for minimum size errors // of the overlapping region. DRCTemplate wRule = DRC.getMinValue(layer1, DRCTemplate.DRCRuleType.MINWID); if (wRule == null) return false; // no rule double minWidth = wRule.getValue(0); double lxb = DBMath.round(Math.max(trueBox1.getMinX(), trueBox2.getMinX())); double hxb = DBMath.round(Math.min(trueBox1.getMaxX(), trueBox2.getMaxX())); double lyb = DBMath.round(Math.max(trueBox1.getMinY(), trueBox2.getMinY())); double hyb = DBMath.round(Math.min(trueBox1.getMaxY(), trueBox2.getMaxY())); Point2D lowB = new Point2D.Double(lxb, lyb); Point2D highB = new Point2D.Double(hxb, hyb); Rectangle2D bounds = new Rectangle2D.Double(lxb, lyb, hxb-lxb, hyb-lyb); // If resulting bounding box is identical to one of the original polygons // then one polygon is contained in the other one if (bounds.equals(trueBox1) || bounds.equals(trueBox2)) { return false; } //+-------------------+F //| | //| | //| |B E //| +-------+---------+ //| | | | //|C A| | | //+-----------+-------+ | // | | // D+-----------------+ // Checking A-B distance double actual = lowB.distance(highB); // !DBMath.areEquals(actual, 0) is on, it skips cases where A==B. // Condition off as of July 2nd 2008. Bugzilla 1745 if (/*!DBMath.areEquals(actual, 0) &&*/ DBMath.isGreaterThan(minWidth, actual) && foundSmallSizeDefect(cell, geom1, poly1, layer1, geom2, poly2, pd, lxb, lyb, hxb, hyb)) { // you can't pass geom1 or geom2 becuase they could be in different cells and therefore the message // could mislead DRC.createDRCErrorLogger(reportInfo, DRC.DRCErrorType.MINWIDTHERROR, null, topCell, minWidth, actual, wRule.ruleName, new Poly(bounds), null, layer1, null, null, layer2); foundError = true; } return foundError; } private boolean foundSmallSizeDefect(Cell cell, Geometric geom1, Poly poly1, Layer layer1, Geometric geom2, Poly poly2, double pd, double lxb, double lyb, double hxb, double hyb) { boolean foundError = false; boolean [] pointsFound = new boolean[2]; pointsFound[0] = pointsFound[1] = false; Point2D lowB = new Point2D.Double(lxb, lyb); Point2D highB = new Point2D.Double(hxb, hyb); Rectangle2D bounds = new Rectangle2D.Double(lxb, lyb, hxb-lxb, hyb-lyb); Poly rebuild = new Poly(bounds); Point2D pt1 = null; //new Point2D.Double(lxb-TINYDELTA, lyb-TINYDELTA); Point2D pt2 = null; //new Point2D.Double(lxb-TINYDELTA, hyb+TINYDELTA); Point2D pt1d = null;//(Point2D)pt1.clone(); Point2D pt2d = null; //(Point2D)pt2.clone(); // Search area should be bigger than bounding box otherwise it might not get the cells due to // rounding errors. Rectangle2D search = new Rectangle2D.Double(DBMath.round(lxb- DRC.TINYDELTA), DBMath.round(lyb- DRC.TINYDELTA), DBMath.round(hxb-lxb+2* DRC.TINYDELTA), DBMath.round(hyb-lyb+2* DRC.TINYDELTA)); // Looking for two corners not inside bounding boxes A and B if (pd == 0) // flat bounding box { pt1 = lowB; pt2 = highB; pt1d = lowB; pt2d = highB; } else { Point2D[] points = rebuild.getPoints(); int[] cornerPoints = new int[2]; int corners = 0; // if more than 3 corners are found -> bounding box is flat for (int i = 0; i < points.length && corners < 2; i++) { if (!DBMath.pointInsideRect(points[i], poly1.getBounds2D()) && !DBMath.pointInsideRect(points[i], poly2.getBounds2D())) { cornerPoints[corners++] = i; } } if (corners != 2) throw new Error("Wrong corners in Quick.foundSmallSizeDefect()"); pt1 = points[cornerPoints[0]]; pt2 = points[cornerPoints[1]]; double delta = ((pt2.getY() - pt1.getY())/(pt2.getX() - pt1.getX()) > 0) ? 1 : -1; // getting point lightly out of the elements if (pt1.getX() < pt2.getX()) { // (y2-y1)/(x2-x1)(x1-tinydelta-x1) + y1 pt1d = new Point2D.Double(pt1.getX()- DRC.TINYDELTA, -delta* DRC.TINYDELTA+pt1.getY()); // (y2-y1)/(x2-x1)(x2+tinydelta-x2) + y2 pt2d = new Point2D.Double(pt2.g
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -