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