From 8ba929438d243bca8a9a2de3dae268e5f6e22cb8 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Thu, 24 Mar 2022 23:51:59 +0000 Subject: [PATCH] Fix cloadtags in LLC --- src_Core/RISCY_OOO/coherence/src/L1Bank.bsv | 15 +++-------- src_Core/RISCY_OOO/coherence/src/L1Pipe.bsv | 2 +- src_Core/RISCY_OOO/coherence/src/LLBank.bsv | 30 +++++++++++---------- src_Core/RISCY_OOO/coherence/src/LLPipe.bsv | 2 +- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv b/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv index b60377f..8462fd2 100644 --- a/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv @@ -782,7 +782,6 @@ endfunction Bool enough_cs_to_hit = enoughCacheState(ram.info.cs, procRq.toState); // check if cs is not I Bool cs_valid = ram.info.cs > I; - Bool enough_cs_no_replace = ram.info.cs >= S || (ram.info.cs >= T && procRq.toState == T); if(ram.info.owner matches tagged Valid .cOwner) begin if(cOwner != n) begin // owner is another cRq, so must just go through tag match @@ -822,15 +821,9 @@ endfunction cRqScEarlyFail(True); end else begin - if (enough_cs_no_replace) begin - if (verbose) - $display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time); - cRqMissNoReplacement; - end else begin - if (verbose) - $display("%t L1 %m pipelineResp: cRq: own by itself, replace as upgrade from tag only", $time); - cRqReplacement; - end + if (verbose) + $display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time); + cRqMissNoReplacement; end end end @@ -880,7 +873,7 @@ endfunction if (verbose) $display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time); // Req parent, no replacement needed - cRqMissNoReplacement; // XXX might we need to replace here (based on tag)? + cRqMissNoReplacement; end end end diff --git a/src_Core/RISCY_OOO/coherence/src/L1Pipe.bsv b/src_Core/RISCY_OOO/coherence/src/L1Pipe.bsv index 481edbf..c1d17fa 100644 --- a/src_Core/RISCY_OOO/coherence/src/L1Pipe.bsv +++ b/src_Core/RISCY_OOO/coherence/src/L1Pipe.bsv @@ -318,7 +318,7 @@ module mkL1Pipe( ); actionvalue doAssert(toState > oldCs, "should truly upgrade cs"); - doAssert((oldCs == I) == dataV, "valid resp data for upgrade from I"); + doAssert((oldCs < S) == dataV, "valid resp data when data already up to date"); return UpdateByUpCs {cs: toState}; endactionvalue endfunction diff --git a/src_Core/RISCY_OOO/coherence/src/LLBank.bsv b/src_Core/RISCY_OOO/coherence/src/LLBank.bsv index f77689a..0fbe4ba 100644 --- a/src_Core/RISCY_OOO/coherence/src/LLBank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/LLBank.bsv @@ -872,6 +872,7 @@ endfunction ); // decide upgrade state Msi toState = cRq.toState; + // XXX Add auto update to S from T here if(cRq.toState == S && cRq.canUpToE && ram.info.dir == replicate(I) && respLoadWithE(isMRs)) begin toState = E; end @@ -882,7 +883,7 @@ endfunction toState: toState }); cRqMshr.pipelineResp.setStateSlot(n, Done, ?); // we no longer need slot info - cRqMshr.pipelineResp.setData(n, ram.info.dir[cRq.child] == I ? Valid (ram.line) : Invalid); + cRqMshr.pipelineResp.setData(n, ram.info.dir[cRq.child] <= T ? Valid (ram.line) : Invalid); // update child dir dirT newDir = ram.info.dir; newDir[cRq.child] = toState; @@ -1068,25 +1069,26 @@ endfunction endfunction // function to process cRq from child miss without replacement (MSHR slot may have garbage) - function Action cRqFromCMissNoReplacement(Vector#(childNum, DirPend) dirPend); + function Action cRqFromCMissNoReplacement(Vector#(childNum, DirPend) dirPend, Bool dataReq); action doAssert(isRqFromC(cRq.id), "should be cRq from child"); // it is impossible in LLC to have slot.waitP == True in this function // because there is no pRq in LLC to interrupt a cRq cRqSlotT cSlot = pipeOutCSlot; doAssert(!cSlot.waitP, "waitP must be false"); - // in LLC, we req memory only when cur cs is I - if(ram.info.cs == I) begin + // in LLC, we req memory only when we don't have enough data + Bool reqMem = ram.info.cs == I || (dataReq && ram.info.cs == T); + if(reqMem) begin toMInfoQ.enq(ToMemInfo{ mshrIdx: n, t: Ld }); - doAssert(ram.info.dir == replicate(I), "dir should be all I"); + //doAssert(ram.info.dir == replicate(I), "dir should be all I"); end // update mshr (data field is irrelevant, should be already invalid) cRqMshr.pipelineResp.setStateSlot(n, WaitSt, LLCRqSlot { way: pipeOut.way, // use way from pipeline - waitP: ram.info.cs == I, + waitP: reqMem, repTag: ?, // no replacement dirPend: dirPend }); @@ -1229,7 +1231,7 @@ endfunction if(cRq.id matches tagged Child ._i) begin // req from child, get dir pend Vector#(childNum, DirPend) dirPend = getDirPendNonCompatForChild; - if(dirPend == replicate(Invalid)) begin + if(dirPend == replicate(Invalid) && (cRq.toState == T || ram.info.cs >= S)) begin if (verbose) $display("%t LL %m pipelineResp: cRq from child: own by itself, hit", $time); cRqFromCHit(n, cRq, False); @@ -1239,13 +1241,13 @@ endfunction $display("%t LL %m pipelineResp: cRq from child: own by itself, miss no replace: ", $time, fshow(dirPend) ); - cRqFromCMissNoReplacement(dirPend); + cRqFromCMissNoReplacement(dirPend, cRq.toState >= S); end end else begin // req from DMA, get dir pend Vector#(childNum, DirPend) dirPend = getDirPendNonCompatForDma; - if(dirPend == replicate(Invalid)) begin + if(dirPend == replicate(Invalid) && (cRq.toState == T || ram.info.cs >= S)) begin if (verbose) $display("%t LL %m pipelineResp: cRq from dma: own by itself, hit", $time); cRqFromDmaHit(n, cRq); @@ -1282,7 +1284,7 @@ endfunction if(ram.info.cs == I || ram.info.tag == getTag(cRq.addr)) begin // No Replacement necessary, check dir Vector#(childNum, DirPend) dirPend = getDirPendNonCompatForChild; - if(ram.info.cs > I && dirPend == replicate(Invalid)) begin + if(ram.info.cs > I && dirPend == replicate(Invalid) && (cRq.toState == T || ram.info.cs >= S)) begin if (verbose) $display("%t LL %m pipelineResp: cRq: no owner, hit", $time); cRqFromCHit(n, cRq, False); @@ -1292,7 +1294,7 @@ endfunction $display("%t LL %m pipelineResp: cRq: no owner, miss no replace: ", $time, fshow(dirPend) ); - cRqFromCMissNoReplacement(dirPend); + cRqFromCMissNoReplacement(dirPend, cRq.toState >= S); end end else begin @@ -1310,11 +1312,11 @@ endfunction // cRq from DMA if(ram.info.cs > I && ram.info.tag == getTag(cRq.addr)) begin // hit in LLC, check dir - if(dirPend == replicate(Invalid)) begin + if(dirPend == replicate(Invalid) && (cRq.toState == T || ram.info.cs >= S)) begin cRqFromDmaHit(n, cRq); end else begin - cRqFromDmaMissByChildren(dirPend); + cRqFromDmaMissByChildren(dirPend); // XXX this might need fixing up in the T->S case? end end else begin @@ -1360,7 +1362,7 @@ endfunction doAssert(ram.info.cs >= cRq.toState && ram.info.tag == getTag(cRq.addr), "mRs must be tag match & have enough cs" ); - doAssert(ram.info.dir == replicate(I), "all children must be I"); + //doAssert(ram.info.dir == replicate(I), "all children must be I"); doAssert(!cOwner.replacing, "mRs cannot hit on replacing line"); doAssert(cSlot.way == pipeOut.way, "mRs should hit on way in MSHR slot"); doAssert(cSlot.waitP, "mRs should match cRq which is waiting for it"); diff --git a/src_Core/RISCY_OOO/coherence/src/LLPipe.bsv b/src_Core/RISCY_OOO/coherence/src/LLPipe.bsv index 9880deb..fd3f316 100644 --- a/src_Core/RISCY_OOO/coherence/src/LLPipe.bsv +++ b/src_Core/RISCY_OOO/coherence/src/LLPipe.bsv @@ -276,7 +276,7 @@ module mkLLPipe( ); actionvalue doAssert(toState > oldCs, "should truly upgrade cs"); - doAssert((oldCs == I) && dataV, "LLC mRs always has data"); + doAssert((oldCs == I || (oldCs == T && toState >= S)) && dataV, "LLC mRs always has data"); return UpdateByUpCs {cs: toState}; endactionvalue endfunction