📄 layercoveragetool.java
字号:
// Checking if job is scheduled for abort or already aborted if (isJobAborted()) return (false); Cell curCell = info.getCell(); Netlist netlist = info.getNetlist(); // Nothing to visit CAREFUL WITH TRANSFORMATION IN SUBCELL!! if (!doesIntersectBoundingBox(curCell.getBounds(), info)) return false; // Checking if any network is found boolean found = (netSet == null); for (Iterator<Network> it = netlist.getNetworks(); !found && it.hasNext(); ) { // In case there are many networks if (isJobAborted()) return (false); Network parentNet = it.next(); HierarchyEnumerator.CellInfo cinfo = info; boolean netFound = false; while ((netFound = netSet.contains(parentNet)) == false && cinfo.getParentInst() != null) { parentNet = cinfo.getNetworkInParent(parentNet); cinfo = cinfo.getParentInfo(); } found = netFound; } if (!found) return (false); // Traversing arcs for (Iterator<ArcInst> it = curCell.getArcs(); it.hasNext(); ) { ArcInst arc = it.next(); int width = netlist.getBusWidth(arc); found = (netSet == null); for (int i=0; !found && i<width; i++) { Network parentNet = netlist.getNetwork(arc, i); HierarchyEnumerator.CellInfo cinfo = info; boolean netFound = false; while ((netFound = netSet.contains(parentNet)) == false && cinfo.getParentInst() != null) { parentNet = cinfo.getNetworkInParent(parentNet); cinfo = cinfo.getParentInfo(); } found = netFound; } if (!found) continue; // skipping this arc ArcProto arcType = arc.getProto(); Technology tech = arcType.getTechnology(); Poly[] polyList = tech.getShapeOfArc(arc); // Treating the arcs associated to each node // Arcs don't need to be rotated for (Poly poly : polyList) { Layer layer = poly.getLayer(); boolean value = isValidFunction(layer, function); if (!value) continue; poly.transform(info.getTransformToRoot()); // If points are not rounded, in IMPLANT map.containsValue() might not work poly.roundPoints(); storeOriginalPolygons(layer, poly); Shape pnode = cropGeometry(poly, origBBoxArea); // empty intersection if (pnode == null) continue; tree.add(layer, pnode); // tmp fix } } return (true); } /** * To store original polygons checked by coverage implant run and then * able to determine if new implants should be created. * @param layer * @param poly */ private void storeOriginalPolygons(Layer layer, PolyBase poly) { if (function != LCMode.IMPLANT) return; // For coverage implants Set<PolyBase> polySet = originalPolygons.get(layer); if (polySet == null) { polySet = new HashSet<PolyBase>(); originalPolygons.put(layer, polySet); } //map.put(pnode, pnode.clone()); polySet.add(poly); } /** * * @param no * @param info * @return true if node was visited */ public boolean visitNodeInst(Nodable no, HierarchyEnumerator.CellInfo info) { if (isJobAborted()) return false; //if (checkAbort()) return false; NodeInst node = no.getNodeInst(); // Its like pins, facet-center if (NodeInst.isSpecialNode(node)) return (false); boolean inside = doesIntersectBoundingBox(node.getBounds(), info); // Its a cell if (node.isCellInstance()) return (inside); // Geometry outside contour if (!inside) return false;// boolean found = (netSet == null);// for(Iterator<PortInst> pIt = node.getPortInsts(); !found && pIt.hasNext(); )// {// PortInst pi = pIt.next();// PortProto subPP = pi.getPortProto();// Network parentNet = info.getNetlist().getNetwork(node, subPP, 0);// HierarchyEnumerator.CellInfo cinfo = info;// boolean netFound = false;// while ((netFound = netSet.contains(parentNet)) == false && cinfo.getParentInst() != null) {// parentNet = cinfo.getNetworkInParent(parentNet);// cinfo = cinfo.getParentInfo();// }// found = netFound;// }// if (!found) return (false); // skipping this node // Coverage implants are pure primitive nodes and they are ignored. if (node.isPrimtiveSubstrateNode()) //node.getFunction() == PrimitiveNode.Function.NODE) { if (info.isRootCell()) deleteList.add(node); return (false); } Technology tech = node.getProto().getTechnology(); Poly[] polyList = tech.getShapeOfNode(node, true, false, null); AffineTransform transform = node.rotateOut(); boolean includedNode = false; for (int i = 0; i < polyList.length; i++) { Poly poly = polyList[i]; if (netSet != null) { PortProto subPP = poly.getPort(); Network parentNet = info.getNetlist().getNetwork(node, subPP, 0); HierarchyEnumerator.CellInfo cinfo = info; boolean netFound = false; while ((netFound = netSet.contains(parentNet)) == false && cinfo.getParentInst() != null) { parentNet = cinfo.getNetworkInParent(parentNet); cinfo = cinfo.getParentInfo(); } if (!netFound) continue; // skipping this polygon } includedNode = true; Layer layer = poly.getLayer(); // Only checking poly or metal for AREA case boolean value = isValidFunction(layer, function); if (!value) continue; if (poly.getPoints().length < 3) { // When is this happening? continue; } poly.transform(transform); // Not sure if I need this for general merge polygons function poly.transform(info.getTransformToRoot()); // If points are not rounded, in IMPLANT map.containsValue() might not work poly.roundPoints(); storeOriginalPolygons(layer, poly); Shape pnode = cropGeometry(poly, origBBoxArea); // empty intersection if (pnode == null) continue; tree.add(layer, pnode); } // add transistor gate/active if any part of the node matched a network if (includedNode && geoms != null) { PrimitiveNode.Function fun = node.getFunction(); if (fun.isTransistor()) { if (fun.isNTypeTransistor()) { TransistorSize ts = node.getTransistorSize(info.getContext()); geoms.n_active.area += ts.getDoubleArea(); geoms.n_active.width += ts.getDoubleWidth(); geoms.n_gate.area += ts.getDoubleArea(); geoms.n_gate.width += ts.getDoubleWidth(); } else if (fun.isPTypeTransistor()) { TransistorSize ts = node.getTransistorSize(info.getContext()); geoms.p_active.area += ts.getDoubleArea(); geoms.p_active.width += ts.getDoubleWidth(); geoms.p_gate.area += ts.getDoubleArea(); geoms.p_gate.width += ts.getDoubleWidth(); } } } return (true); } /** * Method to crop original polygon by given bounding box. If they * don't intersect, returns original shape * @param origGeom polygon to crop * @param bBoxArea area that defines bounding box * @return cropped shape */ private static Shape cropGeometry(Shape origGeom, Area bBoxArea) { Shape pnode = origGeom; // exclude area outside bounding box if (bBoxArea != null) { Area tmpA = new Area(pnode); tmpA.intersect(bBoxArea); // Empty intersection if (tmpA.isEmpty()) return null; pnode = tmpA; } return pnode; } } public static class TransistorInfo { /** sum of area of transistors */ public double area; /** sum of width of transistors */ public double width; }; /** * Class to represent all geometry on a network during layer coverage analysis. */ public static class GeometryOnNetwork { public final Cell cell; protected Set<Network> nets; private double lambda; private boolean printable; private Layer onlyThisLayer; // these lists tie together a layer, its area, and its half-perimeter private ArrayList<Layer> layers; private ArrayList<Double> areas; private ArrayList<Double> halfPerimeters; private double totalWire; private double totalArea; // these are the area and transistor widths for gate and active in N and P TransistorInfo p_gate, n_gate, p_active, n_active; public GeometryOnNetwork(Cell cell, Set<Network> nets, double lambda, boolean printable, Layer onlyThisLayer) { this.cell = cell; this.nets = nets; this.lambda = lambda; this.onlyThisLayer = onlyThisLayer; layers = new ArrayList<Layer>(); areas = new ArrayList<Double>(); halfPerimeters = new ArrayList<Double>(); this.printable = printable; totalWire = 0; totalArea = 0; p_gate = new TransistorInfo(); n_gate = new TransistorInfo(); p_active = new TransistorInfo(); n_active = new TransistorInfo(); } public double getTotalWireLength() { return totalWire; } protected void setTotalArea(double area) {totalArea = area; } public TransistorInfo getPGate() { return p_gate; } public TransistorInfo getNGate() { return n_gate; } public TransistorInfo getPActive() { return p_active; } public TransistorInfo getNActive() { return n_active; } public List<Layer> getLayers() { return layers; } public List<Double> getAreas() { return areas; } public List<Double> getHalfPerimeters() { return halfPerimeters; } private void addLayer(Layer layer, double area, double halfperimeter) { assert(layer != null); if (onlyThisLayer != null && layer != onlyThisLayer) return; // skip this one layers.add(layer); areas.add(new Double(area)); halfPerimeters.add(new Double(halfperimeter)); Layer.Function func = layer.getFunction(); // accumulate total wire length on all metal/poly layers if (func.isPoly() && !func.isGatePoly() || func.isMetal()) { totalWire += halfperimeter; } } /** * Method to analyze amount of area covered by layer and if meets the minimum * specified * @param bbox * @param errorLogger * @return true if no errors are found */ public boolean analyzeCoverage(Rectangle2D bbox, ErrorLogger errorLogger) { totalArea = (bbox.getHeight()*bbox.getWidth())/(lambda*lambda); boolean foundError = false; for (int i = 0; i < layers.size(); i++) { Layer layer = layers.get(i); Double area = areas.get(i); double percentage = area.doubleValue()/totalArea * 100; double minV = layer.getAreaCoverage(); if (percentage < minV) { String msg = "Error area coverage " + layer.getName() + " min value = " + minV + " actual value = " + percentage; PolyBase poly = new PolyBase(bbox); errorLogger.logError(msg, poly, cell, layer.getIndex()); foundError = true; } } return foundError; } public void print() { // Doesn't print information if (!printable) return; // nets is null for mode=AREA if (nets != null) { for(Network net : nets) { System.out.println("For " + net + " in " + cell + ":"); } } for (int i=0; i<layers.size(); i++) { Layer layer = layers.get(i); // autoboxing double area = areas.get(i).doubleValue(); // autoboxing double halfperim = halfPerimeters.get(i).doubleValue(); System.out.println("\tLayer " + layer.getName() + ":\t area " + TextUtils.formatDouble(area) + "(" + TextUtils.formatDouble((area/totalArea)*100, 2) + "%)" + "\t half-perimeter " + TextUtils.formatDouble(halfperim) + "\t ratio " + TextUtils.formatDouble(area/halfperim)); } if (totalWire > 0) System.out.println("Total wire length = " + TextUtils.formatDouble(totalWire/lambda)); if (totalArea > 0) System.out.println("Total cell area = " + TextUtils.formatDouble(totalArea, 2)); } } /*********************************** * JUnit interface ***********************************/ public static boolean testAll() { //return (LayerCoverageToolTest.basicAreaCoverageTest("area.log")); return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -