📄 parasitictool.java
字号:
private ParasiticBucket[] elements = new ParasiticBucket[2];// /** True if faces are perpendicular */ private boolean angle;// private double distance = -1; /** * Overwrite Object.toString() */ public String toString() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 2; i++) buf.append("Poly " + i + ":" + elements[i].poly.getBounds2D() + "(area=" + elements[i].area + ", length=" + elements[i].length + ") "); return (buf.toString()); } /** * similar to PolyBase.separationBox */ public static List<ParasiticValue> initParasiticValues(Poly p1, Poly p2) { Rectangle2D thisBounds = p1.getBox(); Rectangle2D otherBounds = p2.getBox(); List<ParasiticValue> values = new ArrayList<ParasiticValue>(); // Both polygons must be manhattan-shaped type if (thisBounds == null || otherBounds == null) return (null); int dir = -1; double [][] points1 = {{thisBounds.getMinX(), thisBounds.getMinY()}, {thisBounds.getMaxX(), thisBounds.getMaxY()}}; double [][] points2 = {{otherBounds.getMinX(), otherBounds.getMinY()}, {otherBounds.getMaxX(), otherBounds.getMaxY()}}; double pdx = Math.max(points2[0][PolyBase.X]-points1[1][PolyBase.X], points1[0][PolyBase.X]-points2[1][PolyBase.X]); double pdy = Math.max(points2[0][PolyBase.Y]-points1[1][PolyBase.Y], points1[0][PolyBase.Y]-points2[1][PolyBase.Y]); double area1 = 0, area2 = 0; double over1 = 0, over2 = 0; double length1 = 0, length2 = 0; double thickP1 = p1.getLayer().getThickness(); double thickP2 = p1.getLayer().getThickness(); // 1 for now thickP1 = thickP2 = 1; if (pdx > 0 && pdy > 0) // Diagonal { // Two elements ParasiticValue newValue1 = new ParasiticValue(); ParasiticValue newValue2 = new ParasiticValue();// newValue1.distance = newValue2.distance = Math.hypot(pdx, pdy);// newValue1.angle = newValue2.angle = true; // Poly1:X v/s Poly2:Y length1 = p1.getBox().getWidth(); length2 = p2.getBox().getHeight(); area1 = thickP1 * p1.getBox().getHeight(); area2 = thickP2 * p2.getBox().getWidth(); newValue1.elements[0] = new ParasiticBucket(p1, area1, length1); newValue1.elements[1] = new ParasiticBucket(p2, area2, length2); // Poly1:X v/s Poly2:Y length1 = p1.getBox().getHeight(); length2 = p2.getBox().getWidth(); area1 = thickP1 * p1.getBox().getWidth(); area2 = thickP2 * p2.getBox().getHeight(); newValue2.elements[0] = new ParasiticBucket(p1, area1, length1); newValue2.elements[1] = new ParasiticBucket(p2, area2, length2); values.add(newValue1); values.add(newValue2); } else { if (pdx == 0 || pdy == 0) System.out.println("How do I treat this?"); ParasiticValue newValue = new ParasiticValue();// newValue.angle = false; if (pdx > pdy) { dir = PolyBase.X;// newValue.distance = pdx; length1 = p1.getBox().getWidth(); length2 = p2.getBox().getWidth(); } else { dir = PolyBase.Y;// newValue.distance = pdy; length1 = p1.getBox().getHeight(); length2 = p2.getBox().getHeight(); } int oppDir = (dir+1)%2; over1 = over2 = Math.min(points1[1][oppDir], points2[1][oppDir]) - Math.max(points1[0][oppDir], points2[0][oppDir]); area1 = thickP1 * over1; area2 = thickP2 * over2; newValue.elements[0] = new ParasiticBucket(p1, area1, length1); newValue.elements[1] = new ParasiticBucket(p2, area2, length2); values.add(newValue); } return values; } } /****************************** OPTIONS ******************************/ /****************************** Job ******************************/ private static class AnalyzeParasitic extends Job { Cell cell; Network net; protected AnalyzeParasitic(Network network, Cell cell) { super ("Analyze "+ network, tool, Job.Type.EXAMINE, null, cell, Job.Priority.USER); this.net = network; this.cell = cell; this.startJob(); } private List<ParasiticValue> getClosestPolys(Cell cell, Geometric geom, Technology tech, Poly poly, Rectangle2D bounds) { List<ParasiticValue> polyList = new ArrayList<ParasiticValue>(); for(Iterator<RTBounds> it = cell.searchIterator(bounds); it.hasNext(); ) { Geometric nGeom = (Geometric)it.next(); if (nGeom == geom) continue; // Touching elements out if (nGeom.isConnected(geom)) continue; if (nGeom instanceof NodeInst) { NodeInst ni = (NodeInst)nGeom; NodeProto np = ni.getProto(); if (np == Generic.tech().cellCenterNode) continue; if (np.getFunction() == PrimitiveNode.Function.PIN) continue; // don't check between technologies if (np.getTechnology() != tech) continue; // ignore nodes that are not primitive if (ni.isCellInstance()) System.out.println("Skipping case for now"); else { //if (layer.isNonElectrical()) continue; // Valid for Pins System.out.println("Found node " + nGeom + " for " + geom); AffineTransform trans = ni.rotateOut(); Poly [] nodeInstPolyList = tech.getShapeOfNode(ni); for(int i = 0; i < nodeInstPolyList.length; i++) { Poly nPoly = nodeInstPolyList[i]; Layer layer = nPoly.getLayer(); if (!layer.getFunction().isMetal()) continue; nPoly.transform(trans); polyList.addAll(ParasiticValue.initParasiticValues(poly, nPoly)); } } } else { // Arc then ArcInst ai = (ArcInst)nGeom; ArcProto ap = ai.getProto(); // don't check between technologies if (ap.getTechnology() != tech) continue; System.out.println("Found arc " + nGeom + " for " + geom); Poly [] arcInstPolyList = tech.getShapeOfArc(ai); for(int i = 0; i < arcInstPolyList.length; i++) { Poly nPoly = arcInstPolyList[i]; Layer layer = nPoly.getLayer(); if (!layer.getFunction().isMetal()) continue; nPoly = ai.cropPerLayer(nPoly); if (nPoly != null) // @TODO check this null condition polyList.addAll(ParasiticValue.initParasiticValues(poly, nPoly)); } } } return polyList; } /** * Implementation of Job.doIt() abstract function */ public boolean doIt() throws JobException { long startTime = System.currentTimeMillis(); System.out.println("Extracting Parasitic for " + cell + " " + net); Rectangle2D bounds = new Rectangle2D.Double(); double maxDistance = getMaxDistance(); List<ParasiticValue> polyToCheckList = new ArrayList<ParasiticValue>(); // Selecting arcs attached to this network for (Iterator<ArcInst> it = net.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); Technology tech = ai.getProto().getTechnology(); Poly [] arcInstPolyList = tech.getShapeOfArc(ai); for(int i = 0; i < arcInstPolyList.length; i++) { Poly poly = arcInstPolyList[i]; Layer layer = poly.getLayer(); if (!layer.getFunction().isMetal()) continue; //polyToCheckList.add(poly); poly = ai.cropPerLayer(poly); Rectangle2D bnd = poly.getBounds2D(); bounds.setRect(bnd.getMinX()-maxDistance, bnd.getMinY()-maxDistance, bnd.getWidth()+maxDistance*2, bnd.getHeight()+maxDistance*2); polyToCheckList.addAll(getClosestPolys(cell, ai, tech, poly, bounds)); //merge.add(layer, new PolyQTree.PolyNode(poly), false); } } // Adding related nodes, searching per ports Map<NodeInst,NodeInst> nodeMap = new HashMap<NodeInst,NodeInst>(); for (Iterator<PortInst> it = net.getPorts(); it.hasNext(); ) { PortInst pi = it.next(); NodeInst ni = pi.getNodeInst(); if (nodeMap.get(ni) != null) continue; // Already analyzed AffineTransform trans = ni.rotateOut(); NodeProto np = ni.getProto(); nodeMap.put(ni, ni); if (!ni.isCellInstance()) { PrimitiveNode pNp = (PrimitiveNode)np; Technology tech = pNp.getTechnology(); Poly [] nodeInstPolyList = tech.getShapeOfNode(ni); for(int i = 0; i < nodeInstPolyList.length; i++) { Poly poly = nodeInstPolyList[i]; if (poly.isPseudoLayer()) continue; Layer layer = poly.getLayer(); if (!layer.getFunction().isMetal()) continue; poly.transform(trans); Rectangle2D bnd = poly.getBounds2D(); bounds.setRect(bnd.getMinX()-maxDistance, bnd.getMinY()-maxDistance, bnd.getWidth()+maxDistance*2, bnd.getHeight()+maxDistance*2); polyToCheckList.addAll(getClosestPolys(cell, ni, tech, poly, bounds)); //merge.add(layer, new PolyQTree.PolyNode(poly), false); } } else System.out.println("Not implemented"); } for (ParasiticValue val : polyToCheckList) { System.out.println("Value " + val + " Layer " + val.elements[1].poly.getLayer()); } long endTime = System.currentTimeMillis(); System.out.println("Done (took " + TextUtils.getElapsedTime(endTime - startTime) + ")"); // sort the errors by layer errorLogger.sortLogs(); return true; } } //----------------------------IRSIM Cell Info for HierarchyEnumerator-------------------- /** * Class to define cell information for Parasitic extraction */ public static class ParasiticCellInfo extends HierarchyEnumerator.CellInfo { /** M-factor to be applied to size */ private float mFactor; /** initialize ParasiticCellInfo: called from enterCell */ protected void extInit() { HierarchyEnumerator.CellInfo parent = getParentInfo(); if (parent == null) mFactor = 1f; else mFactor = ((ParasiticCellInfo)parent).getMFactor(); // get mfactor from instance we pushed into Nodable ni = getContext().getNodable(); if (ni == null) return; Variable mvar = ni.getVar(Simulation.M_FACTOR_KEY); if (mvar == null) return; Object mval = getContext().evalVar(mvar, null); if (mval == null) return; mFactor = mFactor * VarContext.objectToFloat(mval, 1f); } /** get mFactor */ public float getMFactor() { return mFactor; } } /** PREFERENCES */ private static Pref cacheMaxDistance = Pref.makeDoublePref("MaximumDistance", ParasiticTool.tool.prefs, 20); /** * Method to get maximum dstance for searching window * @return double representing the preference */ public static double getMaxDistance() { return cacheMaxDistance.getDouble(); } /** * Method to set maximum distance to use during searching window * @param value to set */ public static void setMaxDistance(double value) { cacheMaxDistance.setDouble(value); } /** * Method to get maximum dstance for searching window, by default. * @return double representing the preference, by default. */ public static double getFactoryMaxDistance() { return cacheMaxDistance.getDoubleFactoryValue(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -