📄 verilog.java
字号:
// use "assign" statement if requested if (Simulation.getVerilogUseAssign()) { if (nodeType == PrimitiveNode.Function.GATEAND || nodeType == PrimitiveNode.Function.GATEOR || nodeType == PrimitiveNode.Function.GATEXOR || nodeType == PrimitiveNode.Function.BUFFER) { // assign possible: determine operator String op = ""; if (nodeType == PrimitiveNode.Function.GATEAND) op = " & "; else if (nodeType == PrimitiveNode.Function.GATEOR) op = " | "; else if (nodeType == PrimitiveNode.Function.GATEXOR) op = " ^ "; // write a line describing this signal StringBuffer infstr = new StringBuffer(); boolean wholeNegated = false; first = true; NodeInst ni = (NodeInst)no; for(int i=0; i<2; i++) { for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); PortInst pi = con.getPortInst(); if (i == 0) { if (!pi.getPortProto().getName().equals("y")) continue; } else { if (!pi.getPortProto().getName().equals("a")) continue; } // determine the network name at this port ArcInst ai = con.getArc(); Network net = netList.getNetwork(ai, 0); CellSignal cs = cni.getCellSignal(net); String sigName = getSignalName(cs); // see if this end is negated boolean isNegated = false; if (ai.isTailNegated() || ai.isHeadNegated()) isNegated = true; // write the port name if (i == 0) { // got the output port: do the left-side of the "assign" infstr.append("assign " + sigName + " = "); if (isNegated) { infstr.append("~("); wholeNegated = true; } break; } if (!first) infstr.append(op); first = false; if (isNegated) infstr.append("~"); infstr.append(sigName); } } if (wholeNegated) infstr.append(")"); infstr.append(";\n"); writeWidthLimited(infstr.toString()); continue; } } // get the name of the node int implicitPorts = 0; boolean dropBias = false; String nodeName = ""; if (no.isCellInstance()) { // make sure there are contents for this cell instance if (((Cell)niProto).isIcon()) continue; nodeName = parameterizedName(no, context); // cells defined as "primitives" in Verilog View must have implicit port ordering if (definedPrimitives.containsKey(niProto)) { implicitPorts = 3; } } else { // convert 4-port transistors to 3-port PrimitiveNode.Function threePortEquiv = nodeType.make3PortTransistor(); if (threePortEquiv != null) { nodeType = threePortEquiv; dropBias = true; } if (nodeType.isNTypeTransistor()) { implicitPorts = 2; nodeName = "tranif1"; Variable varWeakNode = ((NodeInst)no).getVar(Simulation.WEAK_NODE_KEY); if (varWeakNode != null) nodeName = "rtranif1"; } else if (nodeType.isPTypeTransistor()) { implicitPorts = 2; nodeName = "tranif0"; Variable varWeakNode = ((NodeInst)no).getVar(Simulation.WEAK_NODE_KEY); if (varWeakNode != null) nodeName = "rtranif0"; } else if (nodeType == PrimitiveNode.Function.GATEAND) { implicitPorts = 1; nodeName = chooseNodeName((NodeInst)no, "and", "nand"); } else if (nodeType == PrimitiveNode.Function.GATEOR) { implicitPorts = 1; nodeName = chooseNodeName((NodeInst)no, "or", "nor"); } else if (nodeType == PrimitiveNode.Function.GATEXOR) { implicitPorts = 1; nodeName = chooseNodeName((NodeInst)no, "xor", "xnor"); } else if (nodeType == PrimitiveNode.Function.BUFFER) { implicitPorts = 1; nodeName = chooseNodeName((NodeInst)no, "buf", "not"); } } if (nodeName.length() == 0) continue; // write the type of the node StringBuffer infstr = new StringBuffer(); infstr.append(" " + nodeName + " " + nameNoIndices(no.getName()) + "("); // write the rest of the ports first = true; NodeInst ni = null; switch (implicitPorts) { case 0: // explicit ports (for cell instances) CellNetInfo subCni = getCellNetInfo(nodeName); for(Iterator<CellAggregateSignal> sIt = subCni.getCellAggregateSignals(); sIt.hasNext(); ) { CellAggregateSignal cas = sIt.next(); // ignore networks that aren't exported PortProto pp = cas.getExport(); if (pp == null) continue; if (first) first = false; else infstr.append(", "); if (cas.getLowIndex() > cas.getHighIndex()) { // single signal infstr.append("." + cas.getName() + "("); Network net = netList.getNetwork(no, pp, cas.getExportIndex()); CellSignal cs = cni.getCellSignal(net); infstr.append(getSignalName(cs)); infstr.append(")"); accumulatePortConnectivity(instancePortsOnNet, net, (Export)pp); } else { int [] indices = cas.getIndices(); if (indices != null) { // broken bus internally, write signals individually for(int i=0; i<indices.length; i++) { CellSignal cInnerSig = cas.getSignal(i); Network net = netList.getNetwork(no, cas.getExport(), cInnerSig.getExportIndex()); CellSignal outerSignal = cni.getCellSignal(net); accumulatePortConnectivity(instancePortsOnNet, net, (Export)pp); int ind = i; if (cas.isDescending()) ind = indices.length - i - 1; if (i > 0) infstr.append(", "); infstr.append(".\\" + cas.getName() + "[" + indices[ind] + "] ("); infstr.append(getSignalName(outerSignal)); infstr.append(")"); } } else { // simple bus, write signals int total = cas.getNumSignals(); CellSignal [] outerSignalList = new CellSignal[total]; for(int j=0; j<total; j++) { CellSignal cInnerSig = cas.getSignal(j); Network net = netList.getNetwork(no, cas.getExport(), cInnerSig.getExportIndex()); outerSignalList[j] = cni.getCellSignal(net); accumulatePortConnectivity(instancePortsOnNet, net, (Export)pp); } writeBus(outerSignalList, total, cas.isDescending(), cas.getName(), cni.getPowerNet(), cni.getGroundNet(), infstr); } } } infstr.append(");"); break; case 1: // and/or gate: write ports in the proper order ni = (NodeInst)no; for(int i=0; i<2; i++) { for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); PortInst pi = con.getPortInst(); if (i == 0) { if (!pi.getPortProto().getName().equals("y")) continue; } else { if (!pi.getPortProto().getName().equals("a")) continue; } if (first) first = false; else infstr.append(", "); ArcInst ai = con.getArc(); Network net = netList.getNetwork(ai, 0); CellSignal cs = cni.getCellSignal(net); if (cs == null) continue; String sigName = getSignalName(cs); if (i != 0 && con.isNegated()) { // this input is negated: write the implicit inverter Integer invIndex; if (con.getEndIndex() == ArcInst.HEADEND) invIndex = implicitHeadInverters.get(ai); else invIndex = implicitTailInverters.get(ai); if (invIndex != null) { String invSigName = IMPLICITINVERTERSIGNAME + invIndex.intValue(); printWriter.println(" inv " + IMPLICITINVERTERNODENAME + invIndex.intValue() + " (" + invSigName + ", " + sigName + ");"); sigName = invSigName; } } infstr.append(sigName); } } infstr.append(");"); break; case 2: // transistors: write ports in the proper order: s/d/g ni = (NodeInst)no; Network gateNet = netList.getNetwork(ni.getTransistorGatePort()); for(int i=0; i<2; i++) { boolean didGate = false; for(Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext(); ) { PortInst pi = pIt.next(); Network net = netList.getNetwork(pi); if (dropBias && pi.getPortProto().getName().equals("b")) continue; CellSignal cs = cni.getCellSignal(net); if (cs == null) continue; if (i == 0) { if (net == gateNet) continue; } else { if (net != gateNet) continue; if (didGate) continue; didGate = true; } if (first) first = false; else infstr.append(", "); String sigName = getSignalName(cs); infstr.append(sigName); } } infstr.append(");"); break; case 3: // implicit ports ordering for cells defined as primitives in Verilog View ni = no.getNodeInst(); VerilogData.VerilogModule module = definedPrimitives.get(niProto); if (module == null) break; System.out.print(cell.getName()+" ports: "); for (VerilogData.VerilogPort port : module.getPorts()) { List<String> portnames = port.getPinNames(true); if (portnames.size() == 0) { // continue } else if (portnames.size() > 1) { // Bill thinks bussed ports are not allowed for primitives System.out.println("Error: bussed ports not allowed on Verilog primitives: "+niProto.getName()); } else { String portname = portnames.get(0); PortInst pi = ni.findPortInst(portname); Network net = netList.getNetwork(no, pi.getProtoEquivalent(), 0); CellSignal cs = cni.getCellSignal(net); String sigName = getSignalName(cs); if (first) first = false; else infstr.append(", "); infstr.append(sigName); System.out.print(portname+" "); } } System.out.println(); infstr.append(");"); break; } infstr.append("\n"); writeWidthLimited(infstr.toString()); } printWriter.println("endmodule /* " + cni.getParameterizedName() + " */"); // check export direction consistency (inconsistent directions can cause opens in some tools) for (Iterator<Export> it = cell.getExports(); it.hasNext(); ) { Export ex = it.next(); PortCharacteristic type = ex.getCharacteristic(); if (type == PortCharacteristic.BIDIR) continue; // whatever it is connect to is fine for (int i=0; i<ex.getNameKey().busWidth(); i++) { Network net = netList.getNetwork(ex, i); List<Export> subports = instancePortsOnNet.get(net); if (subports == null) continue; for (Export subex : subports) { PortCharacteristic subtype = subex.getCharacteristic(); if (type != subtype) { System.out.println("Warning: Port Direction Inconsistency in cell "+cell.describe(false)+ " between export "+ex.getNameKey().subname(i)+" ("+type+") and instance port "+ subex.getParent().noLibDescribe()+" - "+subex.getName()+" ("+subtype+")"); } } } } } private String getSignalName(CellSignal cs) { CellAggregateSignal cas = cs.getAggregateSignal(); if (cas == null) return cs.getName(); if (cas.getIndices() == null) return cs.getName(); return " \\" + cs.getName() + " "; } private String chooseNodeName(NodeInst ni, String positive, String negative) { for(Iterator<Connection> aIt = ni.getConnections(); aIt.hasNext(); ) { Connection con = aIt.next(); if (con.isNegated() && con.getPortInst().getPortProto().getName().equals("y")) return negative; } return positive; } private void writeTemplate(String line, Nodable no, CellNetInfo cni, VarContext context) { // special case for Verilog templates Netlist netList = cni.getNetList(); StringBuffer infstr = new StringBuffer(); infstr.append(" "); for(int pt = 0; pt < line.length(); pt++) { char chr = line.charAt(pt); if (chr != '$' || pt+1 >= line.length() || line.charAt(pt+1) != '(') { // process normal character infstr.append(chr); continue; } int startpt = pt + 2; for(pt = startpt; pt < line.length(); pt++) if (line.charAt(pt) == ')') break; String paramName = line.substring(startpt, pt); PortProto pp = no.getProto().findPortProto(paramName); String nodeName = parameterizedName(no, context); CellNetInfo subCni = getCellNetInfo(nodeName); // see if aggregate signal matches pp CellAggregateSignal cas = null; CellSignal netcs = null; if (pp != null) { // it matches the whole port (may be a bussed port) for (Iterator<CellAggregateSignal> it = subCni.getCellAggregateSignals(); it.hasNext(); ) { CellAggregateSignal cas2 = it.next(); if (cas2.getExport() == pp) { cas = cas2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -