📄 exportchecker.java
字号:
exportNameToPortIndex.put(it.next(), new Integer(portNdx)); } } return exportNameToPortIndex; } private Circuit getNthCircuit(EquivRecord er, int nth) { LayoutLib.error(!er.isLeaf(), "only leaf EquivRecords have Circuits!"); Iterator<Circuit> it = er.getCircuits(); for (int i=0; i<nth; i++) { LayoutLib.error(!it.hasNext(), "EquivRec has no Circuit at index: "+nth); it.next(); } LayoutLib.error(!it.hasNext(), "EquivRec has no Circuit at index: "+nth); return it.next(); } /** Find a possible matching Wire or Port for lonely in the nth * circuit by examining lonely's Wire's equivalence record. * @return the matching Port or Wire. Return null if no unique matching * Port or Wire can be found */ private Object findMatchingPortOrWire(Port lonely, int nth) { Wire lonelyWire = lonely.getWire(); Circuit lonelyCkt = lonelyWire.getParent(); if (lonelyCkt.numNetObjs()!=1) return null; EquivRecord equivRecord = lonelyCkt.getParent(); Circuit nthCircuit = getNthCircuit(equivRecord, nth); if (nthCircuit.numNetObjs()!=1) return null; Wire wire = (Wire) nthCircuit.getNetObjs().next(); Port port = wire.getPort(); return port!=null ? (Object)port : (Object)wire; } private String getDescription(Object portOrWire) { if (portOrWire instanceof Wire) { return "network: "+((Wire)portOrWire).getName(); } else { LayoutLib.error(!(portOrWire instanceof Port), "not a Wire?"); return "network with Exports: "+ ((Port)portOrWire).exportNamesString(); } } private void markPortForRenaming(Port p, NccCellAnnotations ann) { for (Iterator<String> it=p.getExportNames(); it.hasNext();) { String name = it.next(); if (ann.renameExport(name)) {p.setToBeRenamed(); return;} } } private void markPortsForRenaming(Cell cell, Port[] ports) { NccCellAnnotations ann = NccCellAnnotations.getAnnotations(cell); if (ann==null) return; for (int portNdx=0; portNdx<ports.length; portNdx++) markPortForRenaming(ports[portNdx], ann); } private void printNewPortNames(Port[] ports, Cell rootCell, int cktIndex) { boolean printedHeader = false; int otherCktIndex = cktIndex==0 ? 1 : 0; for (int portNdx=0; portNdx<ports.length; portNdx++) { Port p = ports[portNdx]; if (p.getToBeRenamed()) { if (!printedHeader) { prln(" Attempting to find better names for Exports in Cell: "+ NccUtils.fullName(rootCell)); printedHeader = true; } Object o = findMatchingPortOrWire(p, otherCktIndex); prln(" "+ p.exportNamesString()+" -> "+ getDescription(o)); } } } private void printNewNamesForPortsThatTheUserWantsUsToRename() { Cell[] rootCells = globals.getRootCells(); Port[][] portsPerCell = getPortsForEachCell(); for (int cellNdx=0; cellNdx<portsPerCell.length; cellNdx++) printNewPortNames(portsPerCell[cellNdx], rootCells[cellNdx], cellNdx); } /** For each port not matched by name, suggest a possible match */ private void suggestMatchForPortsThatDontMatchByName() { String[] rootCellNames = globals.getRootCellNames(); boolean printedHeader = false; VarContext rootContexts[] = globals.getRootContexts(); Cell rootCells[] = globals.getRootCells(); for (NoPortNameMatch no=noPortNameMatches.removeFirst(); no!=null; no=noPortNameMatches.removeFirst()) { // skip Ports for which the user has already requested a new name if (no.port.getToBeRenamed()) continue; Object o = findMatchingPortOrWire(no.port, no.circuitNoMatchingPort); if (o==null) { ExportMismatch.MultiMatch em = new ExportMismatch.MultiMatch(); em.setNames(rootCellNames[no.circuit], rootCellNames[no.circuitNoMatchingPort]); em.setCells(rootCells[no.circuit], rootCells[no.circuitNoMatchingPort]); em.setContexts(rootContexts[no.circuit], rootContexts[no.circuitNoMatchingPort]); em.add(0, no.port); globals.getNccGuiInfo().addExportMismatch(em); continue; } if (!printedHeader) { printedHeader = true; prln(" The following list suggests possible matches for "+ "Exports that failed to match by name."); } prln(" in Cell "+rootCellNames[no.circuit]+ " the network with Exports: "+ no.port.exportNamesString()+ " might match in Cell "+rootCellNames[no.circuitNoMatchingPort]+ " the "+getDescription(o)); if (o instanceof Port) { noPortNameMatches.removeMismatches(no.port, no.circuit, (Port)o, no.circuitNoMatchingPort); } ExportMismatch.NameMismatch esm = new ExportMismatch.NameMismatch(); esm.setNames(rootCellNames[no.circuit], rootCellNames[no.circuitNoMatchingPort]); esm.setCells(rootCells[no.circuit], rootCells[no.circuitNoMatchingPort]); esm.setContexts(rootContexts[no.circuit], rootContexts[no.circuitNoMatchingPort]); esm.setFirstExport(no.port); esm.setSuggestion((NetObject)o); globals.getNccGuiInfo().addExportMismatch(esm); } if (printedHeader) prln(""); } // -------------------------- public methods ------------------------------ public ExportChecker(NccGlobals globals) {this.globals=globals;} public void markPortsForRenaming() { Cell[] rootCells = globals.getRootCells(); Port[][] portsPerCell = getPortsForEachCell(); for (int cellNdx=0; cellNdx<portsPerCell.length; cellNdx++) markPortsForRenaming(rootCells[cellNdx], portsPerCell[cellNdx]); } /** match Exports by name. Run this before Gemini algorithm in order to * give user early warning about Export name inconsistencies. */ public boolean matchByName() { int numCkts = globals.getNumNetlistsBeingCompared(); String[] rootCellNames = globals.getRootCellNames(); Port[][] portsPerCell = getPortsForEachCell(); equivPortMaps = new HashMap[numCkts]; boolean match=true; for (int i=1; i<numCkts; i++) { match &= matchPortsByName(null, portsPerCell, rootCellNames, i, 0); HashMap<Port,Port> p0ToPi = new HashMap<Port,Port>(); match &= matchPortsByName(p0ToPi, portsPerCell, rootCellNames, 0, i); equivPortMaps[i] = p0ToPi; } return match; } /** Gather information that will allow hierarchical netlist comparison * at higher level to treat me as a subcircuit. */ public void saveInfoNeededToMakeMeASubcircuit(HierarchyInfo hierInfo) { if (hierInfo==null) return; Cell[] rootCells = globals.getRootCells(); Cell refCell = globals.getRootCells()[0]; SubcircuitInfo refCellInfo = getInfoForReferenceCell(refCell, hierInfo); // It is reasonable for two different designs to share some // cells. It's also reasonable to compare the same schematic Cell // with two different VarContexts. When this happens, don't create // two SubcircuitInfo's for the same cell. Set<Cell> doneCells = new HashSet<Cell>(); doneCells.add(refCell); for (int i=1; i<equivPortMaps.length; i++) { if (doneCells.contains(rootCells[i])) continue; doneCells.add(rootCells[i]); Map<String,Integer> exportNameToPortIndex = mapExportNameToPortIndex(refCellInfo, equivPortMaps[i]); SubcircuitInfo subInf = new SubcircuitInfo(refCellInfo, exportNameToPortIndex); hierInfo.addSubcircuitInfo(rootCells[i], subInf); } } /** Check that Exports with matching names are on equivalent nets. * @return true if equivalent. */ public boolean ensureExportsWithMatchingNamesAreOnEquivalentNets() { boolean match=true; String[] rootCellNames = globals.getRootCellNames(); VarContext rootContexts[] = globals.getRootContexts(); Cell rootCells[] = globals.getRootCells(); for (int i=1; i<equivPortMaps.length; i++) { HashMap<Port,Port> portToPort = equivPortMaps[i]; for (Port p0 : portToPort.keySet()) { Port pn = portToPort.get(p0); // skip Ports that the user wants us to rename if (p0.getToBeRenamed() || pn.getToBeRenamed()) continue; Wire w0 = p0.getWire(); Wire wn = pn.getWire(); EquivRecord er0 = w0.getParent().getParent(); EquivRecord ern = wn.getParent().getParent(); if (er0!=ern) { prln(" Exports that match by name aren't on equivalent"+ " networks"); prln(" Cell1: "+rootCellNames[0]); prln(" Exports1: "+p0.exportNamesString()); prln(" Cell2: "+rootCellNames[i]); prln(" Exports2: "+pn.exportNamesString()); Object portOrWire = findMatchingPortOrWire(p0, i); if (portOrWire!=null) prln(" However the Cell1 network appears to match Cell2's: "+ getDescription(portOrWire)); prln(""); match = false; ExportMismatch.TopologyMismatch esm = new ExportMismatch.TopologyMismatch(); esm.setNames(rootCellNames[0], rootCellNames[i]); esm.setCells(rootCells[0], rootCells[i]); esm.setContexts(rootContexts[0], rootContexts[i]); esm.setFirstExport(p0); esm.setSecondExport(pn); if(portOrWire != null) esm.setSuggestion((NetObject)portOrWire); globals.getNccGuiInfo().addExportMismatch(esm); } } } return match; } public void suggestPortMatchesBasedOnTopology() { printNewNamesForPortsThatTheUserWantsUsToRename(); suggestMatchForPortsThatDontMatchByName(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -