Add tag-only state to MESI and interface with tagOnlyReq of tag controller

This commit is contained in:
Peter Rugg
2021-10-25 17:29:39 +01:00
parent 25013c9713
commit 6d4644ce73
7 changed files with 36 additions and 23 deletions

View File

@@ -85,20 +85,19 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
// Functions to interact with the fabric // Functions to interact with the fabric
// Send a read-request into the fabric // Send a read-request into the fabric
function Action fa_fabric_send_read_req (Fabric_Addr addr); function Action fa_fabric_send_read_req (Fabric_Addr addr, Bool tag_req);
action action
AXI4_Size size = 8;
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_default_mid, let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_default_mid,
araddr: addr, araddr: addr,
arlen: 7, // burst len = arlen+1 arlen: tag_req ? 0 : 7, // burst len = arlen+1
arsize: 8, arsize: tag_req ? 1 : 8,
arburst: INCR, arburst: INCR,
arlock: fabric_default_lock, arlock: fabric_default_lock,
arcache: fabric_default_arcache, arcache: fabric_default_arcache,
arprot: fabric_default_prot, arprot: fabric_default_prot,
arqos: fabric_default_qos, arqos: fabric_default_qos,
arregion: fabric_default_region, arregion: fabric_default_region,
aruser: fabric_default_aruser}; aruser: pack(tag_req)};
masterPortShim.slave.ar.put(mem_req_rd_addr); masterPortShim.slave.ar.put(mem_req_rd_addr);
@@ -128,7 +127,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
end end
Addr line_addr = {ld.addr [63:6], 6'h0 }; // Addr of containing cache line Addr line_addr = {ld.addr [63:6], 6'h0 }; // Addr of containing cache line
fa_fabric_send_read_req (line_addr); fa_fabric_send_read_req (line_addr, ld.tag_req);
f_pending_reads.enq (ld); f_pending_reads.enq (ld);
llc.toM.deq; llc.toM.deq;
endrule endrule
@@ -160,6 +159,10 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
child: ldreq.child, child: ldreq.child,
id: ldreq.id}; id: ldreq.id};
if (ldreq.tag_req) begin
resp.data = CLine { tag: unpack(truncate(mem_rsp.rdata)), data: ?};
end
llc.rsFromM.enq (resp); llc.rsFromM.enq (resp);
if (cfg_verbosity > 1) if (cfg_verbosity > 1)

View File

@@ -73,7 +73,7 @@ typedef 64 Wd_Data;
// Width of fabric 'user' datapaths. Carry capability tags on data lines. // Width of fabric 'user' datapaths. Carry capability tags on data lines.
typedef 0 Wd_AW_User; typedef 0 Wd_AW_User;
typedef 0 Wd_B_User; typedef 0 Wd_B_User;
typedef 0 Wd_AR_User; typedef 1 Wd_AR_User;
typedef TMax#(TDiv#(Wd_Data, CLEN),1) Wd_W_User; typedef TMax#(TDiv#(Wd_Data, CLEN),1) Wd_W_User;
typedef TMax#(TDiv#(Wd_Data, CLEN),1) Wd_R_User; typedef TMax#(TDiv#(Wd_Data, CLEN),1) Wd_R_User;

View File

