📄 generatevhdl.java
字号:
for(Iterator<Export> it = subCell.getExports(); it.hasNext(); ) { Export e = it.next(); if (!matchesPass(e.getCharacteristic(), pass)) continue; int exportWidth = subNL.getBusWidth(e); for(int i=0; i<exportWidth; i++) { Network net = nl.getNetwork(no, e, i); // get connection boolean portNamed = false; for(Iterator<Connection> cIt = no.getNodeInst().getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); PortProto otherPP = con.getPortInst().getPortProto(); if (otherPP instanceof Export) otherPP = ((Export)otherPP).getEquivalent(); if (otherPP == e) { ArcInst ai = con.getArc(); if (ai.getProto().getFunction() != ArcProto.Function.NONELEC) { if (con.isNegated()) { Integer index; if (con.getEndIndex() == ArcInst.HEADEND) index = negatedHeads.get(ai); else index = negatedTails.get(ai); if (index != null) { if (first) infstr.append(", "); first = true; String sigName = "PINV" + index.intValue(); infstr.append(sigName); continue; } } } break; } } if (portNamed) continue; // write connection String sigName = addString(net.getName(), null); if (!net.getExports().hasNext() && !net.getArcs().hasNext()) sigName = "open"; if (first) infstr.append(", "); first = true; infstr.append(sigName); } } } return infstr.toString(); } /** * Method to write actual signals that connect to a primitive instance. * @param no the primitive node. * @param special a code describing special features of the primitive. * @param negatedHeads map of arcs with negated head ends. * @param negatedTails map of arcs with negated tail ends. * @param nl the Netlist for the Cell containing the instance. * @return a string with the connection signals. */ private String addRealPortsPrim(Nodable no, int special, Map<ArcInst,Integer> negatedHeads, Map<ArcInst,Integer> negatedTails, Netlist nl) { NodeProto np = no.getProto(); boolean first = false; StringBuffer infstr = new StringBuffer(); for(int pass = 0; pass < 5; pass++) { for(Iterator<PortProto> it = np.getPorts(); it.hasNext(); ) { PortProto pp = it.next(); // ignore the bias port of 4-port transistors if (np == Schematics.tech().transistor4Node) { if (pp.getName().equals("b")) continue; } if (!matchesPass(pp.getCharacteristic(), pass)) continue; if (special == BLOCKMOSTRAN) { // ignore electrically connected ports boolean connected = false; for(Iterator<PortProto> oIt = np.getPorts(); oIt.hasNext(); ) { PrimitivePort oPp = (PrimitivePort)oIt.next(); if (oPp == pp) break; if (oPp.getTopology() == ((PrimitivePort)pp).getTopology()) { connected = true; break; } } if (connected) continue; } if (special == BLOCKPOSLOGIC || special == BLOCKBUFFER || special == BLOCKINVERTER || special == BLOCKNAND || special == BLOCKNOR || special == BLOCKXNOR) { // ignore ports not named "a" or "y" if (!pp.getName().equals("a") && !pp.getName().equals("y")) continue; } if (special == BLOCKFLOPTS || special == BLOCKFLOPDS) { // ignore ports not named "i1", "ck", "preset", or "q" if (!pp.getName().equals("i1") && !pp.getName().equals("ck") && !pp.getName().equals("preset") && !pp.getName().equals("q")) continue; } if (special == BLOCKFLOPTR || special == BLOCKFLOPDR) { // ignore ports not named "i1", "ck", "clear", or "q" if (!pp.getName().equals("i1") && !pp.getName().equals("ck") && !pp.getName().equals("clear") && !pp.getName().equals("q")) continue; } // if multiple connections, get them all if (pp.getBasePort().isIsolated()) { for(Iterator<Connection> cIt = no.getNodeInst().getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); if (con.getPortInst().getPortProto() != pp) continue; ArcInst ai = con.getArc(); ArcProto.Function fun = ai.getProto().getFunction(); if (fun == ArcProto.Function.NONELEC) continue; String sigName = "open"; Network net = nl.getNetwork(ai, 0); if (net != null) sigName = addString(net.describe(false), no.getParent()); if (con.isNegated()) { Integer index; if (con.getEndIndex() == ArcInst.HEADEND) index = negatedHeads.get(ai); else index = negatedTails.get(ai); if (index != null) sigName = "PINV" + index.intValue(); } if (first) infstr.append(", "); first = true; infstr.append(sigName); } continue; } // get connection boolean portNamed = false; for(Iterator<Connection> cIt = no.getNodeInst().getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); PortProto otherPP = con.getPortInst().getPortProto(); if (otherPP instanceof Export) otherPP = ((Export)otherPP).getEquivalent(); boolean aka = false; if (otherPP instanceof PrimitivePort && pp instanceof PrimitivePort) { if (((PrimitivePort)otherPP).getTopology() == ((PrimitivePort)pp).getTopology()) aka = true; } if (otherPP == pp || aka) { ArcInst ai = con.getArc(); if (ai.getProto().getFunction() != ArcProto.Function.NONELEC) { if (con.isNegated()) { Integer index; if (con.getEndIndex() == ArcInst.HEADEND) index = negatedHeads.get(ai); else index = negatedTails.get(ai); if (index != null) { if (first) infstr.append(", "); first = true; String sigName = "PINV" + index.intValue(); infstr.append(sigName); continue; } } int wid = nl.getBusWidth(ai); for(int i=0; i<wid; i++) { if (first) infstr.append(", "); first = true; Network subNet = nl.getNetwork(ai, i); String subNetName = getOneNetworkName(subNet); String sigName = addString(subNetName, no.getParent()); infstr.append(sigName); } portNamed = true; } break; } } if (portNamed) continue; for(Iterator<Export> eIt = no.getNodeInst().getExports(); eIt.hasNext(); ) { Export e = eIt.next(); PortProto otherPP = e.getOriginalPort().getPortProto(); if (otherPP instanceof Export) otherPP = ((Export)otherPP).getEquivalent(); if (otherPP == pp) { int wid = nl.getBusWidth(e); for(int i=0; i<wid; i++) { if (first) infstr.append(", "); first = true; Network subNet = nl.getNetwork(e, i); String subNetName = getOneNetworkName(subNet); infstr.append(addString(subNetName, no.getParent())); } portNamed = true; break; } } if (portNamed) continue; // port is not connected or an export if (first) infstr.append(", "); first = true; infstr.append("open"); } } return infstr.toString(); } /** * Method to return a list of signals connected to a primitive. * @param no the primitive Nodable being written. * @param special special situation for that Nodable. * If "special" is BLOCKPOSLOGIC, BLOCKBUFFER or BLOCKINVERTER, only include input port "a" and output port "y". * If "special" is BLOCKFLOPTS or BLOCKFLOPDS, only include input ports "i1", "ck", "preset" and output port "q". * If "special" is BLOCKFLOPTR or BLOCKFLOPDR, only include input ports "i1", "ck", "clear" and output port "q". */ private String addPortListPrim(Nodable no, int special) { // emit special flip-flop ports if (special == BLOCKFLOPTS || special == BLOCKFLOPDS) return "i1, ck, preset: in BIT; q: out BIT"; if (special == BLOCKFLOPTR || special == BLOCKFLOPDR) return "i1, ck, clear: in BIT; q: out BIT"; String before = ""; StringBuffer infstr = new StringBuffer(); PrimitiveNode pnp = (PrimitiveNode)no.getProto(); for(int pass = 0; pass < 5; pass++) { boolean didsome = false; for(Iterator<PrimitivePort> it = pnp.getPrimitivePorts(); it.hasNext(); ) { PrimitivePort pp = it.next(); if (!matchesPass(pp.getCharacteristic(), pass)) continue; String portName = pp.getName(); if (special == BLOCKPOSLOGIC || special == BLOCKBUFFER || special == BLOCKINVERTER) { // ignore ports not named "a" or "y" if (!portName.equals("a") && !portName.equals("y")) continue; } if (pp.getBasePort().isIsolated()) { int inst = 1; for(Iterator<Connection> cIt = no.getNodeInst().getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); if (con.getPortInst().getPortProto() != pp) continue; infstr.append(before); before = ", "; String exportName = addString(portName, null) + (inst++); infstr.append(exportName); } } else { infstr.append(before); before = ", "; infstr.append(addString(portName, null)); } didsome = true; } if (didsome) { if (pass == 0) { infstr.append(": in BIT"); } else if (pass == 1 || pass == 2 || pass == 3) { infstr.append(": out BIT"); } else { infstr.append(": inout BIT"); } before = "; "; } } return infstr.toString(); } /** * Method to construct a list of export names for a cell. * @param cni the cell information. * @return a list of export names for the Cell. */ private String addPortList(CellNetInfo cni) { String before = ""; StringBuffer infstr = new StringBuffer(); for(int pass = 0; pass < 5; pass++) { boolean didsome = false; for(Iterator<CellSignal> it = cni.getCellSignals(); it.hasNext(); ) { CellSignal cs = it.next(); Export e = cs.getExport(); if (e == null) continue; if (!matchesPass(e.getCharacteristic(), pass)) continue; infstr.append(before); before = ", "; infstr.append(addString(cs.getName(), null)); didsome = true; } if (didsome) { if (pass == 0) { infstr.append(": in BIT"); } else if (pass == 1 || pass == 2 || pass == 3) { infstr.append(": out BIT"); } else { infstr.append(": inout BIT"); } before = "; "; } } return infstr.toString(); } /****************************** SUPPORT ******************************/ /** * Method to determine whether a type of export goes in a particular pass of output. * Ports are written in 5 passes: input, output, power, ground, and everything else. * @param ch the PortCharacteristic of the port. * @param pass the pass number (0-4). * @return true of the given type of port goes in the given pass. */ private boolean matchesPass(PortCharacteristic ch, int pass) { switch (pass) { case 0: // must be an input port return ch == PortCharacteristic.IN; case 1: // must be an output port return ch == PortCharacteristic.OUT; case 2: // must be a power port return ch == PortCharacteristic.PWR; case 3: // must be a ground port return ch == PortCharacteristic.GND; } return ch != PortCharacteristic.IN && ch != PortCharacteristic.OUT && ch != PortCharacteristic.PWR && ch != PortCharacteristic.GND; } /** * Method to return a single name for a Network. * Choose the first if there are more than one. * @param net the Network to name. * @return the name of the Network. */ private String getOneNetworkName(Network net) { Iterator<String> nIt = net.getNames(); if (nIt.hasNext()) return nIt.next(); return net.describe(false); } /** * Class to determine the VHDL name and special factors for a node. */ private static class AnalyzePrimitive { private String primName; private int special; /** * Method to get the name of this analyzed primitive node. * @return the name of this analyzed primitive node. */ private String getPrimName() { return primName; } /** * Method to return the special code for this analyzed primitive node: * @return the special code for the analyzed primitive node:<BR> * BLOCKNORMAL: no special port arrangements necessary.<BR> * BLOCKMOSTRAN: only output ports that are not electrically connected.<BR> * BLOCKBUFFER: only include input port "a" and output port "y".<BR> * BLOCKPOSLOGIC: only include input port "a" and output port "y".<BR> * BLOCKINVERTER: only include input port "a" and output port "y".<BR> * BLOCKNAND: only include input port "a" and output port "y".<BR> * BLOCKNOR: only include input port "a" and output port "y".<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -