📄 edif.java
字号:
{ for (int j = 0; j < i; j++) { blockOpen("port"); String name = "IN" + (j + 1); blockPutIdentifier(name); blockPut("direction", "INPUT"); blockClose("port"); } firstPortIndex = 1; } for(int k=firstPortIndex; k<pn.getNumPorts(); k++) { PortProto pp = pn.getPort(k); String direction = "input"; if (pp.getCharacteristic() == PortCharacteristic.OUT) direction = "output"; else if (pp.getCharacteristic() == PortCharacteristic.BIDIR) direction = "inout"; blockOpen("port"); blockPutIdentifier(makeToken(pp.getName())); blockPut("direction", direction); blockClose("port"); } NodeInst ni = NodeInst.makeDummyInstance(pn); writeSymbol(pn, ni); blockClose("cell"); } // ports is a list of EDIFEquiv.Port objects private void writeExternalDef(String extCell, String extView, String viewType, List<EDIFEquiv.Port> ports) { blockOpen("cell"); blockPutIdentifier(extCell); blockPut("cellType", "generic"); blockOpen("view"); blockPutIdentifier(extView); if (viewType == null) viewType = IOTool.isEDIFUseSchematicView() ? "SCHEMATIC" : "NETLIST"; blockPut("viewType", viewType); // write interface blockOpen("interface"); for (EDIFEquiv.Port port : ports) { if (port.ignorePort) continue; blockOpen("port"); String safeName = makeValidName(port.name); if (!safeName.equals(port.name)) { blockOpen("rename"); blockPutIdentifier(safeName); blockPutString(port.name); blockClose("rename"); } else { blockPutIdentifier(port.name); } blockClose("port"); } blockClose("cell"); } /** * Method to count the usage of primitives hierarchically below cell "np" */ private void writeAllPrims(Cell cell, HashMap<Object,PrimitiveNode> primsFound) { // do not search this cell if it is an icon if (cell.isIcon()) return; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); NodeProto np = ni.getProto(); if (!ni.isCellInstance()) { if (equivs.getNodeEquivalence(ni) != null) continue; // will be defined by external reference PrimitiveNode pn = (PrimitiveNode)np; PrimitiveNode.Function fun = pn.getTechnology().getPrimitiveFunction(pn, ni.getTechSpecific()); //PrimitiveNode.Function fun = ni.getFunction(); int i = 1; if (fun == PrimitiveNode.Function.GATEAND || fun == PrimitiveNode.Function.GATEOR || fun == PrimitiveNode.Function.GATEXOR) { // count the number of inputs for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); if (con.getPortInst().getPortProto().getName().equals("a")) i++; } } if (primsFound.get(getPrimKey(ni, i)) != null) continue; // already written if (fun == PrimitiveNode.Function.UNKNOWN || fun == PrimitiveNode.Function.PIN || fun == PrimitiveNode.Function.ART) continue; writePrimitive(pn, i, fun); primsFound.put(getPrimKey(ni, i), pn); continue; } // ignore recursive references (showing icon in contents) if (ni.isIconOfParent()) continue; // get actual subcell (including contents/body distinction) Cell oNp = ((Cell)np).contentsView(); if (oNp == null) oNp = (Cell)np; // search the subcell writeAllPrims(oNp, primsFound); } } /** * Method to count the usage of primitives hierarchically below cell "np" */ private void countRippers(Cell cell, HashSet<Integer> rippers) { // do not search this cell if it is an icon if (cell.isIcon()) return; Netlist netlist = null; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); NodeProto np = ni.getProto(); if (!ni.isCellInstance()) { if (equivs.getNodeEquivalence(ni) != null) continue; // will be defined by external reference PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.PIN) { // check all the connections int busWidthFound = -1; boolean wireFound = false; for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); ArcInst ai = con.getArc(); if (netlist == null) netlist = cell.acquireUserNetlist(); int width = netlist.getBusWidth(ai); if (width > 1) busWidthFound = width; else wireFound = true; } if (wireFound && busWidthFound > 1) rippers.add(new Integer(busWidthFound)); } continue; } // ignore recursive references (showing icon in contents) if (ni.isIconOfParent()) continue; // get actual subcell (including contents/body distinction) Cell oNp = ((Cell)np).contentsView(); if (oNp == null) oNp = (Cell)np; // search the subcell countRippers(oNp, rippers); } } private Object getPrimKey(NodeInst ni, int i) { if (ni.isCellInstance()) return null; PrimitiveNode pn = (PrimitiveNode)ni.getProto(); PrimitiveNode.Function func = pn.getTechnology().getPrimitiveFunction(pn, ni.getTechSpecific()); String key = pn.getTechnology().getTechShortName() + "_" + pn.getName() + "_" + func.getConstantName() + "_" +i; return key; } /** * Method to generate a pt symbol (pt x y) */ private void writePoint(double x, double y) { blockOpen("pt"); blockPutInteger(scaleValue(x)); blockPutInteger(scaleValue(y)); blockClose("pt"); } /** * Method to convert a bus name to the proper string for output. * @param busName the bus name in Electric. * @return the bus name for EDIF output. */ private String convertBusName(String busName, Netlist netlist, ElectricObject eObj) { if (IOTool.isEDIFCadenceCompatibility()) { // see if the bus is simple int firstOpen = busName.indexOf('['); if (firstOpen < 0) return busName; boolean simple = true; if (busName.indexOf('[', firstOpen+1) >= 0) simple = false; else { int closePos = busName.indexOf(']', firstOpen); for(int i=firstOpen+1; i<closePos; i++) { char ch = busName.charAt(i); if (ch != ':' && ch != ',' && !TextUtils.isDigit(ch)) { simple = false; break; } } } if (simple) { busName = busName.replaceAll("\\[", "\\<").replaceAll("\\]", "\\>"); } else { // complex name: break it into many signals busName = ""; if (eObj instanceof ArcInst) { ArcInst ai = (ArcInst)eObj; int width = netlist.getBusWidth(ai); for(int i=0; i<width; i++) { Network net = netlist.getNetwork(ai, i); if (busName.length() > 0) busName += ","; Iterator<String> nIt = net.getNames(); String netName; if (nIt.hasNext()) netName = nIt.next(); else netName = net.describe(true); busName += netName.replaceAll("\\[", "_").replaceAll("\\]", "_"); } } else if (eObj instanceof Export) { Export e = (Export)eObj; int width = netlist.getBusWidth(e); for(int i=0; i<width; i++) { Network net = netlist.getNetwork(e, i); if (busName.length() > 0) busName += ","; Iterator<String> nIt = net.getNames(); String netName; if (nIt.hasNext()) netName = nIt.next(); else netName = net.describe(true); busName += netName.replaceAll("\\[", "_").replaceAll("\\]", "_"); } } } } return busName; } /** * Method to map Electric orientations to EDIF orientations */ public static String getOrientation(NodeInst ni, int addedRotation) { String orientation = "ERROR"; int angle = (ni.getAngle() - addedRotation); if (angle < 0) angle = angle + 3600; if (angle > 3600) angle = angle % 3600; switch (angle) { case 0: orientation = ""; break; case 900: orientation = "R90"; break; case 1800: orientation = "R180"; break; case 2700: orientation = "R270"; break; } if (ni.isMirroredAboutXAxis()) orientation = "MX" + orientation; if (ni.isMirroredAboutYAxis()) orientation = "MY" + orientation; if (orientation.length() == 0) orientation = "R0"; if (orientation.equals("MXR180")) orientation = "MY"; if (orientation.equals("MYR180")) orientation = "MX"; if (orientation.equals("MXR270")) orientation = "MYR90"; if (orientation.equals("MYR270")) orientation = "MXR90"; return orientation; } /** * Method to scale the requested integer * returns the scaled value */ private double scaleValue(double val) { return (int)(val*scale); }// /**// * Establish whether port 'e' is a global port or not// */// private boolean isGlobalExport(Export e)// {// // pp is a global port if it is marked global// if (e.isBodyOnly()) return true;//// // or if it does not exist on the icon// Cell parent = e.getParent();// Cell inp = parent.iconView();// if (inp == null) return false;// if (e.getEquivalent() == null) return true;// return false;// } /** * Method to properly identify an instance of a primitive node * for ASPECT netlists */ private String describePrimitive(NodeInst ni, PrimitiveNode.Function fun) { if (fun.isResistor()) /* == PrimitiveNode.Function.RESIST)*/ return "Resistor"; if (fun == PrimitiveNode.Function.TRANPN) return "npn"; if (fun == PrimitiveNode.Function.TRAPNP) return "pnp"; if (fun.isNTypeTransistor()) return "nfet"; if (fun.isPTypeTransistor()) return "pfet"; if (fun == PrimitiveNode.Function.SUBSTRATE) return "gtap"; return makeToken(ni.getProto().getName()); } /** * Helper name builder */ private String makeComponentName(Nodable no) { String okname = makeValidName(no.getName()); if (okname.length() > 0) { char chr = okname.charAt(0); if (TextUtils.isDigit(chr) || chr == '_') okname = "&" + okname; } return okname; } /** * Method to return null if there is no valid name in "var", corrected name if valid. */ public static String makeValidName(String name) { StringBuffer iptr = new StringBuffer(name); // allow '&' for the first character (this must be fixed later if digit or '_') int i = 0; if (iptr.charAt(i) == '&') i++; // allow "_" and alphanumeric for others for(; i<iptr.length(); i++) { if (TextUtils.isLetterOrDigit(iptr.charAt(i))) continue; if (iptr.charAt(i) == '_') continue; iptr.setCharAt(i, '_'); } return iptr.toString(); } /** * convert a string token into a valid EDIF string token (note - NOT re-entrant coding) * In order to use NSC program ce2verilog, we need to suppress the '_' which replaces * ']' in bus definitions. */ private String makeToken(String str) { if (str.length() == 0) return str; StringBuffer sb = new StringBuffer(); if (TextUtils.isDigit(str.charAt(0))) sb.append('X'); for(int i=0; i<str.length(); i++) { char chr = str.charAt(i); if (Character.isWhitespace(chr)) break; if (chr == '[' || chr == '<') chr = '_'; if (TextUtils.isLetterOrDigit(chr) || chr == '&' || chr == '_') sb.append(chr); } return sb.toString(); } /****************************** GRAPHIC OUTPUT METHODS ******************************/ /** * Method to output all graphic objects of a symbol. */ private void writeSymbol(Cell cell) { if (cell == null) return; if (!cell.isIcon()) cell = cell.iconView(); if (cell == null) return; blockOpen("symbol"); egraphic_override = EGWIRE; egraphic = EGUNKNOWN; for(Iterator<PortProto> it = cell.getPorts(); it.hasNext(); ) { Export e = (Export)it.next(); writePortImplementation(e, true); } egraphic_override = EGUNKNOWN; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); writeSymbolCell(ni, GenMath.MATID); } for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -