diff --git a/core/Flist.cva6 b/core/Flist.cva6 index bc79986ad7..02f6a76194 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -184,6 +184,7 @@ ${HPDCACHE_DIR}/rtl/src/utils/hpdcache_mem_to_axi_write.sv ${CVA6_REPO_DIR}/core/cache_subsystem/cva6_hpdcache_subsystem.sv ${CVA6_REPO_DIR}/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv ${CVA6_REPO_DIR}/core/cache_subsystem/cva6_hpdcache_if_adapter.sv +${CVA6_REPO_DIR}/core/cache_subsystem/cva6_hpdcache_icache_if_adapter.sv ${CVA6_REPO_DIR}/core/cache_subsystem/cva6_hpdcache_wrapper.sv ${HPDCACHE_DIR}/rtl/src/common/macros/behav/hpdcache_sram_1rw.sv ${HPDCACHE_DIR}/rtl/src/common/macros/behav/hpdcache_sram_wbyteenable_1rw.sv diff --git a/core/cache_subsystem/cva6_hpdcache_icache_if_adapter.sv b/core/cache_subsystem/cva6_hpdcache_icache_if_adapter.sv index 9e1f1bf310..d211c32938 100644 --- a/core/cache_subsystem/cva6_hpdcache_icache_if_adapter.sv +++ b/core/cache_subsystem/cva6_hpdcache_icache_if_adapter.sv @@ -7,7 +7,7 @@ // You may obtain a copy of the License at https://solderpad.org/licenses/ // // Authors: Akiho Kawada -// Date: June, 2024 +// Date: July, 2024 // Description: Icache Interface adapter for the CVA6 core module cva6_hpdcache_icache_if_adapter // Parameters @@ -24,7 +24,7 @@ module cva6_hpdcache_icache_if_adapter parameter type fetch_drsp_t = logic, parameter type obi_fetch_req_t = logic, parameter type obi_fetch_rsp_t = logic, - parameter logic [CVA6Cfg.MEM_TID_WIDTH-1:0] RdTxId = 0 + parameter logic [CVA6Cfg.MEM_TID_WIDTH-1:0] RdTxId = 0 // TODO ) // }}} @@ -39,10 +39,10 @@ module cva6_hpdcache_icache_if_adapter input hpdcache_req_sid_t hpdcache_req_sid_i, // Request/response ports from/to the CVA6 core - input fetch_dreq_t fetch_dreq_i, - output fetch_drsp_t fetch_dreq_o, - input obi_fetch_req_t obi_fetch_req_i, - output obi_fetch_rsp_t obi_fetch_rsp_o, + input fetch_dreq_t dreq_i, + output fetch_drsp_t dreq_o, + input obi_fetch_req_t fetch_obi_req_i, + output obi_fetch_rsp_t fetch_obi_rsp_o, // Request port to the L1 Dcache output logic hpdcache_req_valid_o, @@ -58,9 +58,8 @@ module cva6_hpdcache_icache_if_adapter ); // }}} - // Internal nets and registers - // {{{ - logic hpdcache_req_is_uncacheable; + // localparam ICACHE_OFFSET_WIDTH = $clog2(CVA6Cfg.ICACHE_LINE_WIDTH / 8); + localparam ICACHE_OFFSET_WIDTH = 3; localparam int ICACHE_CL_SIZE = $clog2(CVA6Cfg.ICACHE_LINE_WIDTH / 8); localparam int ICACHE_WORD_SIZE = 3; localparam int ICACHE_MEM_REQ_CL_SIZE = @@ -68,57 +67,91 @@ module cva6_hpdcache_icache_if_adapter $clog2( CVA6Cfg.AxiDataWidth / 8 ) : ICACHE_CL_SIZE; + + // Internal nets and registers + // {{{ + logic hpdcache_req_is_uncacheable; + logic va_transferred_q, va_transferred_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin : transferred_state_magnegement + if (!rst_ni) begin + va_transferred_q <= '0; + end else begin + va_transferred_q <= va_transferred_d; + end + end + + assign va_transferred_d = dreq_i.req & hpdcache_req_ready_i; // }}} // Request forwarding // {{{ - // LOAD request - // {{{ - assign hpdcache_req_is_uncacheable = !config_pkg::is_inside_cacheable_regions( CVA6Cfg, { {64 - CVA6Cfg.PLEN{1'b0}}, - obi_fetch_req_i.a.addrr[CVA6Cfg.ICACHE_TAG_WIDTH+CVA6Cfg.ICACHE_INDEX_WIDTH-1:CVA6Cfg.ICACHE_INDEX_WIDTH], + fetch_obi_req_i.a.addr[CVA6Cfg.ICACHE_TAG_WIDTH+CVA6Cfg.ICACHE_INDEX_WIDTH-1:CVA6Cfg.ICACHE_INDEX_WIDTH], // TODO {CVA6Cfg.ICACHE_INDEX_WIDTH{1'b0}} } ); // Request forwarding - assign hpdcache_req_valid_o = fetch_dreq_i.data_req, - hpdcache_req_o.addr_offset = fetch_dreq_i.vaddr[CVA6Cfg.ICACHE_INDEX_WIDTH-1:3], + assign hpdcache_req_valid_o = dreq_i.req, + hpdcache_req_o.addr_offset = dreq_i.vaddr[CVA6Cfg.ICACHE_INDEX_WIDTH-1:0], hpdcache_req_o.wdata = '0, hpdcache_req_o.op = hpdcache_pkg::HPDCACHE_REQ_LOAD, - hpdcache_req_o.be = obi_fetch_req_i.a.data_be, - hpdcache_req_o.size = hpdcache_req_is_uncacheable ? ICACHE_WORD_SIZE : ICACHE_MEM_REQ_CL_SIZE, + hpdcache_req_o.be = fetch_obi_req_i.a.be, + hpdcache_req_o.size = hpdcache_req_is_uncacheable ? ICACHE_WORD_SIZE : ICACHE_MEM_REQ_CL_SIZE, // TODO hpdcache_req_o.sid = '0, - hpdcache_req_o.tid = RdTxId, // TODO + hpdcache_req_o.tid = RdTxId, // TODO hpdcache_req_o.need_rsp = 1'b1, hpdcache_req_o.phys_indexed = 1'b0, hpdcache_req_o.addr_tag = '0, // unused on virtually indexed request hpdcache_req_o.pma = '0; // unused on virtually indexed request - assign hpdcache_req_abort_o = fetch_dreq_i.kill_req, - hpdcache_req_tag_o = obi_fetch_req_i.a.addrr[CVA6Cfg.ICACHE_TAG_WIDTH+CVA6Cfg.ICACHE_INDEX_WIDTH-1:CVA6Cfg.ICACHE_INDEX_WIDTH], + assign hpdcache_req_abort_o = va_transferred_q & (dreq_i.kill_req | ~fetch_obi_req_i.req), + hpdcache_req_tag_o = fetch_obi_req_i.a.addr[CVA6Cfg.ICACHE_TAG_WIDTH+CVA6Cfg.ICACHE_INDEX_WIDTH-1:CVA6Cfg.ICACHE_INDEX_WIDTH], hpdcache_req_pma_o.uncacheable = hpdcache_req_is_uncacheable, hpdcache_req_pma_o.io = 1'b0; // Response forwarding - assign cva6_req_o.data_rvalid = hpdcache_rsp_valid_i, - cva6_req_o.data_rdata = hpdcache_rsp_i.rdata, - cva6_req_o.data_rid = hpdcache_rsp_i.tid, - cva6_req_o.data_gnt = hpdcache_req_ready_i; - - assign fetch_obi_rsp_o.gnt = hpdcache_req_ready_i, // TODO - fetch_obi_rsp_o.gntpar = !hpdcache_req_ready_i, // TODO - fetch_obi_rsp_o.rvalid = hpdcache_rsp_valid_i, // TODO - fetch_obi_rsp_o.rvalidpar = !hpdcache_rsp_valid_i, // TODO - fetch_obi_rsp_o.r.rid = '0, + assign dreq_o.ready = hpdcache_req_ready_i; + logic obi_gnt_q, obi_gnt_d; // TODO + + assign obi_gnt_d = dreq_i.req; + + always_ff @(posedge clk_i or negedge rst_ni) begin : obi_gnt_gen + if (!rst_ni) begin + obi_gnt_q <= '0; + end else begin + obi_gnt_q <= obi_gnt_d; + end + end + + logic which_half_d, which_half_q; + assign which_half_d = (fetch_obi_req_i.req) ? fetch_obi_req_i.a.addr[2] : which_half_q; + + + always_ff @(posedge clk_i or negedge rst_ni) begin : gen_offset + if (!rst_ni) begin + which_half_q <= '0; + end else begin + which_half_q <= which_half_d; + end + end + + assign fetch_obi_rsp_o.gnt = obi_gnt_q, + fetch_obi_rsp_o.gntpar = !obi_gnt_q, + fetch_obi_rsp_o.rvalid = hpdcache_rsp_valid_i, + fetch_obi_rsp_o.rvalidpar = !hpdcache_rsp_valid_i, + fetch_obi_rsp_o.r.rid = hpdcache_rsp_i.tid, fetch_obi_rsp_o.r.r_optional.exokay = '0, fetch_obi_rsp_o.r.r_optional.rchk = '0, - fetch_obi_rsp_o.r.err = '0, - fetch_obi_rsp_o.r.rdata = hpdcache_rsp_i.rdata, - fetch_obi_rsp_o.r.r_optional.ruser = '0; + fetch_obi_rsp_o.r.err = hpdcache_rsp_i.error, + fetch_obi_rsp_o.r.rdata = hpdcache_rsp_i.rdata[0][{ + which_half_q, 5'b0 + }+:CVA6Cfg.FETCH_WIDTH], + fetch_obi_rsp_o.r.r_optional.ruser = '0; // TODO // }}} // }}} diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem.sv b/core/cache_subsystem/cva6_hpdcache_subsystem.sv index 6951feeacb..2c03abca0f 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem.sv @@ -25,8 +25,6 @@ module cva6_hpdcache_subsystem parameter type icache_rtrn_t = logic, parameter type dbus_req_t = logic, parameter type dbus_rsp_t = logic, - parameter type obi_dbus_req_t = logic, - parameter type obi_dbus_rsp_t = logic, parameter int NumPorts = 4, parameter int NrHwPrefetchers = 4, // AXI types @@ -67,16 +65,14 @@ module cva6_hpdcache_subsystem input logic icache_flush_i, // instructino cache miss - PERF_COUNTERS output logic icache_miss_o, - // Access request - FRONTEND + // Input data translation request - FRONTEND input fetch_dreq_t fetch_dreq_i, - // Output Access request - FRONTEND + // Output data translation request - FRONTEND output fetch_drsp_t fetch_dreq_o, - - // OBI Fetch Request channel - FRONTEND - input obi_fetch_req_t fetch_obi_req_i, - // OBI Fetch Response channel - FRONTEND + // Input address translation request - EX_STAGE + input obi_fetch_req_t fetch_obi_req_i, + // Output address translation request - EX_STAGE output obi_fetch_rsp_t fetch_obi_rsp_o, - // }}} // D$ @@ -141,46 +137,220 @@ module cva6_hpdcache_subsystem return y < x ? x : y; endfunction + `include "hpdcache_typedef.svh" + // I$ instantiation // {{{ - logic icache_miss_valid, icache_miss_ready; - icache_req_t icache_miss; - logic icache_miss_resp_valid; - icache_rtrn_t icache_miss_resp; + // 0: Page-Table Walk (PTW) + // 1: Load unit + // 2: Accelerator load + // 3: Store/AMO + // . + // . + // . + // NumPorts: CMO + // NumPorts + 1: Hardware Memory Prefetcher (hwpf) + localparam int HPDCACHE_NREQUESTERS = NumPorts + 2; + + + localparam hpdcache_pkg::hpdcache_user_cfg_t hpdcacheIcacheUserCfg = '{ + nRequesters: 4, + paWidth: CVA6Cfg.PLEN, + wordWidth: CVA6Cfg.XLEN, + sets: CVA6Cfg.DCACHE_NUM_WORDS, + ways: CVA6Cfg.DCACHE_SET_ASSOC, + clWords: CVA6Cfg.DCACHE_LINE_WIDTH / CVA6Cfg.XLEN, + reqWords: 1, + reqTransIdWidth: CVA6Cfg.DcacheIdWidth, + reqSrcIdWidth: 3, // Up to 8 requesters + victimSel: hpdcache_pkg::HPDCACHE_VICTIM_RANDOM, + dataWaysPerRamWord: __minu(CVA6Cfg.DCACHE_SET_ASSOC, 128 / CVA6Cfg.XLEN), + dataSetsPerRam: CVA6Cfg.DCACHE_NUM_WORDS, + dataRamByteEnable: 1'b1, + accessWords: __maxu(CVA6Cfg.DCACHE_LINE_WIDTH / (2 * CVA6Cfg.XLEN), 1), + mshrSets: 1, + mshrWays: 1, + mshrWaysPerRamWord: CVA6Cfg.NrLoadBufEntries < 16 ? CVA6Cfg.NrLoadBufEntries : 2, + mshrSetsPerRam: CVA6Cfg.NrLoadBufEntries < 16 ? 1 : CVA6Cfg.NrLoadBufEntries / 2, + mshrRamByteEnable: 1'b1, + mshrUseRegbank: (CVA6Cfg.NrLoadBufEntries < 16), + refillCoreRspFeedthrough: 1'b1, + refillFifoDepth: 2, + wbufDirEntries: CVA6Cfg.WtDcacheWbufDepth, + wbufDataEntries: CVA6Cfg.WtDcacheWbufDepth, + wbufWords: 1, + wbufTimecntWidth: 3, + wbufSendFeedThrough: 1'b0, + rtabEntries: 4, + memAddrWidth: CVA6Cfg.AxiAddrWidth, + memIdWidth: CVA6Cfg.MEM_TID_WIDTH, + memDataWidth: CVA6Cfg.AxiDataWidth + }; + + localparam hpdcache_pkg::hpdcache_cfg_t hpdcacheIcacheCfg = hpdcache_pkg::hpdcacheBuildConfig( + hpdcacheIcacheUserCfg + ); + + `HPDCACHE_TYPEDEF_MEM_ATTR_T(hpdcache_mem_addr_t, hpdcache_mem_id_t, hpdcache_mem_data_t, + hpdcache_mem_be_t, hpdcacheIcacheCfg); + `HPDCACHE_TYPEDEF_MEM_REQ_T(hpdcache_mem_req_t, hpdcache_mem_addr_t, hpdcache_mem_id_t); + `HPDCACHE_TYPEDEF_MEM_RESP_R_T(hpdcache_mem_resp_r_t, hpdcache_mem_id_t, hpdcache_mem_data_t); + `HPDCACHE_TYPEDEF_MEM_REQ_W_T(hpdcache_mem_req_w_t, hpdcache_mem_data_t, hpdcache_mem_be_t); + `HPDCACHE_TYPEDEF_MEM_RESP_W_T(hpdcache_mem_resp_w_t, hpdcache_mem_id_t); + + `HPDCACHE_TYPEDEF_REQ_ATTR_T(hpdcache_req_offset_t, hpdcache_data_word_t, hpdcache_data_be_t, + hpdcache_req_data_t, hpdcache_req_be_t, hpdcache_req_sid_t, + hpdcache_req_tid_t, hpdcache_tag_t, hpdcacheIcacheCfg); + `HPDCACHE_TYPEDEF_REQ_T(hpdcache_req_t, hpdcache_req_offset_t, hpdcache_req_data_t, + hpdcache_req_be_t, hpdcache_req_sid_t, hpdcache_req_tid_t, + hpdcache_tag_t); + `HPDCACHE_TYPEDEF_RSP_T(hpdcache_rsp_t, hpdcache_req_data_t, hpdcache_req_sid_t, + hpdcache_req_tid_t); + + + localparam int HPDCACHE_ICACHE_UC_READ_ID = 1 << (CVA6Cfg.MEM_TID_WIDTH - 1); + localparam int HPDCACHE_ICACHE_MISS_ID = 0; // TODO + + + // {{{ + logic icache_miss_uc_ready; + logic icache_miss_uc_valid; + hpdcache_mem_req_t icache_miss_uc; + + logic icache_miss_uc_resp_ready; + logic icache_miss_uc_resp_valid; + hpdcache_mem_resp_r_t icache_miss_uc_resp; + + logic icache_miss_ready; + logic icache_miss_valid; + hpdcache_mem_req_t icache_miss; + + logic icache_miss_resp_ready; + logic icache_miss_resp_valid; + hpdcache_mem_resp_r_t icache_miss_resp; + + logic icache_uc_read_ready; + logic icache_uc_read_valid; + hpdcache_mem_req_t icache_uc_read; - localparam int ICACHE_RDTXID = 1 << (CVA6Cfg.MEM_TID_WIDTH - 1); + logic icache_uc_read_resp_ready; + logic icache_uc_read_resp_valid; + hpdcache_mem_resp_r_t icache_uc_read_resp; + + logic paddr_is_nc; + logic [CVA6Cfg.ICACHE_TAG_WIDTH-1:0] cl_tag_d, cl_tag_q; // this is the cache tag + + // }}} - cva6_icache #( + cva6_hpdcache_wrapper #( .CVA6Cfg(CVA6Cfg), + .HPDcacheCfg(hpdcacheIcacheCfg), + .USE_AS_ICACHE('1), .fetch_dreq_t(fetch_dreq_t), .fetch_drsp_t(fetch_drsp_t), .obi_fetch_req_t(obi_fetch_req_t), .obi_fetch_rsp_t(obi_fetch_rsp_t), - .icache_req_t(icache_req_t), - .icache_rtrn_t(icache_rtrn_t), - .RdTxId(ICACHE_RDTXID) - ) i_cva6_icache ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .flush_i (icache_flush_i), - .en_i (icache_en_i), - .miss_o (icache_miss_o), - .dreq_i (fetch_dreq_i), - .dreq_o (fetch_dreq_o), + .dcache_req_i_t(dbus_req_t), + .dcache_req_o_t(dbus_rsp_t), + .NumPorts(2), + .NrHwPrefetchers(6), + .hpdcache_mem_addr_t(hpdcache_mem_addr_t), + .hpdcache_mem_id_t(hpdcache_mem_id_t), + .hpdcache_mem_data_t(hpdcache_mem_data_t), + .hpdcache_mem_be_t(hpdcache_mem_be_t), + .hpdcache_mem_req_t(hpdcache_mem_req_t), + .hpdcache_mem_req_w_t(hpdcache_mem_req_w_t), + .hpdcache_mem_resp_r_t(hpdcache_mem_resp_r_t), + .hpdcache_mem_resp_w_t(hpdcache_mem_resp_w_t), + .hpdcache_req_offset_t(hpdcache_req_offset_t), + .hpdcache_data_word_t(hpdcache_data_word_t), + .hpdcache_req_data_t(hpdcache_req_data_t), + .hpdcache_req_be_t(hpdcache_req_be_t), + .hpdcache_req_sid_t(hpdcache_req_sid_t), + .hpdcache_req_tid_t(hpdcache_req_tid_t), + .hpdcache_tag_t(hpdcache_tag_t), + .hpdcache_req_t(hpdcache_req_t), + .hpdcache_rsp_t(hpdcache_rsp_t), + .hpdcache_data_be_t(hpdcache_data_be_t) + ) i_icache ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .dcache_enable_i(icache_en_i), + .dcache_flush_i(icache_flush_i), + .dcache_flush_ack_o( /* TODO */), + .dcache_miss_o(icache_miss_o), + .dcache_amo_req_i('0), + .dcache_amo_resp_o( /* unused */), + .dcache_cmo_req_i('0), + .dcache_cmo_resp_o( /* unused */), + .fetch_dreq_i(fetch_dreq_i), + .fetch_dreq_o(fetch_dreq_o), .fetch_obi_req_i(fetch_obi_req_i), .fetch_obi_rsp_o(fetch_obi_rsp_o), - .mem_rtrn_vld_i (icache_miss_resp_valid), - .mem_rtrn_i (icache_miss_resp), - .mem_data_req_o (icache_miss_valid), - .mem_data_ack_i (icache_miss_ready), - .mem_data_o (icache_miss) + .dcache_req_ports_i( /* unused */), + .dcache_req_ports_o( /* unused */), + .wbuffer_empty_o( /* unused */), + .wbuffer_not_ni_o( /* unused */), + .hwpf_base_set_i('0), + .hwpf_base_i('0), + .hwpf_base_o( /* unused */), + .hwpf_param_set_i('0), + .hwpf_param_i('0), + .hwpf_param_o( /* unused */), + .hwpf_throttle_set_i('0), + .hwpf_throttle_i('0), + .hwpf_throttle_o( /* unused */), + .hwpf_status_o( /* unused */), + + .dcache_mem_req_miss_read_ready_i(icache_miss_ready), + .dcache_mem_req_miss_read_valid_o(icache_miss_valid), + .dcache_mem_req_miss_read_o(icache_miss), + + .dcache_mem_resp_miss_read_ready_o(icache_miss_resp_ready), + .dcache_mem_resp_miss_read_valid_i(icache_miss_resp_valid), + .dcache_mem_resp_miss_read_i(icache_miss_resp), + + .dcache_mem_req_wbuf_write_ready_i('0), + .dcache_mem_req_wbuf_write_valid_o( /* unused */), + .dcache_mem_req_wbuf_write_o( /* unused */), + + .dcache_mem_req_wbuf_write_data_ready_i('0), + .dcache_mem_req_wbuf_write_data_valid_o( /* unused */), + .dcache_mem_req_wbuf_write_data_o( /* unused */), + + .dcache_mem_resp_wbuf_write_ready_o( /* unused */), + .dcache_mem_resp_wbuf_write_valid_i('0), + .dcache_mem_resp_wbuf_write_i( /* unused */), + + .dcache_mem_req_uc_read_ready_i(icache_uc_read_ready), + .dcache_mem_req_uc_read_valid_o(icache_uc_read_valid), + .dcache_mem_req_uc_read_o(icache_uc_read), + + .dcache_mem_resp_uc_read_ready_o(icache_uc_read_resp_ready), + .dcache_mem_resp_uc_read_valid_i(icache_uc_read_resp_valid), + .dcache_mem_resp_uc_read_i(icache_uc_read_resp), + + .dcache_mem_req_uc_write_ready_i('0), + .dcache_mem_req_uc_write_valid_o( /* unused */), + .dcache_mem_req_uc_write_o( /* unused */), + + .dcache_mem_req_uc_write_data_ready_i('0), + .dcache_mem_req_uc_write_data_valid_o( /* unused */), + .dcache_mem_req_uc_write_data_o( /* unused */), + + .dcache_mem_resp_uc_write_ready_o( /* unused */), + .dcache_mem_resp_uc_write_valid_i('0), + .dcache_mem_resp_uc_write_i( /* unused */), + + .HPDCACHE_UC_READ_ID (HPDCACHE_ICACHE_UC_READ_ID), + .HPDCACHE_UC_WRITE_ID( /* unused */) + ); - // }}} + // D$ instantiation // {{{ - `include "hpdcache_typedef.svh" // 0: Page-Table Walk (PTW) // 1: Load unit @@ -191,9 +361,8 @@ module cva6_hpdcache_subsystem // . // NumPorts: CMO // NumPorts + 1: Hardware Memory Prefetcher (hwpf) - localparam int HPDCACHE_NREQUESTERS = NumPorts + 2; - localparam hpdcache_pkg::hpdcache_user_cfg_t HPDcacheUserCfg = '{ + localparam hpdcache_pkg::hpdcache_user_cfg_t hpdcacheDcacheUserCfg = '{ nRequesters: HPDCACHE_NREQUESTERS, paWidth: CVA6Cfg.PLEN, wordWidth: CVA6Cfg.XLEN, @@ -227,28 +396,16 @@ module cva6_hpdcache_subsystem memDataWidth: CVA6Cfg.AxiDataWidth }; - localparam hpdcache_pkg::hpdcache_cfg_t HPDcacheCfg = hpdcache_pkg::hpdcacheBuildConfig( - HPDcacheUserCfg + localparam hpdcache_pkg::hpdcache_cfg_t hpdcacheDcacheCfg = hpdcache_pkg::hpdcacheBuildConfig( + hpdcacheDcacheUserCfg ); - `HPDCACHE_TYPEDEF_MEM_ATTR_T(hpdcache_mem_addr_t, hpdcache_mem_id_t, hpdcache_mem_data_t, - hpdcache_mem_be_t, HPDcacheCfg); - `HPDCACHE_TYPEDEF_MEM_REQ_T(hpdcache_mem_req_t, hpdcache_mem_addr_t, hpdcache_mem_id_t); - `HPDCACHE_TYPEDEF_MEM_RESP_R_T(hpdcache_mem_resp_r_t, hpdcache_mem_id_t, hpdcache_mem_data_t); - `HPDCACHE_TYPEDEF_MEM_REQ_W_T(hpdcache_mem_req_w_t, hpdcache_mem_data_t, hpdcache_mem_be_t); - `HPDCACHE_TYPEDEF_MEM_RESP_W_T(hpdcache_mem_resp_w_t, hpdcache_mem_id_t); - - `HPDCACHE_TYPEDEF_REQ_ATTR_T(hpdcache_req_offset_t, hpdcache_data_word_t, hpdcache_data_be_t, - hpdcache_req_data_t, hpdcache_req_be_t, hpdcache_req_sid_t, - hpdcache_req_tid_t, hpdcache_tag_t, HPDcacheCfg); - `HPDCACHE_TYPEDEF_REQ_T(hpdcache_req_t, hpdcache_req_offset_t, hpdcache_req_data_t, - hpdcache_req_be_t, hpdcache_req_sid_t, hpdcache_req_tid_t, - hpdcache_tag_t); - `HPDCACHE_TYPEDEF_RSP_T(hpdcache_rsp_t, hpdcache_req_data_t, hpdcache_req_sid_t, - hpdcache_req_tid_t); + typedef logic [hpdcacheDcacheCfg.u.wbufTimecntWidth-1:0] hpdcache_wbuf_timecnt_t; - typedef logic [HPDcacheCfg.u.wbufTimecntWidth-1:0] hpdcache_wbuf_timecnt_t; + localparam logic [hpdcacheDcacheCfg.u.memIdWidth-1:0] HPDCACHE_DCACHE_UC_READ_ID = {hpdcacheDcacheCfg.u.memIdWidth{1'b1}}; + localparam logic [hpdcacheDcacheCfg.u.memIdWidth-1:0] HPDCACHE_DCACHE_UC_WRITE_ID = {hpdcacheDcacheCfg.u.memIdWidth{1'b1}}; + // {{{ logic dcache_miss_ready; logic dcache_miss_valid; hpdcache_mem_req_t dcache_miss; @@ -288,38 +445,48 @@ module cva6_hpdcache_subsystem logic dcache_uc_write_resp_ready; logic dcache_uc_write_resp_valid; hpdcache_mem_resp_w_t dcache_uc_write_resp; + // }}} cva6_hpdcache_wrapper #( - .CVA6Cfg (CVA6Cfg), - .HPDcacheCfg (HPDcacheCfg), - .dbus_req_t (dbus_req_t), - .dbus_rsp_t (dbus_rsp_t), - .NumPorts (NumPorts), - .NrHwPrefetchers (NrHwPrefetchers), - .cmo_req_t (cmo_req_t), - .cmo_rsp_t (cmo_rsp_t), - .hpdcache_mem_addr_t (hpdcache_mem_addr_t), - .hpdcache_mem_id_t (hpdcache_mem_id_t), - .hpdcache_mem_data_t (hpdcache_mem_data_t), - .hpdcache_mem_be_t (hpdcache_mem_be_t), - .hpdcache_mem_req_t (hpdcache_mem_req_t), - .hpdcache_mem_req_w_t (hpdcache_mem_req_w_t), - .hpdcache_mem_resp_r_t (hpdcache_mem_resp_r_t), - .hpdcache_mem_resp_w_t (hpdcache_mem_resp_w_t), - .hpdcache_req_offset_t (hpdcache_req_offset_t), - .hpdcache_data_word_t (hpdcache_data_word_t), - .hpdcache_req_data_t (hpdcache_req_data_t), - .hpdcache_req_be_t (hpdcache_req_be_t), - .hpdcache_req_sid_t (hpdcache_req_sid_t), - .hpdcache_req_tid_t (hpdcache_req_tid_t), - .hpdcache_tag_t (hpdcache_tag_t), - .hpdcache_req_t (hpdcache_req_t), - .hpdcache_rsp_t (hpdcache_rsp_t), + .CVA6Cfg(CVA6Cfg), + .HPDcacheCfg(hpdcacheDcacheCfg), + .USE_AS_ICACHE('0), + .fetch_dreq_t(fetch_dreq_t), + .fetch_drsp_t(fetch_drsp_t), + .obi_fetch_req_t(obi_fetch_req_t), + .obi_fetch_rsp_t(obi_fetch_rsp_t), + .dcache_req_i_t(dbus_req_t), + .dcache_req_o_t(dbus_rsp_t), + .NumPorts(NumPorts), + .NrHwPrefetchers(NrHwPrefetchers), + .cmo_req_t(cmo_req_t), + .cmo_rsp_t(cmo_rsp_t), + .hpdcache_mem_addr_t(hpdcache_mem_addr_t), + .hpdcache_mem_id_t(hpdcache_mem_id_t), + .hpdcache_mem_data_t(hpdcache_mem_data_t), + .hpdcache_mem_be_t(hpdcache_mem_be_t), + .hpdcache_mem_req_t(hpdcache_mem_req_t), + .hpdcache_mem_req_w_t(hpdcache_mem_req_w_t), + .hpdcache_mem_resp_r_t(hpdcache_mem_resp_r_t), + .hpdcache_mem_resp_w_t(hpdcache_mem_resp_w_t), + .hpdcache_req_offset_t(hpdcache_req_offset_t), + .hpdcache_data_word_t(hpdcache_data_word_t), + .hpdcache_req_data_t(hpdcache_req_data_t), + .hpdcache_req_be_t(hpdcache_req_be_t), + .hpdcache_req_sid_t(hpdcache_req_sid_t), + .hpdcache_req_tid_t(hpdcache_req_tid_t), + .hpdcache_tag_t(hpdcache_tag_t), + .hpdcache_req_t(hpdcache_req_t), + .hpdcache_rsp_t(hpdcache_rsp_t), .hpdcache_wbuf_timecnt_t(hpdcache_wbuf_timecnt_t), - .hpdcache_data_be_t (hpdcache_data_be_t) + .hpdcache_data_be_t(hpdcache_data_be_t) ) i_dcache ( .clk_i(clk_i), .rst_ni(rst_ni), + .fetch_dreq_i( /* unused */), + .fetch_dreq_o( /* unused */), + .fetch_obi_req_i( /* unused */), + .fetch_obi_rsp_o( /* unused */), .dcache_enable_i(dcache_enable_i), .dcache_flush_i(dcache_flush_i), .dcache_flush_ack_o(dcache_flush_ack_o), @@ -381,9 +548,13 @@ module cva6_hpdcache_subsystem .dcache_mem_resp_uc_write_ready_o(dcache_uc_write_resp_ready), .dcache_mem_resp_uc_write_valid_i(dcache_uc_write_resp_valid), - .dcache_mem_resp_uc_write_i(dcache_uc_write_resp) + .dcache_mem_resp_uc_write_i(dcache_uc_write_resp), + + .HPDCACHE_UC_READ_ID (HPDCACHE_DCACHE_UC_READ_ID), + .HPDCACHE_UC_WRITE_ID(HPDCACHE_DCACHE_UC_WRITE_ID) ); + // }}} // AXI arbiter instantiation // {{{ @@ -412,13 +583,23 @@ module cva6_hpdcache_subsystem .clk_i, .rst_ni, - .icache_miss_valid_i(icache_miss_valid), + .icache_uc_read_ready_o(icache_uc_read_ready), + .icache_uc_read_valid_i(icache_uc_read_valid), + .icache_uc_read_i(icache_uc_read), + .icache_uc_read_id_i (hpdcache_mem_id_t'(HPDCACHE_ICACHE_UC_READ_ID)), + + .icache_uc_read_resp_ready_i(icache_uc_read_resp_ready), + .icache_uc_read_resp_valid_o(icache_uc_read_resp_valid), + .icache_uc_read_resp_o(icache_uc_read_resp), + .icache_miss_ready_o(icache_miss_ready), - .icache_miss_i (icache_miss), - .icache_miss_id_i (hpdcache_mem_id_t'(ICACHE_RDTXID)), + .icache_miss_valid_i(icache_miss_valid), + .icache_miss_i(icache_miss), + .icache_miss_id_i (hpdcache_mem_id_t'(HPDCACHE_ICACHE_MISS_ID)), + .icache_miss_resp_ready_i(icache_miss_resp_ready), .icache_miss_resp_valid_o(icache_miss_resp_valid), - .icache_miss_resp_o (icache_miss_resp), + .icache_miss_resp_o(icache_miss_resp), .dcache_miss_ready_o(dcache_miss_ready), .dcache_miss_valid_i(dcache_miss_valid), @@ -443,7 +624,7 @@ module cva6_hpdcache_subsystem .dcache_uc_read_ready_o(dcache_uc_read_ready), .dcache_uc_read_valid_i(dcache_uc_read_valid), .dcache_uc_read_i (dcache_uc_read), - .dcache_uc_read_id_i ('1), + .dcache_uc_read_id_i (hpdcache_mem_id_t'(HPDCACHE_DCACHE_UC_READ_ID)), .dcache_uc_read_resp_ready_i(dcache_uc_read_resp_ready), .dcache_uc_read_resp_valid_o(dcache_uc_read_resp_valid), @@ -452,7 +633,7 @@ module cva6_hpdcache_subsystem .dcache_uc_write_ready_o(dcache_uc_write_ready), .dcache_uc_write_valid_i(dcache_uc_write_valid), .dcache_uc_write_i (dcache_uc_write), - .dcache_uc_write_id_i ('1), + .dcache_uc_write_id_i (hpdcache_mem_id_t'(HPDCACHE_DCACHE_UC_WRITE_ID)), .dcache_uc_write_data_ready_o(dcache_uc_write_data_ready), .dcache_uc_write_data_valid_i(dcache_uc_write_data_valid), @@ -471,26 +652,28 @@ module cva6_hpdcache_subsystem // {{{ // pragma translate_off initial begin : initial_assertions - assert (HPDcacheCfg.u.reqSrcIdWidth >= $clog2(HPDCACHE_NREQUESTERS)) + assert (hpdcacheDcacheCfg.u.reqSrcIdWidth >= $clog2(HPDCACHE_NREQUESTERS)) else $fatal(1, "HPDCACHE_REQ_SRC_ID_WIDTH is not wide enough"); assert (CVA6Cfg.MEM_TID_WIDTH <= CVA6Cfg.AxiIdWidth) else $fatal(1, "MEM_TID_WIDTH shall be less or equal to the AxiIdWidth"); - assert (CVA6Cfg.MEM_TID_WIDTH >= ($clog2(HPDcacheCfg.u.mshrSets * HPDcacheCfg.u.mshrWays) + 1)) + assert (CVA6Cfg.MEM_TID_WIDTH >= ($clog2( + hpdcacheDcacheCfg.u.mshrSets * hpdcacheDcacheCfg.u.mshrWays + ) + 1)) else $fatal(1, "MEM_TID_WIDTH shall allow to uniquely identify all D$ and I$ miss requests "); - assert (CVA6Cfg.MEM_TID_WIDTH >= ($clog2(HPDcacheCfg.u.wbufDirEntries) + 1)) + assert (CVA6Cfg.MEM_TID_WIDTH >= ($clog2(hpdcacheDcacheCfg.u.wbufDirEntries) + 1)) else $fatal(1, "MEM_TID_WIDTH shall allow to uniquely identify all D$ write requests "); end - a_invalid_instruction_fetch : - assert property ( - @(posedge clk_i) disable iff (~rst_ni) (fetch_obi_rsp_o.rvalid && !fetch_dreq_o.invalid_data) |-> (|fetch_obi_rsp_o.r.rdata) !== 1'hX) - else - $warning( - 1, - "[l1 dcache] reading invalid instructions: vaddr=%08X, data=%08X", - fetch_dreq_i.vaddr, - fetch_obi_rsp_o.r.rdata - ); + // a_invalid_instruction_fetch : + // assert property ( + // @(posedge clk_i) disable iff (!rst_ni) fetch_dreq_o.valid |-> (|fetch_dreq_o.data) !== 1'hX) + // else + // $warning( + // 1, + // "[l1 dcache] reading invalid instructions: vaddr=%08X, data=%08X", + // fetch_dreq_o.vaddr, + // fetch_dreq_o.data + // ); a_invalid_write_data : assert property ( diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv b/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv index 48ee3f5d9c..c6b22c8c30 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv @@ -47,13 +47,23 @@ module cva6_hpdcache_subsystem_axi_arbiter // Interfaces from/to I$ // {{{ - input logic icache_miss_valid_i, - output logic icache_miss_ready_o, - input icache_req_t icache_miss_i, - input hpdcache_mem_id_t icache_miss_id_i, - - output logic icache_miss_resp_valid_o, - output icache_rtrn_t icache_miss_resp_o, + input logic icache_uc_read_valid_i, + output logic icache_uc_read_ready_o, + input hpdcache_mem_req_t icache_uc_read_i, + input hpdcache_mem_id_t icache_uc_read_id_i, + + input logic icache_uc_read_resp_ready_i, + output logic icache_uc_read_resp_valid_o, + output hpdcache_mem_resp_r_t icache_uc_read_resp_o, + + input logic icache_miss_valid_i, + output logic icache_miss_ready_o, + input hpdcache_mem_req_t icache_miss_i, + input hpdcache_mem_id_t icache_miss_id_i, + + input logic icache_miss_resp_ready_i, + output logic icache_miss_resp_valid_o, + output hpdcache_mem_resp_r_t icache_miss_resp_o, // }}} // Interfaces from/to D$ @@ -114,186 +124,38 @@ module cva6_hpdcache_subsystem_axi_arbiter // Internal type definitions // {{{ - localparam int MEM_RESP_RT_DEPTH = (1 << CVA6Cfg.MEM_TID_WIDTH); typedef hpdcache_mem_id_t [MEM_RESP_RT_DEPTH-1:0] mem_resp_rt_t; - typedef logic [CVA6Cfg.ICACHE_LINE_WIDTH-1:0] icache_resp_data_t; - // }}} - - // Adapt the I$ interface to the HPDcache memory interface - // {{{ - localparam int ICACHE_CL_WORDS = CVA6Cfg.ICACHE_LINE_WIDTH / 64; - localparam int ICACHE_CL_WORD_INDEX = $clog2(ICACHE_CL_WORDS); - localparam int ICACHE_CL_SIZE = $clog2(CVA6Cfg.ICACHE_LINE_WIDTH / 8); - localparam int ICACHE_WORD_SIZE = 3; - localparam int ICACHE_MEM_REQ_CL_LEN = - (CVA6Cfg.ICACHE_LINE_WIDTH + CVA6Cfg.AxiDataWidth - 1)/CVA6Cfg.AxiDataWidth; - localparam int ICACHE_MEM_REQ_CL_SIZE = - (CVA6Cfg.AxiDataWidth <= CVA6Cfg.ICACHE_LINE_WIDTH) ? - $clog2( - CVA6Cfg.AxiDataWidth / 8 - ) : ICACHE_CL_SIZE; - - // I$ request - hpdcache_mem_req_t icache_miss_req_wdata; - logic icache_miss_req_w, icache_miss_req_wok; - - hpdcache_mem_req_t icache_miss_req_rdata; - logic icache_miss_req_r, icache_miss_req_rok; - - logic icache_miss_pending_q; - - // This FIFO has two functionnalities: - // - Stabilize the ready-valid protocol. The ICACHE can abort a valid - // transaction without receiving the corresponding ready signal. This - // behavior is not supported by AXI. - // - Cut a possible long timing path. - hpdcache_fifo_reg #( - .FIFO_DEPTH (1), - .fifo_data_t(hpdcache_mem_req_t) - ) i_icache_miss_req_fifo ( - .clk_i, - .rst_ni, - - .w_i (icache_miss_req_w), - .wok_o (icache_miss_req_wok), - .wdata_i(icache_miss_req_wdata), - - .r_i (icache_miss_req_r), - .rok_o (icache_miss_req_rok), - .rdata_o(icache_miss_req_rdata) - ); - - assign icache_miss_req_w = icache_miss_valid_i, icache_miss_ready_o = icache_miss_req_wok; - - assign icache_miss_req_wdata.mem_req_addr = icache_miss_i.paddr, - icache_miss_req_wdata.mem_req_len = icache_miss_i.nc ? 0 : ICACHE_MEM_REQ_CL_LEN - 1, - icache_miss_req_wdata.mem_req_size = icache_miss_i.nc ? ICACHE_WORD_SIZE : ICACHE_MEM_REQ_CL_SIZE, - icache_miss_req_wdata.mem_req_id = icache_miss_i.tid, - icache_miss_req_wdata.mem_req_command = hpdcache_pkg::HPDCACHE_MEM_READ, - icache_miss_req_wdata.mem_req_atomic = hpdcache_pkg::hpdcache_mem_atomic_e'(0), - icache_miss_req_wdata.mem_req_cacheable = ~icache_miss_i.nc; - - - // I$ response - logic icache_miss_resp_w, icache_miss_resp_wok; - hpdcache_mem_resp_r_t icache_miss_resp_wdata; - - logic icache_miss_resp_data_w, icache_miss_resp_data_wok; - logic icache_miss_resp_data_r, icache_miss_resp_data_rok; - icache_resp_data_t icache_miss_resp_data_rdata; - - logic icache_miss_resp_meta_w, icache_miss_resp_meta_wok; - logic icache_miss_resp_meta_r, icache_miss_resp_meta_rok; - hpdcache_mem_id_t icache_miss_resp_meta_id; - - icache_resp_data_t icache_miss_rdata; - - generate - if (CVA6Cfg.AxiDataWidth < CVA6Cfg.ICACHE_LINE_WIDTH) begin - hpdcache_fifo_reg #( - .FIFO_DEPTH (1), - .fifo_data_t(hpdcache_mem_id_t) - ) i_icache_refill_meta_fifo ( - .clk_i, - .rst_ni, - - .w_i (icache_miss_resp_meta_w), - .wok_o (icache_miss_resp_meta_wok), - .wdata_i(icache_miss_resp_wdata.mem_resp_r_id), - - .r_i (icache_miss_resp_meta_r), - .rok_o (icache_miss_resp_meta_rok), - .rdata_o(icache_miss_resp_meta_id) - ); - - hpdcache_data_upsize #( - .WR_WIDTH(CVA6Cfg.AxiDataWidth), - .RD_WIDTH(CVA6Cfg.ICACHE_LINE_WIDTH), - .DEPTH (1) - ) i_icache_hpdcache_data_upsize ( - .clk_i, - .rst_ni, - - .w_i (icache_miss_resp_data_w), - .wlast_i(icache_miss_resp_wdata.mem_resp_r_last), - .wok_o (icache_miss_resp_data_wok), - .wdata_i(icache_miss_resp_wdata.mem_resp_r_data), - - .r_i (icache_miss_resp_data_r), - .rok_o (icache_miss_resp_data_rok), - .rdata_o(icache_miss_resp_data_rdata) - ); - - assign icache_miss_resp_meta_r = 1'b1, icache_miss_resp_data_r = 1'b1; - - assign icache_miss_resp_meta_w = icache_miss_resp_w & icache_miss_resp_wdata.mem_resp_r_last; - - assign icache_miss_resp_data_w = icache_miss_resp_w; - - assign icache_miss_resp_wok = icache_miss_resp_data_wok & ( - icache_miss_resp_meta_wok | ~icache_miss_resp_wdata.mem_resp_r_last); - - assign icache_miss_rdata = icache_miss_resp_data_rdata; - - end else begin - assign icache_miss_resp_data_rok = icache_miss_resp_w; - assign icache_miss_resp_meta_rok = icache_miss_resp_w; - assign icache_miss_resp_wok = 1'b1; - assign icache_miss_resp_meta_id = icache_miss_resp_wdata.mem_resp_r_id; - assign icache_miss_resp_data_rdata = icache_miss_resp_wdata.mem_resp_r_data; - - // In the case of uncacheable accesses, the Icache expects the data to be right-aligned - always_comb begin : icache_miss_resp_data_comb - if (!icache_miss_req_rdata.mem_req_cacheable) begin - automatic logic [ICACHE_CL_WORD_INDEX - 1:0] icache_miss_word_index; - automatic logic [63:0] icache_miss_word; - icache_miss_word_index = icache_miss_req_rdata.mem_req_addr[3+:ICACHE_CL_WORD_INDEX]; - icache_miss_word = icache_miss_resp_data_rdata[icache_miss_word_index*64+:64]; - icache_miss_rdata = {{CVA6Cfg.ICACHE_LINE_WIDTH - 64{1'b0}}, icache_miss_word}; - end else begin - icache_miss_rdata = icache_miss_resp_data_rdata; - end - end - end - endgenerate - - assign icache_miss_resp_valid_o = icache_miss_resp_meta_rok, - icache_miss_resp_o.rtype = wt_cache_pkg::ICACHE_IFILL_ACK, - icache_miss_resp_o.user = '0, - icache_miss_resp_o.inv = '0, - icache_miss_resp_o.tid = icache_miss_resp_meta_id, - icache_miss_resp_o.data = icache_miss_rdata; - - // consume the Icache miss on the arrival of the response. The request - // metadata is decoded to forward the correct word in case of uncacheable - // Icache access - assign icache_miss_req_r = icache_miss_resp_meta_rok; // }}} // Read request arbiter // {{{ - logic mem_req_read_ready [2:0]; - logic mem_req_read_valid [2:0]; - hpdcache_mem_req_t mem_req_read [2:0]; + logic mem_req_read_ready [3:0]; + logic mem_req_read_valid [3:0]; + hpdcache_mem_req_t mem_req_read [3:0]; logic mem_req_read_ready_arb; logic mem_req_read_valid_arb; hpdcache_mem_req_t mem_req_read_arb; - assign mem_req_read_valid[0] = icache_miss_req_rok & ~icache_miss_pending_q, - mem_req_read[0] = icache_miss_req_rdata; + assign icache_miss_ready_o = mem_req_read_ready[0], + mem_req_read_valid[0] = icache_miss_valid_i, + mem_req_read[0] = icache_miss_i; + + assign icache_uc_read_ready_o = mem_req_read_ready[1], + mem_req_read_valid[1] = icache_uc_read_valid_i, + mem_req_read[1] = icache_uc_read_i; - assign dcache_miss_ready_o = mem_req_read_ready[1], - mem_req_read_valid[1] = dcache_miss_valid_i, - mem_req_read[1] = dcache_miss_i; + assign dcache_miss_ready_o = mem_req_read_ready[2], + mem_req_read_valid[2] = dcache_miss_valid_i, + mem_req_read[2] = dcache_miss_i; - assign dcache_uc_read_ready_o = mem_req_read_ready[2], - mem_req_read_valid[2] = dcache_uc_read_valid_i, - mem_req_read[2] = dcache_uc_read_i; + assign dcache_uc_read_ready_o = mem_req_read_ready[3], + mem_req_read_valid[3] = dcache_uc_read_valid_i, + mem_req_read[3] = dcache_uc_read_i; hpdcache_mem_req_read_arbiter #( - .N (3), + .N (4), .hpdcache_mem_req_t(hpdcache_mem_req_t) ) i_mem_req_read_arbiter ( .clk_i, @@ -315,21 +177,22 @@ module cva6_hpdcache_subsystem_axi_arbiter logic mem_resp_read_valid; hpdcache_mem_resp_r_t mem_resp_read; - logic mem_resp_read_ready_arb[2:0]; - logic mem_resp_read_valid_arb[2:0]; - hpdcache_mem_resp_r_t mem_resp_read_arb [2:0]; + logic mem_resp_read_ready_arb[3:0]; + logic mem_resp_read_valid_arb[3:0]; + hpdcache_mem_resp_r_t mem_resp_read_arb [3:0]; mem_resp_rt_t mem_resp_read_rt; always_comb begin for (int i = 0; i < MEM_RESP_RT_DEPTH; i++) begin mem_resp_read_rt[i] = (i == int'( icache_miss_id_i)) ? 0 : - (i == int'(dcache_uc_read_id_i)) ? 2 : 1; + (i == int'( icache_uc_read_id_i)) ? 1 : + (i == int'(dcache_uc_read_id_i)) ? 3 : 2; end end hpdcache_mem_resp_demux #( - .N (3), + .N (4), .resp_t (hpdcache_mem_resp_r_t), .resp_id_t(hpdcache_mem_id_t) ) i_mem_resp_read_demux ( @@ -348,17 +211,21 @@ module cva6_hpdcache_subsystem_axi_arbiter .mem_resp_rt_i(mem_resp_read_rt) ); - assign icache_miss_resp_w = mem_resp_read_valid_arb[0], - icache_miss_resp_wdata = mem_resp_read_arb[0], - mem_resp_read_ready_arb[0] = icache_miss_resp_wok; + assign icache_miss_resp_valid_o = mem_resp_read_valid_arb[0], + icache_miss_resp_o = mem_resp_read_arb[0], + mem_resp_read_ready_arb[0] = icache_miss_resp_ready_i; - assign dcache_miss_resp_valid_o = mem_resp_read_valid_arb[1], - dcache_miss_resp_o = mem_resp_read_arb[1], - mem_resp_read_ready_arb[1] = dcache_miss_resp_ready_i; + assign icache_uc_read_resp_valid_o = mem_resp_read_valid_arb[1], + icache_uc_read_resp_o = mem_resp_read_arb[1], + mem_resp_read_ready_arb[1] = icache_uc_read_resp_ready_i; - assign dcache_uc_read_resp_valid_o = mem_resp_read_valid_arb[2], - dcache_uc_read_resp_o = mem_resp_read_arb[2], - mem_resp_read_ready_arb[2] = dcache_uc_read_resp_ready_i; + assign dcache_miss_resp_valid_o = mem_resp_read_valid_arb[2], + dcache_miss_resp_o = mem_resp_read_arb[2], + mem_resp_read_ready_arb[2] = dcache_miss_resp_ready_i; + + assign dcache_uc_read_resp_valid_o = mem_resp_read_valid_arb[3], + dcache_uc_read_resp_o = mem_resp_read_arb[3], + mem_resp_read_ready_arb[3] = dcache_uc_read_resp_ready_i; // }}} // Write request arbiter @@ -468,17 +335,6 @@ module cva6_hpdcache_subsystem_axi_arbiter mem_resp_write_ready_arb[1] = dcache_uc_write_resp_ready_i; // }}} - // I$ miss pending - // {{{ - always_ff @(posedge clk_i or negedge rst_ni) begin : icache_miss_pending_ff - if (!rst_ni) begin - icache_miss_pending_q <= 1'b0; - end else begin - icache_miss_pending_q <= ( (icache_miss_req_rok & mem_req_read_ready[0]) & ~icache_miss_pending_q) | - (~(icache_miss_req_r & icache_miss_req_rok) & icache_miss_pending_q); - end - end - // }}} // AXI adapters // {{{ diff --git a/core/cache_subsystem/cva6_hpdcache_wrapper.sv b/core/cache_subsystem/cva6_hpdcache_wrapper.sv index 3e2932a8c9..4e25d95e5d 100644 --- a/core/cache_subsystem/cva6_hpdcache_wrapper.sv +++ b/core/cache_subsystem/cva6_hpdcache_wrapper.sv @@ -17,9 +17,14 @@ module cva6_hpdcache_wrapper // {{{ #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter hpdcache_pkg::hpdcache_cfg_t HPDcacheCfg = '0, - parameter type dbus_req_t = logic, - parameter type dbus_rsp_t = logic, + parameter hpdcache_pkg::hpdcache_cfg_t HPDcacheCfg, + parameter logic USE_AS_ICACHE, + parameter type fetch_dreq_t = logic, + parameter type fetch_drsp_t = logic, + parameter type obi_fetch_req_t = logic, + parameter type obi_fetch_rsp_t = logic, + parameter type dcache_req_i_t = logic, + parameter type dcache_req_o_t = logic, parameter int NumPorts = 4, parameter int NrHwPrefetchers = 4, @@ -56,6 +61,14 @@ module cva6_hpdcache_wrapper // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // I$ + // {{{ + input fetch_dreq_t fetch_dreq_i, + output fetch_drsp_t fetch_dreq_o, + input obi_fetch_req_t fetch_obi_req_i, + output obi_fetch_rsp_t fetch_obi_rsp_o, + // }}} + // D$ // {{{ // Cache management @@ -77,9 +90,9 @@ module cva6_hpdcache_wrapper // CMO interface response - TO_BE_COMPLETED output cmo_rsp_t dcache_cmo_resp_o, // Data cache input request ports - EX_STAGE - input dbus_req_t [NumPorts-1:0] dcache_req_ports_i, + input dcache_req_i_t [NumPorts-1:0] dcache_req_ports_i, // Data cache output request ports - EX_STAGE - output dbus_rsp_t [NumPorts-1:0] dcache_req_ports_o, + output dcache_req_o_t [NumPorts-1:0] dcache_req_ports_o, // Write buffer status to know if empty - EX_STAGE output logic wbuffer_empty_o, // Write buffer status to know if not non idempotent - EX_STAGE @@ -145,20 +158,22 @@ module cva6_hpdcache_wrapper output logic dcache_mem_resp_uc_write_ready_o, input logic dcache_mem_resp_uc_write_valid_i, - input hpdcache_mem_resp_w_t dcache_mem_resp_uc_write_i -); - localparam int HPDCACHE_NREQUESTERS = NumPorts + 2; + input hpdcache_mem_resp_w_t dcache_mem_resp_uc_write_i, + input logic [HPDcacheCfg.u.memIdWidth-1:0] HPDCACHE_UC_READ_ID, + input logic [HPDcacheCfg.u.memIdWidth-1:0] HPDCACHE_UC_WRITE_ID + +); typedef logic [63:0] hwpf_stride_param_t; - logic dcache_req_valid[HPDCACHE_NREQUESTERS]; - logic dcache_req_ready[HPDCACHE_NREQUESTERS]; - hpdcache_req_t dcache_req [HPDCACHE_NREQUESTERS]; - logic dcache_req_abort[HPDCACHE_NREQUESTERS]; - hpdcache_tag_t dcache_req_tag [HPDCACHE_NREQUESTERS]; - hpdcache_pkg::hpdcache_pma_t dcache_req_pma [HPDCACHE_NREQUESTERS]; - logic dcache_rsp_valid[HPDCACHE_NREQUESTERS]; - hpdcache_rsp_t dcache_rsp [HPDCACHE_NREQUESTERS]; + logic dcache_req_valid[HPDcacheCfg.u.nRequesters]; + logic dcache_req_ready[HPDcacheCfg.u.nRequesters]; + hpdcache_req_t dcache_req [HPDcacheCfg.u.nRequesters]; + logic dcache_req_abort[HPDcacheCfg.u.nRequesters]; + hpdcache_tag_t dcache_req_tag [HPDcacheCfg.u.nRequesters]; + hpdcache_pkg::hpdcache_pma_t dcache_req_pma [HPDcacheCfg.u.nRequesters]; + logic dcache_rsp_valid[HPDcacheCfg.u.nRequesters]; + hpdcache_rsp_t dcache_rsp [HPDcacheCfg.u.nRequesters]; logic dcache_read_miss, dcache_write_miss; logic [ 2:0] snoop_valid; @@ -173,43 +188,80 @@ module cva6_hpdcache_wrapper hwpf_stride_pkg::hwpf_stride_throttle_t [NrHwPrefetchers-1:0] hwpf_throttle_out; generate - dbus_req_t dcache_req_ports[NumPorts - 1]; + dcache_req_i_t dcache_req_ports[HPDcacheCfg.u.nRequesters-1:0]; for (genvar r = 0; r < (NumPorts - 1); r++) begin : gen_cva6_hpdcache_load_if_adapter assign dcache_req_ports[r] = dcache_req_ports_i[r]; - cva6_hpdcache_if_adapter #( - .CVA6Cfg (CVA6Cfg), - .HPDcacheCfg (HPDcacheCfg), - .hpdcache_tag_t (hpdcache_tag_t), - .hpdcache_req_offset_t(hpdcache_req_offset_t), - .hpdcache_req_sid_t (hpdcache_req_sid_t), - .hpdcache_req_t (hpdcache_req_t), - .hpdcache_rsp_t (hpdcache_rsp_t), - .dbus_req_t (dbus_req_t), - .dbus_rsp_t (dbus_rsp_t), - .is_load_port (1'b1) - ) i_cva6_hpdcache_load_if_adapter ( - .clk_i, - .rst_ni, - - .hpdcache_req_sid_i(hpdcache_req_sid_t'(r)), - - .cva6_req_i (dcache_req_ports[r]), - .cva6_req_o (dcache_req_ports_o[r]), - .cva6_amo_req_i ('0), - .cva6_amo_resp_o( /* unused */), - - .hpdcache_req_valid_o(dcache_req_valid[r]), - .hpdcache_req_ready_i(dcache_req_ready[r]), - .hpdcache_req_o (dcache_req[r]), - .hpdcache_req_abort_o(dcache_req_abort[r]), - .hpdcache_req_tag_o (dcache_req_tag[r]), - .hpdcache_req_pma_o (dcache_req_pma[r]), - - .hpdcache_rsp_valid_i(dcache_rsp_valid[r]), - .hpdcache_rsp_i (dcache_rsp[r]) - ); + if (USE_AS_ICACHE) begin + cva6_hpdcache_icache_if_adapter #( + .CVA6Cfg (CVA6Cfg), + .hpdcacheCfg (HPDcacheCfg), + .hpdcache_tag_t (hpdcache_tag_t), + .hpdcache_req_offset_t(hpdcache_req_offset_t), + .hpdcache_req_sid_t (hpdcache_req_sid_t), + .hpdcache_req_t (hpdcache_req_t), + .hpdcache_rsp_t (hpdcache_rsp_t), + .fetch_dreq_t (fetch_dreq_t), + .fetch_drsp_t (fetch_drsp_t), + .obi_fetch_req_t (obi_fetch_req_t), + .obi_fetch_rsp_t (obi_fetch_rsp_t), + // .is_load_port (1'b1) + ) i_cva6_hpdcache_load_if_icache_adapter ( + .clk_i, + .rst_ni, + + .hpdcache_req_sid_i(hpdcache_req_sid_t'(r)), + + .dreq_i(fetch_dreq_i), + .dreq_o(fetch_dreq_o), + .fetch_obi_req_i(fetch_obi_req_i), + .fetch_obi_rsp_o(fetch_obi_rsp_o), + + .hpdcache_req_valid_o(dcache_req_valid[r]), + .hpdcache_req_ready_i(dcache_req_ready[r]), + .hpdcache_req_o (dcache_req[r]), + .hpdcache_req_abort_o(dcache_req_abort[r]), + .hpdcache_req_tag_o (dcache_req_tag[r]), + .hpdcache_req_pma_o (dcache_req_pma[r]), + + .hpdcache_rsp_valid_i(dcache_rsp_valid[r]), + .hpdcache_rsp_i (dcache_rsp[r]) + ); + end else begin + cva6_hpdcache_if_adapter #( + .CVA6Cfg (CVA6Cfg), + .HPDcacheCfg (HPDcacheCfg), + .hpdcache_tag_t (hpdcache_tag_t), + .hpdcache_req_offset_t(hpdcache_req_offset_t), + .hpdcache_req_sid_t (hpdcache_req_sid_t), + .hpdcache_req_t (hpdcache_req_t), + .hpdcache_rsp_t (hpdcache_rsp_t), + .dbus_req_t (dcache_req_i_t), + .dbus_rsp_t (dcache_req_o_t), + .is_load_port (1'b1) + ) i_cva6_hpdcache_load_if_adapter ( + .clk_i, + .rst_ni, + + .hpdcache_req_sid_i(hpdcache_req_sid_t'(r)), + + .cva6_req_i (dcache_req_ports[r]), + .cva6_req_o (dcache_req_ports_o[r]), + .cva6_amo_req_i ('0), + .cva6_amo_resp_o( /* unused */), + + .hpdcache_req_valid_o(dcache_req_valid[r]), + .hpdcache_req_ready_i(dcache_req_ready[r]), + .hpdcache_req_o (dcache_req[r]), + .hpdcache_req_abort_o(dcache_req_abort[r]), + .hpdcache_req_tag_o (dcache_req_tag[r]), + .hpdcache_req_pma_o (dcache_req_pma[r]), + + .hpdcache_rsp_valid_i(dcache_rsp_valid[r]), + .hpdcache_rsp_i (dcache_rsp[r]) + ); + end end cva6_hpdcache_if_adapter #( @@ -220,8 +272,8 @@ module cva6_hpdcache_wrapper .hpdcache_req_sid_t (hpdcache_req_sid_t), .hpdcache_req_t (hpdcache_req_t), .hpdcache_rsp_t (hpdcache_rsp_t), - .dbus_req_t (dbus_req_t), - .dbus_rsp_t (dbus_rsp_t), + .dbus_req_t (dcache_req_i_t), + .dbus_rsp_t (dcache_req_o_t), .is_load_port (1'b0) ) i_cva6_hpdcache_store_if_adapter ( .clk_i, @@ -461,7 +513,9 @@ module cva6_hpdcache_wrapper .cfg_wbuf_inhibit_write_coalescing_i(1'b0), .cfg_prefetch_updt_plru_i (1'b1), .cfg_error_on_cacheable_amo_i (1'b0), - .cfg_rtab_single_entry_i (1'b0) + .cfg_rtab_single_entry_i (1'b0), + .HPDCACHE_UC_READ_ID (HPDCACHE_UC_READ_ID), + .HPDCACHE_UC_WRITE_ID (HPDCACHE_UC_WRITE_ID) ); assign dcache_miss_o = dcache_read_miss, wbuffer_not_ni_o = wbuffer_empty_o; diff --git a/core/cache_subsystem/hpdcache b/core/cache_subsystem/hpdcache index 25ffa3438c..4a5f66ba54 160000 --- a/core/cache_subsystem/hpdcache +++ b/core/cache_subsystem/hpdcache @@ -1 +1 @@ -Subproject commit 25ffa3438c8150fef791dd165234694a51e3c529 +Subproject commit 4a5f66ba54463280f5a56f1bd9bf11ce33c819d5 diff --git a/core/cva6.sv b/core/cva6.sv index dbe20c7878..a15bff95a1 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1344,8 +1344,6 @@ module cva6 .dbus_rsp_t(dbus_rsp_t), .obi_fetch_req_t(obi_fetch_req_t), .obi_fetch_rsp_t(obi_fetch_rsp_t), - .obi_dbus_req_t(obi_dbus_req_t), - .obi_dbus_rsp_t(obi_dbus_rsp_t), .NumPorts (NumPorts), .axi_ar_chan_t(axi_ar_chan_t), .axi_aw_chan_t(axi_aw_chan_t),