📄 scanchainxml.java
字号:
public void setChipName(String name) { chipName = name; } /** * Set the output file. This may be an absolute or relative path. If this * option is not specified, the output goes to the Electric console. * @param file the name of the file. */ public void setOutput(String file) { // try to open outputFile outputFile = file; try { outFile = new File(outputFile); out = new PrintWriter(new BufferedWriter(new FileWriter(outFile))); } catch (IOException e) { System.out.println(e.getMessage() + "\nWriting XML to console"); } } /** * Start tracing all the scan chains from the any instances of specified * jtag controller */ public void start(String libName, String cellName) { Library lib = Library.findLibrary(libName); if (lib == null) { System.out.println("Did not find library "+libName+" for starting chain analysis in cell "+cellName); return; } Cell cell = lib.findNodeProto(cellName); if (cell == null) { System.out.println("Did not find cell "+cellName+" for starting chain analysis, in library "+libName); return; } Stack<Nodable> startNode = null; if (chainStartExports != null) { for (int i=0; i<chainStartExports.size(); i++) { ExPort startExport = getExPort(cell, chainStartExports.get(i)); if (startExport == null) { System.out.println("Cannot find export "+chainStartExports.get(i)+" in cell "+cell.describe(false)); continue; } chainStartExPorts.add(startExport); } if (jtagController == null) jtagController = new JtagController("", 8); } else { if (jtagCell == null) { return; } startNode = findStartNode(cell, new Stack<Nodable>()); if (startNode == null) { System.out.println("Did not find any usages of the jtag controller: "+jtagCell.getName()); return; } Nodable no = startNode.lastElement(); System.out.println("*** Generating chains starting from jtag controller "+no.getParent().describe(false)+" : "+no.getName()); } start(startNode); if (outFile != null) { System.out.println("Wrote XML file to "+outFile.getAbsolutePath()); } else { System.out.println("Wrote XML file to console"); } } // find the start node. it will be the last nodable in the var context private Stack<Nodable> findStartNode(Cell cell, Stack<Nodable> context) { Netlist netlist = cell.getNetlist(SHORT_RESISTORS); for (Iterator<Nodable> it = netlist.getNodables(); it.hasNext(); ) { Nodable no = it.next(); if (no.getProto().getName().equals(jtagCell.getName())) { context.push(no); return context; } if (no.isCellInstance()) { // descend Cell subCell = (Cell)no.getProto(); subCell = subCell.contentsView(); if (subCell == null) subCell = (Cell)no.getProto(); context.push(no); Stack<Nodable> next = findStartNode(subCell, context); if (next == null) context.pop(); // get rid of no else return next; } } return null; } /** * Start tracing the scan chains. The nodeinst must be the jtag controller * @param startNode The context pointing to the jtag controller. */ private void start(Stack<Nodable> startNode) { if (startNode != null) { // generate a chain for each port for (Iterator<JtagController.Port> it = jtagController.getPorts(); it.hasNext(); ) { JtagController.Port jtagPort = it.next(); if (jtagPort.soutPort == null) continue; if (DEBUG) System.out.println("Starting chain "+jtagPort.opcode+" from port "+jtagPort.soutPort); String chainName = jtagPort.chainName; if (chainName == null) chainName = "chain_"+jtagPort.soutPort; Chain chain = new Chain(chainName, jtagPort.opcode, -1); Stack<Nodable> startNodeCopy = new Stack<Nodable>(); startNodeCopy.addAll(startNode); startChain(chain, startNodeCopy, jtagPort.soutPort); // report number of elements found int found = chain.numScanElements(); System.out.println("Info: completed successfully: chain "+chainName+" had "+found+" scan chain elements"); // make sure chain ended properly SubChain last = chain.getLastSubChain(); if (last != endChain) { System.out.println("Error! Chain "+chainName+" did not end at the jtag controller. Possible error in parsing or schematics."); if (last != null) System.out.println(" Last sub chain is "+last.name+", length="+last.length); } chains.add(chain); } } else if (chainStartExPorts != null) { for (int i=0; i<chainStartExPorts.size(); i++) { ExPort startExport = chainStartExPorts.get(i); String name = chainNames.get(i); Chain chain = new Chain(name, 0, -1); System.out.println("Tracing sub-chain "+name+" from export "+startExport); appendChain(chain, getOtherPorts(startExport)); int found = chain.numScanElements(); System.out.println("Info: completed successfully: chain "+name+" had "+found+" scan chain elements"); chains.add(chain); } } else { System.out.println("No starting point, aborting."); return; } // post process postProcessEntitiesRemovePassThroughs(); if (REDUCE) postProcessEntitiesPhase1(); // write header out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); out.println("\n<!--"); out.println(" Document : "+outputFile); out.println(" Author : automatically generated by Electric"); out.println(" Description : none"); out.println("-->\n"); out.println(); out.println("<!DOCTYPE ChainG SYSTEM \"file:./ChainG.dtd\" ["); // print all entities if (!FLAT) { for (Entity ent : entities.values()) { ent.writeDefinition(out, new StringBuffer(), cellsToFlatten); } out.println("]>"); out.println(); } // print all chains StringBuffer indent = new StringBuffer(); out.println("<ChainG>"); indent.append("\t"); out.println(indent+"<system>"); indent.append("\t"); out.println(indent+"<chip name=\""+chipName+"\" lengthIR=\""+jtagController.lengthIR+"\">"); indent.append("\t"); for (Chain chain : chains) { if (chain.numScanElements() == 0) continue; chain.write(out, indent, null, cellsToFlatten); if (DEBUG) System.out.println("Double Check: chain "+chain.name+" had "+chain.numScanElements()+" scan chain elements"); } indent.setLength(indent.length() - 1); out.println(indent+"</chip>"); indent.setLength(indent.length() - 1); out.println(indent+"</system>"); indent.setLength(indent.length() - 1); out.println("</ChainG>"); out.flush(); } // ------------------------- Elements ---------------------------------------- private static class SubChainInst { private Port inport; private Port outport; private Nodable no; private SubChain content; private SubChainInst(Port inport, Port outport, Nodable no, SubChain content) { this.inport = inport; this.outport = outport; this.no = no; this.content = content; } protected void setInport(Port port) { this.inport = port; } protected Port getInport() { return inport; } protected void setOutport(Port port) { this.outport = port; } protected Port getOutport() { return outport; } public String toString() { return "SubChainInst "+no.getName()+"; in: "+inport+", out: "+outport; } protected SubChain getSubChain() { return content; } protected String getName() { return no.getName(); } } /** * A chain is a description of an entire scan chain */ private static class Chain { protected String name; private int opcode; // the opcode to control this chain protected int length; // not output if 0 or less protected String access; // not output if null protected String clears; // not output if null protected DataNet dataNet; // network data is written to, not output if null protected DataNet dataNet2; // network dataBar is written to, not output if null private List<SubChainInst> subchains; // list of ScanChainInstances private Chain(String name, int opcode, int length, String access, String clears, DataNet dataNet, DataNet dataNet2) { this.name = name; this.opcode = opcode; this.length = length; this.access = access; this.clears = clears; this.dataNet = dataNet; this.dataNet2 = dataNet2; subchains = new ArrayList<SubChainInst>(); } private Chain(String name, int opcode, int length) { this(name, opcode, length, null, null, null, null); } protected void addSubChainInst(SubChainInst subChain) { subchains.add(subChain); } protected int getSubChainSize() { return subchains.size(); } protected SubChainInst getSubChainInst(int i) { return subchains.get(i); } protected SubChain getSubChain(int i) { SubChainInst inst = subchains.get(i); if (inst == null) return null; return inst.getSubChain(); } protected Iterator<SubChainInst> getSubChainInsts() { return subchains.iterator(); } protected Iterator<SubChain> getSubChains() { List<SubChain> subs = new ArrayList<SubChain>(); for (SubChainInst inst : subchains) { subs.add(inst.getSubChain()); } return subs.iterator(); } protected int getLength() { return length; } protected String getAccess() { return access; } protected String getClears() { return clears; } protected void write(PrintWriter out, StringBuffer indent, String instName, Map<Cell,Cell> cellsToFlatten) { if (numScanElements() == 0) return; // nothing to print String n = (instName == null) ? name : instName; out.print(indent+"<"+getTag()+" name=\""+n+"\""); if (opcode > -1) out.print(" opcode=\""+Integer.toBinaryString(opcode)+"\""); if (length > 0) out.print(" length=\""+length+"\""); if (access != null) out.print(" access=\""+access+"\""); if (clears != null) out.print(" clears=\""+clears+"\""); if (dataNet != null) out.print(" dataNet=\""+dataNet+"\""); if (dataNet2 != null) out.print(" dataNet2=\""+dataNet2+"\""); // short hand if no elements if (subchains.size() == 0) { out.println(" />"); return; } out.println(">"); 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+"</"+getTag()+">"); } protected String getTag() { return "chain"; } protected int numScanElements() { int num = 0; if (length > 0) num += length; for (SubChainInst inst : subchains) { SubChain sub = inst.getSubChain(); num += sub.numScanElements(); } //System.out.println("Num scan chain elements in "+name+": "+num+" (length="+length+")"); return num; } /** * Get the last subchain in this chain * @return */ protected SubChain getLastSubChain() { if (subchains.size() == 0) return null; SubChainInst last = subchains.get(subchains.size() - 1); return last.getSubChain().getLastSubChain(); } protected void copyTo(Chain dest) { dest.name = this.name; dest.length = this.length; dest.access = this.access; dest.clears = this.clears; dest.subchains.clear(); dest.subchains.addAll(this.subchains); } protected void removePassThroughs() { List<SubChainInst> toRemove = new ArrayList<SubChainInst>(); for (Iterator<SubChainInst> it2 = getSubChainInsts(); it2.hasNext(); ) { SubChainInst inst = it2.next(); SubChain sub = inst.getSubChain(); if (sub.isPassThrough()) { //System.out.println("Removed pass through cell "+sub.name); toRemove.add(inst); } } for (SubChainInst sci : toRemove) { subchains.remove(sci); } } protected void replaceSubChainInsts(List<SubChainInst> newSubChainInsts) { subchains.clear(); subchains.addAll(newSubChainInsts); } protected void remove(SubChainInst inst) { subchains.remove(inst); } protected List<SubChainInst> getSubChainsInsts() { ArrayList<SubChainInst> copy = new ArrayList<SubChainInst>(); for (Iterator<SubChainInst> it = getSubChainInsts(); it.hasNext(); ) copy.add(it.next()); return copy; } protected void addAllSubChainInsts(int i, List<SubChainInst> list) { subchains.addAll(i, list); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -