punk@1
|
1 import RegFile::*;
|
punk@1
|
2 import ProcTypes::*;
|
punk@1
|
3 import FIFO::*;
|
punk@1
|
4
|
punk@1
|
5 typedef Maybe#(Addr) BrPred;
|
punk@1
|
6 typedef Bit#(4) BPindx;
|
punk@1
|
7
|
punk@1
|
8 typedef struct {Addr brpc; Addr nextpc;} BrPair deriving (Bits,Eq);
|
punk@1
|
9
|
punk@1
|
10 typedef union tagged
|
punk@1
|
11 {
|
punk@1
|
12 BrPair Valid;
|
punk@1
|
13 void Invalid;
|
punk@1
|
14 } CBranchPath deriving(Bits, Eq); // have the cache start out invalid and add valid values.
|
punk@1
|
15
|
punk@1
|
16 interface BranchPred;
|
punk@1
|
17 method BrPred get(Addr pres); //returns a maybe type that is invalid if no predition
|
punk@1
|
18 method Action upd(Addr pres, Addr next);
|
punk@1
|
19 endinterface
|
punk@1
|
20
|
punk@1
|
21 module mkBranchPred(BranchPred);
|
punk@1
|
22
|
punk@1
|
23 //state variables
|
punk@1
|
24 RegFile#(BPindx, CBranchPath) bcache <- mkRegFileFull(); // cache to hold 16 (based on BPindx)
|
punk@1
|
25
|
punk@1
|
26 method Action upd(Addr pres, Addr next);
|
punk@1
|
27 BrPair brp;
|
punk@1
|
28 brp = BrPair {brpc:pres, nextpc:next};
|
punk@1
|
29 bcache.upd(pres[5:2], tagged Valid brp);
|
punk@1
|
30 endmethod
|
punk@1
|
31
|
punk@1
|
32 method BrPred get(Addr prespc);
|
punk@1
|
33 BPindx rd = prespc[5:2];
|
punk@1
|
34 let cbp = bcache.sub(rd);
|
punk@1
|
35 if (cbp matches tagged Valid .bp &&& bp.brpc == prespc) //make sure that the read value was actually put there and the full address matches
|
punk@1
|
36 return tagged Valid bp.nextpc;
|
punk@1
|
37 else return Invalid;
|
punk@1
|
38 endmethod
|
punk@1
|
39
|
punk@1
|
40 endmodule
|
punk@1
|
41
|