diff --git a/src_Core/CPU/LLC_AXI4_Adapter.bsv b/src_Core/CPU/LLC_AXI4_Adapter.bsv index adf771f..e92c7c2 100644 --- a/src_Core/CPU/LLC_AXI4_Adapter.bsv +++ b/src_Core/CPU/LLC_AXI4_Adapter.bsv @@ -61,13 +61,21 @@ endinterface // ================================================================ +typedef struct { + Bool tag_req; // meaningful to upgrade to E if toState is S + idT id; // slot id in child cache + childT child; // from which child +} LLC_AXI_ID#(type idT, type childT) deriving(Bits, Eq, FShow); + module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) (LLC_AXI4_Adapter_IFC) - provisos(Bits#(idT, a__), - Bits#(childT, b__), + provisos(Bits#(idT, idSz), + Bits#(childT, childSz), FShow#(ToMemMsg#(idT, childT)), FShow#(MemRsMsg#(idT, childT)), - Add#(SizeOf#(Line), 0, TAdd#(512, 4))); // assert Line sz = 512 + 4 tags + Add#(SizeOf#(Line), 0, TAdd#(512, 4)), + Add#(c__, TAdd#(1, TAdd#(idSz, childSz)), Wd_MId) // LLC_AXI_ID must fit into the external ID. + ); // assert Line sz = 512 + 4 tags // Verbosity: 0: quiet; 1: LLC transactions; 2: loop detail Integer verbosity = 2; @@ -79,25 +87,26 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) let masterPortShim <- mkAXI4ShimFF; // For discarding write-responses - CreditCounter_IFC #(4) ctr_wr_rsps_pending <- mkCreditCounter; // Max 15 writes outstanding + CreditCounter_IFC #(4) ctr_wr_rsps_pending <- mkCreditCounter; // 16 outstanding writes. // ================================================================ // Functions to interact with the fabric // Send a read-request into the fabric - function Action fa_fabric_send_read_req (Fabric_Addr addr, Bool tag_req); + function Action fa_fabric_send_read_req (Fabric_Addr addr, LLC_AXI_ID#(idT, childT) id); action - let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_default_mid, + Bit#(Wd_MId) arid = zeroExtend(pack(id)); + let mem_req_rd_addr = AXI4_ARFlit {arid: arid, araddr: addr, arlen: 0, // burst len = arlen+1 - arsize: tag_req ? 1 : 64, + arsize: id.tag_req ? 1 : 64, arburst: INCR, arlock: fabric_default_lock, arcache: fabric_default_arcache, arprot: fabric_default_prot, arqos: fabric_default_qos, arregion: fabric_default_region, - aruser: pack(tag_req)}; + aruser: pack(id.tag_req)}; masterPortShim.slave.ar.put(mem_req_rd_addr); @@ -110,16 +119,8 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) // ================================================================ // Handle read requests and responses - // Don't do reads while writes are outstanding. - // Each 512b cache line takes 8 beats, each handling 64 bits - Reg #(Bit #(3)) rg_rd_rsp_beat <- mkReg (0); - - FIFOF #(LdMemRq #(idT, childT)) f_pending_reads <- mkFIFOF; - Reg #(CLine) rg_cline <- mkRegU; - - rule rl_handle_read_req (llc.toM.first matches tagged Ld .ld - &&& (ctr_wr_rsps_pending.value == 0)); + rule rl_handle_read_req (llc.toM.first matches tagged Ld .ld); if ((cfg_verbosity > 0)) begin $display ("%0d: LLC_AXI4_Adapter.rl_handle_read_req: Ld request from LLC to memory", cur_cycle); @@ -127,15 +128,14 @@ 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, ld.tag_req); - f_pending_reads.enq (ld); + fa_fabric_send_read_req (line_addr, LLC_AXI_ID{tag_req: ld.tag_req, id: ld.id, child: ld.child}); llc.toM.deq; endrule rule rl_handle_read_rsps; let mem_rsp <- get(masterPortShim.slave.r); if (cfg_verbosity > 1) begin - $display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsps: beat %0d ", cur_cycle, rg_rd_rsp_beat); + $display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsps: ", cur_cycle); $display (" ", fshow (mem_rsp)); end if (mem_rsp.rresp != OKAY) begin @@ -146,11 +146,11 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) end let new_cline = CLine { tag: unpack(mem_rsp.ruser) , data: unpack(mem_rsp.rdata) }; - let ldreq <- pop (f_pending_reads); + LLC_AXI_ID#(idT, childT) id = unpack(truncate(mem_rsp.rid)); MemRsMsg #(idT, childT) resp = MemRsMsg {data: new_cline, - child: ldreq.child, - id: ldreq.id}; - if (ldreq.tag_req) begin + child: id.child, + id: id.id}; + if (id.tag_req) begin resp.data = CLine { tag: unpack(truncate(mem_rsp.rdata)), data: ?}; end llc.rsFromM.enq (resp); @@ -160,7 +160,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) // ================================================================ // Handle write requests and responses - + Reg#(Bit#(Wd_MId)) wid_reg <- mkRegU; rule rl_handle_write_req (llc.toM.first matches tagged Wb .wb); if (cfg_verbosity > 0) begin $display ("%d: LLC_AXI4_Adapter.rl_handle_write_req: Wb request from LLC to memory:", cur_cycle); @@ -169,7 +169,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) // send AXI4 AW flit masterPortShim.slave.aw.put (AXI4_AWFlit { - awid: fabric_default_mid, + awid: wid_reg, awaddr: { wb.addr [63:6], 6'h0 }, awlen: 0, // burst len = awlen+1 awsize: 64, @@ -182,11 +182,9 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc) awuser: 0}); // Expect a fabric response ctr_wr_rsps_pending.incr; + wid_reg <= wid_reg + 1; // Best effort to use unique IDs to allow reordering in the fabric. llc.toM.deq; - - // on each flit ... - // ================ Vector #(8, Bit #(8)) line_strb = unpack(pack(wb.byteEn)); Vector #(4, MemTaggedData) line_data = clineToMemTaggedDataVector(wb.data); // send AXI4 W flit