rlm@8: import RegFile::*; rlm@8: import ProcTypes::*; rlm@8: import FIFO::*; rlm@8: rlm@8: typedef Maybe#(Addr) BrPred; rlm@8: typedef Bit#(4) BPindx; rlm@8: rlm@8: typedef struct {Addr brpc; Addr nextpc;} BrPair deriving (Bits,Eq); rlm@8: rlm@8: typedef union tagged rlm@8: { rlm@8: BrPair Valid; rlm@8: void Invalid; rlm@8: } CBranchPath deriving(Bits, Eq); // have the cache start out invalid and add valid values. rlm@8: rlm@8: interface BranchPred; rlm@8: method BrPred get(Addr pres); //returns a maybe type that is invalid if no predition rlm@8: method Action upd(Addr pres, Addr next); rlm@8: endinterface rlm@8: rlm@8: module mkBranchPred(BranchPred); rlm@8: rlm@8: //state variables rlm@8: RegFile#(BPindx, CBranchPath) bcache <- mkRegFileFull(); // cache to hold 16 (based on BPindx) rlm@8: rlm@8: method Action upd(Addr pres, Addr next); rlm@8: BrPair brp; rlm@8: brp = BrPair {brpc:pres, nextpc:next}; rlm@8: bcache.upd(pres[5:2], tagged Valid brp); rlm@8: endmethod rlm@8: rlm@8: method BrPred get(Addr prespc); rlm@8: BPindx rd = prespc[5:2]; rlm@8: let cbp = bcache.sub(rd); rlm@8: if (cbp matches tagged Valid .bp &&& bp.brpc == prespc) //make sure that the read value was actually put there and the full address matches rlm@8: return tagged Valid bp.nextpc; rlm@8: else return Invalid; rlm@8: endmethod rlm@8: rlm@8: endmodule rlm@8: