Merge pull request #36 from h-chal/fix_rv64mi-p-access
fix: cache full virtual address for TLB micro-cache (cherry picked from commit a79a4502c0e689058e6a2ffafd75b507c57ed3b9)
This commit is contained in:
committed by
Jessica Clarke
parent
ed011ac0fe
commit
8fc12c1dee
@@ -520,10 +520,24 @@ module mkFetchStage(FetchStage);
|
||||
nextAddrPred.put_pc(pc_reg[pc_final_port]);
|
||||
endrule
|
||||
|
||||
Reg#(Vector#(PageBuffSize,Maybe#(Vpn))) buffered_translation_virt_pc <- mkReg(replicate(Invalid));
|
||||
Reg#(Vector#(PageBuffSize,Maybe#(Addr))) buffered_translation_virt_pc <- mkReg(replicate(Invalid));
|
||||
Reg#(Vector#(PageBuffSize,TlbResp)) buffered_translation_tlb_resp <- mkRegU;
|
||||
Reg#(Bit#(TLog#(PageBuffSize))) buffered_translation_count <- mkRegU;
|
||||
|
||||
function Maybe#(UInt#(TLog#(PageBuffSize))) matchingVpnOrInvalidAddress(Addr pc);
|
||||
// Maybe return an entry with the same VPN or same full PC if its an invalid address.
|
||||
if (validVirtualAddress(pc)) begin
|
||||
// Compare VPNs.
|
||||
function Maybe#(Vpn) getVpnIfPossible(Maybe#(Addr) maybePc);
|
||||
if (maybePc matches tagged Valid .pc) getVpnIfPossible = Valid(getVpn(pc));
|
||||
else getVpnIfPossible = Invalid;
|
||||
endfunction
|
||||
matchingVpnOrInvalidAddress = findElem(Valid(getVpn(pc)), map(getVpnIfPossible, buffered_translation_virt_pc));
|
||||
end else
|
||||
// Compare entire PCs.
|
||||
matchingVpnOrInvalidAddress = findElem(Valid(pc), buffered_translation_virt_pc);
|
||||
endfunction
|
||||
|
||||
rule invalidate_buffered_translation(!iTlb.flush_done);
|
||||
buffered_translation_virt_pc <= replicate(Invalid);
|
||||
endrule
|
||||
@@ -536,9 +550,10 @@ module mkFetchStage(FetchStage);
|
||||
translateAddress.deq;
|
||||
if (iTlb.flush_done) begin
|
||||
// Check if, because of pipelining, we already have this vpn.
|
||||
Bool found = elem(Valid(getVpn(translateAddress.first)), buffered_translation_virt_pc);
|
||||
if (!found) begin
|
||||
buffered_translation_virt_pc[buffered_translation_count] <= Valid(getVpn(translateAddress.first));
|
||||
let pc = translateAddress.first;
|
||||
if (!isValid(matchingVpnOrInvalidAddress(pc))) begin
|
||||
// If we don't have this VPN or the PC is invalid and doesn't match in full:
|
||||
buffered_translation_virt_pc[buffered_translation_count] <= Valid(pc);
|
||||
buffered_translation_tlb_resp[buffered_translation_count] <= tr;
|
||||
buffered_translation_count <= buffered_translation_count + 1;
|
||||
end
|
||||
@@ -570,8 +585,11 @@ module mkFetchStage(FetchStage);
|
||||
Maybe#(CapMem) pred_next_pc = pred_future_pc[posLastSupX2];
|
||||
|
||||
// Search the last few translations to look for a match.
|
||||
Maybe#(UInt#(TLog#(PageBuffSize))) m_buff_match_idx = findElem(Valid(getVpn(getAddr(pc))), buffered_translation_virt_pc);
|
||||
Maybe#(UInt#(TLog#(PageBuffSize))) m_buff_match_idx = matchingVpnOrInvalidAddress(getAddr(pc));
|
||||
if (m_buff_match_idx matches tagged Valid .buff_match_idx) begin
|
||||
// Invalidate the buffered TLB response if it was for an invalid virtual address.
|
||||
if (!validVirtualAddress(getAddr(pc)))
|
||||
buffered_translation_virt_pc[buff_match_idx] <= Invalid;
|
||||
let next_fetch_pc = fromMaybe(addPc(pc, 2 * (zeroExtend(posLastSupX2) + 1)), pred_next_pc);
|
||||
let pc_idxs <- pcBlocks.insertAndReserve(truncateLSB(pc), truncateLSB(next_fetch_pc));
|
||||
PcIdx pc_idx = pc_idxs.inserted;
|
||||
|
||||
Reference in New Issue
Block a user