3 == Ports ===========================================================
13 == TeX ==============================================================
15 The {\tt Memory} ship represents an interface to a storage space,
16 which can be used to read from it or write to it. This storage space
17 might be a fast on-chip cache, off chip DRAM, or perhaps even a disk drive.
19 There may be multiple {\tt Memory} ships which interface to the same
20 physical storage space. An implementation of Fleet must provide
21 additional documentation to the programmer indicating which {\tt
22 Memory} ships correspond to which storage spaces. A single {\tt
23 Memory} ship may also access a ``virtual storage space'' formed by
24 concatenating multiple physical storage spaces.
26 \subsection*{Code Bag Fetch}
28 When a word appears at the {\tt inCBD} port, it is treated as a {\it
29 code bag descriptor}, as shown below:
32 \setlength{\bitwidth}{3mm}
35 \bitheader[b]{36,6,5,0}\\
42 When a word arrives at the {\tt inCBD} port, it is treated as a memory
43 read with {\tt inAddrRead=Address}, {\tt inStride=1}, and {\tt
48 When a word is delivered to {\tt inAddrRead}, the word residing in
49 memory at that address is provided at {\tt out}.
53 When a word is delivered to {\tt inAddrWrite} and {\tt inDataWrite},
54 the word at {\tt inDataWrite} is written to the address specified by
55 {\tt inAddrWrite}. Once the word is successfully committed to memory,
56 the value {\tt inAddr+inStride} is provided at {\tt out} (that is, the
57 address of the next word to be written).
61 Stride and count are not implemented.
63 We need a way to do an ``unordered fetch'' -- a way to tell the memory
64 unit to retrieve some block of words in any order it likes. This can
65 considerably accelerate fetches when the first word of the region is
66 not cached, but other parts are cached. This can also be used for
67 dispatching codebags efficiently -- but how will we make sure that
68 instructions destined for a given pump are dispatched in the correct
69 order (source sequence guarantee)?
71 A more advanced form would be ``unordered fetch of ordered records''
72 -- the ability to specify a record size (in words), the offset of the
73 first record, and the number of records to be fetched. The memory
74 unit would then fetch the records in any order it likes, but would be
75 sure to return the words comprising a record in the order in which
76 they appear in memory. This feature could be used to solve the source
77 sequence guarantee problem mentioned in the previous paragraph.
79 == Fleeterpreter ====================================================
80 private long[] mem = new long[0];
81 public long readMem(int addr) { return mem[addr]; }
82 public void writeMem(int addr, long val) {
83 if (addr >= mem.length) {
84 long[] newmem = new long[addr * 2 + 1];
85 System.arraycopy(mem, 0, newmem, 0, mem.length);
91 public void dispatch(int addr, int size) {
92 for(int i=addr; i<addr+size; i++) {
93 Instruction instr = ((Interpreter)getFleet()).readInstruction(readMem(i));
94 ((Interpreter)getFleet()).dispatch(instr, i);
98 public void boot(byte[] instructions) {
99 Interpreter fleet = (Interpreter)getFleet();
100 // load the iscratch and take note of the 0-address INCBD
102 for(int i=0; i<instructions.length; i+=6) {
104 for(int j=0; j<6; j++)
105 word = (word << 8) | (instructions[i+j] & 0xff);
107 if (i==0) launch = word;
110 // dispatch the 0-address INCBD
111 int base = (int)(launch >> 6);
112 base = base & ~(0xffffffff << 18);
113 int size = (int)launch;
114 size = size & ~(0xffffffff << 6);
115 dispatch(base, size);
118 private long stride = 0;
119 private long count = 0;
120 private long addr = 0;
121 private boolean writing = false;
123 public void service() {
124 if (box_inCBD.dataReadyForShip()) {
125 long val = box_inCBD.removeDataForShip();
126 long addr = val >> 6;
127 long size = val & 0x3f;
128 dispatch((int)addr, (int)size);
132 if (box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) {
133 writeMem((int)addr, box_inDataWrite.removeDataForShip());
134 box_out.addDataFromShip(0);
139 if (box_out.readyForDataFromShip()) {
140 box_out.addDataFromShip(readMem((int)addr));
146 } else if (box_inAddrRead.dataReadyForShip()) {
147 addr = box_inAddrRead.removeDataForShip();
152 } else if (box_inAddrWrite.dataReadyForShip()) {
153 addr = box_inAddrWrite.peekPacketForShip().value;
154 box_inAddrWrite.removeDataForShip();
161 == FleetSim ==============================================================
163 == FPGA ==============================================================
165 `define BRAM_ADDR_WIDTH 14
166 `define BRAM_DATA_WIDTH `INSTRUCTION_WIDTH
167 `define BRAM_NAME some_bram
170 module `BRAM_NAME(clk, rst, we, a, dpra, di, spo, dpo);
174 input [(`BRAM_ADDR_WIDTH-1):0] a;
175 input [(`BRAM_ADDR_WIDTH-1):0] dpra;
176 input [(`BRAM_DATA_WIDTH-1):0] di;
177 output [(`BRAM_DATA_WIDTH-1):0] spo;
178 output [(`BRAM_DATA_WIDTH-1):0] dpo;
179 reg [(`BRAM_DATA_WIDTH-1):0] ram [((1<<(`BRAM_ADDR_WIDTH))-1):0];
180 reg [(`BRAM_ADDR_WIDTH-1):0] read_a;
181 reg [(`BRAM_ADDR_WIDTH-1):0] read_dpra;
182 always @(posedge clk) begin
188 assign spo = ram[read_a];
189 assign dpo = ram[read_dpra];
193 module memory (clk, rst,
194 cbd_r, cbd_a_, cbd_d,
195 in_addr_r, in_addr_a_, in_addr_d,
196 write_addr_r, write_addr_a_, write_addr_d,
197 write_data_r, write_data_a_, write_data_d,
198 stride_r, stride_a_, stride_d,
199 count_r, count_a_, count_d,
200 out_r_, out_a, out_d_,
201 preload_r, preload_a_, preload_d,
202 ihorn_r_, ihorn_a, ihorn_d_,
203 dhorn_r_, dhorn_a, dhorn_d_
208 `input(in_addr_r, in_addr_a, in_addr_a_, [(2+`DATAWIDTH-1):0], in_addr_d)
209 `input(write_addr_r, write_addr_a, write_addr_a_, [(2+`DATAWIDTH-1):0], write_addr_d)
210 `input(write_data_r, write_data_a, write_data_a_, [(`DATAWIDTH-1):0], write_data_d)
211 `input(stride_r, stride_a, stride_a_, [(`DATAWIDTH-1):0], stride_d)
212 `input(count_r, count_a, count_a_, [(`DATAWIDTH-1):0], count_d)
213 `output(out_r, out_r_, out_a, [(`DATAWIDTH-1):0], out_d_)
214 `input(preload_r, preload_a, preload_a_, [(`DATAWIDTH-1):0], preload_d)
215 `input(cbd_r, cbd_a, cbd_a_, [(`DATAWIDTH-1):0], cbd_d)
216 `output(ihorn_r, ihorn_r_, ihorn_a, [(`PACKET_WIDTH-1):0], ihorn_d_)
217 `defreg(ihorn_d_, [(`PACKET_WIDTH-1):0], ihorn_d)
218 `output(dhorn_r, dhorn_r_, dhorn_a, [(`PACKET_WIDTH-1):0], dhorn_d_)
219 `defreg(dhorn_d_, [(`PACKET_WIDTH-1):0], dhorn_d)
222 initial ihorn_full = 0;
224 initial dhorn_full = 0;
226 initial command_valid = 0;
228 reg [(`BRAM_ADDR_WIDTH-1):0] preload_pos;
229 reg [(`BRAM_ADDR_WIDTH-1):0] preload_size;
230 initial preload_size = 0;
232 reg [(`BRAM_ADDR_WIDTH-1):0] current_instruction_read_from;
233 reg [(`BRAM_ADDR_WIDTH-1):0] temp_base;
234 reg [(`CODEBAG_SIZE_BITS-1):0] temp_size;
235 reg [(`BRAM_ADDR_WIDTH-1):0] cbd_base;
236 reg [(`CODEBAG_SIZE_BITS-1):0] cbd_size;
237 reg [(`CODEBAG_SIZE_BITS-1):0] cbd_pos;
238 reg [(`INSTRUCTION_WIDTH-1):0] command;
239 reg [(`BRAM_DATA_WIDTH-1):0] ram [((1<<(`BRAM_ADDR_WIDTH))-1):0];
243 reg [(`INSTRUCTION_WIDTH-(2+`DESTINATION_ADDRESS_BITS)):0] temp;
244 reg [(`DATAWIDTH-1):0] data;
247 reg [(`BRAM_ADDR_WIDTH-1):0] in_addr;
248 reg [(`BRAM_DATA_WIDTH-1):0] write_data;
250 wire [(`BRAM_DATA_WIDTH-1):0] ramread;
252 reg command_valid_read;
253 initial command_valid_read = 0;
256 initial launched = 0;
258 some_bram mybram(clk, rst, write_flag, in_addr, current_instruction_read_from, write_data, not_connected, ramread);
259 assign out_d_ = ramread;
261 always @(posedge clk /*or negedge rst*/) begin
268 // uncommenting either of these causes headaches
275 command_valid_read <= 0;
285 if (!in_addr_r && in_addr_a) in_addr_a = 0;
286 if (!write_data_r && write_data_a) write_data_a = 0;
287 if (!write_addr_r && write_addr_a) write_addr_a = 0;
289 if (command_valid_read) begin
290 command_valid_read <= 0;
293 end else if (send_done) begin
294 `onwrite(out_r, out_a)
298 end else if (send_read) begin
299 `onwrite(out_r, out_a)
303 end else if (in_addr_r) begin
306 current_instruction_read_from <= in_addr_d[(`DATAWIDTH-1):0];
308 end else if (write_addr_r && write_data_r) begin
313 in_addr <= write_addr_d[(`DATAWIDTH-1):0];
314 write_data <= write_data_d;
316 end else if (ihorn_full && launched) begin
317 `onwrite(ihorn_r, ihorn_a)
321 end else if (dhorn_full) begin
322 `onwrite(dhorn_r, dhorn_a)
326 end else if (command_valid) begin
330 `packet_data(ihorn_d) <= `instruction_data(command);
331 `packet_dest(ihorn_d) <= `instruction_dest(command);
333 end else if (cbd_pos < cbd_size) begin
334 current_instruction_read_from <= cbd_base+cbd_pos;
335 command_valid_read <= 1;
336 cbd_pos <= cbd_pos + 1;
339 `onread(cbd_r, cbd_a)
341 cbd_size <= cbd_d[(`CODEBAG_SIZE_BITS-1):0];
342 cbd_base <= cbd_d[(`INSTRUCTION_WIDTH-1):(`CODEBAG_SIZE_BITS)];
345 `onread(preload_r, preload_a)
346 if (preload_size == 0) begin
347 preload_size <= preload_d;
349 end else if (!launched) begin
351 write_data <= preload_d;
352 in_addr <= preload_pos;
353 if (preload_pos == 0) begin
354 temp_base = preload_d[(`INSTRUCTION_WIDTH-(3+`DESTINATION_ADDRESS_BITS)):(`CODEBAG_SIZE_BITS)];
355 temp_size = preload_d[(`CODEBAG_SIZE_BITS-1):0];
357 if ((preload_pos+1) == preload_size) begin
359 cbd_base <= temp_base;
360 cbd_size <= temp_size;
363 preload_pos <= preload_pos + 1;
378 == Test ==============================================================
384 // ships required in order to run this code
386 #ship memory : Memory
388 // instructions not in any codebag are part of the "root codebag"
389 // which is dispatched when the code is loaded
403 == Constants ========================================================
405 == Contributors =========================================================
406 Adam Megacz <megacz@cs.berkeley.edu>