Make the associative BTB compressed.
That is, only store the bottom 16 bits of the target if the upper bits of pc and nextPc match. Have a single "way" dedicated to full targets.
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user