Add tag-only state to MESI and interface with tagOnlyReq of tag controller
This commit is contained in:
Submodule libs/TagController updated: 2e2198b05f...ce80cd006c
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 (enough_cs_no_replace) begin
|
||||||
if (verbose)
|
if (verbose)
|
||||||
$display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time);
|
$display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time);
|
||||||
cRqMissNoReplacement;
|
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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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: ?,
|
||||||
|
|||||||
Reference in New Issue
Block a user