8 input [AWIDTH-1:0] dwb_adr_i,
11 input [3:0] dwb_sel_i,
12 input [31:0] dwb_dat_i,
13 output [31:0] dwb_dat_o,
16 input [31:0] dram_dat_i,
17 output [31:0] dram_dat_o,
18 output [AWIDTH-1:0] dram_adr_o,
21 output [3:0] dram_sel_o );
23 localparam TAGWIDTH = AWIDTH-CWIDTH-2;
24 reg stb_d1, ack_d1, miss_d1;
25 reg [AWIDTH-1:0] held_addr;
26 reg [31:0] ddata [0:(1<<CWIDTH)-1];
27 reg [TAGWIDTH-1:0] dtags [0:(1<<CWIDTH)-1];
28 reg dvalid [0:(1<<CWIDTH)-1];
30 wire [CWIDTH-1:0] rd_line, wr_line;
31 wire [TAGWIDTH-1:0] wr_tags;
32 wire cache_write, invalidate;
35 // /////////////////////////////////////
38 always @(posedge wb_clk_i)
40 for(i=0;i<(1<<CWIDTH);i=i+1)
44 dvalid[wr_line] <= 1'b0;
46 dvalid[wr_line] <= 1'b1;
48 always @(posedge wb_clk_i)
51 ddata[wr_line] <= wr_data;
52 dtags[wr_line] <= wr_tags;
55 // //////////////////////////////////////
57 wire [TAGWIDTH-1:0] tag_out = dtags[rd_line];
58 wire valid_out = dvalid[rd_line];
59 wire [31:0] data_out = ddata[rd_line];
60 wire cache_hit = valid_out & (tag_out == dwb_adr_i[AWIDTH-1:CWIDTH+2]);
61 wire cache_miss = ~cache_hit;
63 // //////////////////////////////////////
64 // Handle 1-cycle delay of Block-RAM
65 always @(posedge wb_clk_i)
71 always @(posedge wb_clk_i)
75 held_addr <= dwb_adr_i;
77 always @(posedge wb_clk_i)
83 always @(posedge wb_clk_i)
87 miss_d1 <= cache_miss;
91 //`define DC_FORWARDING_DP
92 //`define DC_FORWARDING_SP
96 assign dwb_dat_o = dram_dat_i;
97 assign dwb_ack_o = dwb_stb_i & (dwb_we_i | (stb_d1 & ~ack_d1));
98 assign dram_adr_o = dwb_adr_i;
99 assign dram_en_o = dwb_stb_i;
100 assign dram_dat_o = dwb_dat_i;
101 assign dram_we_o = dwb_we_i;
102 assign dram_sel_o = dwb_sel_i;
107 assign cache_write = 0;
108 assign invalidate = 0;
111 `ifdef DC_BASIC // Very basic, no forwarding, 2 wait states on miss
112 assign dwb_dat_o = data_out;
113 assign dwb_ack_o = dwb_stb_i & cache_hit;
114 assign dram_adr_o = dwb_adr_i;
115 assign dram_en_o = dwb_stb_i;
116 assign dram_dat_o = dwb_dat_i;
117 assign dram_we_o = dwb_we_i;
118 assign dram_sel_o = dwb_sel_i;
119 assign rd_line = dwb_adr_i[CWIDTH+1:2];
120 assign wr_line = rd_line;
121 assign wr_tags = dwb_adr_i[AWIDTH-1:CWIDTH+2];
122 assign wr_data = dwb_we_i ? dwb_dat_i : dram_dat_i;
123 assign cache_write = dwb_stb_i & (dwb_we_i | (stb_d1 & miss_d1));
124 assign invalidate = dwb_we_i & ~(&dwb_sel_i);
127 `ifdef DC_FORWARDING_DP // Simple forwarding, 1 wait state on miss, dual-port ram
128 assign dwb_dat_o = cache_hit ? data_out : dram_dat_i;
129 assign dwb_ack_o = dwb_stb_i & (cache_hit | (stb_d1 & ~ack_d1));
130 assign dram_adr_o = dwb_adr_i;
131 assign dram_en_o = 1'b1;
132 assign dram_dat_o = dwb_dat_i;
133 assign dram_we_o = dwb_we_i;
134 assign dram_sel_o = dwb_sel_i;
135 assign rd_line = dwb_adr_i[CWIDTH+1:2];
136 assign wr_line = held_addr[CWIDTH+1:2];
137 assign wr_tags = held_addr[AWIDTH-1:CWIDTH+2];
138 assign wr_data = dram_dat_i;
139 assign cache_write = dwb_stb_i & stb_d1 & miss_d1 & ~ack_d1;
140 assign invalidate = 0;
143 `ifdef DC_FORWARDING_SP // Simple forwarding, 1 wait state on miss, single-port ram
144 assign dwb_dat_o = cache_hit ? data_out : dram_dat_i;
145 assign dwb_ack_o = dwb_stb_i & (cache_hit | (stb_d1 & ~ack_d1));
146 assign dram_adr_o = dwb_adr_i;
147 assign dram_en_o = 1'b1;
148 assign dram_dat_o = dwb_dat_i;
149 assign dram_we_o = dwb_we_i;
150 assign dram_sel_o = dwb_sel_i;
151 assign rd_line = dwb_adr_i[CWIDTH+1:2];
152 assign wr_line = rd_line;
153 assign wr_tags = dwb_adr_i[AWIDTH-1:CWIDTH+2];
154 assign wr_data = dram_dat_i;
155 assign cache_write = dwb_stb_i & stb_d1 & miss_d1 & ~ack_d1;
156 assign invalidate = 0;
159 `ifdef DC_PREFETCH // Forwarding plus prefetch