X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ships%2FMemory.ship;h=2d1d6f15dbe6abc7fe5b7e02c51d47ebcdfdf943;hb=aee85d3dd0435554e14e03b97f268752843a441f;hp=39110c8f8a9417b6aa0deea90c07d92788f72c38;hpb=b2659591cbf030b6e6fc5ff68e8f4bcceaafc58c;p=fleet.git diff --git a/ships/Memory.ship b/ships/Memory.ship index 39110c8..2d1d6f1 100644 --- a/ships/Memory.ship +++ b/ships/Memory.ship @@ -5,14 +5,98 @@ data in: inCBD data in: inAddrRead data in: inAddrWrite data in: inDataWrite -data in: inStride -data in: inCount data out: out +== TeX ============================================================== + +The {\tt Memory} ship represents an interface to a storage space, +which can be used to read from it or write to it. This storage space +might be a fast on-chip cache, off chip DRAM, or perhaps even a disk +drive. + +Generally, distinct {\tt Memory} ships do not access the same backing +storage, although this is not strictly prohibited. + +Each {\tt Memory} ship may have multiple {\it interfaces}, numbered +starting with {\tt 0}. Each interface may have any subset of the +following docks: {\tt inCBD}, {\tt inAddrRead}, {\tt inAddrWrite}, +{\tt inDataWrite}, and {\tt out}. If {\tt inCBD} or {\tt inAddrRead} +is present on an interface, then {\tt out} must be present as well. +If {\tt inAddrWrite} is present then {\tt inDataWrite} must be present +as well. + +Each interface serializes the operations presented to it; this means +that an interface with both read and write capabilities will not be +able to read and write concurrently. Instead, a {\tt Memory} ship +with the ability to read and write concurrently should have two +interfaces, one which is read-only and one which is write-only. + +There may be multiple {\tt Memory} ships which interface to the same +physical storage space. An implementation of Fleet must provide +additional documentation to the programmer indicating which {\tt +Memory} ships correspond to which storage spaces. A single {\tt +Memory} ship may also access a ``virtual storage space'' formed by +concatenating multiple physical storage spaces. + +\subsection*{Code Bag Fetch} + +When a word appears at the {\tt inCBD} port, it is treated as a {\it +code bag descriptor}, as shown below: + +\begin{center} +\setlength{\bitwidth}{3mm} +{\tt +\begin{bytefield}{37} + \bitheader[b]{36,6,5,0}\\ + \bitbox{31}{Address} + \bitbox{6}{size} +\end{bytefield} +} +\end{center} + +When a word arrives at the {\tt inCBD} port, it is treated as a memory +read with {\tt inAddrRead=Address}, {\tt inStride=1}, and {\tt +inCount=size}. + +\subsection*{Reading} + +When a word is delivered to {\tt inAddrRead}, the word residing in +memory at that address is provided at {\tt out}. The {\tt c-flag} at +the {\tt out} port is set to zero. + +\subsection*{Writing} + +When a word is delivered to {\tt inAddrWrite} and {\tt inDataWrite}, +the word at {\tt inDataWrite} is written to the address specified by +{\tt inAddrWrite}. Once the word is successfully committed to memory, +the value {\tt inAddr+inStride} is provided at {\tt out} (that is, the +address of the next word to be written). The {\tt c-flag} at +the {\tt out} port is set to one. + +\subsection*{To Do} + +Stride and count are not implemented. + +We need a way to do an ``unordered fetch'' -- a way to tell the memory +unit to retrieve some block of words in any order it likes. This can +considerably accelerate fetches when the first word of the region is +not cached, but other parts are cached. This can also be used for +dispatching codebags efficiently -- but how will we make sure that +instructions destined for a given pump are dispatched in the correct +order (source sequence guarantee)? + +A more advanced form would be ``unordered fetch of ordered records'' +-- the ability to specify a record size (in words), the offset of the +first record, and the number of records to be fetched. The memory +unit would then fetch the records in any order it likes, but would be +sure to return the words comprising a record in the order in which +they appear in memory. This feature could be used to solve the source +sequence guarantee problem mentioned in the previous paragraph. + == Fleeterpreter ==================================================== private long[] mem = new long[0]; - public long readMem(int addr) { return mem[addr]; } + public long readMem(int addr) { return addr >= mem.length ? 0 : mem[addr]; } public void writeMem(int addr, long val) { if (addr >= mem.length) { long[] newmem = new long[addr * 2 + 1]; @@ -21,339 +105,144 @@ data out: out } mem[addr] = val; } - - public void dispatch(int addr, int size) { - for(int i=addr; i> 6); - base = base & ~(0xffffffff << 18); - int size = (int)launch; - size = size & ~(0xffffffff << 6); - dispatch(base, size); + private Queue toDispatch = new LinkedList(); + public void reset() { + super.reset(); + mem = new long[0]; + toDispatch.clear(); } - - private long stride = 0; - private long count = 0; - private long addr = 0; - private boolean writing = false; - public void service() { + if (toDispatch.size() > 0) { + if (!box_out.readyForDataFromShip()) return; + box_out.addDataFromShip(toDispatch.remove()); + } if (box_inCBD.dataReadyForShip()) { long val = box_inCBD.removeDataForShip(); - long addr = val >> 6; - long size = val & 0x3f; - dispatch((int)addr, (int)size); - } - if (count > 0 && writing) { - if (box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) { - writeMem((int)addr, box_inDataWrite.removeDataForShip()); - box_out.addDataFromShip(0); - count--; - addr += stride; - } - - } else if (count > 0 && !writing) { - if (box_out.readyForDataFromShip()) { - box_out.addDataFromShip(readMem((int)addr)); - count--; - addr += stride; - } - + long addr = ((Interpreter)getFleet()).CBD_OFFSET.getval(val); + long size = ((Interpreter)getFleet()).CBD_SIZE.getval(val); + for(int i=0; i