diff --git a/rtl/friscv_cache_pusher.sv b/rtl/friscv_cache_pusher.sv index b738e52..58aa010 100644 --- a/rtl/friscv_cache_pusher.sv +++ b/rtl/friscv_cache_pusher.sv @@ -26,8 +26,6 @@ module friscv_cache_pusher parameter AXI_ADDR_W = 8, // AXI ID width, setup by default to 8 and unused parameter AXI_ID_W = 8, - // AXI4 data width, independant of control unit width - parameter AXI_DATA_W = 8, // ID Mask to apply to identify the instruction cache in the AXI4 // infrastructure parameter AXI_ID_MASK = 'h20, @@ -105,9 +103,11 @@ module friscv_cache_pusher logic data_fifo_afull; logic resp_fifo_full; logic resp_fifo_empty; - logic [XLEN/8 -1:0] wstrb; + logic wrbf_fifo_full; + logic wrbf_fifo_afull; + logic wrbf_fifo_empty; - logic [AXI_ID_W -1:0] cache_rid; + // Write-through path signals logic [AXI_ID_W -1:0] cpl_bid; logic [2 -1:0] cpl_bresp; logic push_addr_data; @@ -117,8 +117,19 @@ module friscv_cache_pusher logic [AXI_ID_W -1:0] cpl_id_m; logic [AXI_ID_W -1:0] req_id_m; logic to_cpl; - logic awready; - logic wready; + logic wt_awready; + logic wt_wready; + + // Write path signals + logic [XLEN/8 -1:0] wstrb; + logic [XLEN -1:0] wdata; + logic [AXI_ID_W -1:0] cache_rid_r; + logic [AXI_ADDR_W -1:0] cache_waddr_r; + logic [XLEN -1:0] cache_wdata_r; + logic [XLEN/8 -1:0] cache_wstrb_r; + logic [AXI_ID_W -1:0] cache_rid; + logic pull_wrbf; + logic is_io_req; // Tracer setup `ifdef TRACE_CACHE @@ -137,53 +148,87 @@ module friscv_cache_pusher // the cache blocks // /////////////////////////////////////////////////////////////////////////// + + assign mst_awready = wt_awready & wt_wready & !wrbf_fifo_afull & !wrbf_fifo_full; + assign mst_wready = wt_awready & wt_wready & !wrbf_fifo_afull & !wrbf_fifo_full; + + assign cache_ren = mst_awvalid && mst_awready && mst_wvalid && mst_wready && !mst_awcache[1]; + assign cache_raddr = mst_awaddr; // Monitor the write requests and drive the cache block updater. Acts as a pipeline // of the incoming write request to check if the data needs to be updated in a cache block always @ (posedge aclk or negedge aresetn) begin if (!aresetn) begin - cache_waddr <= '0; - cache_rid <= '0; - cache_wdata <= '0; - cache_wstrb <= '0; + cache_waddr_r <= '0; + cache_rid_r <= '0; + cache_wdata_r <= '0; + cache_wstrb_r <= '0; push_addr_data <= '0; - wstrb <= '0; + is_io_req <= '0; end else if (srst) begin - cache_waddr <= '0; - cache_rid <= '0; - cache_wdata <= '0; - cache_wstrb <= '0; + cache_waddr_r <= '0; + cache_rid_r <= '0; + cache_wdata_r <= '0; + cache_wstrb_r <= '0; push_addr_data <= '0; - wstrb <= '0; + is_io_req <= '0; end else begin + push_addr_data <= mst_awvalid && mst_awready && mst_wvalid && mst_wready; + cache_waddr_r <= mst_awaddr; + cache_rid_r <= mst_awid; + cache_wdata_r <= mst_wdata; + cache_wstrb_r <= mst_wstrb; + is_io_req <= mst_awcache[1] & mst_awvalid && mst_awready && mst_wvalid && mst_wready; + end + end + + friscv_scfifo + #( + .PASS_THRU (0), + .ADDR_WIDTH ($clog2(OSTDREQ_NUM)), + .DATA_WIDTH (AXI_ADDR_W+AXI_ID_W+XLEN+XLEN/8) + ) + wr_buffer + ( + .aclk (aclk), + .aresetn (aresetn), + .srst (srst), + .flush (1'b0), + .data_in ({cache_wstrb_r, cache_wdata_r, cache_rid_r, cache_waddr_r}), + .push (cache_hit), + .full (wrbf_fifo_full), + .afull (wrbf_fifo_afull), + .data_out ({wstrb, wdata, cache_rid, cache_waddr}), + .pull (pull_wrbf), + .empty (wrbf_fifo_empty), + .aempty () + ); + + always @ (*) begin - push_addr_data <= mst_awvalid && awready && mst_wvalid && wready; - cache_waddr <= mst_awaddr; - cache_rid <= mst_awid; - cache_wdata <= {SCALE{mst_wdata}}; - wstrb <= mst_wstrb; - - for (int i=0;i