From 6d4644ce73103a82f4e117046da203ea90696b2b Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Mon, 25 Oct 2021 17:29:39 +0100 Subject: [PATCH] Add tag-only state to MESI and interface with tagOnlyReq of tag controller --- libs/TagController | 2 +- src_Core/CPU/LLC_AXI4_Adapter.bsv | 15 ++++++++----- src_Core/Core/Fabric_Defs.bsv | 2 +- src_Core/RISCY_OOO/coherence/src/CCTypes.bsv | 8 ++++--- src_Core/RISCY_OOO/coherence/src/L1Bank.bsv | 22 ++++++++++++------- src_Core/RISCY_OOO/coherence/src/LLBank.bsv | 8 ++++--- .../procs/RV64G_OOO/MemExePipeline.bsv | 2 +- 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/libs/TagController b/libs/TagController index 2e2198b..ce80cd0 160000 --- a/libs/TagController +++ b/libs/TagController @@ -1 +1 @@ -Subproject commit 2e2198b05f3c7cea61d690e3aa438211d0de9e8d +Subproject commit ce80cd006c437303e4c31691e994342a6d016424 diff --git a/src_Core/CPU/LLC_AXI4_Adapter.bsv b/src_Core/CPU/LLC_AXI4_Adapter.bsv index 3a03154..91bee61 100644 --- a/src_Core/CPU/LLC_AXI4_Adapter.bsv +++ b/src_Core/CPU/LLC_AXI4_Adapter.bsv @@ -85,20 +85,19 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) // Functions to interact with 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 - AXI4_Size size = 8; let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_default_mid, araddr: addr, - arlen: 7, // burst len = arlen+1 - arsize: 8, + arlen: tag_req ? 0 : 7, // burst len = arlen+1 + arsize: tag_req ? 1 : 8, arburst: INCR, arlock: fabric_default_lock, arcache: fabric_default_arcache, arprot: fabric_default_prot, arqos: fabric_default_qos, arregion: fabric_default_region, - aruser: fabric_default_aruser}; + aruser: pack(tag_req)}; masterPortShim.slave.ar.put(mem_req_rd_addr); @@ -128,7 +127,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) end 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); llc.toM.deq; endrule @@ -160,6 +159,10 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) child: ldreq.child, id: ldreq.id}; + if (ldreq.tag_req) begin + resp.data = CLine { tag: unpack(truncate(mem_rsp.rdata)), data: ?}; + end + llc.rsFromM.enq (resp); if (cfg_verbosity > 1) diff --git a/src_Core/Core/Fabric_Defs.bsv b/src_Core/Core/Fabric_Defs.bsv index c9cdb1a..e21c46e 100644 --- a/src_Core/Core/Fabric_Defs.bsv +++ b/src_Core/Core/Fabric_Defs.bsv @@ -73,7 +73,7 @@ typedef 64 Wd_Data; // Width of fabric 'user' datapaths. Carry capability tags on data lines. typedef 0 Wd_AW_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_R_User; diff --git a/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv b/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv index 76f3f1a..90a3038 100644 --- a/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv +++ b/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv b/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv index b7f3d1b..b60377f 100644 --- a/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/coherence/src/LLBank.bsv b/src_Core/RISCY_OOO/coherence/src/LLBank.bsv index bf792a4..f77689a 100644 --- a/src_Core/RISCY_OOO/coherence/src/LLBank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/LLBank.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv index 10426a3..2c06486 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv @@ -1518,7 +1518,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); dMem.procReq.req(ProcRq { id: zeroExtend(lsqTag), 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, byteEn: ?, data: ?,