@@ -47,9 +47,10 @@ import ClientServer::*;
typedef enum { typedef enum {
I = 2'd0, I = 2'd0,
S = 2'd1, T = 2'd1,
E = 2'd2, S = 2'd2,
M = 2'd3 E = 2'd3,
M = 2'd4
} MESI deriving(Bits, Eq, FShow); } MESI deriving(Bits, Eq, FShow);
typedef MESI Msi; typedef MESI Msi;
@@ -317,6 +318,7 @@ typedef struct {
Addr addr; Addr addr;
childT child; // from which LLC/Dir childT child; // from which LLC/Dir
idT id; // ld req id and other info need encoding 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); } LdMemRq#(type idT, type childT) deriving(Bits, Eq, FShow);
typedef struct { // LdMemRq id with more info encoded to handle DMA req in LLC typedef struct { // LdMemRq id with more info encoded to handle DMA req in LLC

View File

@@ -779,10 +779,10 @@ endfunction
// check tag match // check tag match
Bool tag_match = ram.info.tag == getTag(procRq.addr); Bool tag_match = ram.info.tag == getTag(procRq.addr);
// check enough cache state for hit // 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 // check if cs is not I
Bool cs_valid = ram.info.cs > 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(ram.info.owner matches tagged Valid .cOwner) begin
if(cOwner != n) begin if(cOwner != n) begin
// owner is another cRq, so must just go through tag match // 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" "cRq swapped in by previous cRq, tag must match & cs > I"
); );
// Hit or Miss (but no replacement) // Hit or Miss (but no replacement)
if(enough_cs) begin if(enough_cs_to_hit) begin
if (verbose) if (verbose)
$display("%t L1 %m pipelineResp: cRq: own by itself, hit", $time); $display("%t L1 %m pipelineResp: cRq: own by itself, hit", $time);
cRqHit(n, procRq); cRqHit(n, procRq);
@@ -822,9 +822,15 @@ endfunction
cRqScEarlyFail(True); cRqScEarlyFail(True);
end end
else begin else begin
if (verbose) if (enough_cs_no_replace) begin
$display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time); if (verbose)
cRqMissNoReplacement; $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 end
end end
@@ -847,7 +853,7 @@ endfunction
end end
else begin else begin
// Check hit or miss, replacment may be needed // Check hit or miss, replacment may be needed
if(tag_match && enough_cs) begin if(tag_match && enough_cs_to_hit) begin
// Hit // Hit
doAssert(cs_valid, "hit, so cs must > I"); doAssert(cs_valid, "hit, so cs must > I");
if (verbose) if (verbose)
@@ -874,7 +880,7 @@ endfunction
if (verbose) if (verbose)
$display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time); $display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time);
// Req parent, no replacement needed // Req parent, no replacement needed
cRqMissNoReplacement; cRqMissNoReplacement; // XXX might we need to replace here (based on tag)?
end end
end end
end end

View File

@@ -523,7 +523,7 @@ endfunction
// send to pipeline // send to pipeline
pipeline.send(MRs (LLPipeMRsIn { pipeline.send(MRs (LLPipeMRsIn {
addr: cRq.addr, 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, data: respData,
way: cSlot.way way: cSlot.way
})); }));
@@ -578,7 +578,8 @@ endfunction
// child rq needs refill cache line, dma rq does not // child rq needs refill cache line, dma rq does not
refill: isRqFromC(cRq.id), refill: isRqFromC(cRq.id),
mshrIdx: n mshrIdx: n
} },
tag_req: cRq.toState == T
}); });
toMQ.enq(msg); toMQ.enq(msg);
toMInfoQ.deq; // deq info toMInfoQ.deq; // deq info
@@ -623,7 +624,8 @@ endfunction
id: LdMemRqId { id: LdMemRqId {
refill: True, refill: True,
mshrIdx: n mshrIdx: n
} },
tag_req: cRq.toState == T
}); });
toMQ.enq(msg); toMQ.enq(msg);
// whole thing is done, reset bit and deq info // whole thing is done, reset bit and deq info

View File

@@ -1518,7 +1518,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
dMem.procReq.req(ProcRq { dMem.procReq.req(ProcRq {
id: zeroExtend(lsqTag), id: zeroExtend(lsqTag),
addr: addr, addr: addr,
toState: multicore ? S : E, // in case of single core, just fetch to E toState: loadTags ? T : (multicore ? S : E), // in case of single core, just fetch to E
op: Ld, op: Ld,
byteEn: ?, byteEn: ?,
data: ?, data: ?,