update everything to naming conventions agreed upon in class last week
[fleet.git] / ships / Dscratch.ship
1 ship: Dscratch
2
3 == Ports ===========================================================
4 data  in:    inReadAddr
5 data out:    outReadData
6
7 data  in:    inWriteAddr
8 data  in:    inWriteData
9 token out:   outWriteDone
10
11 == Fleeterpreter ====================================================
12     private long[] mem = new long[0];
13     public long readMem(int addr) { return mem[addr]; }
14     public void writeMem(int addr, long val) {
15         if (addr >= mem.length) {
16             long[] newmem = new long[addr * 2 + 1];
17             System.arraycopy(mem, 0, newmem, 0, mem.length);
18             mem = newmem;
19         }
20         mem[addr] = val;
21     }
22
23     public void service() {
24         if (box_inReadAddr.dataReadyForShip() &&
25             box_outReadData.readyForItemFromShip()) {
26             box_outReadData.addDataFromShip((int)readMem(box_inReadAddr.removeDataForShip()));
27         }
28
29         if (box_inWriteAddr.dataReadyForShip() &&
30             box_inWriteData.dataReadyForShip() &&
31             box_outWriteDone.readyForItemFromShip()) {
32             writeMem(box_inWriteAddr.removeDataForShip(),
33                      box_inWriteData.removeDataForShip());
34             box_outWriteDone.addTokenFromShip();
35         }
36     }
37
38 == ArchSim ==============================================================
39
40 == FPGA ==============================================================
41 `include "macros.v"
42 `define BRAM_ADDR_WIDTH 14
43 `define BRAM_DATA_WIDTH `DATAWIDTH
44 `define BRAM_NAME dscratch_bram
45 `include "bram.inc"
46
47 module dscratch (clk, 
48                read_addr_r,    read_addr_a_,   read_addr_d,
49                read_data_r_,   read_data_a,    read_data_d_,
50                write_addr_r,   write_addr_a_,  write_addr_d,
51                write_data_r,   write_data_a_,  write_data_d,
52                write_done_r_,  write_done_a,   write_done_d_
53               );
54
55   input  clk;
56   `input(read_addr_r,    read_addr_a,   read_addr_a_,   [(`DATAWIDTH-1):0],  read_addr_d)
57   `output(read_data_r,   read_data_r_,  read_data_a,    [(`DATAWIDTH-1):0],  read_data_d_)
58   `defreg(read_data_d_,                                 [(`DATAWIDTH-1):0],  read_data_d)
59
60   `input(write_addr_r,   write_addr_a,  write_addr_a_,  [(`DATAWIDTH-1):0],  write_addr_d)
61   `input(write_data_r,   write_data_a,  write_data_a_,  [(`DATAWIDTH-1):0],  write_data_d)
62   `output(write_done_r,  write_done_r_, write_done_a,   [(`DATAWIDTH-1):0],  write_done_d_)
63   `defreg(write_done_d_,                                [(`DATAWIDTH-1):0],  write_done_d)
64
65   reg                           bram_we;
66   wire                          bram_we_;
67   assign bram_we_ = bram_we;
68   wire [(`BRAM_DATA_WIDTH-1):0] bram_read_data;
69   reg  [(`BRAM_ADDR_WIDTH-1):0] bram_write_address;
70   wire [(`BRAM_ADDR_WIDTH-1):0] bram_read_address;
71   reg  [(`BRAM_DATA_WIDTH-1):0] bram_write_data;
72   wire [(`BRAM_DATA_WIDTH-1):0] bram_write_data_;
73   assign bram_write_data_ = bram_write_data;
74   `BRAM_NAME mybram(clk,
75                     bram_we_,          bram_write_address,
76                     bram_read_address, bram_write_data_,
77                     not_connected,     bram_read_data);
78
79   reg send_done;
80
81   reg have_read;    initial have_read = 0;
82   reg read_pending; initial read_pending = 0;
83   assign bram_read_address = read_addr_d;
84
85   always @(posedge clk) begin
86     bram_we = 0;
87     if (send_done) begin
88       `onwrite(write_done_r, write_done_a)
89         send_done = 0;
90       end
91     end else begin
92       if (!write_addr_r && write_addr_a) write_addr_a = 0;
93       if (!write_data_r && write_data_a) write_data_a = 0;
94       if (write_addr_r && write_data_r) begin
95         write_addr_a = 1;
96         write_data_a = 1;
97         bram_we = 1;
98         send_done = 1;
99         bram_write_address = write_addr_d;
100         bram_write_data = write_data_d;
101       end
102     end
103
104     if (read_pending) begin
105         read_pending <= 0;
106         have_read    <= 1;
107         read_data_d  <= bram_read_data;
108     end else if (have_read) begin
109       `onwrite(read_data_r, read_data_a)
110         have_read <= 0;
111       end
112     end else begin
113       `onread(read_addr_r, read_addr_a)
114         // ======= Careful with the timing here! =====================
115         // We MUST capture bram_read_data on the very next clock since
116         // read_addr_d is free to change after the next clock
117         // ===========================================================
118         read_pending <= 1;
119       end
120     end
121
122   end
123
124 endmodule
125
126
127 == Constants ========================================================
128 == TeX ==============================================================
129
130 == Contributors =========================================================
131 Adam Megacz <megacz@cs.berkeley.edu>