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.
+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
\subsection*{Reading}
When a word is delivered to {\tt inAddrRead}, the word residing in
-memory at that address is provided at {\tt out}.
+memory at that address is provided at {\tt out}. The {\tt c-flag} at
+the {\tt out} port is set to zero.
\subsection*{Writing}
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).
+address of the next word to be written). The {\tt c-flag} at
+the {\tt out} port is set to one.
\subsection*{To Do}
write_flag <= 0;
dispatching_cbd <= 0;
end else begin
+ `flush
write_flag <= 0;
- if (!inAddrRead_r && inAddrRead_a) inAddrRead_a <= 0;
- if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0;
- if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0;
- if (!inCBD_r && inCBD_a) inCBD_a <= 0;
+ if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0;
+ if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+ if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+ if (!inCBD_r_ && inCBD_a) inCBD_a <= 0;
// assumes we never want a zero-length codebag
if ( inCBD_r && !inCBD_a && !out_r && !out_a) begin
if (!dispatching_cbd) begin
- cursor <= inCBD_d[(`INSTRUCTION_WIDTH-1):(`CODEBAG_SIZE_BITS)];
+ cursor <= inCBD_d[(`DATAWIDTH-1):(`CODEBAG_SIZE_BITS)];
counter <= 0;
dispatching_cbd <= 1;
end
== Test ==============================================================
+// FIXME: test c-flag at out dock
+// FIXME: rename to inCBD0, inAddrWrite0, etc
+
// expected output
#expect 12
#expect 13
// which is dispatched when the code is loaded
memory.out:
- [*] take, send;
+ set ilc=*; collect packet, send;
memory.inCBD:
- literal BOB;
+ set word= BOB;
deliver;
BOB: {
debug.in:
- literal 12; deliver;
- literal 13; deliver;
- literal 14; deliver;
+ set word= 12; deliver;
+ set word= 13; deliver;
+ set word= 14; deliver;
}