2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
15 /*===== Pacakge imports ===== */
19 import SpecialFIFOs::*;
25 /*===== project imports==== */
26 import defined_types::*;
28 import branchpredictor::*;
30 `include "core_parameters.bsv"
31 /*========================= */
35 method Action virtual_address(Bit#(`VADDR) vaddress,Bool fence);
36 method Maybe#(Tuple3#(Bit#(32), Trap_type, Bit#(`PERFMONITORS))) response_to_core;
37 method Action response_from_memory(From_Memory#(`DCACHE_WORD_SIZE) resp);
38 method ActionValue#(To_Memory#(`PADDR)) request_to_memory;
39 method Action stall_fetch(Bool stall);
41 // method Bool init_complete;
43 method Maybe#(Tuple2#(Bit#(`VADDR),Bit#(2))) prediction_response;
44 method Action training (Maybe#(Training_data#(`VADDR)) training_data);
47 method Action physical_address(Bit#(`PADDR) paddr, Trap_type ex);
50 method Bit#(`PERFMONITORS) icache_perfmon;
52 method ActionValue#(Bit#(`VADDR)) prefetch();
56 typedef enum {Idle,Stall,ReadingCache,Fence,IOReadResp} IcacheState deriving (Bits,Eq,FShow);
59 (*preempts="fillcache,fencing_the_cache"*)
60 module mkicache(Ifc_icache);
61 /* VAddr = [tag_bits|set_bits|word_bits|byte_bits] */
62 let byte_bits=valueOf(TLog#(`ICACHE_WORD_SIZE)); // number of bits to select a byte within a word. = 2
63 let word_bits=valueOf(TLog#(`ICACHE_BLOCK_SIZE)); // number of bits to select a word within a block. = 4
64 let set_bits=valueOf(TLog#(`ICACHE_SETS)); // number of bits to select a set from the cache. =
66 Ifc_branchpredictor bpu <-mkbranchpredictor;
67 Wire#(Maybe#(Tuple2#(Bit#(`VADDR),Bit#(2)))) wr_prediction_to_cpu <-mkDWire(tagged Invalid);
70 BRAM_DUAL_PORT#(Bit#(TLog#(`ICACHE_SETS)),Bit#(TAdd#(`ICACHE_TAG_BITS,2))) tag [`ICACHE_WAYS];
71 BRAM_DUAL_PORT_BE#(Bit#(TLog#(`ICACHE_SETS)),Bit#(TMul#(TMul#(8,`ICACHE_WORD_SIZE),`ICACHE_BLOCK_SIZE)),64) data [`ICACHE_WAYS];
72 for(Integer i=0;i<`ICACHE_WAYS;i=i+1)begin
73 tag[i] <- mkBRAMCore2(`ICACHE_SETS,False);
74 data[i] <-mkBRAMCore2BE(`ICACHE_SETS,False);
77 LFSR#(Bit#(2)) random_line<-mkRCounter(3); // for random line replacement
78 Reg#(Bit#(`VADDR)) rg_vaddress<-mkReg(0);
79 Reg#(Bit#(`PADDR)) rg_paddress<-mkReg(0);
80 Reg#(Trap_type) rg_tlb_exception[2]<-mkCReg(2,tagged None);
81 Reg#(Bool) rg_trnslte_done[2] <- mkCReg(2, `ifdef MMU False `else True `endif );
82 Reg#(Bool) rg_stall_fetch <- mkReg(False);
84 Reg#(Bit#(`PERFMONITORS)) rg_perf_monitor<-mkReg(0);
85 Reg#(IcacheState) rg_state[3]<-mkCReg(3,Fence); // this needs to be a CReg so that request can fire in the same cycle as response
86 Reg#(Bit#(TAdd#(1,TLog#(`ICACHE_SETS)))) rg_index <-mkReg(0);
87 Reg#(Maybe#(Bit#(TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE)))) rg_we<-mkReg(tagged Invalid);
88 Reg#(Bit#(TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE))) line_bytes_written<-mkReg(0);
89 Reg#(Bool) increment_counters <-mkReg(True);
90 Reg#(Bool) capture_counters <-mkDReg(False);
92 Wire#(Maybe#(Bit#(`VADDR))) wr_memoperation_address <-mkDWire(tagged Invalid);
94 Reg#(Bool) ignore_memory_response<-mkReg(False);
96 Reg#(Bool) prefetchmode<-mkReg(False);
97 Reg#(Maybe#(Bit#(`VADDR))) rg_prefetchpc<-mkReg(tagged Invalid);
100 Wire#(Maybe#(Tuple3#(Bit#(32), Trap_type,Bit#(`PERFMONITORS)))) wr_response_to_cpu<-mkDWire(tagged Invalid);
101 FIFOF#(To_Memory#(`PADDR)) ff_request_to_memory <-mkSizedBypassFIFOF(1);
102 FIFOF#(From_Memory#(`DCACHE_WORD_SIZE)) ff_response_from_memory <-mkSizedBypassFIFOF(1);
103 FIFOF#(Tuple4#(Bit#(`PADDR),Bit#(`VADDR),Bit#(TLog#(`ICACHE_WAYS)),Bit#(TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE)))) memoperation <-mkUGSizedFIFOF(2);
105 `ifdef verbose $display($time,"\tICACHE: State: ",fshow(rg_state[2])," wr_flush ",fshow(wr_flush)," rg_flush ",fshow(rg_flush)); `endif
106 `ifdef verbose $display($time,"\tICACHE: translation done %h tlbexception: ", rg_trnslte_done[1], fshow(rg_tlb_exception[1])); `endif
109 /*====== Invalidate all the entries in the cache on startup or during Fence ==== */
110 rule fencing_the_cache(rg_state[0]==Fence);
111 rg_we<=tagged Invalid;
113 `ifdef verbose $display($time,"\tFencing icache of index %d", rg_index); `endif
114 for(Integer i=0;i<`ICACHE_WAYS;i=i+1)begin
115 tag[i].b.put(True,truncate(rg_index),0);
117 if(rg_index==fromInteger(`ICACHE_SETS)) begin
118 if(!rg_stall_fetch) begin
119 `ifdef verbose $display($time,"\tFencing icache of is over"); `endif
122 random_line.seed('d3);
126 rg_index<=rg_index+1;
128 rule discard_memory_responses_during_fence;
129 ff_response_from_memory.deq;
131 /*=============================================================================== */
132 rule read_data_fromcache(rg_state[0]==ReadingCache && memoperation.notFull);
133 /*========== Check for hit or miss =================== */
134 Bit#(TLog#(`ICACHE_WAYS)) linenum=0;
135 Bit#(`PERFMONITORS) perf_monitor=rg_perf_monitor;
136 Bit#(TMul#(TMul#(`ICACHE_BLOCK_SIZE,`ICACHE_WORD_SIZE),8)) dataline=0;
137 increment_counters<=True;
139 Bit#(`ICACHE_WAYS) valid_values; // hold the valid and dirty bits
140 Bit#(TLog#(`ICACHE_BLOCK_SIZE)) byteoffset=rg_vaddress[word_bits+byte_bits-1:byte_bits];
141 Bit#(TLog#(`DCACHE_SETS)) setindex=rg_vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits];
143 Bit#(`ICACHE_TAG_BITS) cpu_tag=rg_paddress[`PADDR-1:`PADDR-`ICACHE_TAG_BITS];
145 Bit#(`ICACHE_TAG_BITS) cpu_tag=rg_vaddress[`PADDR-1:`PADDR-`ICACHE_TAG_BITS];
147 if(rg_trnslte_done[0]) begin
149 if(rg_tlb_exception[0] matches tagged None)begin
150 if(!is_IO_Addr(rg_paddress))begin
152 if(!is_IO_Addr(truncate(rg_vaddress)))begin
155 if(!prefetchmode && increment_counters)
156 perf_monitor[`ICACHE_CACHEABLE]=1; // cacheable access increment
158 perf_monitor[`ICACHE_CACHEABLE]=1; // cacheable access increment
160 for(Integer i=0;i<`ICACHE_WAYS;i=i+1)begin
161 let stored_tag=tag[i].a.read[19:0];
162 let stored_valid=tag[i].a.read[20];
163 valid_values[i]=tag[i].a.read[20];
164 if(stored_valid==1 && stored_tag==cpu_tag)begin // if a tag matches capture the tag and data
166 linenum=fromInteger(i);
167 dataline=data[i].a.read;
168 `ifdef verbose $display($time,"ICACHE: DATALINE: %h",dataline); `endif
171 Bit#(32) data_value=(dataline>>{5'd0,byteoffset}*32)[31:0];
173 /*====================================================== */
174 /*=========== Respond to Core ============================ */
175 if(rg_vaddress[1:0]!=0)begin // miss-aligned error.
176 perf_monitor[`ICACHE_MISALIGNED]=1; // cache mis-aligned error.
177 wr_response_to_cpu<=tagged Valid (tuple3(0,tagged Exception Inst_addr_misaligned,perf_monitor));
180 `ifdef prefetch prefetchmode<=False; `endif
181 let x<-bpu.prediction_response;
182 wr_prediction_to_cpu<=tagged Valid x;
183 `ifdef MMU rg_trnslte_done[0] <= False; `endif
185 else if(hit)begin // if there has been a hit.
186 `ifdef verbose $display($time,"\tICACHE: Hit for address : %h data: %h offset: %h line: %d",rg_vaddress,data_value,byteoffset,linenum); `endif
187 rg_prefetchpc<=tagged Invalid;
189 if(!prefetchmode)begin
190 wr_response_to_cpu<=tagged Valid (tuple3(data_value,tagged None,perf_monitor));
192 `ifdef MMU rg_trnslte_done[0] <= False; `endif
197 wr_response_to_cpu<=tagged Valid (tuple3(data_value,tagged None,perf_monitor));
199 `ifdef MMU rg_trnslte_done[0] <= False; `endif
202 let x<-bpu.prediction_response;
203 wr_prediction_to_cpu<=tagged Valid x;
205 /*====================================================== */
206 /*==== Request to memory =============================== */
209 if(!prefetchmode) begin
210 if(rg_vaddress[11:5]!='1)begin // check that prefetch does not cross physical page boundary
211 Bit#(`VADDR) mask='1<<(byte_bits+word_bits);
212 rg_prefetchpc<=tagged Valid ((rg_vaddress&mask)+('d1<<(word_bits+byte_bits)));
213 perf_monitor[`ICACHE_MISS]=1; // cache miss increment.
217 else // in prefetch mode send memory request and leave
220 perf_monitor[`ICACHE_MISS]=1; // cache miss increment.
223 Bit#(TLog#(`ICACHE_WAYS)) replaceblock;
224 if(valid_values=='1)begin // if all the lines are valid and no match then replace line
225 perf_monitor[`ICACHE_LINEREPLACE]=1; // cache line replacement increment.
226 replaceblock=truncate(random_line.value);
228 if(prefetchmode)begin
229 `ifdef verbose $display($time,"\tICACHE: Prefetch Miss of address: %h Replacing line: %d valid: %b",rg_vaddress,random_line.value[1:0],valid_values); `endif
230 perf_monitor[`ICACHE_PREFETCHMISS]=1;
233 $display($time,"\tICACHE: Miss of address: %h Replacing line: %d valid: %b",rg_vaddress,random_line.value[1:0],valid_values); `endif
235 else begin // find the line which is not valid and fill it
236 let x=countZerosLSB(valid_values)-1;
237 replaceblock=pack(truncate(x));
238 if(prefetchmode)begin
239 `ifdef verbose $display($time,"\tICACHE: Prefetch Miss of address: %h Filling line: %d",rg_vaddress,x); `endif
240 perf_monitor[`ICACHE_PREFETCHMISS]=1;
243 $display($time,"\tICACHE: Miss of address: %h Filling line: %d",rg_vaddress,x); `endif
246 ff_request_to_memory.enq(To_Memory {address:truncate(rg_paddress&'hfffffff8),burst_length:fromInteger(`ICACHE_BLOCK_SIZE/2),ld_st:Load, transfer_size:3});
248 ff_request_to_memory.enq(To_Memory {address:truncate(rg_vaddress&'hfffffff8),burst_length:fromInteger(`ICACHE_BLOCK_SIZE/2),ld_st:Load, transfer_size:3});
250 Bit#(TLog#(`ICACHE_BLOCK_SIZE)) val1=(rg_vaddress&'hfffffff8)[word_bits+byte_bits-1:byte_bits];
251 Bit#(TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE)) writeenable='hFF;
252 writeenable=writeenable<<{3'b0,val1}*4;
253 memoperation.enq(tuple4(rg_paddress,rg_vaddress,replaceblock,writeenable));
254 `ifdef verbose $display($time,"\tICACHE: mask: %h byteoffset: %h perfmonitors: %h",writeenable,val1,perf_monitor); `endif
255 rg_perf_monitor<=perf_monitor;
259 if(!prefetchmode)begin
261 ff_request_to_memory.enq(To_Memory {address:truncate(rg_paddress),burst_length:1,ld_st:Load, transfer_size:2});
263 ff_request_to_memory.enq(To_Memory {address:truncate(rg_vaddress),burst_length:1,ld_st:Load, transfer_size:2});
265 rg_state[0]<=IOReadResp;
266 `ifdef verbose $display($time,"\tICACHE: Sending Address for IO ACCESS: %h",rg_paddress); `endif
269 $display($time,"\tICACHE: Do not prefetch in IO space");
276 if(!prefetchmode)begin
277 wr_response_to_cpu<=tagged Valid tuple3(0,rg_tlb_exception[0],perf_monitor);
278 let x<-bpu.prediction_response;
279 wr_prediction_to_cpu<=tagged Valid x;
282 $display($time,"\tICACHE: do not respond if Prefetch generated a exception");
286 `ifdef MMU rg_trnslte_done[0] <= False; `endif
287 rg_tlb_exception[0]<=tagged None;
289 /*===================================================================*/
292 `ifdef verbose $display($time,"\tICACHE: Translated Address not Available"); `endif
293 rg_state[0] <= Stall;
296 /*======= filling up the cache from the data recieved from the external memory ======= */
297 rule read_IO_response(rg_state[0]==IOReadResp && !memoperation.notEmpty);
298 let memresp=ff_response_from_memory.first;
299 `ifdef verbose $display($time,"\tICACHE: Got response from IO ADDRESS: %h",memresp.data_line); `endif
300 wr_response_to_cpu<=tagged Valid (tuple3(truncate(memresp.data_line),memresp.bus_error==1?tagged Exception Inst_access_fault:tagged None,1));
301 wr_prediction_to_cpu<=tagged Valid (tuple2(0,0));
304 rule temp(memoperation.notEmpty);
305 let {paddress,vaddress,replaceblock,writeenable}=memoperation.first;
306 wr_memoperation_address<=tagged Valid vaddress;
308 rule fillcache(memoperation.notEmpty);
309 let memresp=ff_response_from_memory.first;
310 let {paddress,vaddress,replaceblock,writeenable}=memoperation.first;
312 let cpu_tag=paddress[`PADDR-1:`PADDR-`ICACHE_TAG_BITS];
314 let cpu_tag=vaddress[`PADDR-1:`PADDR-`ICACHE_TAG_BITS];
316 let setindex=vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits];
317 `ifdef verbose $display($time,"\tICACHE: Response from Memory: %h ",memresp.data_line); `endif
319 if(rg_we matches tagged Valid .x)begin
322 Bit#(TMul#(2,TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE))) extended_mask=zeroExtend(we)<<8;
323 data[replaceblock].b.put(we,setindex,duplicate(memresp.data_line));
324 `ifdef verbose $display($time,"\tICACHE ExtendedMASK: %h RgMASK: %h line_bytes_written: %h",extended_mask,we,line_bytes_written); `endif
325 tag[replaceblock].b.put(True,setindex,{2'b1,cpu_tag}); // update the tag value
326 if(memresp.last_word)begin // if all the data words have been fetched exit
327 `ifdef verbose $display($time,"\tICACHE: Received Last response from Memory"); `endif
331 rg_we<=tagged Invalid;
333 line_bytes_written<=0;
336 rg_we<=tagged Valid (extended_mask[2*`ICACHE_BLOCK_SIZE*`ICACHE_WORD_SIZE-1:`ICACHE_BLOCK_SIZE*`ICACHE_WORD_SIZE]|extended_mask[`ICACHE_BLOCK_SIZE*`ICACHE_WORD_SIZE-1:0]);
337 line_bytes_written<=line_bytes_written|we;
340 /*===================================================================================== */
341 /*===================================================================================== */
342 rule keep_polling_on_stall(rg_state[0]==Stall);
343 Bit#(TLog#(`ICACHE_BLOCK_SIZE)) byteoffset=rg_vaddress[word_bits+byte_bits-1:byte_bits];
344 Bit#(TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE)) requested_word=('hF<<({2'd0,byteoffset}*4));
345 Bool generate_request=True;
346 Bit#(`PERFMONITORS) perf_monitor=0;
347 if(capture_counters)begin
348 perf_monitor[`ICACHE_CACHEABLE]=1;
349 perf_monitor[`ICACHE_MISS]=1;
350 rg_perf_monitor<=perf_monitor;
353 if(!memoperation.notFull)
354 generate_request=False;
355 else if(wr_memoperation_address matches tagged Valid .x)begin // some line is being filled from memory
356 Bit#(TSub#(`VADDR,TAdd#(TLog#(`ICACHE_WORD_SIZE),TLog#(`ICACHE_BLOCK_SIZE)))) memline=x[`VADDR-1:word_bits+byte_bits];
357 Bit#(TSub#(`VADDR,TAdd#(TLog#(`ICACHE_WORD_SIZE),TLog#(`ICACHE_BLOCK_SIZE)))) reqline=rg_vaddress[`VADDR-1:word_bits+byte_bits];
358 if(memline==reqline) // they are accessing the same line
359 if((line_bytes_written & requested_word) != requested_word)
360 generate_request=False;
362 if(generate_request && rg_trnslte_done[1])begin
363 Bit#(TLog#(`ICACHE_SETS)) setindex=rg_vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits];
364 `ifdef verbose $display($time,"\tICACHE: POLLING ON VAddr: %h set: %d rg_trnslte_done: %b",rg_vaddress, setindex,rg_trnslte_done[1]); `endif
365 increment_counters<=False;
366 for(Integer i=0;i<`ICACHE_WAYS;i=i+1)begin // send address to the Block_rams
367 tag[i].a.put(False,rg_vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits], ?);
368 data[i].a.put('d0,rg_vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits], ?);
371 bpu.send_prediction_request(rg_vaddress);
373 rg_state[0]<=ReadingCache;
377 /*============= Prediction in burst mode ================================ */
378 method Action virtual_address(Bit#(`VADDR) vaddress,Bool fence)if(rg_state[1]==Idle);
383 Bit#(TLog#(`ICACHE_SETS)) setindex=vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits];
384 `ifdef verbose $display($time,"\tICACHE: Request of VAddr: %h set: %d",vaddress, setindex); `endif
385 Bit#(TLog#(`ICACHE_BLOCK_SIZE)) byteoffset=vaddress[word_bits+byte_bits-1:byte_bits];
386 Bit#(TMul#(`ICACHE_WORD_SIZE,`ICACHE_BLOCK_SIZE)) requested_word=('hF<<({2'd0,byteoffset}*4));
387 Bool generate_request=True;
388 if(!memoperation.notFull)
389 generate_request=False;
390 else if(wr_memoperation_address matches tagged Valid .x)begin // some line is being filled from memory
391 Bit#(TSub#(`VADDR,TAdd#(TLog#(`ICACHE_WORD_SIZE),TLog#(`ICACHE_BLOCK_SIZE)))) memline=x[`VADDR-1:word_bits+byte_bits];
392 Bit#(TSub#(`VADDR,TAdd#(TLog#(`ICACHE_WORD_SIZE),TLog#(`ICACHE_BLOCK_SIZE)))) reqline=vaddress[`VADDR-1:word_bits+byte_bits];
393 if(memline==reqline) // they are accessing the same line
394 if((line_bytes_written & requested_word) != requested_word)
395 generate_request=False;
397 rg_vaddress<=vaddress;
398 if(generate_request)begin
399 for(Integer i=0;i<`ICACHE_WAYS;i=i+1)begin // send address to the Block_rams
400 tag[i].a.put(False,vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits], ?);
401 data[i].a.put('d0,vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits], ?);
404 bpu.send_prediction_request(vaddress);
406 rg_state[1]<=ReadingCache;
409 `ifdef verbose $display($time,"\tICACHE: Miss during Cache Fill"); `endif
410 capture_counters<=True;
415 method Maybe#(Tuple3#(Bit#(32), Trap_type, Bit#(`PERFMONITORS))) response_to_core;
416 return wr_response_to_cpu;
419 method Action physical_address(Bit#(`PADDR) paddr, Trap_type ex);
420 `ifdef verbose $display($time,"\tICACHE: Sending physical address %h to icache ",paddr); `endif
422 rg_tlb_exception[1]<=ex;
423 //rg_state[1]<=ReadingCache;
424 rg_trnslte_done[1] <= True;
427 method ActionValue#(To_Memory#(`PADDR)) request_to_memory;
428 ff_request_to_memory.deq;
429 return ff_request_to_memory.first;
431 method Action response_from_memory(From_Memory#(`DCACHE_WORD_SIZE) resp);
432 if(!ignore_memory_response)
433 ff_response_from_memory.enq(resp);
434 else if(resp.last_word)
435 ignore_memory_response<=False;
437 method Bit#(`PERFMONITORS) icache_perfmon;
438 return rg_perf_monitor;
440 // method Bool init_complete;
441 // return (rg_state[1]!=Fence `ifdef bpu && bpu.init_complete `endif );
443 method Action stall_fetch(Bool stall);
444 rg_stall_fetch <= stall;
447 method ActionValue#(Bit#(`VADDR)) prefetch() if(rg_state[1]==Idle &&& rg_prefetchpc matches tagged Valid .vaddress &&& !memoperation.notEmpty);
448 Bit#(TLog#(`ICACHE_SETS)) setindex=vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits];
449 `ifdef verbose $display($time,"\tICACHE: Prefetch Request of VAddr: %h set: %d",vaddress, setindex); `endif
450 for(Integer i=0;i<`ICACHE_WAYS;i=i+1)begin // send address to the Block_rams
451 tag[i].a.put(False,vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits], ?);
452 data[i].a.put('d0,vaddress[set_bits+word_bits+byte_bits-1:word_bits+byte_bits], ?);
454 rg_state[1]<=ReadingCache;
455 rg_vaddress<=vaddress;
457 rg_prefetchpc<=tagged Invalid;
462 method Maybe#(Tuple2#(Bit#(`VADDR),Bit#(2))) prediction_response;
463 return wr_prediction_to_cpu;
465 method Action training (Maybe#(Training_data#(`VADDR)) training_data)=bpu.training(training_data);