📄 l.java
字号:
printWriter.print(" W=" + TextUtils.formatDouble(wid) + " L=" + TextUtils.formatDouble(len)); } // write location if (ni.isCellInstance()) { Rectangle2D cellBounds = ((Cell)ni.getProto()).getBounds(); printWriter.println(" AT (" + TextUtils.formatDouble(ni.getTrueCenterX() - cellBounds.getCenterX()) + "," + TextUtils.formatDouble(ni.getTrueCenterY() - cellBounds.getCenterY()) + ") ;"); } else { printWriter.println(" AT (" + TextUtils.formatDouble(ni.getTrueCenterX()) + "," + TextUtils.formatDouble(ni.getTrueCenterY()) + ") ;"); } } printWriter.println(""); // write all arcs connected to nodes Set<ArcInst> arcsSeen = new HashSet<ArcInst>(); for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); int nature = getNodeType(ni); if (nature == TRUEPIN) continue; for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); ArcInst ai = con.getArc(); if (arcsSeen.contains(ai)) continue; printWriter.print("\tWIRE"); String alt = getArcFunctionName(ai.getProto(), null); if (alt != null) printWriter.print(" " + alt); // write the wire width if nonstandard if (ai.getLambdaBaseWidth() != ai.getProto().getDefaultLambdaBaseWidth()) printWriter.print(" W=" + TextUtils.formatDouble(ai.getLambdaBaseWidth())); // write the starting node name (use port name if pin is an export) if (ni.hasExports() && ni.getFunction() == PrimitiveNode.Function.PIN) { Export e = ni.getExports().next(); printWriter.print(" " + getLegalName(e.getName())); } else { printWriter.print(" "+ getLegalName(ni.getName())); } // qualify node name with port name if a transistor or instance PortInst pi = con.getPortInst(); if (nature == TRANSISTOR) { transistorPorts(ni); if (pi == gateLeft) printWriter.print(".gl"); if (pi == activeTop) printWriter.print(".d"); if (pi == gateRight) printWriter.print(".gr"); if (pi == activeBottom) printWriter.print(".s"); } else if (nature == INSTANCE) printWriter.print("." + getLegalName(pi.getPortProto().getName())); // prepare to run along the wire to a terminating node int thatEnd = 1 - con.getEndIndex(); String lastDir = ""; double segDist = -1; int segCount = 0; int eNature = 0; NodeInst oNi = null; for(;;) { // get information about this segment (arc "ai") arcsSeen.add(ai); int thisEnd = 1 - thatEnd; String dir = lastDir; if (ai.getLocation(thatEnd).getX() == ai.getLocation(thisEnd).getX()) { if (ai.getLocation(thatEnd).getY() > ai.getLocation(thisEnd).getY()) dir = "UP"; else if (ai.getLocation(thatEnd).getY() < ai.getLocation(thisEnd).getY()) dir = "DOWN"; } else if (ai.getLocation(thatEnd).getY() == ai.getLocation(thisEnd).getY()) { if (ai.getLocation(thatEnd).getX() > ai.getLocation(thisEnd).getX()) dir = "RIGHT"; else if (ai.getLocation(thatEnd).getX() < ai.getLocation(thisEnd).getX()) dir = "LEFT"; } // if segment is different from last, write out last one if (!dir.equals(lastDir) && lastDir.length() > 0) { printWriter.print(" " + lastDir); if (segDist >= 0) printWriter.print("=" + TextUtils.formatDouble(segDist)); segDist = -1; segCount++; } // remember this segment's direction and length lastDir = dir; oNi = ai.getPortInst(thatEnd).getNodeInst(); eNature = getNodeType(oNi); if ((nature != TRANSISTOR || segCount > 0) && eNature != TRANSISTOR) { if (segDist < 0) segDist = 0; segDist += ai.getLambdaLength(); } // if other node not a pin, stop now if (eNature != TRUEPIN) break; // end the loop if more than 1 wire out of next node "oNi" int tot = 0; int ot = 0; ArcInst oAi = null; for(Iterator<Connection> oCIt = oNi.getConnections(); oCIt.hasNext(); ) { Connection oCon = oCIt.next(); if (arcsSeen.contains(oCon.getArc())) continue; oAi = oCon.getArc(); tot++; ot = 1 - oCon.getEndIndex(); } if (tot != 1) break; ai = oAi; thatEnd = ot; } if (lastDir.length() > 0) { printWriter.print(" " + lastDir); if (segDist >= 0) printWriter.print("=" + TextUtils.formatDouble(segDist)); } else printWriter.print(" TO"); // write the terminating node name (use port name if pin is an export) if (oNi.hasExports() && oNi.getFunction() == PrimitiveNode.Function.PIN) { Export e = oNi.getExports().next(); printWriter.print(" " + getLegalName(e.getName())); } else { printWriter.print(" " + getLegalName(oNi.getName())); } // qualify node name with port name if a transistor or an instance PortInst oPi = ai.getPortInst(thatEnd); if (eNature == TRANSISTOR) { transistorPorts(oNi); if (oPi == gateLeft) printWriter.print(".gl"); if (oPi == activeTop) printWriter.print(".d"); if (oPi == gateRight) printWriter.print(".gr"); if (oPi == activeBottom) printWriter.print(".s"); } else if (eNature == INSTANCE) printWriter.print("." + getLegalName(oPi.getPortProto().getName())); printWriter.println(" ;"); } } // write any unmentioned wires (shouldn't be any) for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); if (arcsSeen.contains(ai)) continue; printWriter.println("# WIRE " + ai.describe(true) + " not described!!"); } printWriter.println("}"); } /** * Method to return the ports of a transistor in field variables "gateLeft", "gateRight", * "activeTop", and "activeBottom". If "gateRight" is null, there is only * one gate port. * @param ni the NodeInst to analyze. */ private void transistorPorts(NodeInst ni) { PrimitiveNode.Function fun = ni.getFunction(); gateLeft = activeTop = gateRight = activeBottom = null; if (ni.getNumPortInsts() < 3) return; gateLeft = ni.getPortInst(0); activeTop = ni.getPortInst(1); gateRight = ni.getPortInst(2); if (ni.getNumPortInsts() == 3 || fun == PrimitiveNode.Function.TRANPN || fun == PrimitiveNode.Function.TRAPNP || fun == PrimitiveNode.Function.TRA4NMOS || fun == PrimitiveNode.Function.TRA4DMOS || fun == PrimitiveNode.Function.TRA4PMOS || fun == PrimitiveNode.Function.TRA4NPN || fun == PrimitiveNode.Function.TRA4PNP || fun == PrimitiveNode.Function.TRA4NJFET || fun == PrimitiveNode.Function.TRA4PJFET || fun == PrimitiveNode.Function.TRA4DMES || fun == PrimitiveNode.Function.TRA4EMES) { activeBottom = gateRight; gateRight = null; } else { activeBottom = ni.getPortInst(3); } } /** * Method to convert a name to a legal L name. * @param name the name to convert. * @return the legal L name to use. */ private String getLegalName(String name) { // check for reserved names if (name.equals("VDD")) return "VDDXXX"; if (name.equals("GND")) return "GNDXXX"; // check for special characters boolean badChars = false; for(int i=0; i<name.length(); i++) if (!TextUtils.isLetterOrDigit(name.charAt(i))) badChars = true; if (!badChars) return name; // name has special characters: remove them StringBuffer sb = new StringBuffer(); for(int i=0; i<name.length(); i++) if (TextUtils.isLetterOrDigit(name.charAt(i))) sb.append(name.charAt(i)); return sb.toString(); } /** * Method to determine the type of a NodeInst. * @param ni the NodeInst to analyze. * @return * TRUEPIN if a true pin (exactly two connections)<BR> * TRANSISTOR if a transistor<BR> * INSTANCE if a cell instance<BR> * OTHERNODE otherwise. */ private int getNodeType(NodeInst ni) { if (ni.isCellInstance()) return INSTANCE; PrimitiveNode.Function fun = ni.getFunction(); if (fun.isFET()) return TRANSISTOR; if (fun != PrimitiveNode.Function.PIN) return OTHERNODE; if (ni.getNumConnections() != 2) return OTHERNODE; return TRUEPIN; } /** * Method to return the name of an arc prototype's function. * @param ap the ArcProto to analyze. * @param def the default name to return if nothing can be determined. * @return the name of the ArcProto's function. */ private String getArcFunctionName(ArcProto ap, String def) { ArcProto.Function fun = ap.getFunction(); if (fun.isMetal()) { return "MET" + fun.getLevel(); } if (fun.isPoly()) return "POLY"; if (fun == ArcProto.Function.DIFFP) return "PDIFF"; if (fun == ArcProto.Function.DIFFN) return "NDIFF"; if (fun == ArcProto.Function.DIFFS) return "NWELL"; if (fun == ArcProto.Function.DIFFW) return "PWELL"; return def; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -