From f88bc363c16aeadc1a317d75fe7b6f1ed3cc05fc Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Fri, 4 Oct 2024 13:52:49 +0200 Subject: [PATCH] Use physical address from the MMU output as input to PMP instead of virtual address --- core/cva6_mmu/cva6_mmu.sv | 37 ++------ core/load_store_unit.sv | 166 ++++++++++++++++++------------------ core/pmp/src/pmp.sv | 4 +- core/pmp/src/pmp_data_if.sv | 153 +++++++++++---------------------- 4 files changed, 141 insertions(+), 219 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index fa10d9f80c..ccb12e9fd8 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -99,13 +99,9 @@ module cva6_mmu output dcache_req_i_t req_port_o, // PMP - input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, - input logic pmp_instr_allow_i, - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, - input exception_t pmp_fetch_exception_i, - input exception_t pmp_exception_i, - input exception_t pmp_misaligned_ex_i + + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i ); // memory management, pte for cva6 @@ -442,8 +438,6 @@ module cva6_mmu icache_areq_o.fetch_exception.tinst = '0; icache_areq_o.fetch_exception.gva = v_i; end - end else if (!pmp_instr_allow_i) begin - icache_areq_o.fetch_exception = pmp_fetch_exception_i; end end else if (ptw_active && walking_instr) begin // ---------// @@ -474,7 +468,7 @@ module cva6_mmu end else begin icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) //To confirm this is the right TVAL + if (CVA6Cfg.TvalEn) //To confirm this is the right TVAL icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(update_vaddr); if (CVA6Cfg.RVH) begin icache_areq_o.fetch_exception.tval2 = '0; @@ -484,16 +478,6 @@ module cva6_mmu end end end - - // if it didn't match any execute region throw an `Instruction Access Fault` - // or: if we are not translating, check PMPs immediately on the paddr - if ((!match_any_execute_region_i && !ptw_error) || (!(enable_translation_i || enable_g_translation_i) && !pmp_instr_allow_i)) begin - icache_areq_o.fetch_exception = pmp_fetch_exception_i; - if (CVA6Cfg.TvalEn) begin // To confirm this is the right TVAL - if (enable_translation_i || enable_g_translation_i) - icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(update_vaddr); - end - end end @@ -526,7 +510,7 @@ module cva6_mmu dtlb_is_page_n = dtlb_is_page; lsu_valid_o = lsu_req_q; - lsu_exception_o = pmp_misaligned_ex_i; + lsu_exception_o = misaligned_ex_i; // Check if the User flag is set, then we may only access it in supervisor mode // if SUM is enabled @@ -547,7 +531,7 @@ module cva6_mmu lsu_dtlb_ppn_o = (CVA6Cfg.PPNW)'(lsu_vaddr_n[((CVA6Cfg.PLEN > CVA6Cfg.VLEN) ? CVA6Cfg.VLEN -1: CVA6Cfg.PLEN -1 ):12]); // translation is enabled and no misaligned exception occurred - if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !pmp_misaligned_ex_i.valid) begin + if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !misaligned_ex_i.valid) begin lsu_valid_o = 1'b0; lsu_dtlb_ppn_o = (en_ld_st_g_translation_i && CVA6Cfg.RVH)? dtlb_g_content.ppn :dtlb_content.ppn; @@ -606,9 +590,6 @@ module cva6_mmu lsu_exception_o.tinst = lsu_tinst_q; lsu_exception_o.gva = ld_st_v_i; end - // Check if any PMPs are violated - end else if (!pmp_data_allow_i) begin - lsu_exception_o = pmp_exception_i; end // this is a load end else begin @@ -637,9 +618,6 @@ module cva6_mmu lsu_exception_o.tinst = lsu_tinst_q; lsu_exception_o.gva = ld_st_v_i; end - // Check if any PMPs are violated - end else if (!pmp_data_allow_i) begin - lsu_exception_o = pmp_exception_i; end end end else @@ -735,9 +713,6 @@ module cva6_mmu end end end - // If translation is not enabled, check the paddr immediately against PMPs - end else if (lsu_req_q && !pmp_misaligned_ex_i.valid && !pmp_data_allow_i) begin - lsu_exception_o = pmp_exception_i; end end diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index d99ee675b2..fe0a0ccc96 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -205,37 +205,34 @@ module load_store_unit logic translation_req; logic translation_valid; logic [CVA6Cfg.VLEN-1:0] mmu_vaddr; - logic [CVA6Cfg.PLEN-1:0] pmp_paddr, mmu_paddr, mmu_vaddr_plen, fetch_vaddr_plen; - logic [ 31:0] mmu_tinst; - logic mmu_hs_ld_st_inst; - logic mmu_hlvx_inst; - exception_t mmu_exception; - exception_t pmp_exception; - exception_t pmp_misaligned_ex; - icache_areq_t pmp_icache_areq_o; - logic pmp_data_allow; - logic pmp_instr_allow; - logic pmp_translation_valid; - logic match_any_execute_region; - logic dtlb_hit; - logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn; - - logic ld_valid; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id; - logic [ CVA6Cfg.XLEN-1:0] ld_result; - logic st_valid; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id; - logic [ CVA6Cfg.XLEN-1:0] st_result; - - logic [ 11:0] page_offset; - logic page_offset_matches; - - exception_t misaligned_exception; - exception_t ld_ex; - exception_t st_ex; - - logic hs_ld_st_inst; - logic hlvx_inst; + logic [CVA6Cfg.PLEN-1:0] mmu_paddr, pmp_paddr, lsu_paddr, mmu_vaddr_plen, fetch_vaddr_plen; + logic [ 31:0] mmu_tinst; + logic mmu_hs_ld_st_inst; + logic mmu_hlvx_inst; + exception_t mmu_exception; + exception_t pmp_exception; + exception_t pmp_misaligned_ex; + icache_areq_t pmp_icache_areq_i; + logic pmp_translation_valid; + logic dtlb_hit; + logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn; + + logic ld_valid; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id; + logic [ CVA6Cfg.XLEN-1:0] ld_result; + logic st_valid; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id; + logic [ CVA6Cfg.XLEN-1:0] st_result; + + logic [ 11:0] page_offset; + logic page_offset_matches; + + exception_t misaligned_exception; + exception_t ld_ex; + exception_t st_ex; + + logic hs_ld_st_inst; + logic hlvx_inst; logic [2:0] enable_translation, en_ld_st_translation, flush_tlb; logic [1:0] sum, mxr; @@ -263,12 +260,12 @@ module load_store_unit .clk_i(clk_i), .rst_ni(rst_ni), .flush_i(flush_i), - .enable_translation_i, - .enable_g_translation_i, - .en_ld_st_translation_i, - .en_ld_st_g_translation_i, + .enable_translation_i(enable_translation_i), + .enable_g_translation_i(enable_g_translation_i), + .en_ld_st_translation_i(en_ld_st_translation_i), + .en_ld_st_g_translation_i(en_ld_st_g_translation_i), .icache_areq_i(icache_areq_i), - .icache_areq_o(icache_areq_o), + .icache_areq_o(pmp_icache_areq_i), // misaligned bypass .misaligned_ex_i(misaligned_exception), .lsu_req_i(translation_req), @@ -279,9 +276,9 @@ module load_store_unit .lsu_dtlb_hit_o(dtlb_hit), // send in the same cycle as the request .lsu_dtlb_ppn_o(dtlb_ppn), // send in the same cycle as the request - .lsu_valid_o (translation_valid), - .lsu_paddr_o (mmu_paddr), - .lsu_exception_o(mmu_exception), + .lsu_valid_o (pmp_translation_valid), + .lsu_paddr_o (lsu_paddr), + .lsu_exception_o(pmp_exception), .priv_lvl_i (priv_lvl_i), .v_i, @@ -314,22 +311,35 @@ module load_store_unit .req_port_i(dcache_req_ports_i[0]), .req_port_o(dcache_req_ports_o[0]), - .pmp_data_allow_i(pmp_data_allow), - .pmp_instr_allow_i(pmp_instr_allow), - .match_any_execute_region_i(match_any_execute_region), - .pmp_fetch_exception_i(pmp_icache_areq_o.fetch_exception), - .pmp_misaligned_ex_i(pmp_misaligned_ex), - .pmp_exception_i(pmp_exception), .pmpcfg_i, .pmpaddr_i ); end else begin : gen_no_mmu + // icache request without MMU, virtual and physical address are identical + assign pmp_icache_areq_i.fetch_valid = icache_areq_i.fetch_req; + if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin : gen_virtual_physical_address_instruction + assign pmp_icache_areq_i.fetch_paddr = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0]; + end else begin + assign pmp_icache_areq_i.fetch_paddr = CVA6Cfg.PLEN'(icache_areq_i.fetch_vaddr); + end + assign pmp_icache_areq_i.fetch_exception = 'h0; + // dcache request without mmu for load or store, + // Delay of 1 cycle to match MMU latency giving the address tag + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + lsu_paddr <= 'h0; + end else begin + if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin : gen_virtual_physical_address_lsu + lsu_paddr <= mmu_vaddr[CVA6Cfg.PLEN-1:0]; + end else begin + lsu_paddr <= CVA6Cfg.PLEN'(mmu_vaddr); + end + end + end + assign pmp_exception = misaligned_exception; + assign pmp_translation_valid = translation_req; - assign mmu_exception = pmp_exception; - assign icache_areq_o = pmp_icache_areq_o; - assign translation_valid = pmp_translation_valid; - assign mmu_paddr = pmp_paddr; - + // dcache interface of PTW not used assign dcache_req_ports_o[0].address_index = '0; assign dcache_req_ports_o[0].address_tag = '0; assign dcache_req_ports_o[0].data_wdata = '0; @@ -352,38 +362,30 @@ module load_store_unit // ------------------ pmp_data_if #( - .CVA6Cfg (CVA6Cfg), - .icache_areq_t(icache_areq_t), - .icache_arsp_t(icache_arsp_t), - .exception_t (exception_t) - ) i_pmp_data_if ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .enable_translation_i (enable_translation_i), - .enable_g_translation_i(enable_g_translation_i), - .en_ld_st_translation_i(en_ld_st_translation_i), - .en_ld_st_g_translation_i(en_ld_st_g_translation_i), - .icache_areq_i (icache_areq_i), - .icache_areq_o (pmp_icache_areq_o), - .misaligned_ex_i (misaligned_exception), - .lsu_req_i (translation_req), - .lsu_vaddr_i (mmu_vaddr), - .lsu_tinst_i(mmu_tinst), - .lsu_is_store_i (st_translation_req), - .lsu_valid_o (pmp_translation_valid), - .lsu_paddr_o (pmp_paddr), - .lsu_exception_o (pmp_exception), - .priv_lvl_i (priv_lvl_i), - .v_i (v_i), - .ld_st_priv_lvl_i (ld_st_priv_lvl_i), - .ld_st_v_i (ld_st_v_i), - .pmpcfg_i (pmpcfg_i), - .pmpaddr_i (pmpaddr_i), - .data_allow_o (pmp_data_allow), - .instr_allow_o (pmp_instr_allow), - .match_any_execute_region_o (match_any_execute_region), - .misaligned_ex_o (pmp_misaligned_ex) - ); + .CVA6Cfg (CVA6Cfg), + .icache_areq_t(icache_areq_t), + .exception_t (exception_t) + ) i_pmp_data_if ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .icache_areq_i (pmp_icache_areq_i), + .icache_areq_o (icache_areq_o), + .icache_fetch_vaddr_i(icache_areq_i.fetch_vaddr), + .lsu_valid_i (pmp_translation_valid), + .lsu_paddr_i (lsu_paddr), + .lsu_vaddr_i (mmu_vaddr), + .lsu_exception_i (pmp_exception), + .lsu_is_store_i (st_translation_req), + .lsu_valid_o (translation_valid), + .lsu_paddr_o (mmu_paddr), + .lsu_exception_o (mmu_exception), + .priv_lvl_i (priv_lvl_i), + .v_i (v_i), + .ld_st_priv_lvl_i (ld_st_priv_lvl_i), + .ld_st_v_i (ld_st_v_i), + .pmpcfg_i (pmpcfg_i), + .pmpaddr_i (pmpaddr_i) + ); logic store_buffer_empty; diff --git a/core/pmp/src/pmp.sv b/core/pmp/src/pmp.sv index 439bf901cb..1d2cf02651 100644 --- a/core/pmp/src/pmp.sv +++ b/core/pmp/src/pmp.sv @@ -23,8 +23,8 @@ module pmp #( input riscv::pmp_access_t access_type_i, input riscv::priv_lvl_t priv_lvl_i, // Configuration - input logic [NR_ENTRIES:0][PMP_LEN-1:0] conf_addr_i, - input riscv::pmpcfg_t [NR_ENTRIES:0] conf_i, + input logic [NR_ENTRIES-1:0][PMP_LEN-1:0] conf_addr_i, + input riscv::pmpcfg_t [NR_ENTRIES-1:0] conf_i, // Output output logic allow_o ); diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index 2c08283baa..2e6c03a11f 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -11,27 +11,22 @@ module pmp_data_if #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type icache_areq_t = logic, - parameter type icache_arsp_t = logic, parameter type exception_t = logic ) ( input logic clk_i, input logic rst_ni, - input logic enable_translation_i, - input logic enable_g_translation_i, - input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores - input logic en_ld_st_g_translation_i, // enable G-Stage translation for load/stores // IF interface - input icache_arsp_t icache_areq_i, + input icache_areq_t icache_areq_i, output icache_areq_t icache_areq_o, + input [CVA6Cfg.VLEN-1:0] icache_fetch_vaddr_i, // virtual address for tval only // LSU interface // this is a more minimalistic interface because the actual addressing logic is handled // in the LSU as we distinguish load and stores, what we do here is simple address translation - input exception_t misaligned_ex_i, - input logic lsu_req_i, // request address translation - input logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_i, // virtual address in - input logic [31:0] lsu_tinst_i, // transformed instruction in + input logic lsu_valid_i, // request lsu access + input logic [CVA6Cfg.PLEN-1:0] lsu_paddr_i, // physical address in + input logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_i, // virtual address in, for tval only + input exception_t lsu_exception_i, // lsu exception coming from MMU, or misaligned exception input logic lsu_is_store_i, // the translation is requested by a store - // Cycle 1 output logic lsu_valid_o, // translation is valid output logic [CVA6Cfg.PLEN-1:0] lsu_paddr_o, // translated address output exception_t lsu_exception_o, // address translation threw an exception @@ -41,66 +36,55 @@ module pmp_data_if input riscv::priv_lvl_t ld_st_priv_lvl_i, input logic ld_st_v_i, // PMP - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, - output logic data_allow_o, - output logic instr_allow_o, - output logic match_any_execute_region_o, - output exception_t misaligned_ex_o + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i ); + // virtual address causing the exception + logic [CVA6Cfg.XLEN-1:0] fetch_vaddr_xlen, lsu_vaddr_xlen; - exception_t misaligned_ex_n, misaligned_ex_q; - logic lsu_req_n, lsu_req_q; - logic lsu_is_store_n, lsu_is_store_q; + logic pmp_if_allow; + logic match_any_execute_region; + logic data_allow_o; // Wires to PMP checks riscv::pmp_access_t pmp_access_type; - logic [CVA6Cfg.PLEN-1:0] mmu_vaddr_plen, fetch_vaddr_plen; - logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_q; - logic [31:0] lsu_tinst_q; - logic no_locked_data, no_locked_if; - always_comb begin : vaddr_plen - if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin - mmu_vaddr_plen = lsu_vaddr_q[CVA6Cfg.PLEN-1:0]; - fetch_vaddr_plen = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0]; - end else begin - mmu_vaddr_plen = CVA6Cfg.PLEN'(lsu_vaddr_q); - fetch_vaddr_plen = CVA6Cfg.PLEN'(icache_areq_i.fetch_vaddr); - end + // For exception tval reporting, use the virtual address and resize it + if (CVA6Cfg.VLEN >= CVA6Cfg.XLEN) begin + assign lsu_vaddr_xlen = lsu_vaddr_i[CVA6Cfg.XLEN-1:0]; + assign fetch_vaddr_xlen = icache_fetch_vaddr_i[CVA6Cfg.XLEN-1:0]; + end else begin + assign lsu_vaddr_xlen = CVA6Cfg.XLEN'(lsu_vaddr_i); + assign fetch_vaddr_xlen = CVA6Cfg.XLEN'(icache_fetch_vaddr_i); end - assign misaligned_ex_o = misaligned_ex_q; - //----------------------- // Instruction Interface //----------------------- // check for execute flag on memory - assign match_any_execute_region_o = config_pkg::is_inside_execute_regions( - CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, icache_areq_o.fetch_paddr} + assign match_any_execute_region = config_pkg::is_inside_execute_regions( + CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, icache_areq_i.fetch_paddr} ); - // The instruction interface is a simple request response interface + // As the PMP check is combinatorial, pass the icache_areq directly if no + // exception always_comb begin : instr_interface - icache_areq_o.fetch_valid = icache_areq_i.fetch_req; - icache_areq_o.fetch_paddr = fetch_vaddr_plen; - icache_areq_o.fetch_exception = '0; + icache_areq_o.fetch_valid = icache_areq_i.fetch_valid; + icache_areq_o.fetch_paddr = icache_areq_i.fetch_paddr; + icache_areq_o.fetch_exception = icache_areq_i.fetch_exception; - // if it didn't match any execute region throw an `Instruction Access Fault` - // or: if we are not translating, check PMPs immediately on the paddr - if (!match_any_execute_region_o || !instr_allow_o) begin + // if it didn't match any execute region throw an `Instruction Access Fault` (PMA) + // or if PMP reject the access + if (!match_any_execute_region || !pmp_if_allow) begin icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; - + // For exception, the virtual address is required for tval, if no MMU is + // instantiated then it will be equal to physical address if (CVA6Cfg.TvalEn) begin - if (enable_translation_i || enable_g_translation_i) begin - icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(icache_areq_i.fetch_vaddr); - end else begin - icache_areq_o.fetch_exception.tval=CVA6Cfg.XLEN'(icache_areq_o.fetch_paddr[CVA6Cfg.PLEN-1:(CVA6Cfg.PLEN > CVA6Cfg.VLEN) ? (CVA6Cfg.PLEN - CVA6Cfg.VLEN) : 0]); - end + icache_areq_o.fetch_exception.tval = fetch_vaddr_xlen; end if (CVA6Cfg.RVH) begin icache_areq_o.fetch_exception.tval2 = '0; @@ -117,60 +101,44 @@ module pmp_data_if .PMP_LEN (CVA6Cfg.PLEN - 2), .NR_ENTRIES(CVA6Cfg.NrPMPEntries) ) i_pmp_if ( - .addr_i (icache_areq_o.fetch_paddr), + .addr_i (icache_areq_i.fetch_paddr), .priv_lvl_i (priv_lvl_i), // we will always execute on the instruction fetch port .access_type_i(riscv::ACCESS_EXEC), // Configuration .conf_addr_i (pmpaddr_i), .conf_i (pmpcfg_i), - .allow_o (instr_allow_o) + .allow_o (pmp_if_allow) ); //----------------------- // Data Interface //----------------------- - // The data interface is simpler and only consists of a request/response interface always_comb begin : data_interface // save request and DTLB response - lsu_req_n = lsu_req_i; - misaligned_ex_n = misaligned_ex_i; - lsu_is_store_n = lsu_is_store_i; - - lsu_paddr_o = mmu_vaddr_plen; - lsu_valid_o = lsu_req_q; - lsu_exception_o = misaligned_ex_q; - pmp_access_type = lsu_is_store_q ? riscv::ACCESS_WRITE : riscv::ACCESS_READ; - - // mute misaligned exceptions if there is no request otherwise they will throw accidental exceptions - misaligned_ex_n.valid = misaligned_ex_i.valid & lsu_req_i; + lsu_valid_o = lsu_valid_i; + lsu_paddr_o = lsu_paddr_i; + lsu_exception_o = lsu_exception_i; + pmp_access_type = lsu_is_store_i ? riscv::ACCESS_WRITE : riscv::ACCESS_READ; // If translation is not enabled, check the paddr immediately against PMPs - if (lsu_req_q && !misaligned_ex_q.valid && !data_allow_o) begin + if (lsu_valid_i && !data_allow_o) begin lsu_exception_o.valid = 1'b1; if (CVA6Cfg.TvalEn) begin - if (en_ld_st_translation_i || en_ld_st_g_translation_i) begin - lsu_exception_o.tval = { - {CVA6Cfg.XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q - }; - end else begin - lsu_exception_o.tval = CVA6Cfg.XLEN'(lsu_paddr_o[CVA6Cfg.PLEN-1:(CVA6Cfg.PLEN>CVA6Cfg.VLEN)?(CVA6Cfg.PLEN-CVA6Cfg.VLEN) : 0]); - - end - end - - if (CVA6Cfg.RVH) begin - lsu_exception_o.tval2 = '0; - lsu_exception_o.tinst = lsu_tinst_q; - lsu_exception_o.gva = ld_st_v_i; + lsu_exception_o.tval = lsu_vaddr_xlen; end - if (lsu_is_store_q) begin + if (lsu_is_store_i) begin lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; end else begin lsu_exception_o.cause = riscv::LD_ACCESS_FAULT; end + if (CVA6Cfg.RVH) begin + lsu_exception_o.tval2 = '0; + lsu_exception_o.tinst = '0; + lsu_exception_o.gva = ld_st_v_i; + end end end @@ -181,7 +149,7 @@ module pmp_data_if .PMP_LEN (CVA6Cfg.PLEN - 2), .NR_ENTRIES(CVA6Cfg.NrPMPEntries) ) i_pmp_data ( - .addr_i (lsu_paddr_o), + .addr_i (lsu_paddr_i), .priv_lvl_i (ld_st_priv_lvl_i), .access_type_i(pmp_access_type), // Configuration @@ -190,29 +158,6 @@ module pmp_data_if .allow_o (data_allow_o) ); - // ---------- - // Registers - // ---------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - lsu_req_q <= '0; - misaligned_ex_q <= '0; - lsu_is_store_q <= '0; - lsu_vaddr_q <= '0; - lsu_tinst_q <= '0; - end else begin - lsu_req_q <= lsu_req_n; - misaligned_ex_q <= misaligned_ex_n; - lsu_is_store_q <= lsu_is_store_n; - lsu_vaddr_q <= lsu_vaddr_i; - - if (CVA6Cfg.RVH) begin - lsu_tinst_q <= lsu_tinst_i; - end - end - end - - // ---------------- // Assert for PMPs // ---------------- @@ -245,7 +190,7 @@ module pmp_data_if no_locked_if <= no_locked_if & 1'b0; end else no_locked_if <= no_locked_if & 1'b1; end - if (no_locked_if == 1'b1) assert (instr_allow_o == 1'b1); + if (no_locked_if == 1'b1) assert (pmp_if_allow == 1'b1); end end end