📄 scanchainxml.java
字号:
} /** * A subchain is exactly like a chain, except that it must be part of * a chain, and cannot stand alone. */ private static class SubChain extends Chain { private boolean passThrough; private SubChain(String name, int length, String access, String clears, DataNet dataNet, DataNet dataNet2) { super(name, -1, length, access, clears, dataNet, dataNet2); passThrough = false; } private SubChain(String name, int length) { super(name, -1, length); } protected String getTag() { return "subchain"; } private void setPassThrough(boolean b) { passThrough = b; } private boolean isPassThrough() { return passThrough; } /** * Get the last subchain in this chain * @return */ protected SubChain getLastSubChain() { if (getSubChainSize() == 0) { return this; } return super.getLastSubChain(); } public Object clone() { SubChain sub = new SubChain(name, length, access, clears, dataNet, dataNet2); this.copyTo(sub); sub.passThrough = passThrough; return sub; } } /** * An entity is a SubChain that associate with a cell, and contains * the scan chain elements for that cell. This is unlike a subchain, * which may simply be a single scan element, or a group of scan elements. * Entities also serve as caching mechanisms, and define the chain for a cell. */ private static class Entity extends SubChain { private static final String deftag = "!ENTITY"; private Cell cell; private ExPort inExport; private ExPort outExport; private Entity(Cell cell) { super(cell.getLibrary().getName()+"_"+cell.getName(), -1); this.cell = cell; } private void setInExPort(ExPort port) { this.inExport = port; }// private ExPort getInExPort() { return inExport; } private void setOutExPort(ExPort port) { this.outExport = port; } private ExPort getOutExPort() { return outExport; } protected void writeDefinition(PrintWriter out, StringBuffer indent, Map<Cell,Cell> cellsToFlatten) { if (FLAT) return; // don't write a definition if (numScanElements() < 3 || getSubChainSize() == 0) return; out.println(indent+"<"+deftag+" "+getKey()+" '"); indent.append("\t"); for (Iterator<SubChainInst> it = getSubChainInsts(); it.hasNext(); ) { SubChainInst inst = it.next(); SubChain subChain = inst.getSubChain(); subChain.write(out, indent, inst.getName(), cellsToFlatten); } indent.setLength(indent.length() - 1); out.println(indent+"'>"); } protected void write(PrintWriter out, StringBuffer indent, String instName, Map<Cell,Cell> cellsToFlatten) { if (FLAT) { super.write(out, indent, instName, cellsToFlatten); return; } if (numScanElements() < 3 || getSubChainSize() == 0) { super.write(out, indent, instName, cellsToFlatten); } else { //super.write(out, indent); out.println(indent+"<subchain name=\""+instName+"\"> &"+getKey()+"; </subchain>"); } } private Object getKey() { String key = name+"_"+inExport.name.toString(); key = key.replaceAll("[\\[\\]]", "_"); return key; } public Object clone() { Entity ent = new Entity(cell); this.copyTo(ent); ent.inExport = this.inExport; ent.outExport = this.outExport; return ent; } } /** * A Port holds information about a single port, that may be part of a bussed portinst */ private static class Port { private PortProto pp; private int index; private Name name; private Nodable no; private Port(Name name, Nodable no, PortProto pp, int index) { this.name = name; this.no = no; this.pp = pp; this.index = index; } public String toString() { if (name == null) return null; return no.getName() +":"+name.toString(); } public void print() { System.out.println(" Name: "+name); System.out.println(" No: "+no); System.out.println(" int: "+index); System.out.println(" pp: "+pp); } } private static class ExPort { private Export ex; private int index; private Name name; private ExPort(Name name, Export ex, int index) { this.name = name; this.ex = ex; this.index = index; } public String toString() { if (name == null) return null; return name.toString(); } public void print() { System.out.println(" Name: "+name); System.out.println(" Ex: "+ex); System.out.println(" int: "+index); } } // ------------------------------------------------------------------------- private ScanChainElement getScanChainElement(String name, String sin) { ScanChainElement e = scanChainElements.get(name+"_"+sin); return e; } private PassThroughCell getPassThroughCell(String name, String sin) { PassThroughCell p = passThroughCells.get(name+"_"+sin); return p; } // ------------------------------------------------------------------------- // Entry point. Starts building a scan chain // takes care of adding extra hierarchy if start of chain is not at top level. // other methods are top-down only // Hierarchy denoted by Stack, start (jtag controller) node is at the top of the stack (pop'd off first) private SubChainInst startChain(Chain chain, Stack<Nodable> startNode, String startPortName) { // get top nodable if (startNode == null) return null; if (startNode.size() == 0) return null; Nodable no = startNode.remove(0); if (startNode.isEmpty()) { // no is the jtagController, start following the chain Port startPort = getPort(no, startPortName); if (startPort == null) { System.out.println("Can't find specified start port "+startPortName+" on jtag controller "+jtagController.name); return null; } if (DEBUG) System.out.println("Found startNode. Starting chain "+chain.name+" from port "+startPortName); SubChainInst subChainInst = appendChain(chain, getOtherPorts(startPort)); if (subChainInst == null) { // no chains at this level, make dummy with output so next level up can follow export up return new SubChainInst(null, startPort, null, null); } return subChainInst; } // need to descend to get to start of chain SubChain subChain = new SubChain(no.getName(), 0); SubChainInst curInst = new SubChainInst(null, null, no, subChain); chain.addSubChainInst(curInst); if (DEBUG) System.out.println("Recursing from "+no.getParent().describe(true)+" into "+no.getName()+", looking for startNode"); // recurse, call will add inst to chain SubChainInst inst = startChain(subChain, startNode, startPortName); if( inst == null) return null; // continue chain, get export at lower level Port subOutPort = inst.getOutport(); if (subOutPort != null) { ExPort outEx = getExportedPort(subOutPort); // find associated port on nodable at this level for export if (outEx != null) { Port outport = getPort(no, outEx.name.toString()); curInst.setOutport(outport); // continue chain at this level if (DEBUG) System.out.println("Continuing chain in "+no.getParent().describe(true)+" from port "+outport.name); inst = appendChain(chain, getOtherPorts(outport)); if (inst != null) curInst = inst; } } return curInst; } private SubChainInst getSubChain(Port inport) { Nodable no = inport.no; if (DEBUG) System.out.println("getSubChain for NodeInst: "+no.getName()+", sin: "+inport); NodeProto np = no.getProto(); SubChainInst inst; // check if this is a pass through element PassThroughCell p = getPassThroughCell(np.getName(), inport.name.toString()); if (p != null) { // find output port Port outport = getPort(no, p.outport); // make dummy subchain with no length SubChain sub = new SubChain(p.cellName, -1); sub.setPassThrough(true); inst = new SubChainInst(inport, outport, no, sub); if (DEBUG) System.out.println(" ...matched pass through cell "+p.cellName); return inst; } // check if this is a scan chain element if (no.isCellInstance()) { ScanChainElement e = getScanChainElement(np.getName(), inport.name.toString()); if (e != null) { SubChain sub; Port outport; if (no.getNodeInst().getNameKey().isBus()) { // conglomerate into one subchain int size = no.getNodeInst().getNameKey().busWidth(); sub = new SubChain(no.getNodeInst().getName(), size, e.access, e.clears, e.dataport, e.dataport2); //sub = new SubChain(no.getNodeInst().getName(), size, e.access, e.clears, // getScanDataNet(no, e.dataport), getScanDataNet(no, e.dataport2)); Nodable lastNo = Netlist.getNodableFor(no.getNodeInst(), size-1); outport = getPort(lastNo, e.outport); no = no.getNodeInst(); } else { sub = new SubChain(no.getName(), 1, e.access, e.clears, e.dataport, e.dataport2); //sub = new SubChain(no.getName(), 1, e.access, e.clears, // getScanDataNet(no, e.dataport), getScanDataNet(no, e.dataport2)); // find output port outport = getPort(no, e.outport); } inst = new SubChainInst(inport, outport, no, sub); if (DEBUG) System.out.println(" ...matched scan chain element "+e.name); return inst; } // check if this is the jtag controller, which signals the end of the chain if (jtagCell != null && np.getName().equals(jtagCell.getName())) { if (DEBUG) System.out.println(" ...matched end of chain, port "+inport); inst = new SubChainInst(inport, null, no, endChain); return inst; } // otherwise, descend into cell and get subchain (entity) for it Cell sch = ((Cell)np).contentsView(); if (sch == null) sch = (Cell)np; if (DEBUG) System.out.println(" ...descending into "+sch); inst = getSubChain(sch, inport); return inst; } //System.out.println("Error! Scan chain terminated on node "+ni.getName()+" ("+ni.getParent().getName()+")"); return null; }// private DataNet getScanDataNet(Nodable no, DataNet definition) {// if (definition == null) return null;// String name = getNetName(no, definition.net);// return new DataNet(name, definition.options);// } // get the network name connect to port 'portName' on 'no'. Returns null if none found. private String getNetName(Nodable no, String portName) { String netName = null; PortInst pi = no.getNodeInst().findPortInst(portName); if (pi == null) return null; if (pi.hasConnections()) {// if (pi.getConnections().hasNext()) { ArcInst ai = pi.getConnections().next().getArc(); // see if there is a bus name Name busName = no.getParent().getNetlist(SHORT_RESISTORS).getBusName(ai); if (busName == null) { netName = no.getParent().getNetlist(SHORT_RESISTORS).getNetwork(ai, 0).getName(); } else { netName = busName.toString(); } } return netName; } /** * Create the subchain for the cell * @param cell the cell * @param inport the scan data in port on the nodeinst for this cell * @return a new Entity that contains the scan chain for this cell */ private SubChainInst getSubChain(Cell cell, Port inport) { // get the export corresponding to the nodeInst input port Nodable no = inport.no; Export inputEx = cell.findExport(inport.pp.getNameKey()); ExPort schInPort = new ExPort(inport.name, inputEx, inport.index); // look up entity String key = cell.describe(false) + schInPort.name.toString(); Entity ent = entities.get(key); Port outport = null; // if not found, create it now if (ent == null) { // verify that sinport is part of cell if (inputEx == null) { System.out.println("Error! In "+cell+", scan data input Export "+inport.name+" not found."); return null; } ent = new Entity(cell); ent.setInExPort(schInPort); entities.put(key, ent); List<Port> nextPorts = getOtherPorts(schInPort); SubChainInst lastInst = appendChain(ent, nextPorts); if (lastInst != null) { // last inst is instance within cell, find export in cell on same network Port lastOutport = lastInst.getOutport(); if (lastOutport != null) { ExPort outEx = getExportedPort(lastOutport); if (outEx == null) { System.out.println("Error! In "+cell+", last element \""+lastOutport.no.getName()+"\", output port \""+lastOutport+"\""+ " does not connect to another scan element, is not exported from cell, and does not terminate at the JTAG Controller"); } else { ent.setOutExPort(outEx); // get output port on nodeinst corresponding to export outport = getPort(no, outEx.name.toString()); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -