c8cd957089baf05347526dbb726fc70d74d11d55
[fleet.git] / ships / Memory.ship
1 ship: Memory
2
3 == Ports ===========================================================
4 data  in:    inCBD
5 data  in:    inAddr.read
6 data  in:    inAddr.write
7 data  in:    inAddr.readMany
8 data  in:    inAddr.writeMany
9 data  in:    inData
10 data  in:    inStride
11 data  in:    inCount
12
13 data  out:   out
14
15 == Fleeterpreter ====================================================
16     private long[] mem = new long[0];
17     public long readMem(int addr) { return mem[addr]; }
18     public void writeMem(int addr, long val) {
19         if (addr >= mem.length) {
20             long[] newmem = new long[addr * 2 + 1];
21             System.arraycopy(mem, 0, newmem, 0, mem.length);
22             mem = newmem;
23         }
24         mem[addr] = val;
25     }
26
27     public void dispatch(int addr, int size) {
28         for(int i=addr; i<addr+size; i++) {
29             Instruction instr = ((Interpreter)getFleet()).readInstruction(readMem(i));
30             ((Interpreter)getFleet()).dispatch(instr, i);
31         }
32     }
33
34     public void boot(byte[] instructions) {
35         Interpreter fleet = (Interpreter)getFleet();
36         // load the iscratch and take note of the 0-address INCBD
37         long launch = 0;
38         for(int i=0; i<instructions.length; i+=6) {
39             long word = 0;
40             for(int j=0; j<6; j++)
41                 word = (word << 8) | (instructions[i+j] & 0xff);
42             writeMem(i/6, word);
43             if (i==0) launch = word;
44         }
45
46         // dispatch the 0-address INCBD
47         int base = (int)(launch >> 6);
48         base = base & ~(0xffffffff << 18);
49         int size = (int)launch;
50         size = size & ~(0xffffffff <<  6);
51         dispatch(base, size);
52     }
53
54     public void service() {
55         if (box_inCBD.dataReadyForShip()) {
56             long val = box_inCBD.removeDataForShip();
57             long addr = val >> 6;
58             long size = val & 0x3f;
59             dispatch((int)addr, (int)size);
60         }
61         if (box_inAddr.dataReadyForShip() && box_out.readyForItemFromShip()) {
62             Packet packet = box_inAddr.peekPacketForShip();
63             if (packet.destination.getDestinationName().equals("read")) {
64                 box_out.addDataFromShip(readMem((int)box_inAddr.removeDataForShip()));
65             } else if (packet.destination.getDestinationName().equals("write") && box_inData.dataReadyForShip()) {
66                 writeMem((int)box_inAddr.removeDataForShip(),
67                          box_inData.removeDataForShip());
68                 box_out.addDataFromShip(0);
69             }
70         }
71     }
72
73 == FleetSim ==============================================================
74
75 == FPGA ==============================================================
76 `include "macros.v"
77 `define BRAM_ADDR_WIDTH 14
78 `define BRAM_DATA_WIDTH `DATAWIDTH
79 `define BRAM_NAME dscratch_bram
80 `include "bram.inc"
81
82 module dscratch (clk, 
83                read_addr_r,    read_addr_a_,   read_addr_d,
84                read_data_r_,   read_data_a,    read_data_d_,
85                write_addr_r,   write_addr_a_,  write_addr_d,
86                write_data_r,   write_data_a_,  write_data_d,
87                write_done_r_,  write_done_a,   write_done_d_
88               );
89
90   input  clk;
91   `input(read_addr_r,    read_addr_a,   read_addr_a_,   [(`DATAWIDTH-1):0],  read_addr_d)
92   `output(read_data_r,   read_data_r_,  read_data_a,    [(`DATAWIDTH-1):0],  read_data_d_)
93   `defreg(read_data_d_,                                 [(`DATAWIDTH-1):0],  read_data_d)
94
95   `input(write_addr_r,   write_addr_a,  write_addr_a_,  [(`DATAWIDTH-1):0],  write_addr_d)
96   `input(write_data_r,   write_data_a,  write_data_a_,  [(`DATAWIDTH-1):0],  write_data_d)
97   `output(write_done_r,  write_done_r_, write_done_a,   [(`DATAWIDTH-1):0],  write_done_d_)
98   `defreg(write_done_d_,                                [(`DATAWIDTH-1):0],  write_done_d)
99
100   reg                           bram_we;
101   wire                          bram_we_;
102   assign bram_we_ = bram_we;
103   wire [(`BRAM_DATA_WIDTH-1):0] bram_read_data;
104   reg  [(`BRAM_ADDR_WIDTH-1):0] bram_write_address;
105   wire [(`BRAM_ADDR_WIDTH-1):0] bram_read_address;
106   reg  [(`BRAM_DATA_WIDTH-1):0] bram_write_data;
107   wire [(`BRAM_DATA_WIDTH-1):0] bram_write_data_;
108   assign bram_write_data_ = bram_write_data;
109   `BRAM_NAME mybram(clk,
110                     bram_we_,          bram_write_address,
111                     bram_read_address, bram_write_data_,
112                     not_connected,     bram_read_data);
113
114   reg send_done;
115
116   reg have_read;    initial have_read = 0;
117   reg read_pending; initial read_pending = 0;
118   assign bram_read_address = read_addr_d;
119
120   always @(posedge clk) begin
121     bram_we = 0;
122     if (send_done) begin
123       `onwrite(write_done_r, write_done_a)
124         send_done = 0;
125       end
126     end else begin
127       if (!write_addr_r && write_addr_a) write_addr_a = 0;
128       if (!write_data_r && write_data_a) write_data_a = 0;
129       if (write_addr_r && write_data_r) begin
130         write_addr_a = 1;
131         write_data_a = 1;
132         bram_we = 1;
133         send_done = 1;
134         bram_write_address = write_addr_d;
135         bram_write_data = write_data_d;
136       end
137     end
138
139     if (read_pending) begin
140         read_pending <= 0;
141         have_read    <= 1;
142         read_data_d  <= bram_read_data;
143     end else if (have_read) begin
144       `onwrite(read_data_r, read_data_a)
145         have_read <= 0;
146       end
147     end else begin
148       `onread(read_addr_r, read_addr_a)
149         // ======= Careful with the timing here! =====================
150         // We MUST capture bram_read_data on the very next clock since
151         // read_addr_d is free to change after the next clock
152         // ===========================================================
153         read_pending <= 1;
154       end
155     end
156
157   end
158
159 endmodule
160
161
162 == Constants ========================================================
163 == TeX ==============================================================
164
165 == Contributors =========================================================
166 Adam Megacz <megacz@cs.berkeley.edu>