From eff3a7ffa2b271543ae91ba016a402d13e2e6b07 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Fri, 26 Jul 2024 10:39:16 +0200 Subject: [PATCH 01/25] First public version of extracted pmp --- core/pmp/src/pmp_data_if.sv | 212 ++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 core/pmp/src/pmp_data_if.sv diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv new file mode 100644 index 0000000000..b5aa1ca72e --- /dev/null +++ b/core/pmp/src/pmp_data_if.sv @@ -0,0 +1,212 @@ +//----------------------------------------------------------------------------- +// Copyright 2024 Robert Bosch GmbH +// +// SPDX-License-Identifier: SHL-0.51 +// +// Original Author: Coralie Allioux - Robert Bosch France SAS +//----------------------------------------------------------------------------- + +module pmp_data_if + import ariane_pkg::*; +#( + 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, + output icache_areq_t icache_areq_o, + // 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_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 + // General control signals + input riscv::priv_lvl_t priv_lvl_i, + input logic v_i, + 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 +); + + exception_t misaligned_ex_n, misaligned_ex_q; + logic lsu_req_n, lsu_req_q; + logic lsu_is_store_n, lsu_is_store_q; + + // 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; + + 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 + 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} + ); + + // The instruction interface is a simple request response interface + 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; + + // 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 + icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; + icache_areq_o.fetch_exception.valid = 1'b1; + + 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 + end + if (CVA6Cfg.RVH) begin + icache_areq_o.fetch_exception.tval2 = '0; + icache_areq_o.fetch_exception.tinst = '0; + icache_areq_o.fetch_exception.gva = v_i; + end + end + end + + // Instruction fetch + pmp #( + .CVA6Cfg (CVA6Cfg), + .PLEN (CVA6Cfg.PLEN), + .PMP_LEN (CVA6Cfg.PLEN - 2), + .NR_ENTRIES(CVA6Cfg.NrPMPEntries) + ) i_pmp_if ( + .addr_i (icache_areq_o.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) + ); + + //----------------------- + // 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; + + // If translation is not enabled, check the paddr immediately against PMPs + if (lsu_req_q && !misaligned_ex_q.valid && !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.PLEN{lsu_vaddr_q[CVA6Cfg.PLEN-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; + end + + if (lsu_is_store_q) begin + lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; + end else begin + lsu_exception_o.cause = riscv::LD_ACCESS_FAULT; + end + end + end + + // Load/store PMP check + pmp #( + .CVA6Cfg (CVA6Cfg), + .PLEN (CVA6Cfg.PLEN), + .PMP_LEN (CVA6Cfg.PLEN - 2), + .NR_ENTRIES(CVA6Cfg.NrPMPEntries) + ) i_pmp_data ( + .addr_i (lsu_paddr_o), + .priv_lvl_i (ld_st_priv_lvl_i), + .access_type_i(pmp_access_type), + // Configuration + .conf_addr_i (pmpaddr_i), + .conf_i (pmpcfg_i), + .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 +endmodule From 4517afdc846cd470254f1d527643ed92abf5f2fa Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 11 Jul 2024 17:29:01 +0200 Subject: [PATCH 02/25] Remove misaligned_ex computation: get it from outside --- core/cva6_mmu/cva6_mmu.sv | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 9afe90c17e..b39ed5d490 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -541,7 +541,6 @@ module cva6_mmu logic hs_ld_st_inst_n, hs_ld_st_inst_q; pte_cva6_t dtlb_pte_n, dtlb_pte_q; pte_cva6_t dtlb_gpte_n, dtlb_gpte_q; - 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 dtlb_hit_n, dtlb_hit_q; @@ -560,18 +559,13 @@ module cva6_mmu // save request and DTLB response lsu_vaddr_n = lsu_vaddr_i; lsu_req_n = lsu_req_i; - misaligned_ex_n = misaligned_ex_i; dtlb_pte_n = dtlb_content; dtlb_hit_n = dtlb_lu_hit; lsu_is_store_n = lsu_is_store_i; dtlb_is_page_n = dtlb_is_page; 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_exception_o = pmp_misaligned_ex_i; // Check if the User flag is set, then we may only access it in supervisor mode // if SUM is enabled @@ -592,7 +586,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) && !misaligned_ex_q.valid) begin + if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !pmp_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; @@ -801,7 +795,7 @@ module cva6_mmu end end // If translation is not enabled, check the paddr immediately against PMPs - end else if (lsu_req_q && !misaligned_ex_q.valid && !pmp_data_allow) begin + end else if (lsu_req_q && !pmp_misaligned_ex_i.valid && !pmp_data_allow) begin if (lsu_is_store_q) begin lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; lsu_exception_o.valid = 1'b1; @@ -852,7 +846,6 @@ module cva6_mmu lsu_vaddr_q <= '0; lsu_gpaddr_q <= '0; lsu_req_q <= '0; - misaligned_ex_q <= '0; dtlb_pte_q <= '0; dtlb_gpte_q <= '0; dtlb_hit_q <= '0; @@ -863,7 +856,6 @@ module cva6_mmu end else begin lsu_vaddr_q <= lsu_vaddr_n; lsu_req_q <= lsu_req_n; - misaligned_ex_q <= misaligned_ex_n; dtlb_pte_q <= dtlb_pte_n; dtlb_hit_q <= dtlb_hit_n; lsu_is_store_q <= lsu_is_store_n; From 90f3bae4aae12c7bbcff01e5bf8cb5e9dece10c1 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 11 Jul 2024 17:35:22 +0200 Subject: [PATCH 03/25] Remove data and instr pmps, get match_execution from outside --- core/cva6_mmu/cva6_mmu.sv | 46 ++++----------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index b39ed5d490..91608e52ef 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -99,8 +99,9 @@ module cva6_mmu output dcache_req_i_t req_port_o, // PMP - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, + input exception_t pmp_misaligned_ex_i ); // memory management, pte for cva6 @@ -353,7 +354,6 @@ module cva6_mmu //----------------------- // Instruction Interface //----------------------- - logic match_any_execute_region; logic pmp_instr_allow; localparam int PPNWMin = (CVA6Cfg.PPNW - 1 > 29) ? 29 : CVA6Cfg.PPNW - 1; @@ -492,7 +492,7 @@ module cva6_mmu // 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 && !ptw_error) || (!(enable_translation_i || enable_g_translation_i) && !pmp_instr_allow)) begin + 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.cause = riscv::INSTR_ACCESS_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) begin //To confirm this is the right TVAL @@ -509,28 +509,6 @@ module cva6_mmu end end - // check for execute flag on memory - assign match_any_execute_region = config_pkg::is_inside_execute_regions( - CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, icache_areq_o.fetch_paddr} - ); - - // Instruction fetch - pmp #( - .CVA6Cfg (CVA6Cfg), //comment for hypervisor extension - .PLEN (CVA6Cfg.PLEN), - .PMP_LEN (CVA6Cfg.PLEN - 2), - .NR_ENTRIES(CVA6Cfg.NrPMPEntries) - // .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) // configuration used in hypervisor extension - ) i_pmp_if ( - .addr_i (icache_areq_o.fetch_paddr), - .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 (pmp_instr_allow) - ); //----------------------- // Data Interface @@ -822,22 +800,6 @@ module cva6_mmu end end - // Load/store PMP check - pmp #( - .CVA6Cfg (CVA6Cfg), - .PLEN (CVA6Cfg.PLEN), - .PMP_LEN (CVA6Cfg.PLEN - 2), - .NR_ENTRIES(CVA6Cfg.NrPMPEntries) - ) i_pmp_data ( - .addr_i (lsu_paddr_o), - .priv_lvl_i (ld_st_priv_lvl_i), - .access_type_i(pmp_access_type), - // Configuration - .conf_addr_i (pmpaddr_i), - .conf_i (pmpcfg_i), - .allow_o (pmp_data_allow) - ); - // ---------- // Registers // ---------- From 0bc197d58fb698ab012eb64324381687e3916d6d Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 11 Jul 2024 17:41:21 +0200 Subject: [PATCH 04/25] Get data and instr allow from outside --- core/cva6_mmu/cva6_mmu.sv | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 91608e52ef..06fadebaaa 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -100,6 +100,7 @@ module cva6_mmu // 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 exception_t pmp_misaligned_ex_i ); @@ -354,7 +355,6 @@ module cva6_mmu //----------------------- // Instruction Interface //----------------------- - logic pmp_instr_allow; localparam int PPNWMin = (CVA6Cfg.PPNW - 1 > 29) ? 29 : CVA6Cfg.PPNW - 1; // The instruction interface is a simple request response interface @@ -439,7 +439,7 @@ 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) begin + end else if (!pmp_instr_allow_i) begin icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -527,10 +527,6 @@ module cva6_mmu // check if we need to do translation or if we are always ready (e.g.: we are not translating anything) assign lsu_dtlb_hit_o = (en_ld_st_translation_i || en_ld_st_g_translation_i) ? dtlb_lu_hit : 1'b1; - // Wires to PMP checks - riscv::pmp_access_t pmp_access_type; - logic pmp_data_allow; - // The data interface is simpler and only consists of a request/response interface always_comb begin : data_interface @@ -624,7 +620,7 @@ module cva6_mmu lsu_exception_o.gva = ld_st_v_i; end // Check if any PMPs are violated - end else if (!pmp_data_allow) begin + end else if (!pmp_data_allow_i) begin lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; lsu_exception_o.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -665,7 +661,7 @@ module cva6_mmu lsu_exception_o.gva = ld_st_v_i; end // Check if any PMPs are violated - end else if (!pmp_data_allow) begin + end else if (!pmp_data_allow_i) begin lsu_exception_o.cause = riscv::LD_ACCESS_FAULT; lsu_exception_o.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -773,7 +769,7 @@ module cva6_mmu 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) begin + end else if (lsu_req_q && !pmp_misaligned_ex_i.valid && !pmp_data_allow_i) begin if (lsu_is_store_q) begin lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; lsu_exception_o.valid = 1'b1; From 04a54f741f547dbdc1e371d46e905e176318ef14 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 11 Jul 2024 17:43:16 +0200 Subject: [PATCH 05/25] Simplify fetch_instruction exception when instr not allow by pmp --- core/cva6_mmu/cva6_mmu.sv | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 06fadebaaa..5bfb9e8e51 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -102,6 +102,7 @@ module cva6_mmu 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 exception_t pmp_fetch_exception_i, input exception_t pmp_misaligned_ex_i ); @@ -440,15 +441,7 @@ module cva6_mmu icache_areq_o.fetch_exception.gva = v_i; end end else if (!pmp_instr_allow_i) begin - icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; - icache_areq_o.fetch_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(icache_areq_i.fetch_vaddr); - if (CVA6Cfg.RVH) begin - icache_areq_o.fetch_exception.tval2 = '0; - icache_areq_o.fetch_exception.tinst = '0; - icache_areq_o.fetch_exception.gva = v_i; - end + icache_areq_o.fetch_exception = pmp_fetch_exception_i; end end else if (ptw_active && walking_instr) begin // ---------// @@ -493,18 +486,10 @@ module cva6_mmu // 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.cause = riscv::INSTR_ACCESS_FAULT; - icache_areq_o.fetch_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) begin //To confirm this is the right TVAL + 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); - else - 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 - if (CVA6Cfg.RVH) begin - icache_areq_o.fetch_exception.tval2 = '0; - icache_areq_o.fetch_exception.tinst = '0; - icache_areq_o.fetch_exception.gva = v_i; end end end From a4fbed077077cb43bb3ce7606851abb43042c92d Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 11 Jul 2024 17:43:59 +0200 Subject: [PATCH 06/25] Simplify exception when data not allow by pmp, getting it from outside --- core/cva6_mmu/cva6_mmu.sv | 50 ++++----------------------------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 5bfb9e8e51..8b813547f0 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -102,7 +102,9 @@ module cva6_mmu 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 ); @@ -606,17 +608,7 @@ module cva6_mmu end // Check if any PMPs are violated end else if (!pmp_data_allow_i) begin - lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; - lsu_exception_o.valid = 1'b1; - if (CVA6Cfg.TvalEn) - lsu_exception_o.tval = { - {CVA6Cfg.XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q - }; - if (CVA6Cfg.RVH) begin - lsu_exception_o.tval2 = '0; - lsu_exception_o.tinst = lsu_tinst_q; - lsu_exception_o.gva = ld_st_v_i; - end + lsu_exception_o = pmp_exception_i; end // this is a load end else begin @@ -647,17 +639,7 @@ module cva6_mmu end // Check if any PMPs are violated end else if (!pmp_data_allow_i) begin - lsu_exception_o.cause = riscv::LD_ACCESS_FAULT; - lsu_exception_o.valid = 1'b1; - if (CVA6Cfg.TvalEn) - lsu_exception_o.tval = { - {CVA6Cfg.XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q - }; - if (CVA6Cfg.RVH) begin - lsu_exception_o.tval2 = '0; - lsu_exception_o.tinst = lsu_tinst_q; - lsu_exception_o.gva = ld_st_v_i; - end + lsu_exception_o = pmp_exception_i; end end end else @@ -755,29 +737,7 @@ module cva6_mmu 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 - if (lsu_is_store_q) begin - lsu_exception_o.cause = riscv::ST_ACCESS_FAULT; - lsu_exception_o.valid = 1'b1; - if (CVA6Cfg.TvalEn) - lsu_exception_o.tval = CVA6Cfg.XLEN'(lsu_paddr_o[CVA6Cfg.PLEN-1:(CVA6Cfg.PLEN>CVA6Cfg.VLEN)?(CVA6Cfg.PLEN-CVA6Cfg.VLEN) : 0]); - - if (CVA6Cfg.RVH) begin - lsu_exception_o.tval2 = '0; - lsu_exception_o.tinst = lsu_tinst_q; - lsu_exception_o.gva = ld_st_v_i; - end - end else begin - lsu_exception_o.cause = riscv::LD_ACCESS_FAULT; - lsu_exception_o.valid = 1'b1; - if (CVA6Cfg.TvalEn) - lsu_exception_o.tval = CVA6Cfg.XLEN'(lsu_paddr_o[CVA6Cfg.PLEN-1:(CVA6Cfg.PLEN>CVA6Cfg.VLEN)?(CVA6Cfg.PLEN-CVA6Cfg.VLEN) : 0]); - - if (CVA6Cfg.RVH) begin - lsu_exception_o.tval2 = '0; - lsu_exception_o.tinst = lsu_tinst_q; - lsu_exception_o.gva = ld_st_v_i; - end - end + lsu_exception_o = pmp_exception_i; end end From 436d563d5d466c35ef98142570168e19f8552a5b Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Wed, 24 Jul 2024 10:01:51 +0200 Subject: [PATCH 07/25] Apply verible format --- core/cva6_mmu/cva6_mmu.sv | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 8b813547f0..fa10d9f80c 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -100,12 +100,12 @@ module cva6_mmu // 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 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 ); // memory management, pte for cva6 @@ -757,12 +757,12 @@ module cva6_mmu lsu_tinst_q <= '0; hs_ld_st_inst_q <= '0; end else begin - lsu_vaddr_q <= lsu_vaddr_n; - lsu_req_q <= lsu_req_n; - dtlb_pte_q <= dtlb_pte_n; - dtlb_hit_q <= dtlb_hit_n; - lsu_is_store_q <= lsu_is_store_n; - dtlb_is_page_q <= dtlb_is_page_n; + lsu_vaddr_q <= lsu_vaddr_n; + lsu_req_q <= lsu_req_n; + dtlb_pte_q <= dtlb_pte_n; + dtlb_hit_q <= dtlb_hit_n; + lsu_is_store_q <= lsu_is_store_n; + dtlb_is_page_q <= dtlb_is_page_n; if (CVA6Cfg.RVH) begin lsu_tinst_q <= lsu_tinst_n; From 2998bb761f38ae22f527b123eb3c86d2cbbd21b9 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 11 Jul 2024 17:48:06 +0200 Subject: [PATCH 08/25] Integrate PMP fully outside MMU --- core/load_store_unit.sv | 83 ++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 04c4e00e07..f6de184047 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -205,11 +205,18 @@ module load_store_unit logic translation_req; logic translation_valid; logic [CVA6Cfg.VLEN-1:0] mmu_vaddr; - logic [CVA6Cfg.PLEN-1:0] mmu_paddr, mmu_vaddr_plen, fetch_vaddr_plen; + 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; @@ -306,23 +313,22 @@ 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 - if (CVA6Cfg.VLEN > CVA6Cfg.PLEN) begin - assign mmu_vaddr_plen = mmu_vaddr[CVA6Cfg.PLEN-1:0]; - assign fetch_vaddr_plen = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0]; - end else begin - assign mmu_vaddr_plen = {{{CVA6Cfg.PLEN - CVA6Cfg.VLEN} {1'b0}}, mmu_vaddr}; - assign fetch_vaddr_plen = {{{CVA6Cfg.PLEN - CVA6Cfg.VLEN} {1'b0}}, icache_areq_i.fetch_vaddr}; - end - - assign icache_areq_o.fetch_valid = icache_areq_i.fetch_req; - assign icache_areq_o.fetch_paddr = fetch_vaddr_plen; - assign icache_areq_o.fetch_exception = '0; + assign mmu_exception = pmp_exception; + assign icache_areq_o = pmp_icache_areq_o; + assign pmp_translation = pmp_translation_valid; + assign mmu_paddr = pmp_paddr; assign dcache_req_ports_o[0].address_index = '0; assign dcache_req_ports_o[0].address_tag = '0; @@ -336,22 +342,49 @@ module load_store_unit assign itlb_miss_o = 1'b0; assign dtlb_miss_o = 1'b0; - assign dtlb_ppn = mmu_vaddr_plen[CVA6Cfg.PLEN-1:12]; + assign dtlb_ppn = mmu_vaddr[CVA6Cfg.PLEN-1:12]; assign dtlb_hit = 1'b1; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - mmu_paddr <= '0; - translation_valid <= '0; - mmu_exception <= '0; - end else begin - mmu_paddr <= mmu_vaddr_plen; - translation_valid <= translation_req; - mmu_exception <= misaligned_exception; - end - end end + // ------------------ + // PMP + // ------------------ + + 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) + ); + logic store_buffer_empty; // ------------------ From 405e02e3e8508ef7b5b87c8609be4dee54bb7bd1 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Wed, 24 Jul 2024 10:41:08 +0200 Subject: [PATCH 09/25] fix translation_valid and dtlb_ppn when no mmu --- core/load_store_unit.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index f6de184047..d99ee675b2 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -327,7 +327,7 @@ module load_store_unit assign mmu_exception = pmp_exception; assign icache_areq_o = pmp_icache_areq_o; - assign pmp_translation = pmp_translation_valid; + assign translation_valid = pmp_translation_valid; assign mmu_paddr = pmp_paddr; assign dcache_req_ports_o[0].address_index = '0; @@ -342,7 +342,7 @@ module load_store_unit assign itlb_miss_o = 1'b0; assign dtlb_miss_o = 1'b0; - assign dtlb_ppn = mmu_vaddr[CVA6Cfg.PLEN-1:12]; + assign dtlb_ppn = pmp_paddr[CVA6Cfg.PLEN-1:12]; assign dtlb_hit = 1'b1; end From e85adcbc2c82d4c07f46443888c88cef92d57b44 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Wed, 31 Jul 2024 11:49:50 +0200 Subject: [PATCH 10/25] Add pmp_data_if in needed file lists --- Flist.ariane | 1 + core/Flist.cva6 | 1 + 2 files changed, 2 insertions(+) diff --git a/Flist.ariane b/Flist.ariane index 12b4629404..0edfa8e4f5 100644 --- a/Flist.ariane +++ b/Flist.ariane @@ -160,6 +160,7 @@ vendor/openhwgroup/cvfpu/src/fpnew_rounding.sv vendor/openhwgroup/cvfpu/src/fpnew_top.sv core/pmp/src/pmp.sv core/pmp/src/pmp_entry.sv +core/pmp/src/pmp_data_if.sv common/local/util/instr_tracer.sv core/cvxif_example/cvxif_example_coprocessor.sv core/cvxif_example/instr_decoder.sv diff --git a/core/Flist.cva6 b/core/Flist.cva6 index b54cc3cb1b..cac849e2b7 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -178,6 +178,7 @@ ${HPDCACHE_DIR}/rtl/src/common/macros/behav/hpdcache_sram_wmask_1rw.sv // NOTE: pmp.sv modified for DSIM (unchanged for other simulators) ${CVA6_REPO_DIR}/core/pmp/src/pmp.sv ${CVA6_REPO_DIR}/core/pmp/src/pmp_entry.sv +${CVA6_REPO_DIR}/core/pmp/src/pmp_data_if.sv // Tracer (behavioral code, not RTL) ${CVA6_REPO_DIR}/common/local/util/instr_tracer.sv From ca9796253bacf1cf6ec8e5ad29375bc1df7680de Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Wed, 31 Jul 2024 13:31:30 +0200 Subject: [PATCH 11/25] Fix exception tval when translation is enabled --- core/pmp/src/pmp_data_if.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index b5aa1ca72e..9a06adf8f8 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -150,7 +150,7 @@ module pmp_data_if if (CVA6Cfg.TvalEn) begin if (en_ld_st_translation_i || en_ld_st_g_translation_i) begin lsu_exception_o.tval = { - {CVA6Cfg.XLEN - CVA6Cfg.PLEN{lsu_vaddr_q[CVA6Cfg.PLEN-1]}}, lsu_vaddr_q + {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]); From 77ee14dcae69212067bd6e060a1c790e5134399a Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Mon, 26 Aug 2024 16:40:49 +0200 Subject: [PATCH 12/25] integrate no_locked assertions for pmp: now in blocking assignments to avoid raise condition in simulation --- core/pmp/src/pmp_data_if.sv | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index 9a06adf8f8..9897087f22 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -59,6 +59,8 @@ module pmp_data_if 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 @@ -209,4 +211,43 @@ module pmp_data_if end end end + + + // ---------------- + // Assert for PMPs + // ---------------- + + // synthesis translate_off + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + no_locked_data <= 1'b0; + end else begin + if (ld_st_priv_lvl_i == riscv::PRIV_LVL_M) begin + no_locked_data <= 1'b1; + for (int i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin + if (pmpcfg_i[i].locked && pmpcfg_i[i].addr_mode != riscv::OFF) begin + no_locked_data <= no_locked_data & 1'b0; + end else no_locked_data <= no_locked_data & 1'b1; + end + if (no_locked_data == 1'b1) assert (data_allow_o == 1'b1); + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + no_locked_if <= 1'b0; + end else begin + if (priv_lvl_i == riscv::PRIV_LVL_M) begin + no_locked_if <= 1'b1; + for (int i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin + if (pmpcfg_i[i].locked && pmpcfg_i[i].addr_mode != riscv::OFF) begin + 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); + end + end + end + // synthesis translate_on endmodule From 1dc3f0a6dea9bcb3f4d2adbf873d56a0f43f1421 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Thu, 29 Aug 2024 10:56:49 +0200 Subject: [PATCH 13/25] Fix mixed assignment for no_locked_if --- core/pmp/src/pmp_data_if.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index 9897087f22..9d38ecabb9 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -242,8 +242,8 @@ module pmp_data_if no_locked_if <= 1'b1; for (int i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin if (pmpcfg_i[i].locked && pmpcfg_i[i].addr_mode != riscv::OFF) begin - no_locked_if = no_locked_if & 1'b0; - end else no_locked_if = no_locked_if & 1'b1; + 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); end From 1b635fa826fffc11fbc5bfb6a4a9a6abf431769d Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Mon, 26 Aug 2024 16:40:19 +0200 Subject: [PATCH 14/25] Remove assertion no_locked from pmp: need clk and reset --- core/pmp/src/pmp.sv | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/core/pmp/src/pmp.sv b/core/pmp/src/pmp.sv index 5d8264c9be..439bf901cb 100644 --- a/core/pmp/src/pmp.sv +++ b/core/pmp/src/pmp.sv @@ -75,20 +75,4 @@ module pmp #( end end else assign allow_o = 1'b1; - // synthesis translate_off - always_comb begin - logic no_locked; - no_locked = 1'b0; - if (priv_lvl_i == riscv::PRIV_LVL_M) begin - no_locked = 1'b1; - for (int i = 0; i < NR_ENTRIES; i++) begin - if (conf_i[i].locked && conf_i[i].addr_mode != riscv::OFF) begin - no_locked &= 1'b0; - end else no_locked &= 1'b1; - end - if (no_locked == 1'b1) assert (allow_o == 1'b1); - end - end - // synthesis translate_on - endmodule From 45d0176aaa7105deaa56304ed08687f2b0063fb1 Mon Sep 17 00:00:00 2001 From: Coralie Allioux Date: Thu, 29 Aug 2024 12:02:18 +0200 Subject: [PATCH 15/25] Apply verible format --- core/pmp/src/pmp_data_if.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index 9d38ecabb9..2c08283baa 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -59,7 +59,7 @@ module pmp_data_if 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 @@ -211,8 +211,8 @@ module pmp_data_if end end end - - + + // ---------------- // Assert for PMPs // ---------------- From f88bc363c16aeadc1a317d75fe7b6f1ed3cc05fc Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Fri, 4 Oct 2024 13:52:49 +0200 Subject: [PATCH 16/25] 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 From dcba7614a755a7889910f78d6794edd1bbd8e689 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Thu, 21 Nov 2024 15:57:47 +0100 Subject: [PATCH 17/25] Increase log file --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9aa7b452b4..3b17e3df95 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -132,7 +132,7 @@ build_tools: .simu_after_script: &simu_after_script - for i in $(find verif/sim/out*/[vq]*_sim -type f \( -name "*.csv" -o -name "*.iss" -o -name "*.yaml" \)) ; do head -10000 $i > artifacts/logs/$(basename $i).head ; done - - head -10000 verif/sim/logfile.log > artifacts/logs/logfile.log.head + - head -20000 verif/sim/logfile.log > artifacts/logs/logfile.log.head - if [ -n "$SPIKE_TANDEM" ]; then python3 .gitlab-ci/scripts/report_tandem.py verif/sim/out*/"$DV_SIMULATORS"_sim; else python3 .gitlab-ci/scripts/report_simu.py verif/sim/logfile.log; fi smoke-tests: From 29a019990ecfadd1777ecf2eb3ee7c9cb00a7c4e Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Fri, 22 Nov 2024 10:05:11 +0100 Subject: [PATCH 18/25] Temporarily increase the log size to be able to see the full log --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3b17e3df95..78132c683e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -131,7 +131,7 @@ build_tools: - echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC .simu_after_script: &simu_after_script - - for i in $(find verif/sim/out*/[vq]*_sim -type f \( -name "*.csv" -o -name "*.iss" -o -name "*.yaml" \)) ; do head -10000 $i > artifacts/logs/$(basename $i).head ; done + - for i in $(find verif/sim/out*/[vq]*_sim -type f \( -name "*.csv" -o -name "*.iss" -o -name "*.yaml" \)) ; do head -20000 $i > artifacts/logs/$(basename $i).head ; done - head -20000 verif/sim/logfile.log > artifacts/logs/logfile.log.head - if [ -n "$SPIKE_TANDEM" ]; then python3 .gitlab-ci/scripts/report_tandem.py verif/sim/out*/"$DV_SIMULATORS"_sim; else python3 .gitlab-ci/scripts/report_simu.py verif/sim/logfile.log; fi From cff299f1e1224a6528c560bea9feec5858fb4940 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Tue, 3 Dec 2024 10:25:21 +0100 Subject: [PATCH 19/25] Add 1 cycle delay for misaligned exception and valid translation --- core/load_store_unit.sv | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index fe0a0ccc96..20d04d0866 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -327,17 +327,18 @@ module load_store_unit // 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; + lsu_paddr <= '0; + pmp_exception <= '0; 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 + pmp_exception <= misaligned_exception; + pmp_translation_valid <= translation_req; end end - assign pmp_exception = misaligned_exception; - assign pmp_translation_valid = translation_req; // dcache interface of PTW not used assign dcache_req_ports_o[0].address_index = '0; From 61f31baa642ac5a8c4bd682687ec1f0fe32debce Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Tue, 3 Dec 2024 10:41:36 +0100 Subject: [PATCH 20/25] Restore gitlab ci settings --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 78132c683e..79eba03644 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -131,8 +131,8 @@ build_tools: - echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC .simu_after_script: &simu_after_script - - for i in $(find verif/sim/out*/[vq]*_sim -type f \( -name "*.csv" -o -name "*.iss" -o -name "*.yaml" \)) ; do head -20000 $i > artifacts/logs/$(basename $i).head ; done - - head -20000 verif/sim/logfile.log > artifacts/logs/logfile.log.head + - for i in $(find verif/sim/out*/[vq]*_sim -type f \( -name "*.csv" -o -name "*.iss" -o -name "*.yaml" \)) ; do tail -10000 $i > artifacts/logs/$(basename $i) ; done + - tail -10000 verif/sim/logfile.log > artifacts/logs/logfile.log.head - if [ -n "$SPIKE_TANDEM" ]; then python3 .gitlab-ci/scripts/report_tandem.py verif/sim/out*/"$DV_SIMULATORS"_sim; else python3 .gitlab-ci/scripts/report_simu.py verif/sim/logfile.log; fi smoke-tests: From 85bb2f10a86ab7caf5eeeb8ce1cee0eb65e7f5f8 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Tue, 3 Dec 2024 10:44:44 +0100 Subject: [PATCH 21/25] Fix log file name --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 79eba03644..9abac6acaf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -132,7 +132,7 @@ build_tools: .simu_after_script: &simu_after_script - for i in $(find verif/sim/out*/[vq]*_sim -type f \( -name "*.csv" -o -name "*.iss" -o -name "*.yaml" \)) ; do tail -10000 $i > artifacts/logs/$(basename $i) ; done - - tail -10000 verif/sim/logfile.log > artifacts/logs/logfile.log.head + - tail -10000 verif/sim/logfile.log > artifacts/logs/logfile.log - if [ -n "$SPIKE_TANDEM" ]; then python3 .gitlab-ci/scripts/report_tandem.py verif/sim/out*/"$DV_SIMULATORS"_sim; else python3 .gitlab-ci/scripts/report_simu.py verif/sim/logfile.log; fi smoke-tests: From 3e7b45250da5bafec0c69f2e3ce1fa7c06a312b4 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Tue, 3 Dec 2024 14:21:36 +0100 Subject: [PATCH 22/25] Patch commit for CI --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 048e753248..16ed6ac36b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -275,7 +275,7 @@ asic-synthesis: - echo $DV_TARGET - source ./verif/sim/setup-env.sh - git clone ${SYNTH_SCRIPT} ${SYNTH_SCRIPT_PATH} -b ${SYNTH_SCRIPT_BRANCH} - - git -C ${SYNTH_SCRIPT_PATH} checkout 1e166766d2c91ca905577cccc70813a2a8bbefc2 + - git -C ${SYNTH_SCRIPT_PATH} checkout cce5ea41 - cp -r ${SYNTH_SCRIPT_PATH}/cva6/ ../ - git apply ${SYNTH_SCRIPT_PATH}/patches/*.patch - echo $SYN_DCSHELL_BASHRC; source $SYN_DCSHELL_BASHRC @@ -546,7 +546,7 @@ simu-gate: - echo $PERIOD - source ./verif/sim/setup-env.sh - git clone ${SYNTH_SCRIPT} ${SYNTH_SCRIPT_PATH} -b ${SYNTH_SCRIPT_BRANCH} - - git -C ${SYNTH_SCRIPT_PATH} checkout 1e166766d2c91ca905577cccc70813a2a8bbefc2 + - git -C ${SYNTH_SCRIPT_PATH} checkout cce5ea41 - cp -r ${SYNTH_SCRIPT_PATH}/cva6/ ../ - git apply ${SYNTH_SCRIPT_PATH}/patches/*.patch - source verif/regress/install-riscv-tests.sh From 14065ae29c1f99e342830b26ce8b1a9693fc963f Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Tue, 3 Dec 2024 16:17:40 +0100 Subject: [PATCH 23/25] Remove unused signal --- core/load_store_unit.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 20d04d0866..1638428925 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -205,7 +205,7 @@ module load_store_unit logic translation_req; logic translation_valid; logic [CVA6Cfg.VLEN-1:0] mmu_vaddr; - logic [CVA6Cfg.PLEN-1:0] mmu_paddr, pmp_paddr, lsu_paddr, mmu_vaddr_plen, fetch_vaddr_plen; + logic [CVA6Cfg.PLEN-1:0] mmu_paddr, lsu_paddr; logic [ 31:0] mmu_tinst; logic mmu_hs_ld_st_inst; logic mmu_hlvx_inst; @@ -353,7 +353,7 @@ module load_store_unit assign itlb_miss_o = 1'b0; assign dtlb_miss_o = 1'b0; - assign dtlb_ppn = pmp_paddr[CVA6Cfg.PLEN-1:12]; + assign dtlb_ppn = mmu_vaddr[CVA6Cfg.PLEN-1:12]; assign dtlb_hit = 1'b1; end From 2ecc2c719266e558cb617579ac356d62115c3378 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Tue, 3 Dec 2024 16:18:12 +0100 Subject: [PATCH 24/25] Update gate count to match addition on PMP --- .gitlab-ci/expected_synth.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index 98a2aeb83f..969e5e815d 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 178869 + gates: 188627 From e36852beb59f0b357127f31842876b1e23eee441 Mon Sep 17 00:00:00 2001 From: Olivier Betschi Date: Wed, 4 Dec 2024 09:10:29 +0100 Subject: [PATCH 25/25] Fix dtlb_ppn assignment and remove some unused signals --- core/load_store_unit.sv | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 1638428925..134b6a3dc1 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -211,7 +211,6 @@ module load_store_unit 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; @@ -234,7 +233,6 @@ module load_store_unit logic hs_ld_st_inst; logic hlvx_inst; - logic [2:0] enable_translation, en_ld_st_translation, flush_tlb; logic [1:0] sum, mxr; logic [CVA6Cfg.PPNW-1:0] satp_ppn[2:0]; logic [CVA6Cfg.ASID_WIDTH-1:0] asid[2:0], asid_to_be_flushed[1:0]; @@ -317,9 +315,9 @@ module load_store_unit 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 + if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin : gen_virtual_physical_address_instruction_vlen_greater assign pmp_icache_areq_i.fetch_paddr = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0]; - end else begin + end else begin : gen_virtual_physical_address_instruction_plen_greater assign pmp_icache_areq_i.fetch_paddr = CVA6Cfg.PLEN'(icache_areq_i.fetch_vaddr); end assign pmp_icache_areq_i.fetch_exception = 'h0; @@ -329,6 +327,7 @@ module load_store_unit if (~rst_ni) begin lsu_paddr <= '0; pmp_exception <= '0; + pmp_translation_valid <= 1'b0; end else begin if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin : gen_virtual_physical_address_lsu lsu_paddr <= mmu_vaddr[CVA6Cfg.PLEN-1:0]; @@ -353,7 +352,7 @@ module load_store_unit assign itlb_miss_o = 1'b0; assign dtlb_miss_o = 1'b0; - assign dtlb_ppn = mmu_vaddr[CVA6Cfg.PLEN-1:12]; + assign dtlb_ppn = lsu_paddr[CVA6Cfg.PLEN-1:12]; assign dtlb_hit = 1'b1; end