📄 hierarchyenumerator.java
字号:
this.caching = cache; if (context == null) context = VarContext.globalContext; int[][] exportNdxToNetIDs = null; enumerateCell(null, root, context, netlist, exportNdxToNetIDs, new AffineTransform(), null);// System.out.println("A total of: " + curNetId + " nets were numbered");// System.out.println("A total of: " + cellCnt + " Cells were visited");// System.out.println("A total of: " + instCnt + " NodeInsts were visited"); } // ------------------------ public types --------------------------- /** Perform useful work while the HierarchyEnumerator enumerates * the design. Whereas the HierarchyEnumerator is responsible for * enumerating every Cell and NodeInst in the flattened design, * the Visitor object is responsible for performing useful work * during the enumeration. * * <p>The HierarchyEnumerator performs a recursive descent of the * design hierarchy starting with the root Cell. When the * HierarchyEnumerator enters a Cell instance it calls the Visitor's * enterCell() method to let the Visitor know that it's just started * working on a new Cell instance. Then the HierarchyEnumerator calls * the Visitor's visitNodeInst() method for each NodeInst in that * Cell. Finally, after all the NodeInsts have been visited, the * HierarchyEnumerator calls the Visitor's exitCell() method to * inform the Visitor that the HierarchyEnumerator is done with that * Cell. * * <p>The Visitor's visitNodeInst() method controls whether the * HierarchyEnumerator descends recursively into the Cell * instantiated by that NodeInst. If the visitNodeInst() method * returns true, then the HierarchyEnumerator enumerates the contents * of that NodeInst's child Cell before it continues enumerating the * NodeInsts of the current Cell. */ public static abstract class Visitor { /** A hook to allow the user to add additional information to * a CellInfo. The newCellInfo method is a "Factory" * method. If the user wishes to record additional application * specific information for each Cell, the user should extend * the CellInfo class and then override newCellInfo to return * an instance of that derived class. */ public CellInfo newCellInfo() {return new CellInfo();} /** The HierarchyEnumerator is about to begin enumerating the * contents of a new Cell instance. That instance has just * become the new "current" Cell instance. * @param info information about the Cell instance being * enumerated * @return a boolean indicating if the HierarchyEnumerator * should enumerate the contents of the current Cell. True * means enumerate the current cell */ public abstract boolean enterCell(CellInfo info); /** The HierarchyEnumerator has finished enumerating the * contents of the current Cell instance. It is about to leave * it, never to return. The CellInfo associated with the * current Cell instance is about to be abandoned. * @param info information about the Cell instance being * enumerated */ public abstract void exitCell(CellInfo info); /** The HierarchyEnumerator is visiting Nodable ni. * @param ni the Nodable that HierarchyEnumerator is visiting. * @return a boolean indicating whether or not the * HierarchyEnumerator should expand the Cell instantiated by * ni. True means expand. If ni instantiates a PrimitiveNode * then the return value is ignored by the * HierarchyEnumerator. */ public abstract boolean visitNodeInst(Nodable ni, CellInfo info); /** Using visitNodeInst implements a Top-Down traversal. If one * wishes to implement Bottom-Up traversal, use this method instead, * or in conjunction with visitNodeInst. */ //public abstract void visitNodeInstBottomUp(Nodable ni, CellInfo info); } /** The NetDescription object provides a Network and the level of * hierarchy in which the Network occurs. The visitor can use * NetDescription to formulate, for example, the name of * the net */ public static class NetDescription { private Network net; private CellInfo info; NetDescription(Network net, CellInfo info) { this.net = net; this.info = info; } public Network getNet() {return net;} public CellInfo getCellInfo() {return info;} } /** The CellInfo object is used to pass information to the Visitor * during the enumeration. The CellInfo object contains many methods * that describe the Cell currently being enumerated and the state * of the enumeration. * * <p>The HierarchyEnumerator creates a new CellInfo for a Cell * instance just before it begins enumerating the contents of that * Cell instance. The HierarchyEnumerator abandons the CellInfo once * it is done enumerating the contents of that Cell instance. Once * the CellInfo is abandoned the garbage collector may reclaim the * CellInfo's storage. * * <p>Each CellInfo has a reference to the CellInfo of the parent of * the current Cell instance. Thus the Visitor is able to get * information about all the ancestors of the current Cell * instance. * * <p>In most cases, the user will need to store additional * information in the CellInfo. In those cases the user should * extend the CellInfo class and override the Visitor.newCellInfo() * method to return an instance of the derived class. */ public static class CellInfo { private Nodable parentInst; private Cell cell; private VarContext context; private Netlist netlist; private int[] netNdxToNetID; private int[][] exportNdxToNetIDs; private AffineTransform xformToRoot; private Map<Integer,NetDescription> netIdToNetDesc; private CellInfo parentInfo; // package private void init(Nodable parentInst, Cell cell, VarContext context, Netlist netlist, int[] netToNetID, int[][] exportNdxToNetIDs, AffineTransform xformToRoot, Map<Integer, NetDescription> netIdToNetDesc, CellInfo parentInfo) { this.parentInst = parentInst; this.cell = cell; this.context = context; this.netlist = netlist; this.netNdxToNetID = netToNetID; this.exportNdxToNetIDs = exportNdxToNetIDs; this.xformToRoot = xformToRoot; this.netIdToNetDesc = netIdToNetDesc; this.parentInfo = parentInfo; } /** * <p>Return an AffineTransform that encodes the size, rotation, and * center of this NodeInst. * * <p>The returned AffineTransform has the property that when * it is applied to a unit square centered at the origin the * result is the bounding box of the NodeInst. * This transform is useful because it can be used to * map the position of a NodeInst through levels of the design * hierarchy. * * <p>Note that the user can set the position of a NodeInst * using NodeInst.setPositionFromTransform(). For example, the * following operations make no change to a NodeInst's position: * * <code> * ni.setPositionFromTransform(ni.getPositionFromTransform()); * </code> */// public AffineTransform getPositionAsTransform(NodeInst ni) {// AffineTransform at = new AffineTransform();// at.setToTranslation(getAnchorCenterX(), getAnchorCenterY());// boolean transpose = sX<0 ^ sY<0;// if (transpose){// at.scale(1, -1);// at.rotate(Math.PI/2);// }// at.rotate(angle*Math.PI/1800);// at.scale(sX, sY);// return at;// }//// private double angleFromXY(double x, double y) {// double ans = Math.atan2(y, x) * 180/Math.PI;// //System.out.println("(x, y): ("+x+", "+y+") angle: "+ans);// return ans;// }//// private double angle0To360(double a) {// while (a >= 360) a -= 360;// while (a < 0) a += 360;// return a;// }//// private String makePath(VarContext context, String sep) {// String path = context.getInstPath(sep);// if (!path.equals("")) path+=sep;// return path;// } /** * Temporary for testing the HierarchyEnumerator. * * <p>Set the size, angle, and center of this NodeInst based upon an * affine transformation. * * <p>The AffineTransform must map a unit square centered at the * origin to the desired bounding box for the NodeInst. * * <p>Note that this operation cannot succeed for all affine * transformations. The reason is that Electric's transformations * always preserve right angles whereas, in general, affine * transformations do not. If the given affine transformation does * not preserve right angles this method will print a warning * displaying the angle that results when a right angle is * transformed. * * <p>Warning: this code is experimental * @param xForm the affine transformation. xForm must yield the * bounding box of the NodeInst when applied to a unit square * centered at the origin. */// public void setPositionFromTransform(AffineTransform xForm) {// double sizeX, sizeY, newAngle, centX, centY;// boolean debug = false;//// if (debug) System.out.println(xForm);//// Point2D a = new Point2D.Double(0, 1); // along Y axis// Point2D b = new Point2D.Double(0, 0); // origin// Point2D c = new Point2D.Double(1, 0); // along X axis//// Point2D aP = new Point2D.Double();// Point2D bP = new Point2D.Double();// Point2D cP = new Point2D.Double();//// xForm.transform(a, aP);// xForm.transform(b, bP);// xForm.transform(c, cP);//// if (debug) {// System.out.println("aP: " + aP);// System.out.println("bP: " + bP);// System.out.println("cP: " + cP);// }//// sizeX = bP.distance(cP);// sizeY = bP.distance(aP);// centX = bP.getX();// centY = bP.getY();//// double angleA = angleFromXY(aP.getX() - bP.getX(), aP.getY() - bP.getY());// double angleC = angleFromXY(cP.getX() - bP.getX(), cP.getY() - bP.getY());// double angleAC = angle0To360(angleA - angleC);//// if (debug) {// System.out.println("angleC: " + angleC);// System.out.println("angleA: " + angleA);// System.out.println("angleAC: " + angleAC);// }// // round to 1/10 degrees// angleAC = Math.rint(angleAC * 10) / 10;// if (angleAC == 90) {// newAngle = angle0To360(angleC);// } else if (angleAC == 270) {// // By using geometric constructions on paper I determined that I// // need to rotate by (270 degrees - angleC) and then transpose.// newAngle = angle0To360(270 - angleC);// sizeX = -sizeX; // Negative size means transpose (not mirror)// } else {// System.out.println("error in NodeInst.setPositionFromTransform: "+// "angle not 90 or 270: " + angleAC);// newAngle = angleC;// }//// if (debug) System.out.println(// "setPositionFromTransform: new position {\n"// + " sizeX: " + sizeX + "\n"// + " sizeY: " + sizeY + "\n"// + " angle: " + newAngle + "\n"// + " dx: " + centX + "\n"// + " dy: " + centY + "\n"// + "}\n");//// modifyInstance(centX-getAnchorCenterX(), centY-getAnchorCenterY(), sizeX-sX,// sizeY-sY, (int)Math.round(newAngle*10)-angle);// } /** The Cell currently being visited. */ public final Cell getCell() {return cell;} /** The Cell that is the root of the traversal */ public final boolean isRootCell() {return parentInfo == null;} /** The VarContext to use for evaluating all variables in the * current Cell. */ public final VarContext getContext() {return context;} /** The Netlist of the current Cell. */ public final Netlist getNetlist() {return netlist;} /** Get the CellInfo for the current Cell's parent. If the * current Cell is the root then return null. */ public final CellInfo getParentInfo() {return parentInfo;} /** Get the NodeInst that instantiates the Current * instance. If the current Cell is the root then return * null. */ public final Nodable getParentInst() {return parentInst;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -