📄 memoryinterfacegenerator.java
字号:
for(Iterator mIt = _memoryAccesses.keySet().iterator(); mIt.hasNext(); ) { // For each access... String key = (String) mIt.next(); List accesses = (List) _memoryAccesses.get(key); sort(accesses); // Sort by blockname, then cycle int lIndex = 0, sIndex = 0; for(Iterator aIt = accesses.iterator(); aIt.hasNext(); ) { MemoryAccessInfo aInfo = (MemoryAccessInfo) aIt.next(); if(aInfo.accessType == LOAD) lIndex = mapToPorts(key, aInfo, aInfo.accessType, lIndex); else sIndex = mapToPorts(key, aInfo, aInfo.accessType, sIndex); } } // Connect the block wires to the ports out to memory. // For each memory... for(Iterator mIt = _memoryInterface.keySet().iterator(); mIt.hasNext(); ) { String memory = (String) mIt.next(); // For each port... HashMap ports = (HashMap)_memoryInterface.get(memory); for(Iterator pIt = ports.keySet().iterator(); pIt.hasNext(); ) { String port = (String) pIt.next(); if(_inPorts.contains(port)) // If this is a "dr" port, leave it alone. continue; boolean noReadEn = false, noWrtEn = false; if(port.matches(".*_dw[0-9]*") || port.matches(".*_aw[0-9]*")) noReadEn = true; if(port.matches(".*_dw[0-9]*") || port.matches(".*_ar[0-9]*")) noWrtEn = true; HashMap dOrMap = new HashMap(); // Allocate a map for the OR operator. HashMap enOrMap = new HashMap(); // For the we signals. HashMap weOrMap = new HashMap(); // For each access designated to this port.. int i = 0, widest = 0; HashSet accesses = (HashSet) ports.get(port); for(Iterator aIt = accesses.iterator(); aIt.hasNext(); ) { MemoryAccessInfo info = (MemoryAccessInfo) aIt.next(); System.out.println("Using memory info "+info); System.out.println("Using memory info datawire "+info.dataWire); int width = 0; if(port.matches(".*_dw[0-9]*")) { width = info.dataWidth; dOrMap.put(info.dataWire, new PortTag(null, "in"+i, PortTag.IN, width)); //enOrMap.put(info.dataWire+"_we", new PortTag(null, "in"+i, PortTag.IN, 1)); } else { width = info.addrWidth; dOrMap.put(info.addrWire, new PortTag(null, "in"+i, PortTag.IN, width)); if(!noReadEn) enOrMap.put(info.addrWire+"_we", new PortTag(null, "in"+i, PortTag.IN, 1)); if(!noWrtEn) { System.out.println("we wire : "+info.addrWire); weOrMap.put(info.dataWire+"_we", new PortTag(null, "in"+i, PortTag.IN, 1)); } } if(width > widest) widest = width; i++; } // OR all memory access wires that access this port. dOrMap.put(port, new PortTag(null, "out", PortTag.OUT, widest)); _circuit.insertOperator("op_or"+_circuit.getUniqueName(), Operation.OR, dOrMap); if(!noReadEn) { enOrMap.put(port+"_re", new PortTag(null, "out", PortTag.OUT, 1)); _circuit.insertOperator("op_or"+_circuit.getUniqueName(), Operation.OR, enOrMap); } if(!noWrtEn) { weOrMap.put(port+"_we", new PortTag(null, "out", PortTag.OUT, 1)); _circuit.insertOperator("op_or"+_circuit.getUniqueName(), Operation.OR, weOrMap); } } } } /** * This method maps a memory access to a port of the specified memory. It * returns the next possible port number. */ int mapToPorts(String memory, MemoryAccessInfo info, int type, int index) { HashMap ports = (HashMap)_memoryInterface.get(memory); String addrType = (type == LOAD) ? "_ar" : "_aw"; String dataType = (type == LOAD) ? "_dr" : "_dw"; String dIndex = ""; // Deal with the address port... // If the accessed memory has a single address read-write port. String arwName = memory+"_arw"; if(ports.containsKey(arwName)) { HashSet port = (HashSet)ports.get(arwName); port.add(info); } else { // Otherwise there are separate read and write address ports. String aName = (_singlePorts) ? memory+addrType : memory+addrType+index; if(ports.containsKey(aName)) { HashSet port = (HashSet) ports.get(aName); port.add(info); } else { index = 0; aName = memory+addrType+index; if(ports.containsKey(aName)) { HashSet port = (HashSet) ports.get(aName); port.add(info); } } } // Deal with the data port... dIndex = new Integer(index).toString(); String dName = (_singlePorts) ? memory+dataType : memory+dataType+dIndex; if(ports.containsKey(dName)) { HashSet port = (HashSet) ports.get(dName); port.add(info); } else { dIndex = new Integer(0).toString(); dName = memory+dataType+dIndex; if(ports.containsKey(dName)) { HashSet port = (HashSet) ports.get(dName); port.add(info); } } // If this is a load, then add a buffer for getting input from "_dr" port. if(type == LOAD) insertBuf(_circuit, "buf_"+info.dataWire, dName, info.dataWire, info.dataWidth); return index+1; } /** * Port methods -- * These methods add ports based on its type (addr (out) and * data (in, out)). */ boolean addInPort(String name, HashMap ports, int width) { if(!_inPorts.contains(name)) { String portOut = name+"_s"; if(GlobalOptions.buildTop) _circuit.insertInPort(name, "i_"+name, portOut, width); else _circuit.insertInPort("i_"+name, portOut, width); _inPorts.add(name); ports.put(name, new HashSet()); return true; } return false; } boolean addOutPort(String name, HashMap ports, int width) { if(!_outPorts.contains(name)) { if(GlobalOptions.buildTop) { _circuit.insertOutPort(name, "o_"+name, "o_"+name, width); if(name.matches("mem[0-9]*_ar")) // if this is a read port... _circuit.insertOutPort(name+"_re","o_"+name+"_re","o_"+name+"_re",1); else if(name.matches("mem[0-9]*_aw")) { //if this is a write port... _circuit.insertOutPort(name+"_we","o_"+name+"_we","o_"+name+"_we",1); _desWePorts.add("o_"+name+"_we"); } } else { _circuit.insertOutPort(name, "o_"+name, width); if(name.matches("mem[0-9]*_ar")) // if this is a read port... _circuit.insertOutPort(name+"_re", "o_"+name+"_re",1); else if(name.matches("mem[0-9]*_aw")) {//if this is a write port... _circuit.insertOutPort(name+"_we","o_"+name+"_we",1); _desWePorts.add("o_"+name+"_we"); } } _outPorts.add(name); ports.put(name, new HashSet()); return true; } return false; } void addAddrPort(Memory mb, int type, HashMap ports, int width) { String name = mb.getName(); if(mb.getonlyOneAddy()) addOutPort(name+"_arw", ports, width); else { int nPorts = (type == LOAD) ? mb.getNumOfReadBus() : mb.getNumOfWriteBus(); for(int i = 0; i < nPorts; i++) { String t = (type == LOAD) ? "_ar" : "_aw"; String portName = (nPorts==1) ? name+t : name+t+i; boolean result = addOutPort(portName, ports, width); if(result == true) break; } } } void addDataPort(Memory mb, int type, HashMap ports, int width) { int nPorts = (type == LOAD) ? mb.getNumOfReadBus() : mb.getNumOfWriteBus(); String name = mb.getName(); boolean resultL = false, resultS = false; // Try to add ports until a port is actually added... for(int i = 0; i < nPorts; i++) { String pName = null; if(type==LOAD) { pName = (nPorts == 1) ? name+"_dr" : name+"_dr"+i; resultL = addInPort(pName, ports, DATA_WIDTH); } else { pName = (nPorts == 1) ? name+"_dw" : name+"_dw"+i; resultS = addOutPort(pName, ports, width); } if(resultL) { // If this is a Load, then get the right size of internal wires. int r0 = 0, r1 = r0 + width - 1; if(DATA_WIDTH > width) insertSlice(_circuit, "slice_"+pName, pName+"_s", r0, r1, pName, DATA_WIDTH, width); else if(DATA_WIDTH == width) insertBuf(_circuit, "buf_"+pName, pName+"_s", pName, width); else throw new SynthesisException("DATA_WIDTH < width of circuitry"); break; } else if(resultS) break; } } /** * This method updates the memory access data structure. */ void updateMemoryAccesses(String memory, MemoryAccessInfo access) { List accesses = (List)_memoryAccesses.get(memory); // If this memory hasn't been added yet to the access hashmap, add it... if(accesses == null) { accesses = new LinkedList(); _memoryAccesses.put(memory, accesses); } accesses.add(access); System.out.println("Memory: "+memory+", Array: "+access.getArrayName()); } /** * This method adds a HashMap to the data structure if the memory hasn't * been "seen" yet. The hashmap is returned. The hashmap will be used to * store all of the ports associated with this memory. Then, each port * entry will have a hashset containing all of the memory accesses that * are mapped to this port. */ HashMap updateMemoryInterface(String memory) { // Update the memory interface data structure... HashMap ports = (HashMap)_memoryInterface.get(memory); if(ports == null) { ports = new HashMap(); _memoryInterface.put(memory, ports); } return ports; } /** * This method records a memory access of the specified memory. Also, it * creates ports based on the type of memory access. */ void addMemoryAccess(String memory, String block, String addrwire, String datawire, int addrwidth, int datawidth, int cycle, int type) { Memory mb = (Memory) _mbMap.get(memory); MemoryAccessInfo access = new MemoryAccessInfo(block, addrwire, datawire, addrwidth, datawidth, cycle, type); // Update the data structures. updateMemoryAccesses(memory, access); HashMap ports = updateMemoryInterface(memory); // Add ports if they do not already exist... addAddrPort(mb, type, ports, addrwidth); addDataPort(mb, type, ports, datawidth); } /** * This nested class records information about memory accesses. The * datapath generator uses methods to create them whenever an ALoad or * AStore is come across in the CFG. */ private class MemoryAccessInfo { MemoryAccessInfo(String block, String addrwire, String datawire, int addrwidth, int datawidth, int cycle, int type) { blockName = block; addrWire = addrwire; dataWire = datawire; addrWidth = addrwidth; dataWidth = datawidth; cycle = cycle; accessType = type; } public String blockName; public String addrWire; public int addrWidth; public String dataWire; public int dataWidth; public int cycle; public int accessType; public String toString() { return "[ "+blockName+", "+addrWire+", "+dataWire+" ]"; } public String getArrayName() { return dataWire; } } /** * This method sorts lists of MemoryAccessInfos first by their blockNames * and then in case of ties by cycles. */ private void sort(List a) { class MemoryAccessInfoCompare implements Comparator { public int compare(Object o1, Object o2) { if((o1 instanceof MemoryAccessInfo) && (o2 instanceof MemoryAccessInfo)) { int comp = ((MemoryAccessInfo)o1).blockName.compareTo(((MemoryAccessInfo)o2).blockName); if(comp == 0) return ((MemoryAccessInfo)o1).cycle - ((MemoryAccessInfo)o2).cycle; else return comp; } else throw new ClassCastException("Not a MemoryAccessInfo!"); } } Collections.sort(a, new MemoryAccessInfoCompare()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -