| 1 | module BigBlockRAM( |
| 2 | input clk, |
| 3 | input [31:0] bus_addr, |
| 4 | output wire [31:0] bus_rdata, |
| 5 | input [31:0] bus_wdata, |
| 6 | input bus_rd, |
| 7 | input bus_wr, |
| 8 | output wire bus_ready |
| 9 | ); |
| 10 | |
| 11 | /* This module is mapped in physical memory from 0x00000000 to |
| 12 | * 0x00800000. rdata and ready must be driven to zero if the |
| 13 | * address is not within the range of this module. |
| 14 | */ |
| 15 | wire decode = bus_addr[31:23] == 9'b0; |
| 16 | wire [22:0] ramaddr = {bus_addr[22:2], 2'b0}; /* mask off lower two bits |
| 17 | * for word alignment */ |
| 18 | |
| 19 | reg [31:0] data [((8*1024*1024) / 4 - 1):0]; |
| 20 | |
| 21 | reg [31:0] temprdata = 0; |
| 22 | reg [22:0] lastread = 23'h7FFFFFFF; |
| 23 | assign bus_rdata = (bus_rd && decode) ? temprdata : 32'h0; |
| 24 | |
| 25 | assign bus_ready = decode && |
| 26 | (bus_wr || (bus_rd && (lastread == ramaddr))); |
| 27 | |
| 28 | initial |
| 29 | $readmemh("ram.hex", data); |
| 30 | |
| 31 | always @(posedge clk) |
| 32 | begin |
| 33 | if (bus_wr && decode) |
| 34 | data[ramaddr[22:2]] = bus_wdata; |
| 35 | |
| 36 | /* This is not allowed to be conditional -- stupid Xilinx |
| 37 | * blockram. */ |
| 38 | temprdata <= data[ramaddr[22:2]]; |
| 39 | lastread <= ramaddr; |
| 40 | end |
| 41 | endmodule |