tridoracpu: implement data cache
This commit is contained in:
parent
b2c2e8dc0c
commit
278f90a464
3 changed files with 138 additions and 38 deletions
|
|
@ -107,8 +107,14 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32)
|
|||
);
|
||||
|
||||
(*KEEP*) reg [DRAM_DATA_WIDTH-1:0] ins_cache;
|
||||
(*KEEP*) reg [DRAM_ADDR_WIDTH-1:4] cached_addr;
|
||||
(*KEEP*) wire cache_hit = mem_read_enable && mem_read_ins && (cached_addr == mem_addr[DRAM_ADDR_WIDTH-1:4]);
|
||||
(*KEEP*) reg [DRAM_ADDR_WIDTH-1:4] icached_addr;
|
||||
(*KEEP*) wire icache_hit = mem_read_enable && mem_read_ins && (icached_addr == mem_addr[DRAM_ADDR_WIDTH-1:4]);
|
||||
|
||||
(*KEEP*) reg [DRAM_DATA_WIDTH-1:0] d_cache;
|
||||
(*KEEP*) reg [DRAM_ADDR_WIDTH-1:4] dcached_addr;
|
||||
(*KEEP*) wire dcache_hit = mem_read_enable && !mem_read_ins && (dcached_addr == mem_addr[DRAM_ADDR_WIDTH-1:4]);
|
||||
|
||||
wire cache_hit = icache_hit | dcache_hit;
|
||||
|
||||
reg [WIDTH-1:0] read_buf;
|
||||
reg read_inprogress = 0;
|
||||
|
|
@ -125,25 +131,32 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32)
|
|||
wire [1:0] word_sel = mem_addr[3:2];
|
||||
|
||||
wire [WIDTH-1:0] read_word =
|
||||
word_sel == 3'b11 ? app_rd_data[31:0] :
|
||||
word_sel == 3'b10 ? app_rd_data[63:32] :
|
||||
word_sel == 3'b01 ? app_rd_data[95:64] :
|
||||
word_sel == 2'b11 ? app_rd_data[31:0] :
|
||||
word_sel == 2'b10 ? app_rd_data[63:32] :
|
||||
word_sel == 2'b01 ? app_rd_data[95:64] :
|
||||
app_rd_data[127:96];
|
||||
|
||||
wire [WIDTH-1:0] read_cached_word =
|
||||
word_sel == 3'b11 ? ins_cache[31:0] :
|
||||
word_sel == 3'b10 ? ins_cache[63:32] :
|
||||
word_sel == 3'b01 ? ins_cache[95:64] :
|
||||
wire [WIDTH-1:0] read_icached_word =
|
||||
word_sel == 2'b11 ? ins_cache[31:0] :
|
||||
word_sel == 2'b10 ? ins_cache[63:32] :
|
||||
word_sel == 2'b01 ? ins_cache[95:64] :
|
||||
ins_cache[127:96];
|
||||
|
||||
(*KEEP*) assign mem_read_data = cache_hit ? read_cached_word :
|
||||
wire [WIDTH-1:0] read_dcached_word =
|
||||
word_sel == 2'b11 ? d_cache[31:0] :
|
||||
word_sel == 2'b10 ? d_cache[63:32] :
|
||||
word_sel == 2'b01 ? d_cache[95:64] :
|
||||
d_cache[127:96];
|
||||
|
||||
(*KEEP*) assign mem_read_data = icache_hit ? read_icached_word :
|
||||
dcache_hit ? read_dcached_word :
|
||||
app_rd_data_valid ? read_word : read_buf;
|
||||
|
||||
// set the write mask according to the lower bits of the address
|
||||
// (ignoring bit 0)
|
||||
assign app_wdf_mask = word_sel == 3'b11 ? 16'b1111111111110000 :
|
||||
word_sel == 3'b10 ? 16'b1111111100001111 :
|
||||
word_sel == 3'b01 ? 16'b1111000011111111 :
|
||||
assign app_wdf_mask = word_sel == 2'b11 ? 16'b1111111111110000 :
|
||||
word_sel == 2'b10 ? 16'b1111111100001111 :
|
||||
word_sel == 2'b01 ? 16'b1111000011111111 :
|
||||
16'b0000111111111111 ;
|
||||
|
||||
wire write_ready = mem_write_enable & app_wdf_rdy & app_rdy;
|
||||
|
|
@ -152,7 +165,7 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32)
|
|||
assign app_wdf_data = { {4{mem_write_data}} };
|
||||
|
||||
assign mem_wait = (dram_read_enable & ~read_inprogress) |
|
||||
(mem_write_enable & (~app_wdf_rdy | ~app_rdy)) |
|
||||
(mem_write_enable & ~dcache_hit & (~app_wdf_rdy | ~app_rdy)) |
|
||||
(read_inprogress & ~app_rd_data_valid);
|
||||
|
||||
assign app_en = (dram_read_enable & ~read_inprogress) |
|
||||
|
|
@ -160,25 +173,58 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32)
|
|||
assign app_cmd = dram_read_enable ? CMD_READ : CMD_WRITE;
|
||||
|
||||
|
||||
/* set instruction cache */
|
||||
always @(posedge dram_front_clk)
|
||||
begin
|
||||
if(dram_read_enable && mem_read_ins && app_rd_data_valid)
|
||||
begin
|
||||
ins_cache <= app_rd_data;
|
||||
cached_addr <= mem_addr[DRAM_ADDR_WIDTH-1:4];
|
||||
icached_addr <= mem_addr[DRAM_ADDR_WIDTH-1:4];
|
||||
end
|
||||
end
|
||||
|
||||
/* set data cache */
|
||||
always @(posedge dram_front_clk)
|
||||
begin
|
||||
if(dram_read_enable && !mem_read_ins && app_rd_data_valid)
|
||||
begin
|
||||
d_cache <= app_rd_data;
|
||||
dcached_addr <= mem_addr[DRAM_ADDR_WIDTH-1:4];
|
||||
end
|
||||
|
||||
/* write-through cache - invalidate on write */
|
||||
/* invalidate data cache on write */
|
||||
// if(mem_write_enable && dcached_addr == mem_addr[DRAM_ADDR_WIDTH-1:4])
|
||||
// dcached_addr <= {DRAM_ADDR_WIDTH-4{1'b1}};
|
||||
|
||||
/* write-back cache - update cache on write */
|
||||
// write back to data cache on mem_write
|
||||
if(mem_write_enable && dcached_addr == mem_addr[DRAM_ADDR_WIDTH-1:4])
|
||||
begin
|
||||
case(word_sel)
|
||||
2'b11: d_cache[31:0] <= mem_write_data;
|
||||
2'b10: d_cache[63:32] <= mem_write_data;
|
||||
2'b01: d_cache[95:64] <= mem_write_data;
|
||||
2'b00: d_cache[127:96] <= mem_write_data;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
/* transfer read data, either from cache or from DRAM */
|
||||
always @(posedge dram_front_clk)
|
||||
begin
|
||||
if(dram_read_enable & ~read_inprogress & app_rdy)
|
||||
read_inprogress <= 1;
|
||||
if(read_inprogress & app_rd_data_valid)
|
||||
read_inprogress <= 0;
|
||||
|
||||
if(dram_read_enable & app_rd_data_valid)
|
||||
read_buf <= mem_read_data;
|
||||
else
|
||||
if (mem_read_enable & cache_hit)
|
||||
read_buf <= read_cached_word;
|
||||
if (mem_read_enable & icache_hit)
|
||||
read_buf <= read_icached_word;
|
||||
else
|
||||
if (mem_read_enable & dcache_hit)
|
||||
read_buf <= read_dcached_word;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue