Fix cloadtags in LLC

This commit is contained in:
Peter Rugg
2022-03-24 23:51:59 +00:00
parent 6d4644ce73
commit 8ba929438d
4 changed files with 22 additions and 27 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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");

View File

@@ -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