📄 tegas.java
字号:
// Buffer primitive has a "c" port not used by TDL if (fun == PrimitiveNode.Function.BUFFER && pp.getName().equals("c")) continue; boolean portWired = false; for(Iterator<Connection> aIt = ni.getConnections(); aIt.hasNext(); ) { Connection con = aIt.next(); if (con.getPortInst().getPortProto() == pp) { if (first) first = false; else infstr.append(","); infstr.append(getInvertedConnectionName(con)); portWired = true; // if port is not isolated then write one signal only if (!pp.isIsolated()) break; } } if (!portWired) { System.out.println("UNWIRED PORT " + pp.getName()); if (first) first = false; else infstr.append(","); infstr.append("NC"); } } } infstr.append(")"); String result = infstr.toString(); return result; } /** * Method to write the input signals for flip flops. * @param ni the flip-flop NodeInst to convert. * @return the input signals for the flip-flop. */ private String getFlipFlopInputSignals(NodeInst ni) { String [] signals = new String[5]; int x = 0; for(Iterator<PortProto> it = ni.getProto().getPorts(); it.hasNext(); ) { PortProto pp = it.next(); if (pp.getCharacteristic() == PortCharacteristic.OUT) continue; String ptr = "NC"; // if no-connection write NC for(Iterator<Connection> pIt = ni.getConnections(); pIt.hasNext(); ) { Connection con = pIt.next(); if (con.getPortInst().getPortProto() == pp) { ptr = getInvertedConnectionName(con); break; } } for(Iterator<Export> eIt = ni.getExports(); eIt.hasNext(); ) { Export e = eIt.next(); if (e.getOriginalPort().getPortProto() == pp) { ptr = convertName(e.getName()); break; } } if (x >= 5) break; signals[x++] = ptr; } // We now have the signals in 5 arrays ready to be output in the correct // order which is 2,0,1,3,4.If the flip flop is a D or T type don't put // out array[1][]. StringBuffer infstr = new StringBuffer(); infstr.append("(" + signals[2] + "," + signals[0]); // JK and SR have one input more than D or T flip flops PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.FLIPFLOPRSMS || fun == PrimitiveNode.Function.FLIPFLOPRSP || fun == PrimitiveNode.Function.FLIPFLOPRSN || fun == PrimitiveNode.Function.FLIPFLOPJKMS || fun == PrimitiveNode.Function.FLIPFLOPJKP || fun == PrimitiveNode.Function.FLIPFLOPJKN) { infstr.append("," + signals[1]); } infstr.append("," + signals[3] + "," + signals[4] + ")"); return infstr.toString(); } /****************************** HELPER METHODS ******************************/ /** * Method to determine whether a nodeinst has an output arc that is negated. * @param ni the NodeInst that may be negated. * @return true if the NodeInst is negated (its output is negated). */ private boolean isNegatedNode(NodeInst ni) { for(Iterator<Connection> it = ni.getConnections(); it.hasNext(); ) { Connection con = it.next(); PortInst pi = con.getPortInst(); PortProto pp = pi.getPortProto(); if (pp.getCharacteristic() != PortCharacteristic.OUT) continue; if (con.isNegated()) return true; } return false; } /** * Method to return the TDL delay on a Nodable. * @param no the Nodable to get delay information on. * @return the node delay. If no delay information is on the node, * returns the default: "/1,1/". */ private String getGateDelay(Nodable no) { if (no.isCellInstance()) return ""; NodeInst ni = (NodeInst)no; Variable var = ni.getVar(Simulation.RISE_DELAY_KEY); String str1 = "/1,"; if (var != null) str1 = "/" + var.getPureValue(-1) + ","; var = ni.getVar(Simulation.FALL_DELAY_KEY); String str2 = "/1,"; if (var != null) str2 = "/" + var.getPureValue(-1) + ","; return str1 + str2; } private int getGateWidth(NodeInst ni) { int inputs = 0; for(Iterator<Connection> iIt = ni.getConnections(); iIt.hasNext(); ) { Connection con = iIt.next(); if (con.getPortInst().getPortProto().getCharacteristic() == PortCharacteristic.IN) inputs++; } if (inputs < 2) System.out.println("MUST HAVE AT LEAST TWO INPUTS ON " + ni); return inputs; } private String getGateName(NodeInst ni) { // Determine whether node should be NAND, NOR or NXOR boolean negated = false; if (isNegatedNode(ni)) negated = true; // Write USE description for current node PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.GATEAND) { if (negated) return "NAND"; return "AND"; } if (fun == PrimitiveNode.Function.GATEOR) { if (negated) return "NOR"; return "OR"; } if (fun == PrimitiveNode.Function.GATEXOR) { if (negated) return "NXOR"; return "XOR"; } return ""; } /** * Method to write out an inverter description for a negated Connection. * @param con the Connection that is inverted. * @param str1 the output signal name. * @param str2 the input signal name. */ private void writeInverter(Connection con, String str1, String str2) { Integer index = implicitInverters.get(con.getArc()); if (index == null) return; writeWidthLimited("I" + index + "(" + convertName(str1) + ") = NOT(" + convertName(str2) + ");\n"); implicitInverters.remove(con.getArc()); // write once only } /** * Method to return the name of a Power/Ground node. * @param ni the Power/Ground node. * @return the node name (returns an empty string if not applicable). */ private String getNameOfPower(NodeInst ni) { // To prevent Un-connected power nodes if (!ni.hasConnections())// if (ni.getNumConnections() == 0) { System.out.println("PWR / GND NODE UNCONNECTED"); return ""; } PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.CONGROUND || fun == PrimitiveNode.Function.CONPOWER) { if (ni.hasConnections())// if (ni.getNumConnections() > 0) { Connection con = ni.getConnections().next(); Network net = netList.getNetwork(con.getArc(), 0); String decl = net.describe(false) + " = "; if (fun == PrimitiveNode.Function.CONPOWER) decl += "PWR"; else decl += "GRND"; return decl + ";\n"; } } return ""; } /** * Method to return the name of the network on a given Connection. * @param con the Connection to name. * @return the name of that network. */ private String getConnectionName(Connection con) { Network net = netList.getNetwork(con.getArc(), 0); if (net != null) return convertName(net.describe(false)); return "???"; } /** * Method to return the name of the signal on a Connection. * @param con the Connection to name. * @return the name of the Connection network. * Also emits an implicit inverter if there is one. */ private String getInvertedConnectionName(Connection con) { String conName = getConnectionName(con); ArcInst ai = con.getArc(); if (!con.isNegated()) return conName; // insert an inverter description if a negated arc attached to primitive // other than AND,OR,XOR Integer index = implicitInverters.get(ai); if (index != null) { String str = "I" + index + ".O"; writeInverter(con, str, conName); return str; } return conName; } private PrimitiveNode.Function getNodableFunction(Nodable no) { PrimitiveNode.Function fun = PrimitiveNode.Function.UNKNOWN; if (!no.isCellInstance()) { NodeInst ni = (NodeInst)no; fun = ni.getFunction(); } return fun; } /** * Method to return the TDL name of a Nodable. * @param no the Nodable to report. * @return the name of that Nodable. */ private String getNodeProtoName(Nodable no) { if (no.isCellInstance()) { return convertName(no.getProto().describe(false)); } NodeInst ni = (NodeInst)no; PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.GATEAND || fun == PrimitiveNode.Function.GATEOR || fun == PrimitiveNode.Function.GATEXOR) { return getGateWidth(ni) + "-" + getGateName(ni); } if (fun == PrimitiveNode.Function.BUFFER) { if (isNegatedNode(ni)) return "NOT"; return "DELAY"; } if (fun.isFlipFlop()) return getFlipFlopName(ni); if (fun == PrimitiveNode.Function.TRANS) return "BDSWITCH"; return ""; } /** * Method to limit a string to the max 12 chars and in upper case for TDL. * @param str a name. * @return the name in upper case and limited to 12 characters. */ private String convertName(String str) { if (str.length() > MAXNAMECHARS) str = str.substring(0, MAXNAMECHARS); return str.toUpperCase(); } /** * Method to return the library name to use, given a cell. * @param cell the Cell whose library is desired. * @return the library name of the cell. */ String getLibraryName(Cell cell) { return convertName(cell.getLibrary().getName()); } /** * Method to return the TDL primitive name of a flip-flop. * @param ni the NodeInst that is a flip-flop. * @return the proper TDL name for that type of flip-flop. */ private String getFlipFlopName(NodeInst ni) { PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.FLIPFLOPRSMS) return "SRMNE"; if (fun == PrimitiveNode.Function.FLIPFLOPRSP) return "SREPE"; if (fun == PrimitiveNode.Function.FLIPFLOPRSN) return "SRENE"; if (fun == PrimitiveNode.Function.FLIPFLOPJKMS) return "JKMNE"; if (fun == PrimitiveNode.Function.FLIPFLOPJKP) return "JKEPE"; if (fun == PrimitiveNode.Function.FLIPFLOPJKN) return "JKENE"; if (fun == PrimitiveNode.Function.FLIPFLOPDMS) return "DMNE"; if (fun == PrimitiveNode.Function.FLIPFLOPDP) return "DEPE"; if (fun == PrimitiveNode.Function.FLIPFLOPDN) return "DENE"; if (fun == PrimitiveNode.Function.FLIPFLOPTP || fun == PrimitiveNode.Function.FLIPFLOPTN) System.out.println("T TYPE FLIP-FLOP MUST BE MS"); return "TMNE"; } private List<String> reservedWords = null; /** * Method that takes a string of max length 12 and checks to see if it is a reserved word. * @param str the name to check. * @return true if the word is reserved. * Returns false if the word is not reserved. */ private boolean isReservedWord(String str) { if (reservedWords == null) { reservedWords = new ArrayList<String>(); try { File f = new File(User.getWorkingDirectory() + File.separator + "reservedwords.dat"); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); for(;;) { String line = br.readLine(); if (line == null) break; reservedWords.add(line); } br.close(); fr.close(); } catch (IOException e) { return false; } } if (str.length() < 2) return false; for(String match : reservedWords) { if (match.startsWith(str)) return true; } return false; } /****************************** SUBCLASSED METHODS FOR THE TOPOLOGY ANALYZER ******************************/ /** * Method to adjust a cell name to be safe for Tegas output. * @param name the cell name. * @return the name, adjusted for Tegas output. */ protected String getSafeCellName(String name) { return name; } /** Method to return the proper name of Power */ protected String getPowerName(Network net) { return ".VDD"; } /** Method to return the proper name of Ground */ protected String getGroundName(Network net) { return "GRND"; } /** Method to return the proper name of a Global signal */ protected String getGlobalName(Global glob) { return glob.getName(); } /** Method to report that export names DO take precedence over * arc names when determining the name of the network. */ protected boolean isNetworksUseExportedNames() { return true; } /** Method to report that library names ARE always prepended to cell names. */ protected boolean isLibraryNameAlwaysAddedToCellName() { return false; } /** Method to report that aggregate names (busses) ARE used. */ protected boolean isAggregateNamesSupported() { return false; } /** Abstract method to decide whether aggregate names (busses) can have gaps in their ranges. */ protected boolean isAggregateNameGapsSupported() { return false; } /** Method to report whether input and output names are separated. */ protected boolean isSeparateInputAndOutput() { return true; } /** Abstract method to decide whether netlister is case-sensitive (Verilog) or not (Spice). */ protected boolean isCaseSensitive() { return true; } /** * Method to adjust a network name to be safe for Tegas output. */ protected String getSafeNetName(String name, boolean bus) { return name; } /** Tell the Hierarchy enumerator how to short resistors */ @Override protected Netlist.ShortResistors getShortResistors() { return Netlist.ShortResistors.ALL; } /** * Method to tell whether the topological analysis should mangle cell names that are parameterized. */ protected boolean canParameterizeNames() { return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -