📄 viewchanges.java
字号:
// see which side this type of port sits on if (character == PortCharacteristic.IN) return inputRot; if (character == PortCharacteristic.OUT) return outputRot; if (character == PortCharacteristic.BIDIR) return bidirRot; if (character == PortCharacteristic.PWR) return pwrRot; if (character == PortCharacteristic.GND) return gndRot; if (character.isClock()) return clkRot; return inputRot; } /****************************** CONVERT TO SCHEMATICS ******************************/ /** * Method to converts the current Cell into a schematic. */ public static void makeSchematicView() { Cell oldCell = WindowFrame.needCurCell(); if (oldCell == null) return; new MakeSchematicView(oldCell); } private static class MakeSchematicView extends Job { private Cell oldCell; private Cell newCell; protected MakeSchematicView(Cell cell) { super("Make Schematic View", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.oldCell = cell; startJob(); } public boolean doIt() throws JobException { newCell = convertSchematicCell(oldCell); if (newCell == null) return false; fieldVariableChanged("newCell"); return true; } public void terminateOK() { if (newCell != null) { System.out.println("Cell " + newCell.describe(true) + " created with a schematic representation of " + oldCell); WindowFrame.createEditWindow(newCell); } } } private static Cell convertSchematicCell(Cell oldCell) { // create cell in new technology Cell newCell = makeNewCell(oldCell.getName(), View.SCHEMATIC, oldCell, null); if (newCell == null) return null; // create the parts in this cell Map<NodeInst,NodeInst> newNodes = new HashMap<NodeInst,NodeInst>(); buildSchematicNodes(oldCell, newCell, newNodes); buildSchematicArcs(oldCell, newCell, newNodes); // now make adjustments for manhattan-ness// makeArcsManhattan(newCell); // set "fixed-angle" if reasonable for(Iterator<ArcInst> it = newCell.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); Point2D headPt = ai.getHeadLocation(); Point2D tailPt = ai.getTailLocation(); if (headPt.getX() == tailPt.getX() && headPt.getY() == tailPt.getY()) continue; if ((GenMath.figureAngle(tailPt, headPt)%450) == 0) ai.setFixedAngle(true); } return newCell; } /** * Method to create a new cell called "newcellname" that is to be the * equivalent to an old cell in "cell". The view type of the new cell is * in "newcellview" and the view type of the old cell is in "cellview" */ private static Cell makeNewCell(String newCellName, View newCellView, Cell cell, Library lib) { // create the new cell String cellName = newCellName; if (newCellView.getAbbreviation().length() > 0) { cellName = newCellName + newCellView.getAbbreviationExtension(); } if (lib == null) lib = cell.getLibrary(); Cell newCell = Cell.makeInstance(lib, cellName); if (newCell == null) System.out.println("Could not create cell: " + cellName); else System.out.println("Creating new cell: " + cellName); return newCell; } private static void buildSchematicNodes(Cell cell, Cell newCell, Map<NodeInst,NodeInst> newNodes) { // for each node, create a new node in the newcell, of the correct logical type. for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst mosNI = it.next(); PrimitiveNode.Function type = getNodeType(mosNI); NodeInst schemNI = null; if (type == PrimitiveNode.Function.UNKNOWN) continue; if (type == PrimitiveNode.Function.PIN) { // compute new x, y coordinates NodeProto prim = Schematics.tech().wirePinNode; schemNI = makeSchematicNode(prim, mosNI, prim.getDefWidth(), prim.getDefHeight(), 0, 0, newCell); } else if (type == null) { // a cell Cell proto = (Cell)mosNI.getProto(); Cell equivCell = proto.otherView(View.SCHEMATIC); if (equivCell == null) equivCell = convertSchematicCell(proto); schemNI = makeSchematicNode(equivCell, mosNI, equivCell.getDefWidth(), equivCell.getDefHeight(), mosNI.getAngle(), 0, newCell); } else { int rotate = mosNI.getAngle(); rotate = (rotate + 2700) % 3600; NodeProto prim = Schematics.tech().transistorNode; int bits = Schematics.getPrimitiveFunctionBits(mosNI.getFunction()); schemNI = makeSchematicNode(prim, mosNI, prim.getDefWidth(), prim.getDefHeight(), rotate, bits, newCell); // add in the size TransistorSize ts = mosNI.getTransistorSize(VarContext.globalContext); if (ts != null) { if (mosNI.getFunction().isFET()) { // set length/width TextDescriptor td = TextDescriptor.getNodeTextDescriptor().withRelSize(0.5).withOff(-0.5, -1); schemNI.newVar(Schematics.ATTR_LENGTH, new Double(ts.getDoubleLength()), td); td = TextDescriptor.getNodeTextDescriptor().withRelSize(1).withOff(0.5, -1); schemNI.newVar(Schematics.ATTR_WIDTH, new Double(ts.getDoubleWidth()), td); } else { // set area schemNI.newVar(Schematics.ATTR_AREA, new Double(ts.getDoubleLength())); } } } // store the new node in the old node newNodes.put(mosNI, schemNI); // reexport ports if (schemNI != null) { for(Iterator<Export> eIt = mosNI.getExports(); eIt.hasNext(); ) { Export mosPP = eIt.next(); PortInst schemPI = convertPort(mosNI, mosPP.getOriginalPort().getPortProto(), schemNI); if (schemPI == null) continue; Export schemPP = Export.newInstance(newCell, schemPI, mosPP.getName(), mosPP.getCharacteristic()); if (schemPP != null) { schemPP.copyTextDescriptorFrom(mosPP, Export.EXPORT_NAME); schemPP.copyVarsFrom(mosPP); } } } } } private static NodeInst makeSchematicNode(NodeProto prim, NodeInst orig, double wid, double hei, int angle, int techSpecific, Cell newCell) { Point2D newLoc = new Point2D.Double(orig.getAnchorCenterX(), orig.getAnchorCenterY()); Orientation orient = Orientation.fromAngle(angle); NodeInst newNI = NodeInst.makeInstance(prim, newLoc, wid, hei, newCell, orient, null, techSpecific); return newNI; } /** * for each arc in cell, find the ends in the new technology, and * make a new arc to connect them in the new cell. */ private static void buildSchematicArcs(Cell cell, Cell newcell, Map<NodeInst,NodeInst> newNodes) { for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) { ArcInst mosAI = it.next(); NodeInst mosHeadNI = mosAI.getHeadPortInst().getNodeInst(); NodeInst mosTailNI = mosAI.getTailPortInst().getNodeInst(); NodeInst schemHeadNI = newNodes.get(mosHeadNI); NodeInst schemTailNI = newNodes.get(mosTailNI); if (schemHeadNI == null || schemTailNI == null) continue; PortInst schemHeadPI = convertPort(mosHeadNI, mosAI.getHeadPortInst().getPortProto(), schemHeadNI); PortInst schemTailPI = convertPort(mosTailNI, mosAI.getTailPortInst().getPortProto(), schemTailNI); if (schemHeadPI == null || schemTailPI == null) continue; // create the new arc ArcInst schemAI = ArcInst.makeInstanceBase(Schematics.tech().wire_arc, 0, schemHeadPI, schemTailPI, null, null, mosAI.getName()); if (schemAI == null) continue; schemAI.setFixedAngle(false); schemAI.setRigid(false); } } /** * Method to find the logical portproto corresponding to the mos portproto of ni */ private static PortInst convertPort(NodeInst mosNI, PortProto mosPP, NodeInst schemNI) { PrimitiveNode.Function fun = getNodeType(schemNI); if (fun == PrimitiveNode.Function.PIN) { return schemNI.getOnlyPortInst(); } if (fun == null) { // a cell PortProto schemPP = schemNI.getProto().findPortProto(mosPP.getName()); if (schemPP == null) return null; return schemNI.findPortInstFromProto(schemPP); } // a transistor int portNum = 1; for(Iterator<PortProto> it = mosNI.getProto().getPorts(); it.hasNext(); ) { PortProto pp = it.next(); if (pp == mosPP) break; portNum++; } if (portNum == 4) portNum = 3; else if (portNum == 3) portNum = 1; for(Iterator<PortProto> it = schemNI.getProto().getPorts(); it.hasNext(); ) { PortProto schemPP = it.next(); portNum--; if (portNum > 0) continue; return schemNI.findPortInstFromProto(schemPP); } return null; }// private static final int MAXADJUST = 5;//// private static void makeArcsManhattan(Cell newCell)// {// // copy the list of nodes in the cell// List<NodeInst> nodesInCell = new ArrayList<NodeInst>();// for(Iterator<NodeInst> it = newCell.getNodes(); it.hasNext(); )// nodesInCell.add(it.next());//// // examine all nodes and adjust them// double [] x = new double[MAXADJUST];// double [] y = new double[MAXADJUST];// for(NodeInst ni : nodesInCell)// {// if (ni.isCellInstance()) continue;// PrimitiveNode.Function fun = ni.getFunction();// if (fun != PrimitiveNode.Function.PIN) continue;//// // see if this pin can be adjusted so that all wires are manhattan// int count = 0;// for(Iterator<Connection> aIt = ni.getConnections(); aIt.hasNext(); )// {// Connection con = aIt.next();// ArcInst ai = con.getArc();// int otherEnd = 1 - con.getEndIndex();// if (con.getPortInst().getNodeInst() == ai.getPortInst(otherEnd).getNodeInst()) continue;// x[count] = ai.getLocation(otherEnd).getX();// y[count] = ai.getLocation(otherEnd).getY();// count++;// if (count >= MAXADJUST) break;// }// if (count == 0) continue;//// // now adjust for all these points// double xp = ni.getAnchorCenterX();// double yp = ni.getAnchorCenterY();// double bestDist = Double.MAX_VALUE;// double bestX = 0, bestY = 0;// for(int i=0; i<count; i++) for(int j=0; j<count; j++)// {// double dist = Math.abs(xp - x[i]) + Math.abs(yp - y[j]);// if (dist > bestDist) continue;// bestDist = dist;// bestX = x[i]; bestY = y[j];// }//// // if there was a better place, move the node// if (bestDist != Double.MAX_VALUE)// ni.move(bestX-xp, bestY-yp);// }// } /** * Method to figure out if a NodeInst is a MOS component * (a wire or transistor). If it's a transistor, return its function; * if it's a passive connector, return PrimitiveNode.Function.PIN; * if it's a cell, return null; else return PrimitiveNode.Function.UNKNOWN. */ private static PrimitiveNode.Function getNodeType(NodeInst ni) { if (ni.isCellInstance()) return null; PrimitiveNode.Function fun = ni.getFunction(); if (fun.isTransistor()) return fun; if (fun == PrimitiveNode.Function.PIN || fun == PrimitiveNode.Function.CONTACT || fun == PrimitiveNode.Function.NODE || fun == PrimitiveNode.Function.CONNECT || fun == PrimitiveNode.Function.SUBSTRATE || fun == PrimitiveNode.Function.WELL) return PrimitiveNode.Function.PIN; return PrimitiveNode.Function.UNKNOWN; } /****************************** CONVERT TO ALTERNATE LAYOUT ******************************/ /** * Method to converts the current Cell into a layout in a given technology. */ public static void makeLayoutView() { EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) return; Cell oldCell = wnd.getCell(); if (oldCell == null) return; VarContext context = wnd.getVarContext(); if (context == null) context = VarContext.globalContext; // find out which technology they want to convert to Technology oldTech = oldCell.getTechnology(); List<Technology> newTechs = new ArrayList<Technology>(); for(Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); ) { Technology tech = it.next(); if (tech == oldTech) continue; if (tech.isScaleRelevant()) newTechs.add(tech); } String [] techNames = new String[newTechs.size()]; int i=0; for(Technology tech : newTechs) techNames[i++] = tech.getTechName(); String selectedValue = (String)JOptionPane.showInputDialog(null, "New technology to create", "Technology conversion", JOptionPane.INFORMATION_MESSAGE, null, techNames, User.getSchematicTechnology().getTechName()); if (selectedValue == null) return; Technology newTech = Technology.findTechnology(selectedValue); if (newTech == null) return; if (newTech == oldTech) { System.out.println("Cell " + oldCell.describe(true) + " is already in the " + newTech.getTechName() + " technology"); return; } String newLibName = Job.getUserInterface().askForInput("New library name for the converted cells (leave blank to place new cells in the current library):", "New Library Name", ""); if (newLibName == null) return; new MakeLayoutView(oldCell, oldTech, newTech, context, newLibName); } private static class MakeLayoutView extends Job { private Cell oldCell; private Technology oldTech, newTech; private VarContext context; private String newLibName; private List<Cell> createdCells; protected MakeLayoutView(Cell oldCell, Technology oldTech, Technology newTech, VarContext context, String newLibName) { super("Make Alternate Layout", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.oldCell = oldCell; this.oldTech = oldTech; this.newTech = newTech; this.context = context; this.newLibName = newLibName;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -