From 2dc019ddb180545003d32e6775151f6802b5752c Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Fri, 10 Apr 2026 19:16:41 +0200 Subject: [PATCH 1/8] hpdcache_subsystem: add SPM mode support --- .../cva6_hpdcache_if_adapter.sv | 52 +++++++++++++++- .../cva6_hpdcache_subsystem.sv | 19 +++++- core/cache_subsystem/cva6_hpdcache_wrapper.sv | 60 ++++++++++++++++++- core/cache_subsystem/hpdcache | 2 +- core/cva6.sv | 8 ++- core/include/config_pkg.sv | 8 +++ 6 files changed, 138 insertions(+), 11 deletions(-) diff --git a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv index bddcef4d9c..9c6430559c 100644 --- a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv +++ b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv @@ -69,6 +69,8 @@ module cva6_hpdcache_if_adapter } flush_fsm_t; logic hpdcache_req_is_uncacheable; + logic hpdcache_req_is_ispm; + logic hpdcache_req_is_dspm; hpdcache_req_t hpdcache_req; // }}} @@ -85,6 +87,22 @@ module cva6_hpdcache_if_adapter , cva6_req_i.address_tag , {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} } + ) && !hpdcache_req_is_ispm && !hpdcache_req_is_dspm; + assign hpdcache_req_is_ispm = config_pkg::is_inside_ispm_regions( + CVA6Cfg, + { + {64 - CVA6Cfg.DCACHE_TAG_WIDTH{1'b0}} + , cva6_req_i.address_tag + , {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} + } + ); + assign hpdcache_req_is_dspm = config_pkg::is_inside_dspm_regions( + CVA6Cfg, + { + {64 - CVA6Cfg.DCACHE_TAG_WIDTH{1'b0}} + , cva6_req_i.address_tag + , {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} + } ); // Request forwarding @@ -102,12 +120,16 @@ module cva6_hpdcache_if_adapter assign hpdcache_req.pma.uncacheable = 1'b0; assign hpdcache_req.pma.io = 1'b0; assign hpdcache_req.pma.wr_policy_hint = hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO; + assign hpdcache_req.pma.ispm = 1'b0; + assign hpdcache_req.pma.dspm = 1'b0; assign hpdcache_req_abort_o = cva6_req_i.kill_req; assign hpdcache_req_tag_o = cva6_req_i.address_tag; assign hpdcache_req_pma_o.uncacheable = hpdcache_req_is_uncacheable; assign hpdcache_req_pma_o.io = 1'b0; assign hpdcache_req_pma_o.wr_policy_hint = hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO; + assign hpdcache_req_pma_o.ispm = hpdcache_req_is_ispm; + assign hpdcache_req_pma_o.dspm = hpdcache_req_is_dspm; // Response forwarding assign cva6_req_o.data_rvalid = hpdcache_rsp_valid_i; @@ -235,6 +257,22 @@ module cva6_hpdcache_if_adapter , hpdcache_req.addr_tag, {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} } + ) && !hpdcache_req_is_ispm && !hpdcache_req_is_dspm; + assign hpdcache_req_is_ispm = config_pkg::is_inside_ispm_regions( + CVA6Cfg, + { + {64 - CVA6Cfg.DCACHE_TAG_WIDTH{1'b0}} + , cva6_req_i.address_tag + , {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} + } + ); + assign hpdcache_req_is_dspm = config_pkg::is_inside_dspm_regions( + CVA6Cfg, + { + {64 - CVA6Cfg.DCACHE_TAG_WIDTH{1'b0}} + , cva6_req_i.address_tag + , {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} + } ); assign amo_is_word = (cva6_amo_req_i.size == 2'b10); @@ -261,7 +299,9 @@ module cva6_hpdcache_if_adapter pma: '{ uncacheable: hpdcache_req_is_uncacheable, io: 1'b0, - wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO + wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO, + ispm: 1'b0, // TODO: SPM AMOs support + dspm: 1'b0 // TODO: SPM AMOs support } }; @@ -282,7 +322,9 @@ module cva6_hpdcache_if_adapter pma: '{ uncacheable: hpdcache_req_is_uncacheable, io: 1'b0, - wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO + wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO, + ispm: hpdcache_req_is_ispm, + dspm: hpdcache_req_is_dspm } }; @@ -305,7 +347,9 @@ module cva6_hpdcache_if_adapter pma: '{ uncacheable: 1'b0, io: 1'b0, - wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO + wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO, + ispm: 1'b0, + dspm: 1'b0 } }; @@ -322,6 +366,8 @@ module cva6_hpdcache_if_adapter assign hpdcache_req_pma_o.uncacheable = 1'b0; assign hpdcache_req_pma_o.io = 1'b0; assign hpdcache_req_pma_o.wr_policy_hint = hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO; + assign hpdcache_req_pma_o.ispm = 1'b0; + assign hpdcache_req_pma_o.dspm = 1'b0; // }}} // Response forwarding diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem.sv b/core/cache_subsystem/cva6_hpdcache_subsystem.sv index bbbc68659e..4abf153d3c 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem.sv @@ -65,6 +65,8 @@ module cva6_hpdcache_subsystem input logic icache_flush_i, // instruction cache miss - PERF_COUNTERS output logic icache_miss_o, + // I-cache ways configured as SPM - CSR_REGFILE + input logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] icache_spm_ways_i, // Input address translation request - EX_STAGE input icache_areq_t icache_areq_i, // Output address translation request - EX_STAGE @@ -86,6 +88,8 @@ module cva6_hpdcache_subsystem output logic dcache_flush_ack_o, // Load or store miss - PERF_COUNTERS output logic dcache_miss_o, + // D-cache ways configured as SPM - CSR_REGFILE + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] dcache_spm_ways_i, // AMO request - EX_STAGE input ariane_pkg::amo_req_t dcache_amo_req_i, @@ -145,6 +149,10 @@ module cva6_hpdcache_subsystem logic icache_miss_resp_valid; icache_rtrn_t icache_miss_resp; + // D-cache <-> I-cache SPM signals + dcache_req_o_t d2i_cache_req_in; + dcache_req_i_t d2i_cache_req_out; + localparam int ICACHE_RDTXID = 1 << (CVA6Cfg.MEM_TID_WIDTH - 1); cva6_icache #( @@ -155,6 +163,8 @@ module cva6_hpdcache_subsystem .icache_drsp_t(icache_drsp_t), .icache_req_t(icache_req_t), .icache_rtrn_t(icache_rtrn_t), + .dcache_req_i_t(dcache_req_i_t), + .dcache_req_o_t(dcache_req_o_t), .RdTxId(ICACHE_RDTXID) ) i_cva6_icache ( .clk_i (clk_i), @@ -165,13 +175,13 @@ module cva6_hpdcache_subsystem .busy_o (), .stall_i (1'b0), .init_ni (1'b0), - .icache_spm_ways_i('0), + .icache_spm_ways_i(icache_spm_ways_i), .areq_i (icache_areq_i), .areq_o (icache_areq_o), .dreq_i (icache_dreq_i), .dreq_o (icache_dreq_o), - .ispm_req_i ('0), - .ispm_req_o (), + .ispm_req_i (d2i_cache_req_out), + .ispm_req_o (d2i_cache_req_in), .mem_rtrn_vld_i (icache_miss_resp_valid), .mem_rtrn_i (icache_miss_resp), .mem_data_req_o (icache_miss_valid), @@ -329,6 +339,9 @@ module cva6_hpdcache_subsystem .dcache_req_ports_o(dcache_req_ports_o), .wbuffer_empty_o(wbuffer_empty_o), .wbuffer_not_ni_o(wbuffer_not_ni_o), + .dcache_spm_ways_i(dcache_spm_ways_i), + .ispm_req_o(d2i_cache_req_out), + .ispm_req_i(d2i_cache_req_in), .hwpf_base_set_i(hwpf_base_set_i), .hwpf_base_i(hwpf_base_i), .hwpf_base_o(hwpf_base_o), diff --git a/core/cache_subsystem/cva6_hpdcache_wrapper.sv b/core/cache_subsystem/cva6_hpdcache_wrapper.sv index a6c39a5374..d264dee030 100644 --- a/core/cache_subsystem/cva6_hpdcache_wrapper.sv +++ b/core/cache_subsystem/cva6_hpdcache_wrapper.sv @@ -81,6 +81,13 @@ module cva6_hpdcache_wrapper output logic wbuffer_empty_o, output logic wbuffer_not_ni_o, + // SPM ways configuration + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] dcache_spm_ways_i, + + // ISPM interface (request to i-cache scratchpad / response from i-cache scratchpad) + output dcache_req_i_t ispm_req_o, + input dcache_req_o_t ispm_req_i, + // Hardware memory prefetcher configuration input logic [NrHwPrefetchers-1:0] hwpf_base_set_i, input logic [NrHwPrefetchers-1:0][63:0] hwpf_base_i, @@ -128,6 +135,38 @@ module cva6_hpdcache_wrapper hpdcache_rsp_t dcache_rsp [HPDCACHE_NREQUESTERS]; logic dcache_read_miss, dcache_write_miss; + // ISPM internal signals + logic dcache_ispm_req_valid; + hpdcache_req_t dcache_ispm_req; + logic dcache_ispm_req_abort; + hpdcache_tag_t dcache_ispm_req_tag; + hpdcache_pkg::hpdcache_pma_t dcache_ispm_req_pma; + logic dcache_ispm_rsp_valid; + hpdcache_rsp_t dcache_ispm_rsp; + + // ISPM request conversion: hpdcache -> i-cache ISPM controller + assign ispm_req_o.data_req = dcache_ispm_req_valid; + assign ispm_req_o.address_index = dcache_ispm_req.addr_offset; + assign ispm_req_o.address_tag = dcache_ispm_req_tag; + assign ispm_req_o.data_wdata = dcache_ispm_req.wdata; + assign ispm_req_o.data_wuser = '0; + assign ispm_req_o.data_we = (dcache_ispm_req.op != hpdcache_pkg::HPDCACHE_REQ_LOAD); + assign ispm_req_o.data_be = dcache_ispm_req.be; + assign ispm_req_o.data_size = dcache_ispm_req.size; + assign ispm_req_o.data_id = dcache_ispm_req.tid; + assign ispm_req_o.kill_req = dcache_ispm_req_abort; + assign ispm_req_o.tag_valid = dcache_ispm_req_valid; + assign ispm_req_o.cbo_op = '0; + + // ISPM response conversion: i-cache ISPM controller -> hpdcache + // sid/tid are echoed from the still-valid outgoing request + assign dcache_ispm_rsp_valid = ispm_req_i.data_rvalid; + assign dcache_ispm_rsp.rdata = ispm_req_i.data_rdata; + assign dcache_ispm_rsp.sid = dcache_ispm_req.sid; + assign dcache_ispm_rsp.tid = dcache_ispm_req.tid; + assign dcache_ispm_rsp.error = 1'b0; + assign dcache_ispm_rsp.aborted = 1'b0; + logic [ 2:0] snoop_valid; logic [ 2:0] snoop_abort; hpdcache_req_offset_t [ 2:0] snoop_addr_offset; @@ -398,8 +437,21 @@ module cva6_hpdcache_wrapper .mem_resp_write_valid_i(dcache_mem_resp_write_valid_i), .mem_resp_write_i (dcache_mem_resp_write_i), + .ispm_req_valid_o(dcache_ispm_req_valid), + .ispm_req_o (dcache_ispm_req), + .ispm_req_abort_o(dcache_ispm_req_abort), + .ispm_req_tag_o (dcache_ispm_req_tag), + .ispm_req_pma_o (dcache_ispm_req_pma), + .ispm_rsp_valid_i(dcache_ispm_rsp_valid), + .ispm_rsp_i (dcache_ispm_rsp), + .evt_cache_write_miss_o(dcache_write_miss), .evt_cache_read_miss_o (dcache_read_miss), + .evt_cache_dir_unc_err_o( /* unused */), + .evt_cache_dir_cor_err_o( /* unused */), + .evt_cache_dat_unc_err_o( /* unused */), + .evt_cache_dat_cor_err_o( /* unused */), + .evt_scrub_complete_o ( /* unused */), .evt_uncached_req_o ( /* unused */), .evt_cmo_req_o ( /* unused */), .evt_write_req_o ( /* unused */), @@ -420,7 +472,13 @@ module cva6_hpdcache_wrapper .cfg_prefetch_updt_plru_i (1'b1), .cfg_error_on_cacheable_amo_i (1'b0), .cfg_rtab_single_entry_i (1'b0), - .cfg_default_wb_i (1'b0) + .cfg_default_wb_i (1'b0), + .cfg_scrub_enable_i (1'b0), + .cfg_scrub_period_i (6'd0), + .cfg_scrub_restart_i (1'b0), + .cfg_enable_dspm_i (1'b1), + .cfg_enable_ispm_i (1'b1), + .cfg_dspm_ways_i (dcache_spm_ways_i) ); 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 308a272864..36d8aa4bc3 160000 --- a/core/cache_subsystem/hpdcache +++ b/core/cache_subsystem/hpdcache @@ -1 +1 @@ -Subproject commit 308a2728641209297d9eb7d400f4a58fd48038d0 +Subproject commit 36d8aa4bc30f82210cbba8827c2960de81b5aea0 diff --git a/core/cva6.sv b/core/cva6.sv index 9138ad9c8a..cc0de81480 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1592,9 +1592,10 @@ module cva6 .clk_i (clk_i), .rst_ni(rst_ni), - .icache_en_i (icache_en_csr), - .icache_flush_i(icache_flush_ctrl_cache), - .icache_miss_o (icache_miss_cache_perf), + .icache_en_i (icache_en_csr), + .icache_flush_i (icache_flush_ctrl_cache), + .icache_miss_o (icache_miss_cache_perf), + .icache_spm_ways_i (icache_spm_ways_csr_cache), .icache_areq_i (icache_areq_ex_cache), .icache_areq_o (icache_areq_cache_ex), .icache_dreq_i (icache_dreq_if_cache), @@ -1604,6 +1605,7 @@ module cva6 .dcache_flush_i (dcache_flush_ctrl_cache), .dcache_flush_ack_o(dcache_flush_ack_cache_ctrl), .dcache_miss_o (dcache_miss_cache_perf), + .dcache_spm_ways_i (dcache_spm_ways_csr_cache), .dcache_amo_req_i (amo_req), .dcache_amo_resp_o(amo_resp), diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 81e7615c0c..a9e1329e77 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -535,4 +535,12 @@ package config_pkg; return |pass; endfunction : is_inside_cacheable_regions + function automatic logic is_inside_ispm_regions(cva6_cfg_t Cfg, logic [63:0] address); + return range_check(Cfg.ICacheSpmAddrBase, Cfg.ICacheSpmLength, address); + endfunction : is_inside_ispm_regions + + function automatic logic is_inside_dspm_regions(cva6_cfg_t Cfg, logic [63:0] address); + return range_check(Cfg.DCacheSpmAddrBase, Cfg.DCacheSpmLength, address); + endfunction : is_inside_dspm_regions + endpackage From 91dcefc4dacedd8f937d3cb2467418511b6ecebe Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Fri, 10 Apr 2026 19:17:24 +0200 Subject: [PATCH 2/8] hpdcache_tc_sram: fix missing parameter --- core/cache_subsystem/hpdcache_tc_sram.sv | 63 +++++++++++++----------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/core/cache_subsystem/hpdcache_tc_sram.sv b/core/cache_subsystem/hpdcache_tc_sram.sv index b24e6f9f12..a354dd0771 100644 --- a/core/cache_subsystem/hpdcache_tc_sram.sv +++ b/core/cache_subsystem/hpdcache_tc_sram.sv @@ -10,20 +10,21 @@ module hpdcache_sram_1rw #( parameter int unsigned ADDR_SIZE = 0, parameter int unsigned DATA_SIZE = 0, - parameter int unsigned DEPTH = 2 ** ADDR_SIZE + parameter int unsigned DEPTH = 2 ** ADDR_SIZE, + parameter int unsigned NDATA = 1 ) ( - input logic clk, - input logic rst_n, - input logic cs, - input logic we, - input logic [ADDR_SIZE-1:0] addr, - input logic [DATA_SIZE-1:0] wdata, - output logic [DATA_SIZE-1:0] rdata + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [NDATA-1:0][DATA_SIZE-1:0] wdata, + output logic [NDATA-1:0][DATA_SIZE-1:0] rdata ); tc_sram #( .NumWords (DEPTH), - .DataWidth(DATA_SIZE), - .ByteWidth(DATA_SIZE), + .DataWidth(DATA_SIZE * NDATA), + .ByteWidth(DATA_SIZE * NDATA), .NumPorts (1), .Latency (1) ) i_tc_sram ( @@ -42,20 +43,21 @@ endmodule module hpdcache_sram_wbyteenable_1rw #( parameter int unsigned ADDR_SIZE = 0, parameter int unsigned DATA_SIZE = 0, - parameter int unsigned DEPTH = 2 ** ADDR_SIZE + parameter int unsigned DEPTH = 2 ** ADDR_SIZE, + parameter int unsigned NDATA = 1 ) ( - input logic clk, - input logic rst_n, - input logic cs, - input logic we, - input logic [ ADDR_SIZE-1:0] addr, - input logic [ DATA_SIZE-1:0] wdata, - input logic [DATA_SIZE/8-1:0] wbyteenable, - output logic [ DATA_SIZE-1:0] rdata + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ ADDR_SIZE-1:0] addr, + input logic [NDATA-1:0][DATA_SIZE-1:0] wdata, + input logic [NDATA-1:0][DATA_SIZE/8-1:0] wbyteenable, + output logic [NDATA-1:0][DATA_SIZE-1:0] rdata ); tc_sram #( .NumWords (DEPTH), - .DataWidth(DATA_SIZE), + .DataWidth(DATA_SIZE * NDATA), .ByteWidth(8), .NumPorts (1), .Latency (1) @@ -75,20 +77,21 @@ endmodule module hpdcache_sram_wmask_1rw #( parameter int unsigned ADDR_SIZE = 0, parameter int unsigned DATA_SIZE = 0, - parameter int unsigned DEPTH = 2 ** ADDR_SIZE + parameter int unsigned DEPTH = 2 ** ADDR_SIZE, + parameter int unsigned NDATA = 1 ) ( - input logic clk, - input logic rst_n, - input logic cs, - input logic we, - input logic [ADDR_SIZE-1:0] addr, - input logic [DATA_SIZE-1:0] wdata, - input logic [DATA_SIZE-1:0] wmask, - output logic [DATA_SIZE-1:0] rdata + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [NDATA-1:0][DATA_SIZE-1:0] wdata, + input logic [NDATA-1:0][DATA_SIZE-1:0] wmask, + output logic [NDATA-1:0][DATA_SIZE-1:0] rdata ); tc_sram #( .NumWords (DEPTH), - .DataWidth(DATA_SIZE), + .DataWidth(DATA_SIZE * NDATA), .ByteWidth(1), .NumPorts (1), .Latency (1) From 031e0a60081c6be5992832a42b270de2b275682c Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Fri, 10 Apr 2026 19:17:54 +0200 Subject: [PATCH 3/8] csr_regfile: check `v_q` only when `RVH` is enabled --- core/csr_regfile.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 8d7591f7b1..cb72bc8fd7 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -1123,7 +1123,7 @@ module csr_regfile else read_access_exception = 1'b1; riscv::CSR_ICACHE_SPM_WAYS: begin - if (!v_q) begin + if (!(v_q && CVA6Cfg.RVH)) begin csr_rdata = icache_spm_ways_q; end else begin read_access_exception = 1'b1; @@ -1131,7 +1131,7 @@ module csr_regfile end riscv::CSR_DCACHE_SPM_WAYS: begin - if (!v_q) begin + if (!(v_q && CVA6Cfg.RVH)) begin csr_rdata = dcache_spm_ways_q; end else begin read_access_exception = 1'b1; @@ -2328,7 +2328,7 @@ module csr_regfile else update_access_exception = 1'b1; riscv::CSR_ICACHE_SPM_WAYS: begin - if (!v_q) begin + if (!(v_q && CVA6Cfg.RVH)) begin icache_spm_ways_d = csr_wdata & ((2 ** CVA6Cfg.ICACHE_SET_ASSOC) - 1); end else begin update_access_exception = 1'b1; @@ -2336,7 +2336,7 @@ module csr_regfile end riscv::CSR_DCACHE_SPM_WAYS: begin - if (!v_q) begin + if (!(v_q && CVA6Cfg.RVH)) begin dcache_spm_ways_d = csr_wdata & ((2 ** CVA6Cfg.DCACHE_SET_ASSOC) - 1); end else begin update_access_exception = 1'b1; From 2d31dd5741a911ad4561b891f7f94b39bfaaaa74 Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Mon, 13 Apr 2026 12:14:25 +0200 Subject: [PATCH 4/8] hpdcache: fixes for ISPM support --- core/cache_subsystem/cva6_hpdcache_wrapper.sv | 2 +- core/cache_subsystem/hpdcache | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/cache_subsystem/cva6_hpdcache_wrapper.sv b/core/cache_subsystem/cva6_hpdcache_wrapper.sv index d264dee030..e0d336d569 100644 --- a/core/cache_subsystem/cva6_hpdcache_wrapper.sv +++ b/core/cache_subsystem/cva6_hpdcache_wrapper.sv @@ -160,7 +160,7 @@ module cva6_hpdcache_wrapper // ISPM response conversion: i-cache ISPM controller -> hpdcache // sid/tid are echoed from the still-valid outgoing request - assign dcache_ispm_rsp_valid = ispm_req_i.data_rvalid; + assign dcache_ispm_rsp_valid = ispm_req_i.data_rvalid || ispm_req_i.data_gnt; // TODO: is this correct? assign dcache_ispm_rsp.rdata = ispm_req_i.data_rdata; assign dcache_ispm_rsp.sid = dcache_ispm_req.sid; assign dcache_ispm_rsp.tid = dcache_ispm_req.tid; diff --git a/core/cache_subsystem/hpdcache b/core/cache_subsystem/hpdcache index 36d8aa4bc3..70e3508ff5 160000 --- a/core/cache_subsystem/hpdcache +++ b/core/cache_subsystem/hpdcache @@ -1 +1 @@ -Subproject commit 36d8aa4bc30f82210cbba8827c2960de81b5aea0 +Subproject commit 70e3508ff5b92b88c55b34efa76bd5df754cef89 From 9626cf755350b2250d3d2157eede3c99fe495ffd Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Mon, 13 Apr 2026 12:16:00 +0200 Subject: [PATCH 5/8] tests: use `fence.i` for DSPM tests to ensure cache flushing --- test/sw/tests/dcache_spm_axpy.c | 2 +- test/sw/tests/dcache_spm_simple.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sw/tests/dcache_spm_axpy.c b/test/sw/tests/dcache_spm_axpy.c index b589852947..934131a413 100644 --- a/test/sw/tests/dcache_spm_axpy.c +++ b/test/sw/tests/dcache_spm_axpy.c @@ -44,7 +44,7 @@ void enable_dspm (uint32_t num_ways) { // Disable D-cache asm volatile ("csrwi 0x7C1, 0"); // Flush the D-cache - asm volatile ("fence"); + asm volatile ("fence.i"); // Configure four ways as scratchpad uint32_t way_mask = (1 << num_ways) - 1; asm volatile ("csrw 0x5E0, %0" : : "r"(way_mask)); diff --git a/test/sw/tests/dcache_spm_simple.c b/test/sw/tests/dcache_spm_simple.c index 4224078abf..d35755c4bb 100644 --- a/test/sw/tests/dcache_spm_simple.c +++ b/test/sw/tests/dcache_spm_simple.c @@ -23,7 +23,7 @@ int main(void) { // Disable D-cache asm volatile ("csrwi 0x7C1, 0"); // Flush the D-cache - asm volatile ("fence"); + asm volatile ("fence.i"); // Configure all ways as scratchpad uint32_t way_mask = (1 << DCACHE_NUM_WAYS) - 1; asm volatile ("csrw 0x5E0, %0" : : "r"(way_mask)); From 450aa196332fbc60673d24d61b472b8c355be907 Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Mon, 13 Apr 2026 13:25:47 +0200 Subject: [PATCH 6/8] core: fix verible formatting --- .../cva6_hpdcache_if_adapter.sv | 2 +- .../cva6_hpdcache_subsystem.sv | 4 +- core/cache_subsystem/cva6_hpdcache_wrapper.sv | 60 +++++++++---------- core/cache_subsystem/hpdcache_tc_sram.sv | 46 +++++++------- core/cva6.sv | 16 ++--- core/include/config_pkg.sv | 2 +- 6 files changed, 65 insertions(+), 65 deletions(-) diff --git a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv index 9c6430559c..6950a280e3 100644 --- a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv +++ b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv @@ -300,7 +300,7 @@ module cva6_hpdcache_if_adapter uncacheable: hpdcache_req_is_uncacheable, io: 1'b0, wr_policy_hint: hpdcache_pkg::HPDCACHE_WR_POLICY_AUTO, - ispm: 1'b0, // TODO: SPM AMOs support + ispm: 1'b0, // TODO: SPM AMOs support dspm: 1'b0 // TODO: SPM AMOs support } }; diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem.sv b/core/cache_subsystem/cva6_hpdcache_subsystem.sv index 4abf153d3c..ed8b694523 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem.sv @@ -81,9 +81,9 @@ module cva6_hpdcache_subsystem // {{{ // Cache management // Data cache enable - CSR_REGFILE - input logic dcache_enable_i, + input logic dcache_enable_i, // Data cache flush - CONTROLLER - input logic dcache_flush_i, + input logic dcache_flush_i, // Flush acknowledge - CONTROLLER output logic dcache_flush_ack_o, // Load or store miss - PERF_COUNTERS diff --git a/core/cache_subsystem/cva6_hpdcache_wrapper.sv b/core/cache_subsystem/cva6_hpdcache_wrapper.sv index e0d336d569..11d4352a6c 100644 --- a/core/cache_subsystem/cva6_hpdcache_wrapper.sv +++ b/core/cache_subsystem/cva6_hpdcache_wrapper.sv @@ -82,11 +82,11 @@ module cva6_hpdcache_wrapper output logic wbuffer_not_ni_o, // SPM ways configuration - input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] dcache_spm_ways_i, + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] dcache_spm_ways_i, // ISPM interface (request to i-cache scratchpad / response from i-cache scratchpad) - output dcache_req_i_t ispm_req_o, - input dcache_req_o_t ispm_req_i, + output dcache_req_i_t ispm_req_o, + input dcache_req_o_t ispm_req_i, // Hardware memory prefetcher configuration input logic [NrHwPrefetchers-1:0] hwpf_base_set_i, @@ -145,27 +145,27 @@ module cva6_hpdcache_wrapper hpdcache_rsp_t dcache_ispm_rsp; // ISPM request conversion: hpdcache -> i-cache ISPM controller - assign ispm_req_o.data_req = dcache_ispm_req_valid; + assign ispm_req_o.data_req = dcache_ispm_req_valid; assign ispm_req_o.address_index = dcache_ispm_req.addr_offset; - assign ispm_req_o.address_tag = dcache_ispm_req_tag; - assign ispm_req_o.data_wdata = dcache_ispm_req.wdata; - assign ispm_req_o.data_wuser = '0; - assign ispm_req_o.data_we = (dcache_ispm_req.op != hpdcache_pkg::HPDCACHE_REQ_LOAD); - assign ispm_req_o.data_be = dcache_ispm_req.be; - assign ispm_req_o.data_size = dcache_ispm_req.size; - assign ispm_req_o.data_id = dcache_ispm_req.tid; - assign ispm_req_o.kill_req = dcache_ispm_req_abort; - assign ispm_req_o.tag_valid = dcache_ispm_req_valid; - assign ispm_req_o.cbo_op = '0; + assign ispm_req_o.address_tag = dcache_ispm_req_tag; + assign ispm_req_o.data_wdata = dcache_ispm_req.wdata; + assign ispm_req_o.data_wuser = '0; + assign ispm_req_o.data_we = (dcache_ispm_req.op != hpdcache_pkg::HPDCACHE_REQ_LOAD); + assign ispm_req_o.data_be = dcache_ispm_req.be; + assign ispm_req_o.data_size = dcache_ispm_req.size; + assign ispm_req_o.data_id = dcache_ispm_req.tid; + assign ispm_req_o.kill_req = dcache_ispm_req_abort; + assign ispm_req_o.tag_valid = dcache_ispm_req_valid; + assign ispm_req_o.cbo_op = '0; // ISPM response conversion: i-cache ISPM controller -> hpdcache // sid/tid are echoed from the still-valid outgoing request assign dcache_ispm_rsp_valid = ispm_req_i.data_rvalid || ispm_req_i.data_gnt; // TODO: is this correct? - assign dcache_ispm_rsp.rdata = ispm_req_i.data_rdata; - assign dcache_ispm_rsp.sid = dcache_ispm_req.sid; - assign dcache_ispm_rsp.tid = dcache_ispm_req.tid; - assign dcache_ispm_rsp.error = 1'b0; - assign dcache_ispm_rsp.aborted = 1'b0; + assign dcache_ispm_rsp.rdata = ispm_req_i.data_rdata; + assign dcache_ispm_rsp.sid = dcache_ispm_req.sid; + assign dcache_ispm_rsp.tid = dcache_ispm_req.tid; + assign dcache_ispm_rsp.error = 1'b0; + assign dcache_ispm_rsp.aborted = 1'b0; logic [ 2:0] snoop_valid; logic [ 2:0] snoop_abort; @@ -445,22 +445,22 @@ module cva6_hpdcache_wrapper .ispm_rsp_valid_i(dcache_ispm_rsp_valid), .ispm_rsp_i (dcache_ispm_rsp), - .evt_cache_write_miss_o(dcache_write_miss), - .evt_cache_read_miss_o (dcache_read_miss), + .evt_cache_write_miss_o (dcache_write_miss), + .evt_cache_read_miss_o (dcache_read_miss), .evt_cache_dir_unc_err_o( /* unused */), .evt_cache_dir_cor_err_o( /* unused */), .evt_cache_dat_unc_err_o( /* unused */), .evt_cache_dat_cor_err_o( /* unused */), .evt_scrub_complete_o ( /* unused */), - .evt_uncached_req_o ( /* unused */), - .evt_cmo_req_o ( /* unused */), - .evt_write_req_o ( /* unused */), - .evt_read_req_o ( /* unused */), - .evt_prefetch_req_o ( /* unused */), - .evt_req_on_hold_o ( /* unused */), - .evt_rtab_rollback_o ( /* unused */), - .evt_stall_refill_o ( /* unused */), - .evt_stall_o ( /* unused */), + .evt_uncached_req_o ( /* unused */), + .evt_cmo_req_o ( /* unused */), + .evt_write_req_o ( /* unused */), + .evt_read_req_o ( /* unused */), + .evt_prefetch_req_o ( /* unused */), + .evt_req_on_hold_o ( /* unused */), + .evt_rtab_rollback_o ( /* unused */), + .evt_stall_refill_o ( /* unused */), + .evt_stall_o ( /* unused */), .wbuf_empty_o(wbuffer_empty_o), diff --git a/core/cache_subsystem/hpdcache_tc_sram.sv b/core/cache_subsystem/hpdcache_tc_sram.sv index a354dd0771..3f27f9df3c 100644 --- a/core/cache_subsystem/hpdcache_tc_sram.sv +++ b/core/cache_subsystem/hpdcache_tc_sram.sv @@ -13,13 +13,13 @@ module hpdcache_sram_1rw #( parameter int unsigned DEPTH = 2 ** ADDR_SIZE, parameter int unsigned NDATA = 1 ) ( - input logic clk, - input logic rst_n, - input logic cs, - input logic we, - input logic [ADDR_SIZE-1:0] addr, - input logic [NDATA-1:0][DATA_SIZE-1:0] wdata, - output logic [NDATA-1:0][DATA_SIZE-1:0] rdata + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [ NDATA-1:0][DATA_SIZE-1:0] wdata, + output logic [ NDATA-1:0][DATA_SIZE-1:0] rdata ); tc_sram #( .NumWords (DEPTH), @@ -46,14 +46,14 @@ module hpdcache_sram_wbyteenable_1rw #( parameter int unsigned DEPTH = 2 ** ADDR_SIZE, parameter int unsigned NDATA = 1 ) ( - input logic clk, - input logic rst_n, - input logic cs, - input logic we, - input logic [ ADDR_SIZE-1:0] addr, - input logic [NDATA-1:0][DATA_SIZE-1:0] wdata, - input logic [NDATA-1:0][DATA_SIZE/8-1:0] wbyteenable, - output logic [NDATA-1:0][DATA_SIZE-1:0] rdata + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [ NDATA-1:0][ DATA_SIZE-1:0] wdata, + input logic [ NDATA-1:0][DATA_SIZE/8-1:0] wbyteenable, + output logic [ NDATA-1:0][ DATA_SIZE-1:0] rdata ); tc_sram #( .NumWords (DEPTH), @@ -80,14 +80,14 @@ module hpdcache_sram_wmask_1rw #( parameter int unsigned DEPTH = 2 ** ADDR_SIZE, parameter int unsigned NDATA = 1 ) ( - input logic clk, - input logic rst_n, - input logic cs, - input logic we, - input logic [ADDR_SIZE-1:0] addr, - input logic [NDATA-1:0][DATA_SIZE-1:0] wdata, - input logic [NDATA-1:0][DATA_SIZE-1:0] wmask, - output logic [NDATA-1:0][DATA_SIZE-1:0] rdata + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [ NDATA-1:0][DATA_SIZE-1:0] wdata, + input logic [ NDATA-1:0][DATA_SIZE-1:0] wmask, + output logic [ NDATA-1:0][DATA_SIZE-1:0] rdata ); tc_sram #( .NumWords (DEPTH), diff --git a/core/cva6.sv b/core/cva6.sv index cc0de81480..3a8cfbdb33 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1592,14 +1592,14 @@ module cva6 .clk_i (clk_i), .rst_ni(rst_ni), - .icache_en_i (icache_en_csr), - .icache_flush_i (icache_flush_ctrl_cache), - .icache_miss_o (icache_miss_cache_perf), - .icache_spm_ways_i (icache_spm_ways_csr_cache), - .icache_areq_i (icache_areq_ex_cache), - .icache_areq_o (icache_areq_cache_ex), - .icache_dreq_i (icache_dreq_if_cache), - .icache_dreq_o (icache_dreq_cache_if), + .icache_en_i (icache_en_csr), + .icache_flush_i (icache_flush_ctrl_cache), + .icache_miss_o (icache_miss_cache_perf), + .icache_spm_ways_i(icache_spm_ways_csr_cache), + .icache_areq_i (icache_areq_ex_cache), + .icache_areq_o (icache_areq_cache_ex), + .icache_dreq_i (icache_dreq_if_cache), + .icache_dreq_o (icache_dreq_cache_if), .dcache_enable_i (dcache_en_csr_nbdcache), .dcache_flush_i (dcache_flush_ctrl_cache), diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index a9e1329e77..cb72f1107d 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -540,7 +540,7 @@ package config_pkg; endfunction : is_inside_ispm_regions function automatic logic is_inside_dspm_regions(cva6_cfg_t Cfg, logic [63:0] address); - return range_check(Cfg.DCacheSpmAddrBase, Cfg.DCacheSpmLength, address); + return range_check(Cfg.DCacheSpmAddrBase, Cfg.DCacheSpmLength, address); endfunction : is_inside_dspm_regions endpackage From 375c5d129eaa168c027ccce1a32f125f3033b431 Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Mon, 13 Apr 2026 13:40:10 +0200 Subject: [PATCH 7/8] test: adopt `cv64a6_imafdchsclic_sv39_hpdcache_wb` as baseline configuration --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 4401db52e6..58de487469 100644 --- a/test/Makefile +++ b/test/Makefile @@ -17,7 +17,7 @@ QUESTA ?= questa-2023.4 VERILATOR ?= verilator # Target CVA6 configuration -CVA6_CONFIG ?= cv64a6_imafdchsclic_sv39_wb +CVA6_CONFIG ?= cv64a6_imafdchsclic_sv39_hpdcache_wb HEXFILE ?= $(TEST_DIR)/sw/out/hello.hex MAX_CYCLES ?= 10000 TEST ?= test_simple From c8d66b5f5a32e54fc663cc026acf0c6599c5a69e Mon Sep 17 00:00:00 2001 From: Riccardo Tedeschi Date: Wed, 22 Apr 2026 09:17:30 +0200 Subject: [PATCH 8/8] hpdcache: bump submodule --- core/cache_subsystem/hpdcache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cache_subsystem/hpdcache b/core/cache_subsystem/hpdcache index 70e3508ff5..27400e88f7 160000 --- a/core/cache_subsystem/hpdcache +++ b/core/cache_subsystem/hpdcache @@ -1 +1 @@ -Subproject commit 70e3508ff5b92b88c55b34efa76bd5df754cef89 +Subproject commit 27400e88f70b6bb1025be3b7b677f347d886753b