Add tag-only state to MESI and interface with tagOnlyReq of tag controller
This commit is contained in:
@@ -47,9 +47,10 @@ import ClientServer::*;
|
||||
|
||||
typedef enum {
|
||||
I = 2'd0,
|
||||
S = 2'd1,
|
||||
E = 2'd2,
|
||||
M = 2'd3
|
||||
T = 2'd1,
|
||||
S = 2'd2,
|
||||
E = 2'd3,
|
||||
M = 2'd4
|
||||
} MESI deriving(Bits, Eq, FShow);
|
||||
typedef MESI Msi;
|
||||
|
||||
@@ -317,6 +318,7 @@ typedef struct {
|
||||
Addr addr;
|
||||
childT child; // from which LLC/Dir
|
||||
idT id; // ld req id and other info need encoding
|
||||
Bool tag_req; // request for cap tags, not data
|
||||
} LdMemRq#(type idT, type childT) deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef struct { // LdMemRq id with more info encoded to handle DMA req in LLC
|
||||
|
||||
@@ -779,10 +779,10 @@ endfunction
|
||||
// check tag match
|
||||
Bool tag_match = ram.info.tag == getTag(procRq.addr);
|
||||
// check enough cache state for hit
|
||||
Bool enough_cs = enoughCacheState(ram.info.cs, procRq.toState);
|
||||
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
|
||||
@@ -806,7 +806,7 @@ endfunction
|
||||
"cRq swapped in by previous cRq, tag must match & cs > I"
|
||||
);
|
||||
// Hit or Miss (but no replacement)
|
||||
if(enough_cs) begin
|
||||
if(enough_cs_to_hit) begin
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
@@ -822,9 +822,15 @@ endfunction
|
||||
cRqScEarlyFail(True);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time);
|
||||
cRqMissNoReplacement;
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -847,7 +853,7 @@ endfunction
|
||||
end
|
||||
else begin
|
||||
// Check hit or miss, replacment may be needed
|
||||
if(tag_match && enough_cs) begin
|
||||
if(tag_match && enough_cs_to_hit) begin
|
||||
// Hit
|
||||
doAssert(cs_valid, "hit, so cs must > I");
|
||||
if (verbose)
|
||||
@@ -874,7 +880,7 @@ endfunction
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time);
|
||||
// Req parent, no replacement needed
|
||||
cRqMissNoReplacement;
|
||||
cRqMissNoReplacement; // XXX might we need to replace here (based on tag)?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -523,7 +523,7 @@ endfunction
|
||||
// send to pipeline
|
||||
pipeline.send(MRs (LLPipeMRsIn {
|
||||
addr: cRq.addr,
|
||||
toState: cRq.toState == M ? M : E, // set upgrade state
|
||||
toState: cRq.toState == M ? M : cRq.toState == T ? T : E, // set upgrade state
|
||||
data: respData,
|
||||
way: cSlot.way
|
||||
}));
|
||||
@@ -578,7 +578,8 @@ endfunction
|
||||
// child rq needs refill cache line, dma rq does not
|
||||
refill: isRqFromC(cRq.id),
|
||||
mshrIdx: n
|
||||
}
|
||||
},
|
||||
tag_req: cRq.toState == T
|
||||
});
|
||||
toMQ.enq(msg);
|
||||
toMInfoQ.deq; // deq info
|
||||
@@ -623,7 +624,8 @@ endfunction
|
||||
id: LdMemRqId {
|
||||
refill: True,
|
||||
mshrIdx: n
|
||||
}
|
||||
},
|
||||
tag_req: cRq.toState == T
|
||||
});
|
||||
toMQ.enq(msg);
|
||||
// whole thing is done, reset bit and deq info
|
||||
|
||||
Reference in New Issue
Block a user