diff --git a/src_Core/RISCY_OOO/procs/lib/Btb.bsv b/src_Core/RISCY_OOO/procs/lib/Btb.bsv index 3c572d3..335d1ab 100644 --- a/src_Core/RISCY_OOO/procs/lib/Btb.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Btb.bsv @@ -58,6 +58,7 @@ endinterface // Local BTB Typedefs typedef 1 PcLsbsIgnore; typedef 1024 BtbEntries; +typedef Bit#(16) CompressedTarget; typedef 2 BtbAssociativity; typedef Bit#(TLog#(SupSizeX2)) BtbBank; // Total entries/lanes of superscalar lookup/associativity @@ -94,9 +95,11 @@ module mkBtbCore(NextAddrPred#(hashSz)) Add#(1, a__, TDiv#(tagSz, hashSz)), Add#(b__, tagSz, TMul#(TDiv#(tagSz, hashSz), hashSz))); // Read and Write ordering doesn't matter since this is a predictor - Reg#(BtbBank) firstBank_reg <- mkRegU; - Vector#(SupSizeX2, MapSplit#(HashedTag#(hashSz), BtbIndex, VnD#(CapMem), BtbAssociativity)) - records <- replicateM(mkMapLossyBRAM); + Reg#(CapMem) addr_reg <- mkRegU; + Vector#(SupSizeX2, MapSplit#(HashedTag#(hashSz), BtbIndex, VnD#(CapMem), 1)) + fullRecords <- replicateM(mkMapLossyBRAM); + Vector#(SupSizeX2, MapSplit#(HashedTag#(hashSz), BtbIndex, VnD#(CompressedTarget), BtbAssociativity)) + compressedRecords <- replicateM(mkMapLossyBRAM); RWire#(BtbUpdate) updateEn <- mkRWire; function BtbAddr getBtbAddr(CapMem pc) = unpack(truncateLSB(getAddr(pc))); @@ -114,26 +117,34 @@ module mkBtbCore(NextAddrPred#(hashSz)) let taken = upd.taken; /*$display("MapUpdate in BTB - pc %x, bank: %x, taken: %x, next: %x, time: %t", pc, getBank(pc), taken, nextPc, $time);*/ - records[getBank(pc)].update(lookupKey(pc), VnD{v:taken, d:nextPc}); + CompressedTarget shortMask = -1; + CapMem mask = ~zeroExtend(shortMask); + if ((pc&mask) == (nextPc&mask)) + compressedRecords[getBank(pc)].update(lookupKey(pc), VnD{v:taken, d:truncate(nextPc)}); + else + fullRecords[getBank(pc)].update(lookupKey(pc), VnD{v:taken, d:nextPc}); endrule method Action put_pc(CapMem pc); - BtbAddr addr = getBtbAddr(pc); - firstBank_reg <= addr.bank; + addr_reg <= pc; // Start SupSizeX2 BTB lookups, but ensure to lookup in the appropriate // bank for the alignment of each potential branch. for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) begin - BtbAddr a = unpack(pack(addr) + fromInteger(i)); - records[a.bank].lookupStart(MapKeyIndex{key: hash(a.tag), index: a.index}); + BtbAddr a = unpack(pack(getBtbAddr(pc)) + fromInteger(i)); + fullRecords[a.bank].lookupStart(MapKeyIndex{key: hash(a.tag), index: a.index}); + compressedRecords[a.bank].lookupStart(MapKeyIndex{key: hash(a.tag), index: a.index}); end endmethod method Vector#(SupSizeX2, Maybe#(CapMem)) pred; Vector#(SupSizeX2, Maybe#(CapMem)) ppcs = replicate(Invalid); - for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) - if (records[i].lookupRead matches tagged Valid .record) - ppcs[i] = record.v ? Valid(record.d):Invalid; - ppcs = rotateBy(ppcs,unpack(-firstBank_reg)); // Rotate firstBank down to zeroeth element. + for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) begin + if (fullRecords[i].lookupRead matches tagged Valid .r) + ppcs[i] = r.v ? Valid(r.d):Invalid; + if (compressedRecords[i].lookupRead matches tagged Valid .r) + ppcs[i] = r.v ? Valid({truncateLSB(addr_reg),r.d}):Invalid; + end + ppcs = rotateBy(ppcs,unpack(-getBtbAddr(addr_reg).bank)); // Rotate firstBank down to zeroeth element. return ppcs; endmethod @@ -143,9 +154,12 @@ module mkBtbCore(NextAddrPred#(hashSz)) `ifdef SECURITY method Action flush method Action flush; - for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) records[i].clear; + for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) begin + fullRecords[i].clear; + compressedRecords[i].clear; + end endmethod - method flush_done = records[0].clearDone; + method flush_done = fullRecords[0].clearDone; `else method flush = noAction; method flush_done = True;