add more ship files
[fleet.git] / src / edu / berkeley / fleet / slipway / dcache.v
1 `include "macros.v"
2 `define BRAM_ADDR_WIDTH 14
3 `define BRAM_DATA_WIDTH `DATAWIDTH
4 `define BRAM_NAME dcache_bram
5 `include "bram.inc"
6
7 module dcache (clk, 
8                read_addr_r,    read_addr_a_,   read_addr_d,
9                read_data_r_,   read_data_a,    read_data_d_,
10                write_addr_r,   write_addr_a_,  write_addr_d,
11                write_data_r,   write_data_a_,  write_data_d,
12                write_done_r_,  write_done_a,   write_done_d_
13               );
14
15   input  clk;
16   `input(read_addr_r,    read_addr_a,   read_addr_a_,   [(`DATAWIDTH-1):0],  read_addr_d)
17   `output(read_data_r,   read_data_r_,  read_data_a,    [(`DATAWIDTH-1):0],  read_data_d_)
18   `defreg(read_data_d_,                                 [(`DATAWIDTH-1):0],  read_data_d)
19
20   `input(write_addr_r,   write_addr_a,  write_addr_a_,  [(`DATAWIDTH-1):0],  write_addr_d)
21   `input(write_data_r,   write_data_a,  write_data_a_,  [(`DATAWIDTH-1):0],  write_data_d)
22   `output(write_done_r,  write_done_r_, write_done_a,   [(`DATAWIDTH-1):0],  write_done_d_)
23   `defreg(write_done_d_,                                [(`DATAWIDTH-1):0],  write_done_d)
24
25   reg                           bram_we;
26   wire                          bram_we_;
27   assign bram_we_ = bram_we;
28   wire [(`BRAM_DATA_WIDTH-1):0] bram_read_data;
29   reg  [(`BRAM_ADDR_WIDTH-1):0] bram_write_address;
30   wire [(`BRAM_ADDR_WIDTH-1):0] bram_read_address;
31   reg  [(`BRAM_DATA_WIDTH-1):0] bram_write_data;
32   wire [(`BRAM_DATA_WIDTH-1):0] bram_write_data_;
33   assign bram_write_data_ = bram_write_data;
34   `BRAM_NAME mybram(clk,
35                     bram_we_,          bram_write_address,
36                     bram_read_address, bram_write_data_,
37                     not_connected,     bram_read_data);
38
39   reg send_done;
40
41   reg have_read;    initial have_read = 0;
42   reg read_pending; initial read_pending = 0;
43   assign bram_read_address = read_addr_d;
44
45   always @(posedge clk) begin
46     bram_we = 0;
47     if (send_done) begin
48       `onwrite(write_done_r, write_done_a)
49         send_done = 0;
50       end
51     end else begin
52       if (!write_addr_r && write_addr_a) write_addr_a = 0;
53       if (!write_data_r && write_data_a) write_data_a = 0;
54       if (write_addr_r && write_data_r) begin
55         write_addr_a = 1;
56         write_data_a = 1;
57         bram_we = 1;
58         send_done = 1;
59         bram_write_address = write_addr_d;
60         bram_write_data = write_data_d;
61       end
62     end
63
64     if (read_pending) begin
65         read_pending <= 0;
66         have_read    <= 1;
67         read_data_d  <= bram_read_data;
68     end else if (have_read) begin
69       `onwrite(read_data_r, read_data_a)
70         have_read <= 0;
71       end
72     end else begin
73       `onread(read_addr_r, read_addr_a)
74         // ======= Careful with the timing here! =====================
75         // We MUST capture bram_read_data on the very next clock since
76         // read_addr_d is free to change after the next clock
77         // ===========================================================
78         read_pending <= 1;
79       end
80     end
81
82   end
83
84 endmodule