diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index 9656090a8d1..393950e5b6e 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -3,4 +3,4 @@ cv64a6_imafdc_sv39: cv32a60x: gates: 160719 cv32a6_embedded: - gates: 129129 + gates: 128703 diff --git a/core/alu.sv b/core/alu.sv index fc9775a06b7..3ff3c1a4c31 100644 --- a/core/alu.sv +++ b/core/alu.sv @@ -297,7 +297,7 @@ module alu import ariane_pkg::*; #( default: ; // default case to suppress unique warning endcase end - if (CVA6Cfg.RCONDEXT) begin + if (CVA6Cfg.ZiCondExtEn) begin unique case (fu_data_i.operation) CZERO_EQZ : result_o = (|fu_data_i.operand_b) ? fu_data_i.operand_a : '0; // move zero to rd if rs2 is equal to zero else rs1 CZERO_NEZ : result_o = (|fu_data_i.operand_b) ? '0 : fu_data_i.operand_a; // move zero to rd if rs2 is nonzero else rs1 diff --git a/core/cache_subsystem/cache_ctrl.sv b/core/cache_subsystem/cache_ctrl.sv index 5eaa98bf4e4..b83c1b3267e 100644 --- a/core/cache_subsystem/cache_ctrl.sv +++ b/core/cache_subsystem/cache_ctrl.sv @@ -19,8 +19,7 @@ module cache_ctrl import ariane_pkg::*; import std_cache_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig // contains cacheable regions + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -251,7 +250,7 @@ module cache_ctrl import ariane_pkg::*; import std_cache_pkg::*; #( // ------------------------- // Check for cache-ability // ------------------------- - if (!is_inside_cacheable_regions(ArianeCfg, {{{64-riscv::PLEN}{1'b0}}, tag_o, {DCACHE_INDEX_WIDTH{1'b0}}})) begin + if (!config_pkg::is_inside_cacheable_regions(CVA6Cfg, {{{64-riscv::PLEN}{1'b0}}, tag_o, {DCACHE_INDEX_WIDTH{1'b0}}})) begin mem_req_d.bypass = 1'b1; state_d = WAIT_REFILL_GNT; end diff --git a/core/cache_subsystem/cva6_icache.sv b/core/cache_subsystem/cva6_icache.sv index 8236ba11edc..d8f03fb9836 100644 --- a/core/cache_subsystem/cva6_icache.sv +++ b/core/cache_subsystem/cva6_icache.sv @@ -28,9 +28,7 @@ module cva6_icache import ariane_pkg::*; import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, /// ID to be used for read transactions - parameter logic [MEM_TID_WIDTH-1:0] RdTxId = 0, - /// Contains cacheable regions - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter logic [MEM_TID_WIDTH-1:0] RdTxId = 0 ) ( input logic clk_i, input logic rst_ni, @@ -118,7 +116,7 @@ module cva6_icache import ariane_pkg::*; import wt_cache_pkg::*; #( assign cl_tag_d = (areq_i.fetch_valid) ? areq_i.fetch_paddr[ICACHE_TAG_WIDTH+ICACHE_INDEX_WIDTH-1:ICACHE_INDEX_WIDTH] : cl_tag_q; // noncacheable if request goes to I/O space, or if cache is disabled - assign paddr_is_nc = (~cache_en_q) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{{64-riscv::PLEN}{1'b0}}, cl_tag_d, {ICACHE_INDEX_WIDTH{1'b0}}})); + assign paddr_is_nc = (~cache_en_q) | (~config_pkg::is_inside_cacheable_regions(CVA6Cfg, {{{64-riscv::PLEN}{1'b0}}, cl_tag_d, {ICACHE_INDEX_WIDTH{1'b0}}})); // pass exception through assign dreq_o.ex = areq_i.fetch_exception; @@ -132,7 +130,7 @@ module cva6_icache import ariane_pkg::*; import wt_cache_pkg::*; #( assign cl_index = vaddr_d[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH]; - if (ArianeCfg.AxiCompliant) begin : gen_axi_offset + if (CVA6Cfg.NOCType == config_pkg::NOC_TYPE_AXI4_ATOP) begin : gen_axi_offset // if we generate a noncacheable access, the word will be at offset 0 or 4 in the cl coming from memory assign cl_offset_d = ( dreq_o.ready & dreq_i.req) ? {dreq_i.vaddr>>2, 2'b0} : ( paddr_is_nc & mem_data_req_o ) ? cl_offset_q[2]<<2 : // needed since we transfer 32bit over a 64bit AXI bus in this case @@ -166,7 +164,7 @@ end else begin : gen_piton_offset // main control logic /////////////////////////////////////////////////////// logic addr_ni; - assign addr_ni = is_inside_nonidempotent_regions(ArianeCfg, areq_i.fetch_paddr); + assign addr_ni = config_pkg::is_inside_nonidempotent_regions(CVA6Cfg, areq_i.fetch_paddr); always_comb begin : p_fsm // default assignment state_d = state_q; diff --git a/core/cache_subsystem/cva6_icache_axi_wrapper.sv b/core/cache_subsystem/cva6_icache_axi_wrapper.sv index 00561f33ca7..faeaccc0d0e 100644 --- a/core/cache_subsystem/cva6_icache_axi_wrapper.sv +++ b/core/cache_subsystem/cva6_icache_axi_wrapper.sv @@ -15,7 +15,6 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig, // contains cacheable regions parameter type axi_req_t = logic, parameter type axi_rsp_t = logic ) ( @@ -99,8 +98,7 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #( cva6_icache #( // use ID 0 for icache reads .CVA6Cfg ( CVA6Cfg ), - .RdTxId ( 0 ), - .ArianeCfg ( ArianeCfg ) + .RdTxId ( 0 ) ) i_cva6_icache ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/core/cache_subsystem/std_cache_subsystem.sv b/core/cache_subsystem/std_cache_subsystem.sv index a11fe5615c5..18ae936d956 100644 --- a/core/cache_subsystem/std_cache_subsystem.sv +++ b/core/cache_subsystem/std_cache_subsystem.sv @@ -17,7 +17,6 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig, // contains cacheable regions parameter int unsigned NumPorts = 4, parameter type axi_ar_chan_t = logic, parameter type axi_aw_chan_t = logic, @@ -67,7 +66,6 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #( cva6_icache_axi_wrapper #( .CVA6Cfg ( CVA6Cfg ), - .ArianeCfg ( ArianeCfg ), .axi_req_t ( axi_req_t ), .axi_rsp_t ( axi_rsp_t ) ) i_cva6_icache_axi_wrapper ( @@ -92,7 +90,6 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #( // Port 3: Store Unit std_nbdcache #( .CVA6Cfg ( CVA6Cfg ), - .ArianeCfg ( ArianeCfg ), .NumPorts ( NumPorts ), .axi_req_t ( axi_req_t ), .axi_rsp_t ( axi_rsp_t ) diff --git a/core/cache_subsystem/std_nbdcache.sv b/core/cache_subsystem/std_nbdcache.sv index a48bc9b31fd..dae7699cc42 100644 --- a/core/cache_subsystem/std_nbdcache.sv +++ b/core/cache_subsystem/std_nbdcache.sv @@ -15,7 +15,6 @@ module std_nbdcache import std_cache_pkg::*; import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig, // contains cacheable regions parameter int unsigned NumPorts = 4, parameter type axi_req_t = logic, parameter type axi_rsp_t = logic @@ -93,8 +92,7 @@ import std_cache_pkg::*; generate for (genvar i = 0; i < NumPorts; i++) begin : master_ports cache_ctrl #( - .CVA6Cfg ( CVA6Cfg ), - .ArianeCfg ( ArianeCfg ) + .CVA6Cfg ( CVA6Cfg ) ) i_cache_ctrl ( .bypass_i ( ~enable_i ), .busy_o ( busy [i] ), diff --git a/core/cache_subsystem/wt_cache_subsystem.sv b/core/cache_subsystem/wt_cache_subsystem.sv index 9182a4a511f..1204a051997 100644 --- a/core/cache_subsystem/wt_cache_subsystem.sv +++ b/core/cache_subsystem/wt_cache_subsystem.sv @@ -21,7 +21,6 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig, // contains cacheable regions parameter int unsigned NumPorts = 4, parameter type noc_req_t = logic, parameter type noc_resp_t = logic @@ -77,8 +76,7 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #( cva6_icache #( // use ID 0 for icache reads .CVA6Cfg ( CVA6Cfg ), - .RdTxId ( 0 ), - .ArianeCfg ( ArianeCfg ) + .RdTxId ( 0 ) ) i_cva6_icache ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -105,8 +103,7 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), // use ID 1 for dcache reads and amos. note that the writebuffer // uses all IDs up to DCACHE_MAX_TX-1 for write transactions. - .RdAmoTxId ( 1 ), - .ArianeCfg ( ArianeCfg ) + .RdAmoTxId ( 1 ) ) i_wt_dcache ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -137,7 +134,6 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #( `ifdef PITON_ARIANE wt_l15_adapter #( .CVA6Cfg ( CVA6Cfg ), - .SwapEndianess ( ArianeCfg.SwapEndianess ) ) i_adapter ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/core/cache_subsystem/wt_dcache.sv b/core/cache_subsystem/wt_dcache.sv index a76e5ad5fed..4e377ab0a4e 100644 --- a/core/cache_subsystem/wt_dcache.sv +++ b/core/cache_subsystem/wt_dcache.sv @@ -18,9 +18,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( parameter int unsigned NumPorts = 4, // number of miss ports // ID to be used for read and AMO transactions. // note that the write buffer uses all IDs up to DCACHE_MAX_TX-1 for write transactions - parameter logic [CACHE_ID_WIDTH-1:0] RdAmoTxId = 1, - // contains cacheable regions - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter logic [CACHE_ID_WIDTH-1:0] RdAmoTxId = 1 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -113,7 +111,6 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( wt_dcache_missunit #( .CVA6Cfg ( CVA6Cfg ), - .AxiCompliant ( ArianeCfg.AxiCompliant ), .AmoTxId ( RdAmoTxId ), .NumPorts ( NumPorts ) ) i_wt_dcache_missunit ( @@ -175,8 +172,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( wt_dcache_ctrl #( .CVA6Cfg ( CVA6Cfg ), - .RdTxId ( RdAmoTxId ), - .ArianeCfg ( ArianeCfg ) + .RdTxId ( RdAmoTxId ) ) i_wt_dcache_ctrl ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -220,8 +216,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( assign rd_prio[NumPorts-1] = 1'b0; wt_dcache_wbuffer #( - .CVA6Cfg ( CVA6Cfg ), - .ArianeCfg ( ArianeCfg ) + .CVA6Cfg ( CVA6Cfg ) ) i_wt_dcache_wbuffer ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -279,7 +274,6 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( wt_dcache_mem #( .CVA6Cfg ( CVA6Cfg ), - .AxiCompliant ( ArianeCfg.AxiCompliant ), .NumPorts ( NumPorts ) ) i_wt_dcache_mem ( .clk_i ( clk_i ), diff --git a/core/cache_subsystem/wt_dcache_ctrl.sv b/core/cache_subsystem/wt_dcache_ctrl.sv index c7fc3d25d50..366e0317cbd 100644 --- a/core/cache_subsystem/wt_dcache_ctrl.sv +++ b/core/cache_subsystem/wt_dcache_ctrl.sv @@ -15,8 +15,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 1, // ID to use for read transactions - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions + parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 1 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -89,7 +88,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #( assign miss_size_o = (miss_nc_o) ? data_size_q : 3'b111; // noncacheable if request goes to I/O space, or if cache is disabled - assign miss_nc_o = (~cache_en_i) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH}{1'b0}}, address_tag_q, {DCACHE_INDEX_WIDTH{1'b0}}})); + assign miss_nc_o = (~cache_en_i) | (~config_pkg::is_inside_cacheable_regions(CVA6Cfg, {{{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH}{1'b0}}, address_tag_q, {DCACHE_INDEX_WIDTH{1'b0}}})); assign miss_we_o = '0; diff --git a/core/cache_subsystem/wt_dcache_mem.sv b/core/cache_subsystem/wt_dcache_mem.sv index 62b99f1132e..083c2e8c64f 100644 --- a/core/cache_subsystem/wt_dcache_mem.sv +++ b/core/cache_subsystem/wt_dcache_mem.sv @@ -28,7 +28,6 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter bit AxiCompliant = 1'b0, // set this to 1 when using in conjunction with AXI bus adapter parameter int unsigned NumPorts = 3 ) ( input logic clk_i, @@ -256,12 +255,12 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #( assign wbuffer_ruser = wbuffer_data_i[wbuffer_hit_idx].user; assign wbuffer_be = (|wbuffer_hit_oh) ? wbuffer_data_i[wbuffer_hit_idx].valid : '0; - if (AxiCompliant) begin : gen_axi_off + if (CVA6Cfg.NOCType == config_pkg::NOC_TYPE_AXI4_ATOP) begin : gen_axi_offset // In case of an uncached read, return the desired XLEN-bit segment of the most recent AXI read assign wr_cl_off = (wr_cl_nc_i) ? (CVA6Cfg.AxiDataWidth == riscv::XLEN) ? '0 : wr_cl_off_i[AXI_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES] : wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]; - end else begin : gen_piton_off + end else begin : gen_piton_offset assign wr_cl_off = wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:3]; end diff --git a/core/cache_subsystem/wt_dcache_missunit.sv b/core/cache_subsystem/wt_dcache_missunit.sv index 9d63224f911..8bbb906871a 100644 --- a/core/cache_subsystem/wt_dcache_missunit.sv +++ b/core/cache_subsystem/wt_dcache_missunit.sv @@ -16,7 +16,6 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter bit AxiCompliant = 1'b0, // set this to 1 when using in conjunction with AXI bus adapter parameter logic [CACHE_ID_WIDTH-1:0] AmoTxId = 1, // TX id to be used for AMOs parameter int unsigned NumPorts = 4 // number of miss ports ) ( @@ -255,7 +254,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #( end // note: openpiton returns a full cacheline! - if (AxiCompliant) begin : gen_axi_rtrn_mux + if (CVA6Cfg.NOCType == config_pkg::NOC_TYPE_AXI4_ATOP) begin : gen_axi_rtrn_mux if (CVA6Cfg.AxiDataWidth > 64) begin assign amo_rtrn_mux = mem_rtrn_i.data[amo_req_i.operand_a[$clog2(CVA6Cfg.AxiDataWidth/8)-1:3]*64 +: 64]; end else begin diff --git a/core/cache_subsystem/wt_dcache_wbuffer.sv b/core/cache_subsystem/wt_dcache_wbuffer.sv index 0090a337992..255c482f676 100644 --- a/core/cache_subsystem/wt_dcache_wbuffer.sv +++ b/core/cache_subsystem/wt_dcache_wbuffer.sv @@ -50,8 +50,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -141,10 +140,10 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( logic is_nc_miss; logic is_ni; assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH]; - assign is_nc_miss = !ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH{1'b0}}, miss_tag, {DCACHE_INDEX_WIDTH{1'b0}}}); + assign is_nc_miss = !config_pkg::is_inside_cacheable_regions(CVA6Cfg, {{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH{1'b0}}, miss_tag, {DCACHE_INDEX_WIDTH{1'b0}}}); assign miss_nc_o = !cache_en_i || is_nc_miss; // Non-idempotent if request goes to NI region - assign is_ni = ariane_pkg::is_inside_nonidempotent_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}}); + assign is_ni = config_pkg::is_inside_nonidempotent_regions(CVA6Cfg, {{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}}); assign miss_we_o = 1'b1; assign miss_vld_bits_o = '0; diff --git a/core/cache_subsystem/wt_l15_adapter.sv b/core/cache_subsystem/wt_l15_adapter.sv index 6dd3450d416..5481d24df8e 100644 --- a/core/cache_subsystem/wt_l15_adapter.sv +++ b/core/cache_subsystem/wt_l15_adapter.sv @@ -50,8 +50,7 @@ module wt_l15_adapter import ariane_pkg::*; import wt_cache_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter bit SwapEndianess = 1 + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, input logic rst_ni, @@ -133,8 +132,9 @@ l15_rtrn_t rtrn_fifo_data; // openpiton is big endian - if (SwapEndianess) assign l15_req_o.l15_data = swendian64(dcache_data.data); - else assign l15_req_o.l15_data = dcache_data.data; + if (CVA6Cfg.NOCType == config_pkg::NOC_TYPE_L15_BIG_ENDIAN) assign l15_req_o.l15_data = swendian64(dcache_data.data); + else if (CVA6Cfg.NOCType == config_pkg::NOC_TYPE_L15_LITTLE_ENDIAN) assign l15_req_o.l15_data = dcache_data.data; + else $fatal(1,"[wt_l15_adapter] Unsupported NOC type"); // arbiter rrarbiter #( diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 91da44fc544..14f067c3326 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -15,9 +15,7 @@ module csr_regfile import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address parameter int AsidWidth = 1, - parameter int unsigned NrPMPEntries = 8, parameter int unsigned MHPMCounterNum = 6 ) ( input logic clk_i, // Clock @@ -271,6 +269,7 @@ module csr_regfile import ariane_pkg::*; #( riscv::CSR_MARCHID: csr_rdata = ARIANE_MARCHID; riscv::CSR_MIMPID: csr_rdata = '0; // not implemented riscv::CSR_MHARTID: csr_rdata = hart_id_i; + riscv::CSR_MCONFIGPTR: csr_rdata = '0; // not implemented riscv::CSR_MCOUNTINHIBIT: csr_rdata = mcountinhibit_q; // Counters and Timers riscv::CSR_MCYCLE: csr_rdata = cycle_q[riscv::XLEN-1:0]; @@ -909,7 +908,7 @@ module csr_regfile import ariane_pkg::*; #( mstatus_d.sd = (mstatus_q.xs == riscv::Dirty) | (mstatus_q.fs == riscv::Dirty); // reserve PMPCFG bits 5 and 6 (hardwire to 0) - for (int i = 0; i < NrPMPEntries; i++) pmpcfg_d[i].reserved = 2'b0; + for (int i = 0; i < CVA6Cfg.NrPMPEntries; i++) pmpcfg_d[i].reserved = 2'b0; // write the floating point status register if (CVA6Cfg.FpPresent && csr_write_fflags_i) begin @@ -1269,7 +1268,7 @@ module csr_regfile import ariane_pkg::*; #( // if we are in debug mode jump to a specific address if (debug_mode_q) begin - trap_vector_base_o = DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.ExceptionAddress[riscv::VLEN-1:0]; + trap_vector_base_o = CVA6Cfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.ExceptionAddress[riscv::VLEN-1:0]; end // check if we are in vectored mode, if yes then do BASE + 4 * cause we @@ -1442,7 +1441,7 @@ module csr_regfile import ariane_pkg::*; #( wfi_q <= wfi_d; // pmp for(int i = 0; i < 16; i++) begin - if(i < NrPMPEntries) begin + if(i < CVA6Cfg.NrPMPEntries) begin // We only support >=8-byte granularity, NA4 is disabled if(pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin pmpcfg_q[i] <= pmpcfg_d[i]; diff --git a/core/cva6.sv b/core/cva6.sv index 49c5b6bb851..3738d15ab2f 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -15,7 +15,7 @@ module cva6 import ariane_pkg::*; #( // CVA6 config - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_default, + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg, parameter bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace), // RVFI parameter type rvfi_instr_t = struct packed { @@ -109,7 +109,6 @@ module cva6 import ariane_pkg::*; #( r_chan_t r; }, // - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig, parameter type acc_cfg_t = logic, parameter acc_cfg_t AccCfg = '0, parameter type cvxif_req_t = cvxif_pkg::cvxif_req_t, @@ -179,7 +178,7 @@ module cva6 import ariane_pkg::*; #( CVA6Cfg.RVZCB, CVA6Cfg.XFVec, CVA6Cfg.CvxifEn, - CVA6Cfg.RCONDEXT, + CVA6Cfg.ZiCondExtEn, // Extended bit'(RVF), bit'(RVD), @@ -194,7 +193,22 @@ module cva6 import ariane_pkg::*; #( unsigned'(NrWbPorts), bit'(EnableAccelerator), CVA6Cfg.HaltAddress, - CVA6Cfg.ExceptionAddress + CVA6Cfg.ExceptionAddress, + CVA6Cfg.RASDepth, + CVA6Cfg.BTBEntries, + CVA6Cfg.BHTEntries, + CVA6Cfg.DmBaseAddress, + CVA6Cfg.NrPMPEntries, + CVA6Cfg.NOCType, + CVA6Cfg.NrNonIdempotentRules, + CVA6Cfg.NonIdempotentAddrBase, + CVA6Cfg.NonIdempotentLength, + CVA6Cfg.NrExecuteRegionRules, + CVA6Cfg.ExecuteRegionAddrBase, + CVA6Cfg.ExecuteRegionLength, + CVA6Cfg.NrCachedRegionRules, + CVA6Cfg.CachedRegionAddrBase, + CVA6Cfg.CachedRegionLength }; @@ -432,8 +446,7 @@ module cva6 import ariane_pkg::*; #( // Frontend // -------------- frontend #( - .CVA6Cfg ( CVA6ExtendCfg ), - .ArianeCfg ( ArianeCfg ) + .CVA6Cfg ( CVA6ExtendCfg ) ) i_frontend ( .flush_i ( flush_ctrl_if ), // not entirely correct .flush_bp_i ( 1'b0 ), @@ -595,8 +608,7 @@ module cva6 import ariane_pkg::*; #( // --------- ex_stage #( .CVA6Cfg ( CVA6ExtendCfg ), - .ASID_WIDTH ( ASID_WIDTH ), - .ArianeCfg ( ArianeCfg ) + .ASID_WIDTH ( ASID_WIDTH ) ) ex_stage_i ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -753,8 +765,6 @@ module cva6 import ariane_pkg::*; #( csr_regfile #( .CVA6Cfg ( CVA6ExtendCfg ), .AsidWidth ( ASID_WIDTH ), - .DmBaseAddress ( ArianeCfg.DmBaseAddress ), - .NrPMPEntries ( ArianeCfg.NrPMPEntries ), .MHPMCounterNum ( MHPMCounterNum ) ) csr_regfile_i ( .flush_o ( flush_csr_ctrl ), @@ -923,7 +933,6 @@ module cva6 import ariane_pkg::*; #( // this is a cache subsystem that is compatible with OpenPiton wt_cache_subsystem #( .CVA6Cfg ( CVA6ExtendCfg ), - .ArianeCfg ( ArianeCfg ), .NumPorts ( NumPorts ), .noc_req_t ( noc_req_t ), .noc_resp_t ( noc_resp_t ) @@ -968,7 +977,6 @@ module cva6 import ariane_pkg::*; #( // not as important since this cache subsystem is about to be // deprecated .CVA6Cfg ( CVA6ExtendCfg ), - .ArianeCfg ( ArianeCfg ), .NumPorts ( NumPorts ), .axi_ar_chan_t ( axi_ar_chan_t ), .axi_aw_chan_t ( axi_aw_chan_t ), @@ -1086,7 +1094,7 @@ module cva6 import ariane_pkg::*; #( // ------------------- // pragma translate_off `ifndef VERILATOR - initial ariane_pkg::check_cfg(ArianeCfg); + initial config_pkg::check_cfg(CVA6Cfg); `endif // pragma translate_on diff --git a/core/decoder.sv b/core/decoder.sv index d2d80eb4a11..038d9602846 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -577,7 +577,7 @@ module decoder import ariane_pkg::*; #( end endcase end - if (CVA6Cfg.RCONDEXT) begin + if (CVA6Cfg.ZiCondExtEn) begin unique case ({instr.rtype.funct7, instr.rtype.funct3}) //Conditional move {7'b000_0111, 3'b101}: instruction_o.op = ariane_pkg::CZERO_EQZ; // czero.eqz @@ -587,7 +587,8 @@ module decoder import ariane_pkg::*; #( end endcase end - unique case ({ariane_pkg::BITMANIP, CVA6Cfg.RCONDEXT}) + //VCS coverage on + unique case ({ariane_pkg::BITMANIP, CVA6Cfg.ZiCondExtEn}) 2'b00 : illegal_instr = illegal_instr_non_bm; 2'b01 : illegal_instr = illegal_instr_non_bm & illegal_instr_zic; 2'b10 : illegal_instr = illegal_instr_non_bm & illegal_instr_bm; diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 05dda566e62..28df9a7cc96 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -16,8 +16,7 @@ module ex_stage import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter int unsigned ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int unsigned ASID_WIDTH = 1 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -304,8 +303,7 @@ module ex_stage import ariane_pkg::*; #( load_store_unit #( .CVA6Cfg ( CVA6Cfg ), - .ASID_WIDTH ( ASID_WIDTH ), - .ArianeCfg ( ArianeCfg ) + .ASID_WIDTH ( ASID_WIDTH ) ) lsu_i ( .clk_i, .rst_ni, diff --git a/core/frontend/frontend.sv b/core/frontend/frontend.sv index 22b69dd6c3a..bcb6e286d81 100644 --- a/core/frontend/frontend.sv +++ b/core/frontend/frontend.sv @@ -16,8 +16,7 @@ // change request from the back-end and does branch prediction. module frontend import ariane_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -354,7 +353,7 @@ module frontend import ariane_pkg::*; #( end // 7. Debug // enter debug on a hard-coded base-address - if (set_debug_pc_i) npc_d = ArianeCfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.HaltAddress[riscv::VLEN-1:0]; + if (set_debug_pc_i) npc_d = CVA6Cfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.HaltAddress[riscv::VLEN-1:0]; icache_dreq_o.vaddr = fetch_address; end @@ -396,12 +395,12 @@ module frontend import ariane_pkg::*; #( end end - if (ArianeCfg.RASDepth == 0) begin + if (CVA6Cfg.RASDepth == 0) begin assign ras_predict = '0; end else begin : ras_gen ras #( .CVA6Cfg ( CVA6Cfg ), - .DEPTH ( ArianeCfg.RASDepth ) + .DEPTH ( CVA6Cfg.RASDepth ) ) i_ras ( .clk_i, .rst_ni, @@ -418,12 +417,12 @@ module frontend import ariane_pkg::*; #( //and can be read at the same cycle. assign vpc_btb = (ariane_pkg::FPGA_EN) ? icache_dreq_i.vaddr : icache_vaddr_q; - if (ArianeCfg.BTBEntries == 0) begin + if (CVA6Cfg.BTBEntries == 0) begin assign btb_prediction = '0; end else begin : btb_gen btb #( .CVA6Cfg ( CVA6Cfg ), - .NR_ENTRIES ( ArianeCfg.BTBEntries ) + .NR_ENTRIES ( CVA6Cfg.BTBEntries ) ) i_btb ( .clk_i, .rst_ni, @@ -435,12 +434,12 @@ module frontend import ariane_pkg::*; #( ); end - if (ArianeCfg.BHTEntries == 0) begin + if (CVA6Cfg.BHTEntries == 0) begin assign bht_prediction = '0; end else begin : bht_gen bht #( .CVA6Cfg ( CVA6Cfg ), - .NR_ENTRIES ( ArianeCfg.BHTEntries ) + .NR_ENTRIES ( CVA6Cfg.BHTEntries ) ) i_bht ( .clk_i, .rst_ni, diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 244f9aa5741..8a3af5a8b15 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -23,104 +23,11 @@ `include "l15.tmp.h" `endif +/// This package contains `functions` and global defines for CVA6. +/// *Note*: There are some parameters here as well which will eventually be +/// moved out to favour a fully parameterizable core. package ariane_pkg; - localparam NrMaxRules = 16; - typedef struct packed { - int RASDepth; - int BTBEntries; - int BHTEntries; - // PMAs - int unsigned NrNonIdempotentRules; // Number of non idempotent rules - logic [NrMaxRules-1:0][63:0] NonIdempotentAddrBase; // base which needs to match - logic [NrMaxRules-1:0][63:0] NonIdempotentLength; // bit mask which bits to consider when matching the rule - int unsigned NrExecuteRegionRules; // Number of regions which have execute property - logic [NrMaxRules-1:0][63:0] ExecuteRegionAddrBase; // base which needs to match - logic [NrMaxRules-1:0][63:0] ExecuteRegionLength; // bit mask which bits to consider when matching the rule - int unsigned NrCachedRegionRules; // Number of regions which have cached property - logic [NrMaxRules-1:0][63:0] CachedRegionAddrBase; // base which needs to match - logic [NrMaxRules-1:0][63:0] CachedRegionLength; // bit mask which bits to consider when matching the rule - // cache config - bit AxiCompliant; // set to 1 when using in conjunction with 64bit AXI bus adapter - bit SwapEndianess; // set to 1 to swap endianess inside L1.5 openpiton adapter - // - logic [63:0] DmBaseAddress; // offset of the debug module - int unsigned NrPMPEntries; // Number of PMP entries - } ariane_cfg_t; - - localparam ariane_cfg_t ArianeDefaultConfig = '{ - RASDepth: int'(cva6_config_pkg::CVA6ConfigRASDepth), - BTBEntries: int'(cva6_config_pkg::CVA6ConfigBTBEntries), - BHTEntries: int'(cva6_config_pkg::CVA6ConfigBHTEntries), - // idempotent region - NrNonIdempotentRules: unsigned'(2), - NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), - NonIdempotentLength: 1024'({64'b0, 64'b0}), - NrExecuteRegionRules: unsigned'(3), - // DRAM, Boot ROM, Debug Module - ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), - ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), - // cached region - NrCachedRegionRules: unsigned'(1), - CachedRegionAddrBase: 1024'({64'h8000_0000}), - CachedRegionLength: 1024'({64'h40000000}), - // cache config - AxiCompliant: 1'b1, - SwapEndianess: 1'b0, - // debug - DmBaseAddress: 64'h0, - NrPMPEntries: unsigned'(cva6_config_pkg::CVA6ConfigNrPMPEntries) - }; - - // Function being called to check parameters - function automatic void check_cfg (ariane_cfg_t Cfg); - // pragma translate_off - `ifndef VERILATOR - assert(Cfg.RASDepth > 0); - assert(2**$clog2(Cfg.BTBEntries) == Cfg.BTBEntries); - assert(2**$clog2(Cfg.BHTEntries) == Cfg.BHTEntries); - assert(Cfg.NrNonIdempotentRules <= NrMaxRules); - assert(Cfg.NrExecuteRegionRules <= NrMaxRules); - assert(Cfg.NrCachedRegionRules <= NrMaxRules); - assert(Cfg.NrPMPEntries <= 16); - `endif - // pragma translate_on - endfunction - - function automatic logic range_check(logic[63:0] base, logic[63:0] len, logic[63:0] address); - // if len is a power of two, and base is properly aligned, this check could be simplified - // Extend base by one bit to prevent an overflow. - return (address >= base) && (({1'b0, address}) < (65'(base)+len)); - endfunction : range_check - - function automatic logic is_inside_nonidempotent_regions (ariane_cfg_t Cfg, logic[63:0] address); - logic[NrMaxRules-1:0] pass; - pass = '0; - for (int unsigned k = 0; k < Cfg.NrNonIdempotentRules; k++) begin - pass[k] = range_check(Cfg.NonIdempotentAddrBase[k], Cfg.NonIdempotentLength[k], address); - end - return |pass; - endfunction : is_inside_nonidempotent_regions - - function automatic logic is_inside_execute_regions (ariane_cfg_t Cfg, logic[63:0] address); - // if we don't specify any region we assume everything is accessible - logic[NrMaxRules-1:0] pass; - pass = '0; - for (int unsigned k = 0; k < Cfg.NrExecuteRegionRules; k++) begin - pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address); - end - return |pass; - endfunction : is_inside_execute_regions - - function automatic logic is_inside_cacheable_regions (ariane_cfg_t Cfg, logic[63:0] address); - automatic logic[NrMaxRules-1:0] pass; - pass = '0; - for (int unsigned k = 0; k < Cfg.NrCachedRegionRules; k++) begin - pass[k] = range_check(Cfg.CachedRegionAddrBase[k], Cfg.CachedRegionLength[k], address); - end - return |pass; - endfunction : is_inside_cacheable_regions - // TODO: Slowly move those parameters to the new system. localparam NR_SB_ENTRIES = cva6_config_pkg::CVA6ConfigNrScoreboardEntries; // number of scoreboard entries localparam TRANS_ID_BITS = $clog2(NR_SB_ENTRIES); // depending on the number of scoreboard entries we need that many bits diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 68c34d0f004..ceea6a03b3d 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -15,8 +15,26 @@ package config_pkg; localparam int unsigned ILEN = 32; localparam int unsigned NRET = 1; + /// The NoC type is a top-level parameter, hence we need a bit more + /// information on what protocol those type parameters are supporting. + /// Currently two values are supported" + typedef enum { + /// The "classic" AXI4 protocol. + NOC_TYPE_AXI4_ATOP, + /// In the OpenPiton setting the WT cache is connected to the L15. + NOC_TYPE_L15_BIG_ENDIAN, + NOC_TYPE_L15_LITTLE_ENDIAN + } noc_type_e; + + localparam NrMaxRules = 16; + typedef struct packed { + /// Number of commit ports, i.e., maximum number of instructions that the + /// core can retire per cycle. It can be beneficial to have more commit + /// ports than issue ports, for the scoreboard to empty out in case one + /// instruction stalls a little longer. int unsigned NrCommitPorts; + /// AXI parameters. int unsigned AxiAddrWidth; int unsigned AxiDataWidth; int unsigned AxiIdWidth; @@ -32,7 +50,7 @@ package config_pkg; bit RVZCB; bit XFVec; bit CvxifEn; - bit RCONDEXT; + bit ZiCondExtEn; // Calculated bit RVF; bit RVD; @@ -50,77 +68,147 @@ package config_pkg; // address to which a hart should jump when it was requested to halt logic [63:0] HaltAddress; logic [63:0] ExceptionAddress; + /// Return address stack depth, good values are around 2 to 4. + int unsigned RASDepth; + /// Branch target buffer entries. + int unsigned BTBEntries; + /// Branch history (2-bit saturation counter) size, to keep track of + /// branch otucomes. + int unsigned BHTEntries; + /// Offset of the debug module. + logic [63:0] DmBaseAddress; + /// Number of PMP entries. + int unsigned NrPMPEntries; + /// Set to the bus type in use. + noc_type_e NOCType; + /// Physical Memory Attributes (PMAs) + /// Number of non idempotent rules. + int unsigned NrNonIdempotentRules; + /// Base which needs to match. + logic [NrMaxRules-1:0][63:0] NonIdempotentAddrBase; + /// Bit mask which bits to consider when matching the rule. + logic [NrMaxRules-1:0][63:0] NonIdempotentLength; + /// Number of regions which have execute property. + int unsigned NrExecuteRegionRules; + /// Base which needs to match. + logic [NrMaxRules-1:0][63:0] ExecuteRegionAddrBase; + /// Bit mask which bits to consider when matching the rule. + logic [NrMaxRules-1:0][63:0] ExecuteRegionLength; + /// Number of regions which have cached property. + int unsigned NrCachedRegionRules; + /// Base which needs to match. + logic [NrMaxRules-1:0][63:0] CachedRegionAddrBase; + /// Bit mask which bits to consider when matching the rule. + logic [NrMaxRules-1:0][63:0] CachedRegionLength; } cva6_cfg_t; - localparam cva6_cfg_t cva6_cfg_default = { - unsigned'(1), // NrCommitPorts - unsigned'(64), // AxiAddrWidth - unsigned'(64), // AxiDataWidth - unsigned'(4), // AxiIdWidth - unsigned'(32), // AxiUserWidth - unsigned'(2), // NrLoadBufEntries - bit'(0), // FpuEn - bit'(0), // XF16 - bit'(0), // XF16ALT - bit'(0), // XF8 - bit'(0), // RVA - bit'(0), // RVV - bit'(1), // RVC - bit'(0), // RVZCB - bit'(0), // XFVec - bit'(1), // CvxifEn - bit'(0), // EnableZiCond + localparam cva6_cfg_t cva6_cfg_default = '{ + NrCommitPorts: unsigned'(1), + AxiAddrWidth: unsigned'(64), + AxiDataWidth: unsigned'(64), + AxiIdWidth: unsigned'(4), + AxiUserWidth: unsigned'(32), + NrLoadBufEntries: unsigned'(2), + FpuEn: bit'(0), + XF16: bit'(0), + XF16ALT: bit'(0), + XF8: bit'(0), + RVA: bit'(0), + RVV: bit'(0), + RVC: bit'(1), + RVZCB: bit'(1), + XFVec: bit'(0), + CvxifEn: bit'(1), + ZiCondExtEn: bit'(0), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: 2, + BTBEntries: 32, + BHTEntries: 128, + DmBaseAddress: 64'h0, + NrPMPEntries: 8, + NOCType: NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; - localparam cva6_cfg_t cva6_cfg_empty = { - unsigned'(0), // NrCommitPorts - unsigned'(0), // AxiAddrWidth - unsigned'(0), // AxiDataWidth - unsigned'(0), // AxiIdWidth - unsigned'(0), // AxiUserWidth - unsigned'(0), // NrLoadBufEntries - bit'(0), // FpuEn - bit'(0), // XF16 - bit'(0), // XF16ALT - bit'(0), // XF8 - bit'(0), // RVA - bit'(0), // RVV - bit'(0), // RVC - bit'(0), // RVZCB - bit'(0), // XFVec - bit'(0), // CvxifEn - bit'(0), // EnableZiCond - // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h0, // HaltAddress - 64'h0 // ExceptionAddress - } ; + /// Empty configuration to sanity check proper parameter passing. Whenever + /// you develop a module that resides within the core, assign this constant. + localparam cva6_cfg_t cva6_cfg_empty = '0; + + + /// Utility function being called to check parameters. Not all values make + /// sense for all parameters, here is the place to sanity check them. + function automatic void check_cfg (cva6_cfg_t Cfg); + // pragma translate_off + `ifndef VERILATOR + assert(Cfg.RASDepth > 0); + assert(2**$clog2(Cfg.BTBEntries) == Cfg.BTBEntries); + assert(2**$clog2(Cfg.BHTEntries) == Cfg.BHTEntries); + assert(Cfg.NrNonIdempotentRules <= NrMaxRules); + assert(Cfg.NrExecuteRegionRules <= NrMaxRules); + assert(Cfg.NrCachedRegionRules <= NrMaxRules); + assert(Cfg.NrPMPEntries <= 16); + `endif + // pragma translate_on + endfunction + + function automatic logic range_check(logic[63:0] base, logic[63:0] len, logic[63:0] address); + // if len is a power of two, and base is properly aligned, this check could be simplified + // Extend base by one bit to prevent an overflow. + return (address >= base) && (({1'b0, address}) < (65'(base)+len)); + endfunction : range_check + + + function automatic logic is_inside_nonidempotent_regions (cva6_cfg_t Cfg, logic[63:0] address); + logic[NrMaxRules-1:0] pass; + pass = '0; + for (int unsigned k = 0; k < Cfg.NrNonIdempotentRules; k++) begin + pass[k] = range_check(Cfg.NonIdempotentAddrBase[k], Cfg.NonIdempotentLength[k], address); + end + return |pass; + endfunction : is_inside_nonidempotent_regions + + function automatic logic is_inside_execute_regions (cva6_cfg_t Cfg, logic[63:0] address); + // if we don't specify any region we assume everything is accessible + logic[NrMaxRules-1:0] pass; + pass = '0; + for (int unsigned k = 0; k < Cfg.NrExecuteRegionRules; k++) begin + pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address); + end + return |pass; + endfunction : is_inside_execute_regions + function automatic logic is_inside_cacheable_regions (cva6_cfg_t Cfg, logic[63:0] address); + automatic logic[NrMaxRules-1:0] pass; + pass = '0; + for (int unsigned k = 0; k < Cfg.NrCachedRegionRules; k++) begin + pass[k] = range_check(Cfg.CachedRegionAddrBase[k], Cfg.CachedRegionLength[k], address); + end + return |pass; + endfunction : is_inside_cacheable_regions endpackage diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index 704c47fac5d..711947a4759 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -77,39 +77,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv32a6_embedded_config_pkg.sv b/core/include/cv32a6_embedded_config_pkg.sv index 632b84fdcf3..155d9db22f4 100644 --- a/core/include/cv32a6_embedded_config_pkg.sv +++ b/core/include/cv32a6_embedded_config_pkg.sv @@ -76,40 +76,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn - + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index 0b682d618c4..35a51f5bf50 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -77,39 +77,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index d2b18d872f1..20d4bde6a0b 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -77,39 +77,56 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; - + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index 4aaf594a15f..ce8da998b12 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -77,39 +77,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index 5f29230bc68..6d4cafdd494 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -77,39 +77,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv index a2ad61c8f4e..d3f2e40d9fe 100644 --- a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv +++ b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv @@ -76,39 +76,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_L15_BIG_ENDIAN, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index 5b6aa7a8777..510f643a972 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -77,39 +77,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // RCONDEXT + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress // EnableAccelerator - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 9f22771dc55..1e4d66a0e17 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -77,39 +77,57 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_L15_BIG_ENDIAN, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index 79cdf49d7d3..dc505c8a67b 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -76,39 +76,56 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; - localparam config_pkg::cva6_cfg_t cva6_cfg = { - unsigned'(CVA6ConfigNrCommitPorts), // NrCommitPorts - unsigned'(CVA6ConfigAxiAddrWidth), // AxiAddrWidth - unsigned'(CVA6ConfigAxiDataWidth), // AxiDataWidth - unsigned'(CVA6ConfigAxiIdWidth), // AxiIdWidth - unsigned'(CVA6ConfigDataUserWidth), // AxiUserWidth - unsigned'(CVA6ConfigNrLoadBufEntries), // NrLoadBufEntries - bit'(CVA6ConfigFpuEn), // FpuEn - bit'(CVA6ConfigF16En), // XF16 - bit'(CVA6ConfigF16AltEn), // XF16ALT - bit'(CVA6ConfigF8En), // XF8 - bit'(CVA6ConfigAExtEn), // RVA - bit'(CVA6ConfigVExtEn), // RVV - bit'(CVA6ConfigCExtEn), // RVC - bit'(CVA6ConfigZcbExtEn), // RVZCB - bit'(CVA6ConfigFVecEn), // XFVec - bit'(CVA6ConfigCvxifEn), // CvxifEn - bit'(CVA6ConfigZiCondExtEn), // ZiCondExtEn + localparam config_pkg::cva6_cfg_t cva6_cfg = '{ + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), + AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), + AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), + AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), + AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth), + NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries), + FpuEn: bit'(CVA6ConfigFpuEn), + XF16: bit'(CVA6ConfigF16En), + XF16ALT: bit'(CVA6ConfigF16AltEn), + XF8: bit'(CVA6ConfigF8En), + RVA: bit'(CVA6ConfigAExtEn), + RVV: bit'(CVA6ConfigVExtEn), + RVC: bit'(CVA6ConfigCExtEn), + RVZCB: bit'(CVA6ConfigZcbExtEn), + XFVec: bit'(CVA6ConfigFVecEn), + CvxifEn: bit'(CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), // Extended - bit'(0), // RVF - bit'(0), // RVD - bit'(0), // FpPresent - bit'(0), // NSX - unsigned'(0), // FLen - bit'(0), // RVFVec - bit'(0), // XF16Vec - bit'(0), // XF16ALTVec - bit'(0), // XF8Vec - unsigned'(0), // NrRgprPorts - unsigned'(0), // NrWbPorts - bit'(0), // EnableAccelerator - 64'h800, // HaltAddress - 64'h808 // ExceptionAddress - } ; - + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: 64'h800, + ExceptionAddress: 64'h808, + RASDepth: unsigned'(CVA6ConfigRASDepth), + BTBEntries: unsigned'(CVA6ConfigBTBEntries), + BHTEntries: unsigned'(CVA6ConfigBHTEntries), + DmBaseAddress: 64'h0, + NrPMPEntries: unsigned'(CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(2), + NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), + NonIdempotentLength: 1024'({64'b0, 64'b0}), + NrExecuteRegionRules: unsigned'(3), + // DRAM, Boot ROM, Debug Module + ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), + ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({64'h8000_0000}), + CachedRegionLength: 1024'({64'h40000000}) + }; endpackage diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index 587ae11ea88..77360aac78f 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -457,6 +457,7 @@ package riscv; CSR_MARCHID = 12'hF12, CSR_MIMPID = 12'hF13, CSR_MHARTID = 12'hF14, + CSR_MCONFIGPTR = 12'hF15, CSR_MCYCLE = 12'hB00, CSR_MCYCLEH = 12'hB80, CSR_MINSTRET = 12'hB02, diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index ad96658ad7e..021761f34f9 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -15,8 +15,7 @@ module load_store_unit import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter int unsigned ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int unsigned ASID_WIDTH = 1 )( input logic clk_i, input logic rst_ni, @@ -144,8 +143,7 @@ module load_store_unit import ariane_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), .INSTR_TLB_ENTRIES ( ariane_pkg::INSTR_TLB_ENTRIES ), .DATA_TLB_ENTRIES ( ariane_pkg::DATA_TLB_ENTRIES ), - .ASID_WIDTH ( ASID_WIDTH ), - .ArianeCfg ( ArianeCfg ) + .ASID_WIDTH ( ASID_WIDTH ) ) i_cva6_mmu ( // misaligned bypass .misaligned_ex_i ( misaligned_exception ), @@ -174,8 +172,7 @@ module load_store_unit import ariane_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), .INSTR_TLB_ENTRIES ( ariane_pkg::INSTR_TLB_ENTRIES ), .DATA_TLB_ENTRIES ( ariane_pkg::DATA_TLB_ENTRIES ), - .ASID_WIDTH ( ASID_WIDTH ), - .ArianeCfg ( ArianeCfg ) + .ASID_WIDTH ( ASID_WIDTH ) ) i_cva6_mmu ( // misaligned bypass .misaligned_ex_i ( misaligned_exception ), @@ -289,8 +286,7 @@ module load_store_unit import ariane_pkg::*; #( // Load Unit // ------------------ load_unit #( - .CVA6Cfg ( CVA6Cfg ), - .ArianeCfg ( ArianeCfg ) + .CVA6Cfg ( CVA6Cfg ) ) i_load_unit ( .valid_i ( ld_valid_i ), .lsu_ctrl_i ( lsu_ctrl ), diff --git a/core/load_unit.sv b/core/load_unit.sv index 32085d533bb..e3ba945f451 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -19,8 +19,7 @@ // to the data cache module load_unit import ariane_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -176,7 +175,7 @@ module load_unit import ariane_pkg::*; #( logic not_commit_time; logic inflight_stores; logic stall_ni; - assign paddr_ni = is_inside_nonidempotent_regions(ArianeCfg, {dtlb_ppn_i,12'd0}); + assign paddr_ni = config_pkg::is_inside_nonidempotent_regions(CVA6Cfg, {dtlb_ppn_i,12'd0}); assign not_commit_time = commit_tran_id_i != lsu_ctrl_i.trans_id; assign inflight_stores = (!dcache_wbuffer_not_ni_i || !store_buffer_empty_i); assign stall_ni = (inflight_stores || not_commit_time) && paddr_ni; diff --git a/core/mmu_sv32/cva6_mmu_sv32.sv b/core/mmu_sv32/cva6_mmu_sv32.sv index 162bc20bb40..47c84bde50e 100644 --- a/core/mmu_sv32/cva6_mmu_sv32.sv +++ b/core/mmu_sv32/cva6_mmu_sv32.sv @@ -30,8 +30,7 @@ module cva6_mmu_sv32 import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned INSTR_TLB_ENTRIES = 2, parameter int unsigned DATA_TLB_ENTRIES = 2, - parameter int unsigned ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int unsigned ASID_WIDTH = 1 ) ( input logic clk_i, input logic rst_ni, @@ -198,8 +197,7 @@ module cva6_mmu_sv32 import ariane_pkg::*; #( cva6_ptw_sv32 #( .CVA6Cfg ( CVA6Cfg ), - .ASID_WIDTH ( ASID_WIDTH ), - .ArianeCfg ( ArianeCfg ) + .ASID_WIDTH ( ASID_WIDTH ) ) i_ptw ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -338,13 +336,13 @@ module cva6_mmu_sv32 import ariane_pkg::*; #( end // check for execute flag on memory - assign match_any_execute_region = ariane_pkg::is_inside_execute_regions(ArianeCfg, {{64-riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}); + assign match_any_execute_region = config_pkg::is_inside_execute_regions(CVA6Cfg, {{64-riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}); // Instruction fetch pmp #( .PLEN ( riscv::PLEN ), .PMP_LEN ( riscv::PLEN - 2 ), - .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) + .NR_ENTRIES ( CVA6Cfg.NrPMPEntries ) ) i_pmp_if ( .addr_i ( icache_areq_o.fetch_paddr ), .priv_lvl_i, @@ -486,7 +484,7 @@ module cva6_mmu_sv32 import ariane_pkg::*; #( pmp #( .PLEN ( riscv::PLEN ), .PMP_LEN ( riscv::PLEN - 2 ), - .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) + .NR_ENTRIES ( CVA6Cfg.NrPMPEntries ) ) i_pmp_data ( .addr_i ( lsu_paddr_o ), .priv_lvl_i ( ld_st_priv_lvl_i ), diff --git a/core/mmu_sv32/cva6_ptw_sv32.sv b/core/mmu_sv32/cva6_ptw_sv32.sv index 34fcb2f99a8..d1dda479363 100644 --- a/core/mmu_sv32/cva6_ptw_sv32.sv +++ b/core/mmu_sv32/cva6_ptw_sv32.sv @@ -28,8 +28,7 @@ module cva6_ptw_sv32 import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter int ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int ASID_WIDTH = 1 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -147,7 +146,7 @@ module cva6_ptw_sv32 import ariane_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), .PLEN ( riscv::PLEN ), .PMP_LEN ( riscv::PLEN - 2 ), - .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) + .NR_ENTRIES ( CVA6Cfg.NrPMPEntries ) ) i_pmp_ptw ( .addr_i ( ptw_pptr_q ), // PTW access are always checked as if in S-Mode... diff --git a/core/mmu_sv32/cva6_shared_tlb_sv32.sv b/core/mmu_sv32/cva6_shared_tlb_sv32.sv index 496f065012f..9d454bd44ee 100644 --- a/core/mmu_sv32/cva6_shared_tlb_sv32.sv +++ b/core/mmu_sv32/cva6_shared_tlb_sv32.sv @@ -21,8 +21,7 @@ module cva6_shared_tlb_sv32 import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int SHARED_TLB_DEPTH = 64, parameter int SHARED_TLB_WAYS = 2, - parameter int ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int ASID_WIDTH = 1 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low diff --git a/core/mmu_sv39/mmu.sv b/core/mmu_sv39/mmu.sv index b0d77daa64e..4937c078f34 100644 --- a/core/mmu_sv39/mmu.sv +++ b/core/mmu_sv39/mmu.sv @@ -19,8 +19,7 @@ module mmu import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned INSTR_TLB_ENTRIES = 4, parameter int unsigned DATA_TLB_ENTRIES = 4, - parameter int unsigned ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int unsigned ASID_WIDTH = 1 ) ( input logic clk_i, input logic rst_ni, @@ -145,8 +144,7 @@ module mmu import ariane_pkg::*; #( ptw #( .CVA6Cfg ( CVA6Cfg ), - .ASID_WIDTH ( ASID_WIDTH ), - .ArianeCfg ( ArianeCfg ) + .ASID_WIDTH ( ASID_WIDTH ) ) i_ptw ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -271,14 +269,14 @@ module mmu import ariane_pkg::*; #( end // check for execute flag on memory - assign match_any_execute_region = ariane_pkg::is_inside_execute_regions(ArianeCfg, {{64-riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}); + assign match_any_execute_region = config_pkg::is_inside_execute_regions(CVA6Cfg, {{64-riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}); // Instruction fetch pmp #( .CVA6Cfg ( CVA6Cfg ), .PLEN ( riscv::PLEN ), .PMP_LEN ( riscv::PLEN - 2 ), - .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) + .NR_ENTRIES ( CVA6Cfg.NrPMPEntries ) ) i_pmp_if ( .addr_i ( icache_areq_o.fetch_paddr ), .priv_lvl_i, @@ -427,7 +425,7 @@ module mmu import ariane_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), .PLEN ( riscv::PLEN ), .PMP_LEN ( riscv::PLEN - 2 ), - .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) + .NR_ENTRIES ( CVA6Cfg.NrPMPEntries ) ) i_pmp_data ( .addr_i ( lsu_paddr_o ), .priv_lvl_i ( ld_st_priv_lvl_i ), diff --git a/core/mmu_sv39/ptw.sv b/core/mmu_sv39/ptw.sv index e6c117155b8..7bf68bbda1b 100644 --- a/core/mmu_sv39/ptw.sv +++ b/core/mmu_sv39/ptw.sv @@ -17,8 +17,7 @@ module ptw import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter int ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig + parameter int ASID_WIDTH = 1 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -142,7 +141,7 @@ module ptw import ariane_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), .PLEN ( riscv::PLEN ), .PMP_LEN ( riscv::PLEN - 2 ), - .NR_ENTRIES ( ArianeCfg.NrPMPEntries ) + .NR_ENTRIES ( CVA6Cfg.NrPMPEntries ) ) i_pmp_ptw ( .addr_i ( ptw_pptr_q ), // PTW access are always checked as if in S-Mode... diff --git a/corev_apu/fpga/src/ariane_xilinx.sv b/corev_apu/fpga/src/ariane_xilinx.sv index 575cbf9275a..16f3add20e1 100644 --- a/corev_apu/fpga/src/ariane_xilinx.sv +++ b/corev_apu/fpga/src/ariane_xilinx.sv @@ -156,7 +156,58 @@ module ariane_xilinx ( // CVA6 config localparam bit IsRVFI = bit'(0); -localparam config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg; +// CVA6 Xilinx configuration +localparam config_pkg::cva6_cfg_t CVA6Cfg = '{ + NrCommitPorts: cva6_config_pkg::CVA6ConfigNrCommitPorts, + AxiAddrWidth: cva6_config_pkg::CVA6ConfigAxiAddrWidth, + AxiDataWidth: cva6_config_pkg::CVA6ConfigAxiDataWidth, + AxiIdWidth: cva6_config_pkg::CVA6ConfigAxiIdWidth, + AxiUserWidth: cva6_config_pkg::CVA6ConfigDataUserWidth, + NrLoadBufEntries: cva6_config_pkg::CVA6ConfigNrLoadBufEntries, + RASDepth: cva6_config_pkg::CVA6ConfigRASDepth, + BTBEntries: cva6_config_pkg::CVA6ConfigBTBEntries, + BHTEntries: cva6_config_pkg::CVA6ConfigBHTEntries, + FpuEn: bit'(cva6_config_pkg::CVA6ConfigFpuEn), + XF16: bit'(cva6_config_pkg::CVA6ConfigF16En), + XF16ALT: bit'(cva6_config_pkg::CVA6ConfigF16AltEn), + XF8: bit'(cva6_config_pkg::CVA6ConfigF8En), + RVA: bit'(cva6_config_pkg::CVA6ConfigAExtEn), + RVV: bit'(cva6_config_pkg::CVA6ConfigVExtEn), + RVC: bit'(cva6_config_pkg::CVA6ConfigCExtEn), + RVZCB: bit'(cva6_config_pkg::CVA6ConfigZcbExtEn), + XFVec: bit'(cva6_config_pkg::CVA6ConfigFVecEn), + CvxifEn: bit'(cva6_config_pkg::CVA6ConfigCvxifEn), + ZiCondExtEn: bit'(0), + RVF: bit'(0), + RVD: bit'(0), + FpPresent: bit'(0), + NSX: bit'(0), + FLen: unsigned'(0), + RVFVec: bit'(0), + XF16Vec: bit'(0), + XF16ALTVec: bit'(0), + XF8Vec: bit'(0), + NrRgprPorts: unsigned'(0), + NrWbPorts: unsigned'(0), + EnableAccelerator: bit'(0), + HaltAddress: dm::HaltAddress, + ExceptionAddress: dm::ExceptionAddress, + DmBaseAddress: ariane_soc::DebugBase, + NrPMPEntries: unsigned'(cva6_config_pkg::CVA6ConfigNrPMPEntries), + NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, + // idempotent region + NrNonIdempotentRules: unsigned'(1), + NonIdempotentAddrBase: 1024'({64'b0}), + NonIdempotentLength: 1024'({ariane_soc::DRAMBase}), + NrExecuteRegionRules: unsigned'(3), + ExecuteRegionAddrBase: 1024'({ariane_soc::DRAMBase, ariane_soc::ROMBase, ariane_soc::DebugBase}), + ExecuteRegionLength: 1024'({ariane_soc::DRAMLength, ariane_soc::ROMLength, ariane_soc::DebugLength}), + // cached region + NrCachedRegionRules: unsigned'(1), + CachedRegionAddrBase: 1024'({ariane_soc::DRAMBase}), + CachedRegionLength: 1024'({ariane_soc::DRAMLength}) +}; + localparam type rvfi_instr_t = logic; @@ -705,8 +756,7 @@ ariane_axi::resp_t axi_ariane_resp; ariane #( .CVA6Cfg ( CVA6Cfg ), .IsRVFI ( IsRVFI ), - .rvfi_instr_t ( rvfi_instr_t ), - .ArianeCfg ( ariane_soc::ArianeSocCfg ) + .rvfi_instr_t ( rvfi_instr_t ) ) i_ariane ( .clk_i ( clk ), .rst_ni ( ndmreset_n ), @@ -715,6 +765,7 @@ ariane #( .irq_i ( irq ), .ipi_i ( ipi ), .time_irq_i ( timer_irq ), + .rvfi_o ( /* open */ ), .debug_req_i ( debug_req_irq ), .noc_req_o ( axi_ariane_req ), .noc_resp_i ( axi_ariane_resp ) diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index 6a0327bf760..e45fc1df490 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -17,8 +17,6 @@ module ariane import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter bit IsRVFI = bit'(0), parameter type rvfi_instr_t = logic, - // - parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig, parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth, parameter int unsigned AxiDataWidth = ariane_axi::DataWidth, parameter int unsigned AxiIdWidth = ariane_axi::IdWidth, @@ -55,8 +53,6 @@ module ariane import ariane_pkg::*; #( .CVA6Cfg ( CVA6Cfg ), .IsRVFI ( IsRVFI ), .rvfi_instr_t ( rvfi_instr_t ), - // - .ArianeCfg ( ArianeCfg ), .axi_ar_chan_t (axi_ar_chan_t), .axi_aw_chan_t (axi_aw_chan_t), .axi_w_chan_t (axi_w_chan_t), diff --git a/corev_apu/tb/ariane_soc_pkg.sv b/corev_apu/tb/ariane_soc_pkg.sv index eca485c7db1..fedf95004aa 100644 --- a/corev_apu/tb/ariane_soc_pkg.sv +++ b/corev_apu/tb/ariane_soc_pkg.sv @@ -69,27 +69,4 @@ package ariane_soc; localparam NrRegion = 1; localparam logic [NrRegion-1:0][NB_PERIPHERALS-1:0] ValidRule = {{NrRegion * NB_PERIPHERALS}{1'b1}}; - localparam ariane_pkg::ariane_cfg_t ArianeSocCfg = '{ - RASDepth: int'(cva6_config_pkg::CVA6ConfigRASDepth), - BTBEntries: int'(cva6_config_pkg::CVA6ConfigBTBEntries), - BHTEntries: int'(cva6_config_pkg::CVA6ConfigBHTEntries), - // idempotent region - NrNonIdempotentRules: unsigned'(1), - NonIdempotentAddrBase: 1024'({64'b0}), - NonIdempotentLength: 1024'({DRAMBase}), - NrExecuteRegionRules: unsigned'(3), - ExecuteRegionAddrBase: 1024'({DRAMBase, ROMBase, DebugBase}), - ExecuteRegionLength: 1024'({DRAMLength, ROMLength, DebugLength}), - // cached region - NrCachedRegionRules: unsigned'(1), - CachedRegionAddrBase: 1024'({DRAMBase}), - CachedRegionLength: 1024'({DRAMLength}), - // cache config - AxiCompliant: 1'b1, - SwapEndianess: 1'b0, - // debug - DmBaseAddress: DebugBase, - NrPMPEntries: unsigned'(cva6_config_pkg::CVA6ConfigNrPMPEntries) - }; - endpackage diff --git a/corev_apu/tb/ariane_tb.cpp b/corev_apu/tb/ariane_tb.cpp index a9805ee0b9c..d2339501783 100644 --- a/corev_apu/tb/ariane_tb.cpp +++ b/corev_apu/tb/ariane_tb.cpp @@ -338,7 +338,7 @@ int main(int argc, char **argv) { size_t mem_size = 0xFFFFFF; #if (VERILATOR_VERSION_INTEGER >= 5000000) // Verilator v5: Use rootp pointer and .data() accessor. - memif.read(0x80000000, mem_size, (void *)top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram.data()); + memif.read(0x80000000, mem_size, (void *)top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram.m_storage); #else // Verilator v4 memif.read(0x80000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram); diff --git a/corev_apu/tb/ariane_testharness.sv b/corev_apu/tb/ariane_testharness.sv index 568d3433456..b0cbe2e7f39 100644 --- a/corev_apu/tb/ariane_testharness.sv +++ b/corev_apu/tb/ariane_testharness.sv @@ -636,7 +636,6 @@ module ariane_testharness #( .CVA6Cfg ( CVA6Cfg ), .IsRVFI ( IsRVFI ), .rvfi_instr_t ( rvfi_instr_t ), - .ArianeCfg ( ariane_soc::ArianeSocCfg ), .noc_req_t ( ariane_axi::req_t ), .noc_resp_t ( ariane_axi::resp_t ) ) i_ariane ( diff --git a/corev_apu/tb/tb_cva6_icache/hdl/tb.sv b/corev_apu/tb/tb_cva6_icache/hdl/tb.sv index a697f759b78..c6a18698b07 100644 --- a/corev_apu/tb/tb_cva6_icache/hdl/tb.sv +++ b/corev_apu/tb/tb_cva6_icache/hdl/tb.sv @@ -37,30 +37,6 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); parameter logic [63:0] CachedAddrBeg = MemBytes/4; parameter logic [63:0] CachedAddrEnd = MemBytes; - localparam ariane_cfg_t Cfg = '{ - RASDepth: 2, - BTBEntries: 32, - BHTEntries: 128, - // idempotent region - NrNonIdempotentRules: 0, - NonIdempotentAddrBase: {64'b0}, - NonIdempotentLength: {64'b0}, - // executable region - NrExecuteRegionRules: 0, - ExecuteRegionAddrBase: {64'h0}, - ExecuteRegionLength: {64'h0}, - // cached region - NrCachedRegionRules: 1, - CachedRegionAddrBase: {CachedAddrBeg}, - CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1}, - // cache config - AxiCompliant: 1'b0, - SwapEndianess: 1'b0, - // debug - DmBaseAddress: 64'h0, - NrPMPEntries: 0 - }; - // rates are in percent parameter TlbRandHitRate = 50; parameter MemRandHitRate = 50; @@ -262,7 +238,7 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); /////////////////////////////////////////////////////////////////////////////// cva6_icache #( - .ArianeCfg(Cfg) + .CVA6Cfg(ariane_pkg::CVA6DefaultCfg) ) dut ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/corev_apu/tb/tb_wb_dcache/hdl/tb.sv b/corev_apu/tb/tb_wb_dcache/hdl/tb.sv index 262d669b19e..0b4550fec57 100644 --- a/corev_apu/tb/tb_wb_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wb_dcache/hdl/tb.sv @@ -31,30 +31,6 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()() parameter logic [63:0] CachedAddrBeg = MemBytes>>3;//1/8th of the memory is NC parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF; - localparam ariane_cfg_t ArianeDefaultConfig = '{ - RASDepth: 2, - BTBEntries: 32, - BHTEntries: 128, - // idempotent region - NrNonIdempotentRules: 0, - NonIdempotentAddrBase: {64'b0}, - NonIdempotentLength: {64'b0}, - // executable region - NrExecuteRegionRules: 0, - ExecuteRegionAddrBase: {64'h0}, - ExecuteRegionLength: {64'h0}, - // cached region - NrCachedRegionRules: 1, - CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC - CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1}, - // cache config - AxiCompliant: 1'b1, - SwapEndianess: 1'b0, - // debug - DmBaseAddress: 64'h0, - NrPMPEntries: 0 - }; - // contention and invalidation rates (in %) parameter MemRandHitRate = 75; parameter MemRandInvRate = 10; @@ -418,7 +394,7 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()() /////////////////////////////////////////////////////////////////////////////// std_nbdcache #( - .ArianeCfg ( ArianeDefaultConfig ), + .CVA6Cfg ( ArianeDefaultConfig ), .AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ), .AXI_DATA_WIDTH ( TbAxiDataWidthFull ), .AXI_ID_WIDTH ( TbAxiIdWidthFull ), diff --git a/corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv b/corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv index 5044c1811b9..edfb7b21121 100644 --- a/corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv @@ -376,32 +376,8 @@ module tb import ariane_pkg::*; import wt_cache_pkg::*; import tb_pkg::*; #()(); // MUT /////////////////////////////////////////////////////////////////////////////// - localparam ariane_cfg_t ArianeDefaultConfig = '{ - RASDepth: 2, - BTBEntries: 32, - BHTEntries: 128, - // idempotent region - NrNonIdempotentRules: 0, - NonIdempotentAddrBase: {64'b0}, - NonIdempotentLength: {64'b0}, - // executable region - NrExecuteRegionRules: 0, - ExecuteRegionAddrBase: {64'h0}, - ExecuteRegionLength: {64'h0}, - // cached region - NrCachedRegionRules: 1, - CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC - CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1}, - // cache config - AxiCompliant: 1'b1, - SwapEndianess: 1'b0, - // debug - DmBaseAddress: 64'h0, - NrPMPEntries: 0 - }; - wt_cache_subsystem #( - .ArianeCfg ( ArianeDefaultConfig ), + .CVA6Cfg ( ariane_pkg::CVA6DefaultCfg ), .AxiAddrWidth ( TbAxiAddrWidthFull ), .AxiDataWidth ( TbAxiDataWidthFull ), .AxiIdWidth ( TbAxiIdWidthFull ), diff --git a/corev_apu/tb/tb_wt_dcache/hdl/tb.sv b/corev_apu/tb/tb_wt_dcache/hdl/tb.sv index ed02b103ffc..031f89187d6 100644 --- a/corev_apu/tb/tb_wt_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wt_dcache/hdl/tb.sv @@ -38,30 +38,6 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); parameter logic [63:0] CachedAddrBeg = MemBytes>>3;//1/8th of the memory is NC parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF; - localparam ariane_cfg_t ArianeDefaultConfig = '{ - RASDepth: 2, - BTBEntries: 32, - BHTEntries: 128, - // idempotent region - NrNonIdempotentRules: 0, - NonIdempotentAddrBase: {64'b0}, - NonIdempotentLength: {64'b0}, - // executable region - NrExecuteRegionRules: 0, - ExecuteRegionAddrBase: {64'h0}, - ExecuteRegionLength: {64'h0}, - // cached region - NrCachedRegionRules: 1, - CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC - CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1}, - // cache config - AxiCompliant: 1'b1, - SwapEndianess: 1'b0, - // debug - DmBaseAddress: 64'h0, - NrPMPEntries: 0 - }; - // contention and invalidation rates (in %) parameter MemRandHitRate = 75; parameter MemRandInvRate = 10; @@ -226,7 +202,7 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); /////////////////////////////////////////////////////////////////////////////// wt_dcache #( - .ArianeCfg ( ArianeDefaultConfig ) + .CVA6Cfg ( ariane_pkg::CVA6DefaultCfg ) ) i_dut ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/docs/01_cva6_user/PMA.rst b/docs/01_cva6_user/PMA.rst index 75c247b062f..a01a5133358 100644 --- a/docs/01_cva6_user/PMA.rst +++ b/docs/01_cva6_user/PMA.rst @@ -39,18 +39,18 @@ supports three main access properties: load, and store data from that region. The regions are instantiation-time parameters, they can not be changed during -runtime. CVA6 uses the following fields in the ``ariane_cfg_t`` configuration +runtime. CVA6 uses the following fields in the ``cva6_cfg_t`` configuration structure to describe the PMA regions statically: -- ``ArianeCfg.NrNonIdempotentRules``: Number of active non-idempotent regions. - - ``ArianeCfg.NonIdempotentAddrBase``: Base address of the non-idempotent region. - - ``ArianeCfg.NonIdempotentLength``: Length of the non-idempotent region. -- ``ArianeCfg.NrExecuteRegionRules``: Number of active executable regions. - - ``ArianeCfg.ExecuteRegionAddrBase``: Base address of the executable region. - - ``ArianeCfg.ExecuteRegionLength``: Length of the executable region. -- ``ArianeCfg.NrCachedRegionRules``: Number of active cacheable regions. - - ``ArianeCfg.CachedRegionAddrBase``: Base address of the cacheable region. - - ``ArianeCfg.CachedRegionLength``: Length of the cacheable region. +- ``CVA6Cfg.NrNonIdempotentRules``: Number of active non-idempotent regions. + - ``CVA6Cfg.NonIdempotentAddrBase``: Base address of the non-idempotent region. + - ``CVA6Cfg.NonIdempotentLength``: Length of the non-idempotent region. +- ``CVA6Cfg.NrExecuteRegionRules``: Number of active executable regions. + - ``CVA6Cfg.ExecuteRegionAddrBase``: Base address of the executable region. + - ``CVA6Cfg.ExecuteRegionLength``: Length of the executable region. +- ``CVA6Cfg.NrCachedRegionRules``: Number of active cacheable regions. + - ``CVA6Cfg.CachedRegionAddrBase``: Base address of the cacheable region. + - ``CVA6Cfg.CachedRegionLength``: Length of the cacheable region. Unsupported PMAs ------- diff --git a/docs/01_cva6_user/PMP.rst b/docs/01_cva6_user/PMP.rst index a106522b317..02b3a5772eb 100644 --- a/docs/01_cva6_user/PMP.rst +++ b/docs/01_cva6_user/PMP.rst @@ -22,12 +22,12 @@ PMP === The CVA6 includes a Physical Memory Protection (PMP) unit. The PMP is both statically and dynamically configurable. The static configuration is performed -through the top level parameters ``ArianeCfg.NrPMPEntries``. The dynamic +through the top level parameters ``CVA6Cfg.NrPMPEntries``. The dynamic configuration is performed through the CSRs described in Control and Status Registers. A maximum of 16 PMP entries are supported. All PMP CSRs are always implemented, but CSRs (or bitfields of CSRs) related to -PMP entries with number ``ArianeCfg.NrPMPEntries`` and above are hardwired to +PMP entries with number ``CVA6Cfg.NrPMPEntries`` and above are hardwired to zero. All PMPs reset to zero. When the ``L`` (Lock) bit is set, PMPs are also enforced in M-mode. diff --git a/docs/03_cva6_design/ex_stage.md b/docs/03_cva6_design/ex_stage.md index 2aa98caa4ff..c3a083eb587 100644 --- a/docs/03_cva6_design/ex_stage.md +++ b/docs/03_cva6_design/ex_stage.md @@ -291,7 +291,7 @@ checked during the page table walk as well. During a page walk, all memory access must pass the PMP rules. The amount of entries is parametrizable under the -`ArianeCfg.NrPMPEntries` parameter. However, the core only supports +`CVA6Cfg.NrPMPEntries` parameter. However, the core only supports granularity 8 (G=8). This simplifies the implementation since we do not have to worry about any unaligned accesses. There are a total of three distinct PMP units in the design. They verify instruction diff --git a/docs/04_cv32a6_design/images/LZC.png b/docs/04_cv32a6_design/images/LZC.png new file mode 100644 index 00000000000..9fdae0cf18c Binary files /dev/null and b/docs/04_cv32a6_design/images/LZC.png differ diff --git a/docs/04_cv32a6_design/images/RR.png b/docs/04_cv32a6_design/images/RR.png new file mode 100644 index 00000000000..64922c853be Binary files /dev/null and b/docs/04_cv32a6_design/images/RR.png differ diff --git a/docs/04_cv32a6_design/images/cva6_tlb_entry.png b/docs/04_cv32a6_design/images/cva6_tlb_entry.png new file mode 100644 index 00000000000..cb691d6e877 Binary files /dev/null and b/docs/04_cv32a6_design/images/cva6_tlb_entry.png differ diff --git a/docs/04_cv32a6_design/images/cva6_tlb_hit.png b/docs/04_cv32a6_design/images/cva6_tlb_hit.png new file mode 100644 index 00000000000..d24b61e5c0d Binary files /dev/null and b/docs/04_cv32a6_design/images/cva6_tlb_hit.png differ diff --git a/docs/04_cv32a6_design/images/in_out_tlb.png b/docs/04_cv32a6_design/images/in_out_tlb.png new file mode 100644 index 00000000000..31858be9d8f Binary files /dev/null and b/docs/04_cv32a6_design/images/in_out_tlb.png differ diff --git a/docs/04_cv32a6_design/images/mmu_control_flow.png b/docs/04_cv32a6_design/images/mmu_control_flow.png new file mode 100644 index 00000000000..76609448180 Binary files /dev/null and b/docs/04_cv32a6_design/images/mmu_control_flow.png differ diff --git a/docs/04_cv32a6_design/images/mmu_in_out.png b/docs/04_cv32a6_design/images/mmu_in_out.png new file mode 100644 index 00000000000..ae98acbe596 Binary files /dev/null and b/docs/04_cv32a6_design/images/mmu_in_out.png differ diff --git a/docs/04_cv32a6_design/images/mmu_major_blocks.png b/docs/04_cv32a6_design/images/mmu_major_blocks.png new file mode 100644 index 00000000000..f320ce72413 Binary files /dev/null and b/docs/04_cv32a6_design/images/mmu_major_blocks.png differ diff --git a/docs/04_cv32a6_design/images/plru_tree_indexing.png b/docs/04_cv32a6_design/images/plru_tree_indexing.png new file mode 100644 index 00000000000..b7eb574ec45 Binary files /dev/null and b/docs/04_cv32a6_design/images/plru_tree_indexing.png differ diff --git a/docs/04_cv32a6_design/images/ptw_dptw.png b/docs/04_cv32a6_design/images/ptw_dptw.png new file mode 100644 index 00000000000..1050a5e519f Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_dptw.png differ diff --git a/docs/04_cv32a6_design/images/ptw_dptw_s.png b/docs/04_cv32a6_design/images/ptw_dptw_s.png new file mode 100644 index 00000000000..4ab2f879087 Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_dptw_s.png differ diff --git a/docs/04_cv32a6_design/images/ptw_idle.png b/docs/04_cv32a6_design/images/ptw_idle.png new file mode 100644 index 00000000000..9a84a853887 Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_idle.png differ diff --git a/docs/04_cv32a6_design/images/ptw_in_out.png b/docs/04_cv32a6_design/images/ptw_in_out.png new file mode 100644 index 00000000000..ab5aad7bbe3 Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_in_out.png differ diff --git a/docs/04_cv32a6_design/images/ptw_iptw.png b/docs/04_cv32a6_design/images/ptw_iptw.png new file mode 100644 index 00000000000..f3a1c184e90 Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_iptw.png differ diff --git a/docs/04_cv32a6_design/images/ptw_mis_sup.png b/docs/04_cv32a6_design/images/ptw_mis_sup.png new file mode 100644 index 00000000000..761399bd51f Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_mis_sup.png differ diff --git a/docs/04_cv32a6_design/images/ptw_nlvl.png b/docs/04_cv32a6_design/images/ptw_nlvl.png new file mode 100644 index 00000000000..1de2811465b Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_nlvl.png differ diff --git a/docs/04_cv32a6_design/images/ptw_pte_1.png b/docs/04_cv32a6_design/images/ptw_pte_1.png new file mode 100644 index 00000000000..7be987971dc Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_pte_1.png differ diff --git a/docs/04_cv32a6_design/images/ptw_pte_flowchart.png b/docs/04_cv32a6_design/images/ptw_pte_flowchart.png new file mode 100644 index 00000000000..0e4f2c3763b Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_pte_flowchart.png differ diff --git a/docs/04_cv32a6_design/images/ptw_state_diagram.png b/docs/04_cv32a6_design/images/ptw_state_diagram.png new file mode 100644 index 00000000000..1b8e18ed2b8 Binary files /dev/null and b/docs/04_cv32a6_design/images/ptw_state_diagram.png differ diff --git a/docs/04_cv32a6_design/images/replacement_entry.png b/docs/04_cv32a6_design/images/replacement_entry.png new file mode 100644 index 00000000000..a9d3a00f541 Binary files /dev/null and b/docs/04_cv32a6_design/images/replacement_entry.png differ diff --git a/docs/04_cv32a6_design/images/sfence_vaddr_asid.png b/docs/04_cv32a6_design/images/sfence_vaddr_asid.png new file mode 100644 index 00000000000..12c8363c1e4 Binary files /dev/null and b/docs/04_cv32a6_design/images/sfence_vaddr_asid.png differ diff --git a/docs/04_cv32a6_design/images/sfence_vaddr_x0.png b/docs/04_cv32a6_design/images/sfence_vaddr_x0.png new file mode 100644 index 00000000000..f185b8d775d Binary files /dev/null and b/docs/04_cv32a6_design/images/sfence_vaddr_x0.png differ diff --git a/docs/04_cv32a6_design/images/sfence_x0_asid.png b/docs/04_cv32a6_design/images/sfence_x0_asid.png new file mode 100644 index 00000000000..6324be4678d Binary files /dev/null and b/docs/04_cv32a6_design/images/sfence_x0_asid.png differ diff --git a/docs/04_cv32a6_design/images/sfence_x0_x0.png b/docs/04_cv32a6_design/images/sfence_x0_x0.png new file mode 100644 index 00000000000..3c5c857665f Binary files /dev/null and b/docs/04_cv32a6_design/images/sfence_x0_x0.png differ diff --git a/docs/04_cv32a6_design/images/shared_tlb.png b/docs/04_cv32a6_design/images/shared_tlb.png new file mode 100644 index 00000000000..364cbaf87ef Binary files /dev/null and b/docs/04_cv32a6_design/images/shared_tlb.png differ diff --git a/docs/04_cv32a6_design/images/shared_tlb_in_out.png b/docs/04_cv32a6_design/images/shared_tlb_in_out.png new file mode 100644 index 00000000000..3073acfae5d Binary files /dev/null and b/docs/04_cv32a6_design/images/shared_tlb_in_out.png differ diff --git a/docs/04_cv32a6_design/images/shared_tlb_set.png b/docs/04_cv32a6_design/images/shared_tlb_set.png new file mode 100644 index 00000000000..a892af99494 Binary files /dev/null and b/docs/04_cv32a6_design/images/shared_tlb_set.png differ diff --git a/docs/04_cv32a6_design/images/update_tree.png b/docs/04_cv32a6_design/images/update_tree.png new file mode 100644 index 00000000000..6b41dd2f38b Binary files /dev/null and b/docs/04_cv32a6_design/images/update_tree.png differ diff --git a/docs/04_cv32a6_design/source/cv32a6_execute.rst b/docs/04_cv32a6_design/source/cv32a6_execute.rst new file mode 100644 index 00000000000..092cb3257ba --- /dev/null +++ b/docs/04_cv32a6_design/source/cv32a6_execute.rst @@ -0,0 +1,1613 @@ +.. _CV32A6_EXECUTE: + +############## +Execute Module +############## + +*********** +Description +*********** + +************* +Functionality +************* + +*************************** +Architecture and Submodules +*************************** + +ALU +=== + +Branch Unit +=========== + +Load Store Unit (LSU) +===================== + +---------------------- +Memory Management Unit +---------------------- + +The Memory Management Unit (MMU) SV32 module is a crucial component in the RISC-V-based processor, serving as the backbone for virtual memory management and address translation. + +.. figure:: ../images/mmu_in_out.png + :name: **Figure 1:** Inputs and Outputs of CVA6 MMU SV32 + :align: center + :width: 70% + :alt: mmu_in_out + + **Figure 1:** Inputs and Outputs of CVA6 MMU SV32 + +At its core, the MMU SV32 plays a pivotal role in translating virtual addresses into their corresponding physical counterparts. This translation process is paramount for providing memory protection, isolation, and efficient memory management in modern computer systems. Importantly, it handles both instruction and data accesses, ensuring a seamless interaction between the processor and virtual memory. Within the MMU, several major blocks play pivotal roles in this address translation process. These includes: + +* Instruction TLB (ITLB) +* Data TLB (DTLB) +* Shared TLB +* Page Table Walker (PTW) + +.. figure:: ../images/mmu_major_blocks.png + :name: **Figure 2:** Major Blocks in CVA6 MMU SV32 + :align: center + :width: 60% + :alt: mmu_major_blocks + + **Figure 2:** Major Blocks in CVA6 MMU SV32 + +The MMU SV32 manages privilege levels and access control, enforcing permissions for user and supervisor modes while handling access exceptions. It employs Translation Lookaside Buffers (TLBs) for efficient address translation, reducing the need for page table access. TLB hits yield quick translations, but on misses, the shared TLB is consulted, and if necessary, the Page Table Walker (PTW) performs page table walks, updating TLBs and managing exceptions during the process. + +In addition to these functionalities, the MMU SV32 seamlessly integrates support for Physical Memory Protection (PMP), enabling it to enforce access permissions and memory protection configurations as specified by the PMP settings. This additional layer of security and control enhances the management of memory accesses + +.. raw:: html + + Instruction and Data Interfaces + +The MMU SV32 maintains interfaces with the instruction cache (ICache) and the load-store unit (LSU). It receives virtual addresses from these components and proceeds to translate them into physical addresses, a fundamental task for ensuring proper program execution and memory access. + +.. raw:: html + + Signal Description of MMU + +.. raw:: html + +
Table 1: CVA6 MMU SV32 Input Output Signals
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - Connection Type + - Type + - Description + + * - ``clk_i`` + - in + - Subsystem + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - Subsystem + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - Sfence Committed + + * - ``enable_translation_i`` + - in + - CSR RegFile + - logic + - Indicate address translation request for instruction + + * - ``en_ld_st_translation_i`` + - in + - CSR RegFile + - logic + - Indicate address translation request for load or store + + * - ``icache_areq_i`` + - in + - Cache Subsystem + - icache_arsp_t + - Icache Response + + * - ``icache_areq_o`` + - out + - Cache Subsystem + - icache_areq_t + - Icache Request + + * - ``misaligned_ex_i`` + - in + - Load Store Unit + - exception_t + - Indicate misaligned exception + + * - ``lsu_req_i`` + - in + - Load Store Unit + - logic + - Request address translation + + * - ``lsu_vaddr_i`` + - in + - Load Store Unit + - logic [riscv::VLEN-1:0] + - Virtual Address In + + * - ``lsu_is_store_i`` + - in + - Store Unit + - logic + - Translation is requested by a store + + * - ``lsu_dtlb_hit_o`` + - out + - Store / Load Unit + - logic + - Indicate a DTLB hit + + * - ``lsu_dtlb_ppn_o`` + - out + - Load Unit + - logic [riscv::PPNW-1:0] + - Send PNN to LSU + + * - ``lsu_valid_o`` + - out + - Load Store Unit + - logic + - Indicate a valid translation + + * - ``lsu_paddr_o`` + - out + - Store / Load Unit + - logic [riscv::PLEN-1:0] + - Translated Address + + * - ``lsu_exception_o`` + - out + - Store / Load Unit + - exception_t + - Address Translation threw an exception + + * - ``priv_lvl_i`` + - in + - CSR RegFile + - riscv::priv_lvl_t + - Privilege level for instruction fetch interface + + * - ``ld_st_priv_lvl_i`` + - in + - CSR RegFile + - riscv::priv_lvl_t + - Privilege Level for Data Interface + + * - ``sum_i`` + - in + - CSR RegFile + - logic + - Supervisor User Memory Access bit in xSTATUS CSR register + + * - ``mxr_i`` + - in + - CSR RegFile + - logic + - Make Executable Readable bit in xSTATUS CSR register + + * - ``satp_ppn_I`` + - in + - CSR RegFile + - logic [riscv::PPNW-1:0] + - PPN of top level page table from SATP register + + * - ``asid_i`` + - in + - CSR RegFile + - logic [ASID_WIDTH-1:0] + - ASID to for the lookup + + * - ``asid_to_be_flushed`` + - in + - Execute Stage + - logic [ASID_WIDTH-1:0] + - ASID of the entry to be flushed. + + * - ``vaddr_to_be_flushed_i`` + - in + - Execute Stage + - logic [riscv::VLEN-1:0] + - Virtual address of the entry to be flushed. + + * - ``flush_tlb_i`` + - in + - Controller + - logic + - SFENCE.VMA committed + + * - ``itlb_miss_o`` + - out + - Performance Counter + - logic + - Indicate an ITLB miss + + * - ``dtlb_miss_o`` + - out + - Performance Counter + - logic + - Indicate a DTLB miss + + * - ``req_port_i`` + - in + - Cache Subsystem + - dcache_req_o_t + - D Cache Data Requests + + * - ``req_port_o`` + - out + - Cache Subsystem + - dcache_req_i_t + - D Cache Data Response + + * - ``pmpcfg_i`` + - in + - CSR RegFile + - riscv::pmpcfg_t [15:0] + - PMP configurations + + * - ``pmpaddr_i`` + - in + - CSR RegFile + - logic [15:0][riscv::PLEN-3:0] + - PMP Address + +.. raw:: html + + Struct Description + +.. raw:: html + +Table 2: I Cache Request Struct (icache_areq_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``fetch_valid`` + - logic + - Address Translation Valid + + * - ``fetch_paddr`` + - logic [riscv::PLEN-1:0] + - Physical Address In + + * - ``fetch_exception`` + - exception_t + - Exception occurred during fetch + +.. raw:: html + +Table 3: I Cache Response Struct (icache_arsq_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``fetch_req`` + - logic + - Address Translation Request + + * - ``fetch_vaddr`` + - logic [riscv::VLEN-1:0] + - Virtual Address out + +.. raw:: html + +Table 4: Exception Struct (exception_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``cause`` + - riscv::xlen_t + - Cause of exception + + * - ``tval`` + - riscv::xlen_t + - Additional information of causing exception (e.g. instruction causing it), address of LD/ST fault + + * - ``valid`` + - logic + - Indicate that exception is valid + +.. raw:: html + +Table 5: PMP Configuration Struct (pmpcfg_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``locked`` + - logic + - Lock this configuration + + * - ``reserved`` + - logic[1:0] + - Reserved bits in pmpcfg CSR + + * - ``addr_mode`` + - pmp_addr_mode_t + - Addressing Modes: OFF, TOR, NA4, NAPOT + + * - ``access_type`` + - pmpcfg_access_t + - None, read, write, execute + +.. raw:: html + + Control Flow in MMU SV32 Module + +.. figure:: ../images/mmu_control_flow.png + :name: **Figure 3:** Control Flow in CVA6 MMU SV32 + :align: center + :width: 95% + :alt: mmu_control_flow + + **Figure 3:** Control Flow in CVA6 MMU SV32 + +.. raw:: html + + Exception Sources with Address Translation Enabled + +Two potential exception sources exist: + +* Hardware Page Table Walker (HPTW) throwing an exception, signifying a page fault exception. +* Access error due to insufficient permissions of PMP, known as an access exception. + +.. raw:: html + + Instruction Fetch Interface + +The IF stage initiates a request to retrieve memory content at a specific virtual address. When the MMU is disabled, the instruction fetch request is directly passed to the I$ without modifications. + +.. raw:: html + + Address Translation in Instruction Interface + +If virtual memory translation is enabled for instruction fetches, the following operations are performed in the instruction interface: + +* Compatibility of requested virtual address with selected page based address translation scheme is checked. +* For 4K page translation, the module determines the fetch physical address by combining the physical page number (PPN) from ITLB content and the offset from the virtual address. +* In the case of Mega page translation, if the ITLB indicates a 4M page, the VPN0 from the fetch virtual address is written to the PPN0 of the fetch physical address to ensure alignment for superpage translation. +* If the Instruction TLB (ITLB) lookup hits, the fetch valid signal (which indicates a valid physical address) is activated in response to the input fetch request. Memory region accessibility is checked from the perspective of the fetch operation, potentially triggering a page fault exception in case of an access error or insufficient PMP permission. +* In case of an ITLB miss, if the page table walker (PTW) is active (only active if there is a shared TLB miss) and handling instruction fetches, the fetch valid signal is determined based on PTW errors or access exceptions. + +If the fetch physical address doesn't match any execute region, an Instruction Access Fault is raised. When not translating, PMPs are immediately checked against the physical address for access verification. + +.. raw:: html + + Data Interface + +.. raw:: html + + Address Translation in Data Interface + +If address translation is enabled for load or store, and no misaligned exception has occurred, the following operations are performed in the data interface: + +* Initially, translation is assumed to be invalid, signified by the MMU to LSU. +* The translated physical address is formed by combining the PPN from the Page Table Entry (PTE) and the offset from the virtual address requiring translation. This send one cycle later due to the additional bank of registers which delayed the MMU’s answer. The PPN from the PTE is also shared separately with LSU in the same cycle as the hit. +* In the case of superpage translation, as in SV32, known as the 4M page, PPN0 of the translated physical address and the separately shared PPN are updated with the VPN0 of the virtual address. + +If a Data TLB (DTLB) hit occurs, it indicates a valid translation, and various fault checks are performed depending on whether it's a load or store request. + +* For store requests, if the page is not writable, the dirty flag isn't set, or privileges are violated, it results in a page fault corresponding to the store access. If PMPs are also violated, it leads to an access fault corresponding to the store access. Page faults take precedence over access faults. +* For load requests, a page fault is triggered if there are insufficient access privileges. PMPs are checked again during load access, resulting in an access fault corresponding to load access if PMPs are violated. + +In case of a DTLB miss, potential exceptions are monitored during the page table walk. If the PTW indicates a page fault, the corresponding page fault related to the requested type is signaled. If the PTW indicates an access exception, the load access fault is indicated through address translation because the page table walker can only throw load access faults. + +.. raw:: html + + Address Translation is Disabled + +When address translation is not enabled, the physical address is immediately checked against Physical Memory Protections (PMPs). If there is a request from LSU, no misaligned exception, and PMPs are violated, it results in an access fault corresponding to the request being indicated. + +---------------------------- +Translation Lookaside Buffer +---------------------------- + +Page tables are accessed for translating virtual memory addresses to physical memory addresses. This translation needs to be carried out for every load and store instruction and also for every instruction fetch. Since page tables are resident in physical memory, accessing these tables in all these situations has a significant impact on performance. Page table accesses occur in patterns that are closely related in time. Furthermore, the spatial and temporal locality of data accesses or instruction fetches mean that the same page is referenced repeatedly. Taking advantage of these access patterns the processor keeps the information of recent address translations, to enable fast retrieval, in a small cache called the Translation Lookaside Buffer (TLB) or an address-translation cache. + +The CVA6 TLB is structured as a fully associative cache, where the virtual address that needs to be translated is compared against all the individual TLB entries. Given a virtual address, the processor examines the TLB (TLB lookup) to determine if the virtual page number (VPN) of the page being accessed is in the TLB. When a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is used to calculate the target physical address. If no TLB entry is found (TLB miss) the processor has to read individual page table entries from memory (Table walk). In CVA6 table walking is supported by dedicated hardware. Once the processor finishes the table walk it has the Physical Page Number (PPN) corresponding to the Virtual Page Number (VPN) That needs to be translated. The processor adds an entry for this address translation to the TLB so future translations of that virtual address will happen quickly through the TLB. During the table walk the processor may find out that the corresponding physical page is not resident in memory. At this stage a page table exception (Page Fault) is generated which gets handled by the operating system. The operating system places the appropriate page in memory, updates the appropriate page tables and returns execution to the instruction which generated the exception. + +The inputs and output signals of the TLB are shown in the following two figures. + +.. figure:: ../images/in_out_tlb.png + :name: **Figure 4:** Inputs and Outputs of CVA6 TLB + :align: center + :width: 65% + :alt: in_out_tlb + + **Figure 4:** Inputs and Outputs of CVA6 TLB + +.. raw:: html + + Signal Description of TLB + +.. raw:: html + +Table 6: CVA6 TLB Input Output Signals
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - connection + - Type + - Description + + * - ``clk_i`` + - in + - SUBSYSTEM + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - SUBSYSTEM + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - Asynchronous reset active low + + * - ``update_i`` + - in + - Shared TLB + - tlb_update_sv32_t + - Updated tag and content of TLB + + * - ``lu_access_i`` + - in + - Cache Subsystem + - logic + - Signal indicating a lookup access is being requested + + * - ``lu_asid_i`` + - in + - CSR RegFile + - logic[ASID_WIDTH-1:0] + - ASID (Address Space Identifier) for the lookup + + * - ``lu_vaddr_i`` + - in + - Cache Subsystem + - logic[riscv::VLEN-1:0] + - Virtual address for the lookup + + * - ``lu_content_o`` + - out + - MMU SV32 + - riscv::pte_sv32_t + - Output for the content of the TLB entry + + * - ``asid_to_be_flushed_i`` + - in + - Execute Stage + - logic[ASID_WIDTH-1:0] + - ASID of the entry to be flushed + + * - ``vaddr_to_be_flushed_i`` + - in + - Execute Stage + - logic[riscv::VLEN-1:0] + - Virtual address of the entry to be flushed + + * - ``lu_is_4M_o`` + - out + - MMU SV32 + - logic + - Output indicating whether the TLB entry corresponds to a 4MB page + + * - ``lu_hit_o`` + - out + - MMU SV32 + - logic + - Output indicating whether the lookup resulted in a hit or miss + +.. raw:: html + + Struct Description + +.. raw:: html + +Table 7: SV32 TLB Update Struct (tlb_update_sv32_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``valid`` + - logic + - Indicates whether the TLB update entry is valid or not + + * - ``is_4M`` + - logic + - Indicates if the TLB entry corresponds to a 4MB page + + * - ``vpn`` + - logic[19:0] + - Virtual Page Number (VPN) used for updating the TLB, consisting of 20 bits + + * - ``asid`` + - logic[8:0] + - Address Space Identifier (ASID) used for updating the TLB, with a length of 9 bits for Sv32 MMU + + * - ``content`` + - riscv::pte_sv32_t + - Content of the TLB update entry, defined by the structure + +.. raw:: html + +Table 8: SV32 PTE Struct (riscv::pte_sv32_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``ppn`` + - logic[21:0] + - 22 bit Physical Page Number (PPN) + + * - ``rsw`` + - logic[1:0] + - Reserved for use by supervisor software + + * - ``d`` + - logic + - | Dirty bit indicating whether the page has been modified (dirty) or not + | 0: Page is clean i.e., has not been written + | 1: Page is dirty i.e., has been written + + * - ``a`` + - logic + - | Accessed bit indicating whether the page has been accessed + | 0: Virtual page has not been accessed since the last time A bit was cleared + | 1: Virtual page has been read, written, or fetched from since the last time the A bit was cleared + + * - ``g`` + - logic + - | Global bit marking a page as part of a global address space valid for all ASIDs + | 0: Translation is valid for specific ASID + | 1: Translation is valid for all ASIDs + + * - ``u`` + - logic + - | User bit indicating privilege level of the page + | 0: Page is not accessible in user mode but in supervisor mode + | 1: Page is accessible in user mode but not in supervisor mode + + * - ``x`` + - logic + - | Execute bit which allows execution of code from the page + | 0: Code execution is not allowed + | 1: Code execution is permitted + + * - ``w`` + - logic + - | Write bit allows the page to be written + | 0: Write operations are not allowed + | 1: Write operations are permitted + + * - ``r`` + - logic + - | Read bit allows read access to the page + | 0: Read operations are not allowed + | 1: Read operations are permitted + + * - ``v`` + - logic + - | Valid bit indicating the page table entry is valid + | 0: Page is invalid i.e. page is not in DRAM, translation is not valid + | 1: Page is valid i.e. page resides in the DRAM, translation is valid + +.. raw:: html + + TLB Entry Fields + +The number of TLB entries can be changed via a design parameter. In 32-bit configurations of CVA6 only 2 TLB entries are instantiated. Each TLB entry is made up of two fields: Tag and Content. The Tag field holds the virtual page number (VPN1, VPN0), ASID, page size (is_4M) along with a valid bit (VALID) indicating that the entry is valid. The SV32 virtual page number, which is supported by CV32A6X, is further split into two separate virtual page numbers VPN1 and VPN0. The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. Note that the V bit in the Content field is the V bit which is present in the page table in memory. It is copied from the page table, as is, and the VALID bit in the Tag is set based on its value.The TLB entry fields are shown in **Figure 2**. + +.. figure:: ../images/cva6_tlb_entry.png + :name: **Figure 5:** Fields in CVA6 TLB entry + :align: center + :width: 80% + :alt: cva6_tlb_entry + + **Figure 5:** Fields in CVA6 TLB entry + +.. raw:: html + + CVA6 TLB Management / Implementation + +The CVA6 TLB implements the following three functions: + +* **Translation:** This function implements the address lookup and match logic. +* **Update and Flush:** This function implements the update and flush logic. +* **Pseudo Least Recently Used Replacement Policy:** This function implements the replacement policy for TLB entries. + +.. raw:: html + + Translation + +This function takes in the virtual address and certain other fields, examines the TLB to determine if the virtual page number of the page being accessed is in the TLB or not. If a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is then used to calculate the target physical address. The following checks are done as part of this lookup function to find a match in the TLB: + +* **Validity Check:** For a TLB hit, the associated TLB entry must be valid . +* **ASID and Global Flag Check:** The TLB entry's ASID must match the given ASID (ASID associated with the Virtual address). If the TLB entry’s Global bit (G) bit is set then this check is not done. This ensures that the translation is either specific to the provided ASID or it is globally applicable. +* **Level 1 VPN match:** SV32 implements a two-level page table. As such the virtual address is broken up into three parts which are the virtual page number 1, virtual page number 0 and displacement. So the condition that is checked next is that the virtual page number 1 of the virtual address matches the virtual page number 1(VPN1) of the TLB entry. +* **Level 0 VPN match or 4-Mega Page:** The last condition to be checked, for a TLB hit, is that the virtual page number 0 of the virtual address matches the virtual page number 0 of the TLB entry (VPN0). This match is ignored if the is_4M bit in the Tag is set which implies a super 4M page. + +All the conditions listed above are checked against every TLB entry. If there is a TLB hit then the corresponding bit in the hit array is set. **Figure 3** Illustrates the TLB hit/miss process listed above. + +.. figure:: ../images/cva6_tlb_hit.png + :name: **Figure 6:** Block diagram of CVA6 TLB hit or miss + :align: center + :width: 75% + :alt: cva6_tlb_hit + + **Figure 6:** Block diagram of CVA6 TLB hit or miss + +.. raw:: html + + Flushing TLB entries + +The SFENCE.VMA instruction can be used with certain specific source register specifiers (rs1 & rs2) to flush a specific TLB entry, some set of TLB entries or all TLB entries. Like all instructions this action only takes place when the SFENCE.VMA instruction is committed (shown via the commit_sfence signal in the following figures.) The behavior of the instruction is as follows: + +* **If rs1 is not equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries which contain leaf page table entries corresponding to the virtual address in rs1 (shown below as Virtual Address to be flushed) and that match the address space identifier as specified by integer register rs2 (shown below as asid_to_be_flushed_i), except for entries containing global mappings. This is referred to as the “SFENCE.VMA vaddr asid” case. + +.. figure:: ../images/sfence_vaddr_asid.png + :name: **Figure 7:** Invalidate TLB entry if ASID and virtual address match + :align: center + :width: 75% + :alt: sfence_vaddr_asid + + **Figure 7:** Invalidate TLB entry if ASID and virtual address match + +* **If rs1 is equal to x0 and rs2 is equal to x0:** Invalidate all TLB entries for all address spaces. This is referred to as the "SFENCE.VMA x0 x0" case. + +.. figure:: ../images/sfence_x0_x0.png + :name: **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 + :align: center + :width: 62% + :alt: sfence_x0_x0 + + **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 + +* **If rs1 is not equal to x0 and rs2 is equal to x0:** invalidate all TLB entries that contain leaf page table entries corresponding to the virtual address in rs1, for all address spaces. This is referred to as the “SFENCE.VMA vaddr x0” case. + +.. figure:: ../images/sfence_vaddr_x0.png + :name: **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces + :align: center + :width: 75% + :alt: sfence_vaddr_x0 + + **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces + +* **If rs1 is equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries matching the address space identified by integer register rs2, except for entries containing global mappings. This is referred to as the “SFENCE.VMA 0 asid” case. + +.. figure:: ../images/sfence_x0_asid.png + :name: **Figure 10:** Invalidate TLB entry for matching ASIDs + :align: center + :width: 75% + :alt: sfence_x0_asid + + **Figure 10:** Invalidate TLB entry for matching ASIDs + +.. raw:: html + + Updating TLB + +When a TLB valid update request is signaled by the shared TLB, and the replacement policy select the update of a specific TLB entry, the corresponding entry's tag is updated with the new tag, and its associated content is refreshed with the information from the update request. This ensures that the TLB entry accurately reflects the new translation information. + +.. raw:: html + + Pseudo Least Recently Used Replacement Policy + +Cache replacement algorithms are used to determine which TLB entry should be replaced, because it is not likely to be used in the near future. The Pseudo-Least-Recently-Used (PLRU) is a cache entry replacement algorithm, derived from Least-Recently-Used (LRU) cache entry replacement algorithm, used by the TLB. Instead of precisely tracking recent usage as the LRU algorithm does, PLRU employs an approximate measure to determine which entry in the cache has not been recently used and as such can be replaced. + +CVA6 implements the PLRU algorithm via the Tree-PLRU method which implements a binary tree. The TLB entries are the leaf nodes of the tree. Each internal node, of the tree, consists of a single bit, referred to as the state bit or plru bit, indicating which subtree contains the (pseudo) least recently used entry (the PLRU); 0 for the left hand tree and 1 for the right hand tree. Following this traversal, the leaf node reached, corresponds to the PLRU entry which can be replaced. Having accessed an entry (so as to replace it) we need to promote that entry to be the Most Recently Used (MRU) entry. This is done by updating the value of each node along the access path to point away from that entry. If the accessed entry is a right child i.e., its parent node value is 1, it is set to 0, and if the parent is the left child of its parent (the grandparent of the accessed node) then its node value is set to 1 and so on all the way up to the root node. + +The PLRU binary tree is implemented as an array of node values. Nodes are organized in the array based on levels, with those from lower levels appearing before higher ones. Furthermore those on the left side of a node appear before those on the right side of a node. The figure below shows a tree and the corresponding array. + +.. figure:: ../images/plru_tree_indexing.png + :name: **Figure 11:** PLRU Tree Indexing + :align: center + :width: 60% + :alt: plru_tree_indexing + + **Figure 11:** PLRU Tree Indexing + +For n-way associative, we require n - 1 internal nodes in the tree. With those nodes, two operations need to be performed efficiently. + +* Promote the accessed entry to be MRU +* Identify which entry to replace (i.e. the PLRU entry) + +.. raw:: html + + Updating the PLRU-Tree + +For a TLB entry which is accessed, the following steps are taken to make it the MRU: + +1. Iterate through each level of the binary tree. +2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. +3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. +4. Calculate the new value that the node should have in order to make the accessed entry the Most Recently Used (MRU). The new value of the root node is the opposite of the TLB entry index, MSB at the root node, MSB - 1 at node at next level and so on. +5. Assign this new value to the relevant node, ensuring that the hit entry becomes the MRU within the binary tree structure. + +At level 0, no bit of the TLB entry’s index determines the offset from the index base because it’s a root node. At level 1, MSB of entry’s index determines the amount of offset from index base at that level. At level 2, the first two bits of the entry's index from MSB side determine the offset from the index base because there are 4 nodes at the level 2 and so on. + +.. figure:: ../images/update_tree.png + :name: **Figure 12:** Promote Entry to be MRU + :align: center + :width: 82% + :alt: update_tree + + **Figure 12:** Promote Entry to be MRU + +In the above figure entry at index 5, is accessed. To make it MRU entry, every node along the access path should point away from it. Entry 5 is a right child, therefore, its parent plru bit set to 0, its parent is a left child, its grand parent’s plru bit set to 1, and great grandparent’s plru bit set to 0. + +.. raw:: html + + Entry Selection for Replacement + +Every TLB entry is checked for the replacement entry. The following steps are taken: + +1. Iterate through each level of the binary tree. +2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. +3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. +4. If the corresponding bit of the entry's index matches the value of the node being traversed at the current level, keep the replacement signal high for that entry; otherwise, set the replacement signal to low. + +.. figure:: ../images/replacement_entry.png + :name: **Figure 13:** Possible path traverse for entry selection for replacement + :align: center + :width: 65% + :alt: replacement_entry + + **Figure 13:** Possible path traverse for entry selection for replacement + +Figure shows every possible path that traverses to find out the PLRU entry. If the plru bit at each level matches with the corresponding bit of the entry's index, that’s the next entry to replace. Below Table shows the entry selection for replacement. + +.. raw:: html + +Table 9: Entry Selection for Reaplacement
+ ++-------------------+---------------+----------------------+ +| **Path Traverse** | **PLRU Bits** | **Entry to replace** | ++-------------------+---------------+----------------------+ +| 0 -> 1 -> 3 | 000 | 0 | +| +---------------+----------------------+ +| | 001 | 1 | ++-------------------+---------------+----------------------+ +| 0 -> 1 -> 4 | 010 | 2 | +| +---------------+----------------------+ +| | 011 | 3 | ++-------------------+---------------+----------------------+ +| 0 -> 2 -> 5 | 100 | 4 | +| +---------------+----------------------+ +| | 101 | 5 | ++-------------------+---------------+----------------------+ +| 0 -> 2 -> 6 | 110 | 6 | +| +---------------+----------------------+ +| | 111 | 7 | ++-------------------+---------------+----------------------+ + +----------------------------------- +Shared Translation Lookaside Buffer +----------------------------------- + +The CVA6 shared TLB is structured as a 2-way associative cache, where the virtual address requiring translation is compared with the set indicated by the virtual page number. The shared TLB is looked up in case of an Instruction TLB (ITLB) or data TLB (DTLB) miss, signaled by these TLBs. If the entry is found in the shared TLB set, the respective TLB, whose translation is being requested, is updated. If the entry is not found in the shared TLB, then the processor has to perform a page table walk. Once the processor obtains a PPN corresponding to the VPN, the shared TLB is updated with this information. If the physical page is not found in the page table, it results in a page fault, which is handled by the operating system. The operating system will then place the corresponding physical page in memory. + +The inputs and output signals of the shared TLB are shown in the following two figures. + +.. figure:: ../images/shared_tlb_in_out.png + :name: **Figure 14:** Inputs and outputs of CVA6 shared TLB + :align: center + :width: 60% + :alt: shared_tlb_in_out + + **Figure 14:** Inputs and outputs of CVA6 shared TLB + +.. raw:: html + + Signal Description + +.. raw:: html + +Table 10: Signal Description of CVA6 shared TLB
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - Connection + - Type + - Description + + * - ``clk_i`` + - in + - Subsystem + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - Subsystem + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - TLB flush request + + * - ``enable_translation_i`` + - in + - CSR Regfile + - logic + - CSRs indicate to enable Sv32 + + * - ``en_ld_st_translation_i`` + - in + - CSR Regfile + - logic + - Enable virtual memory translation for load/stores + + * - ``asid_i`` + - in + - CSR Regfile + - logic + - ASID for the lookup + + * - ``itlb_access_i`` + - in + - Cache Subsystem + - logic + - Signal indicating a lookup access in ITLB is being requested. + + * - ``itlb_hit_i`` + - in + - ITLB + - logic + - Signal indicating an ITLB hit + + * - ``itlb_vaddr_i`` + - in + - Cache Subsystem + - logic[31:0] + - Virtual address lookup in ITLB + + * - ``dtlb_access_i`` + - in + - Load/Store Unit + - logic + - Signal indicating a lookup access in DTLB is being requested. + + * - ``dtlb_hit_i`` + - in + - DTLB + - logic + - Signal indicating a DTLB hit + + * - ``dtlb_vaddr_i`` + - in + - Load/Store Unit + - logic[31:0] + - Virtual address lookup in DTLB + + * - ``itlb_update_o`` + - out + - ITLB + - tlb_update_sv32_t + - Tag and content to update ITLB + + * - ``dtlb_update_o`` + - out + - DTLB + - tlb_update_sv32_t + - Tag and content to update DTLB + + * - ``itlb_miss_o`` + - out + - Performance Counter + - logic + - Signal indicating an ITLB miss + + * - ``dtlb_miss_o`` + - out + - Performance Counter + - logic + - Signal indicating a DTLB miss + + * - ``shared_tlb_access_o`` + - out + - PTW + - logic + - Signal indicating a lookup access in shared TLB is being requested + + * - ``shared_tlb_hit_o`` + - out + - PTW + - logic + - Signal indicating a shared TLB hit + + * - ``shared_tlb_vadd_o`` + - out + - PTW + - logic[31:0] + - Virtual address lookup in shared TLB + + * - ``itlb_req_o`` + - out + - PTW + - logic + - ITLB Request Output + + * - ``shared_tlb_update_i`` + - in + - PTW + - tlb_update_sv32_t + - Updated tag and content of shared TLB + +.. raw:: html + + Struct Description + +.. raw:: html + +Table 11: Shared TLB Update Struct (shared_tag_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``is_4M`` + - logic + - Indicates if the shared TLB entry corresponds to a 4MB page. + + * - ``vpn1`` + - logic[9:0] + - Virtual Page Number (VPN) represents the index of PTE in the page table level 1. + + * - ``vpn0`` + - logic[9:0] + - Virtual Page Number (VPN) represents the index of PTE in the page table level 0. + + * - ``asid`` + - logic + - Address Space Identifier (ASID) used to identify different address spaces + +.. raw:: html + + Shared TLB Entry Structure + +Shared TLB is 2-way associative, with a depth of 64. A single entry in the set contains the valid bit, tag and the content. The Tag segment stores details such as the virtual page number (VPN1, VPN0), ASID, and page size (is_4M). The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. + +.. figure:: ../images/shared_tlb.png + :name: **Figure 15:** CVA6 Shared TLB Structure + :align: center + :width: 60% + :alt: shared_tlb + + **Figure 15:** CVA6 Shared TLB Structure + +.. raw:: html + + Shared TLB Implementation in CVA6 + +The implementation of a shared TLB in CVA6 is described in the following sections: + +* **ITLB and DTLB Miss:** Prepare a shared TLB lookup if the entry is not found in ITLB or DTLB. +* **Tag Comparison:** Look up the provided virtual address in the shared TLB. +* **Update and Flush:** Flush the shared TLB or update it. +* **Replacement Policies:** First non-valid entry and random replacement policy. + +.. raw:: html + + ITLB and DTLB Miss + +Consider a scenario where an entry is found in the ITLB or DTLB. In this case, there is no need to perform a lookup in the shared TLB since the entry has already been found. Next, there are two scenarios: an ITLB miss or a DTLB miss. + +To identify an ITLB miss, the following conditions need to be fulfilled: + +* Address translation must be enabled. +* There must be an access request to the ITLB. +* The ITLB should indicate an ITLB miss. +* There should be no access request to the DTLB. + +During an ITLB miss, access is granted to read the tag and content of the shared TLB from their respective sram. The address for reading the tag and content of the shared TLB entry is calculated using the virtual address for which translation is not found in the ITLB. The ITLB miss is also explicitly indicated by the shared TLB. A request for shared TLB access is initiated. + +To identify the DTLB miss, the following conditions need to be fulfilled: + +* Address translation for load and stores must be enabled. +* There must be an access request to the DTLB. +* The DTLB should indicate a DTLB miss. + +In the case of a DTLB miss, the same logic is employed as described for an ITLB miss. + +.. raw:: html + + Tag Comparison + +Shared TLB lookup for a hit occurs under the same conditions as described for the TLB modules used as ITLB and DTLB. However, there are some distinctions. In both the ITLB and DTLB, the virtual address requiring translation is compared against all TLB entries. In contrast, the shared TLB only compares the tag and content of the set indicated by the provided virtual page number. The index of the set is extracted from VPN0 of the requested virtual address. Given that the shared TLB is 2-way associative, each set contains two entries. Consequently, both of these entries are compared. Below figure illustrates how the set is opted for the lookup. + +.. figure:: ../images/shared_tlb_set.png + :name: **Figure 16:** Set opted for lookup in shared TLB + :align: center + :width: 60% + :alt: shared_tlb_set + + **Figure 16:** Set opted for lookup in shared TLB + +.. raw:: html + + Update and Flush + +Differing from the ITLB and DTLB, a specific virtual address or addressing space cannot be flushed in the shared TLB. When SFENCE.VMA is committed, all entries in the shared TLB are invalidated. (Cases of SFENCE.VMA should also be added in shared TLB) + +.. raw:: html + + Updating Shared TLB + +When the Page Table Walker signals a valid update request, the shared TLB is updated by selecting an entry through the replacement policy and marking it as valid. This also triggers the writing of the new tag and content to the respective SRAM. + +.. raw:: html + + Replacement Policy Implemented in CVA6 Shared TLB + +In CVA6's shared TLB, two replacement policies are employed for replacements based on a specific condition. These replacement policies select the entry within the set indicated by the virtual page number. The two policies are: + +* First non-valid encounter replacement policy +* Random replacement policy + +First replacement policy failed if all ways are valid. Therefore, a random replacement policy is opted for. + +.. raw:: html + + First non-valid encounter replacement policy + +The module implemented in CVA6 to find the first non-valid entry in the shared TLB is the Leading Zero Counter (LZC). It takes three parameters as input: + +1. **WIDTH:** The width of the input vector. +2. **MODE:** Mode selection - 0 for trailing zero, 1 for leading zero. +3. **CNT WIDTH:** Width of the output signal containing the zero count. + +The input signal is the vector to be counted, and the output represents the count of trailing/leading zeros. If all bits in the input vector are zero, it will also be indicated. + +When initializing the module, the width of the input vector is set to the number of shared TLB ways. The trailing zero counter mode is selected. The vector of valid bits is set as the input vector, but with negation. This is because we want the index of the first non-valid entry, and LZC returns the count of trailing zeros, which actually corresponds to the index of the first occurrence of 1 from the least significant bit (LSB). if there is at least one non-valid entry, that entry is opted for the replacement, and If not then this is signaled by LZC. + +.. figure:: ../images/LZC.png + :name: **Figure 17:** Replacement of First invalid entry. + :align: center + :width: 60% + :alt: LZC + + **Figure 17:** Replacement of First invalid entry. + +.. raw:: html + + Random replacement policy + +If all ways are valid, a random replacement policy is employed for the replacement process. The Linear Feedback Shift Register (LFSR) is utilized to select the replacement entry randomly. LFSR is commonly used in generating sequences of pseudo-random numbers. When the enable signal is active, the current state of the LFSR undergoes a transformation. Specifically, the state is shifted right by one bit, and the result is combined with a predetermined masking pattern. This masking pattern is derived from the predefined “Masks” array, introducing a non-linear behavior to the sequence generation of the LFSR. The masking process involves XOR operations between the shifted state bits and specific pattern bits, contributing to the complexity and unpredictability of the generated sequence. + +.. figure:: ../images/RR.png + :name: **Figure 18:** Entry selection for replacement using LFSR + :align: center + :width: 95% + :alt: RR + + **Figure 18:** Entry selection for replacement using LFSR + +----------------- +Page Table Walker +----------------- + +The "CVA6 Page Table Walker (PTW) for MMU Sv32" is a hardware module developed for the CV32A6 processor architecture, designed to facilitate the translation of virtual addresses into physical addresses, a crucial task in memory access management. + +.. figure:: ../images/ptw_in_out.png + :name: **Figure 19:** Input and Outputs of Page Table Walker + :align: center + :width: 60% + :alt: ptw_in_out + + **Figure 19:** Input and Outputs of Page Table Walker + +.. raw:: html + + Operation of PTW Module + +The PTW module operates through various states, each with its specific function, such as handling memory access requests, validating page table entries, and responding to errors. + +.. raw:: html + + Key Features and Capabilities + +Key features of this PTW module include support for two levels of page tables (LVL1 and LVL2) in the Sv32 standard, accommodating instruction and data page table walks. It rigorously validates and verifies page table entries (PTEs) to ensure translation accuracy and adherence to access permissions. This module seamlessly integrates with the CV32A6 processor's memory management unit (MMU), which governs memory access control. It also takes into account global mapping, access flags, and privilege levels during the translation process, ensuring that memory access adheres to the processor's security and privilege settings. + +.. raw:: html + + Exception Handling + +In addition to its translation capabilities, the PTW module is equipped to detect and manage errors, including page-fault exceptions and access exceptions, contributing to the robustness of the memory access system. It works harmoniously with physical memory protection (PMP) configurations, a critical aspect of modern processors' memory security. Moreover, the module efficiently processes virtual addresses, generating corresponding physical addresses, all while maintaining speculative translation, a feature essential for preserving processor performance during memory access operations. + +.. raw:: html + + Signal Description + +.. raw:: html + +Table 12: Signal Description of PTW
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - Connection + - Type + - Description + + * - ``clk_i`` + - in + - Subsystem + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - Subsystem + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - Sfence Committed + + * - ``ptw_active_o`` + - out + - MMU + - logic + - Output signal indicating whether the Page Table Walker (PTW) is currently active + + * - ``walking_instr_o`` + - out + - MMU + - logic + - Indicating it's an instruction page table walk or not + + * - ``ptw_error_o`` + - out + - MMU + - logic + - Output signal indicating that an error occurred during PTW operation + + * - ``ptw_access_exception_o`` + - out + - MMU + - logic + - Output signal indicating that a PMP (Physical Memory Protection) access exception occurred during PTW operation. + + * - ``lsu_is_store_i`` + - in + - Store Unit + - logic + - Input signal indicating whether the translation was triggered by a store operation. + + * - ``req_port_i`` + - in + - Cache Subsystem + - dcache_req_o_t + - D Cache Data Requests + + * - ``req_port_o`` + - out + - Cache Subsystem / Perf Counter + - dcache_req_u_t + - D Cache Data Response + + * - ``shared_tlb_update_o`` + - out + - Shared TLB + - tlb_update_sv32_t + - Updated tag and content of shared TLB + + * - ``update_vaddr_o`` + - out + - MMU + - logic[riscv::VLEN-1:0] + - Updated VADDR from shared TLB + + * - ``asid_i`` + - in + - CSR RegFile + - logic[ASID_WIDTH-1:0] + - ASID for the lookup + + * - ``shared_tlb_access_i`` + - in + - Shared TLB + - logic + - Access request of shared TLB + + * - ``shared_tlb_hit_i`` + - in + - Shared TLB + - logic + - Indicate shared TLB hit + + * - ``shared_tlb_vaddr_i`` + - in + - Shared TLB + - logic[riscv::VLEN-1:0] + - Virtual Address from shared TLB + + * - ``itlb_req_i`` + - in + - Shared TLB + - logic + - Indicate request to ITLB + + * - ``satp_ppn_i`` + - in + - CSR RegFile + - logic[riscv::PPNW-1:0] + - PPN of top level page table from SATP register + + * - ``mxr_i`` + - in + - CSR RegFile + - logic + - Make Executable Readable bit in xSTATUS CSR register + + * - ``shared_tlb_miss_o`` + - out + - OPEN + - logic + - Indicate a shared TLB miss + + * - ``pmpcfg_i`` + - in + - CSR RegFile + - riscv::pmpcfg_t[15:0] + - PMP configuration + + * - ``pmpaddr_i`` + - in + - CSR RegFile + - logic[15:0][riscv::PLEN-3:0] + - PMP Address + + * - ``bad_paddr_o`` + - out + - MMU + - logic[riscv::PLEN-1:0] + - Bad Physical Address in case of access exception + +.. raw:: html + + Struct Description + +.. raw:: html + +Table 13: D Cache Response Struct (dcache_req_i_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``address_index`` + - logic [DCACHE_INDEX_WIDTH-1:0] + - Index of the Dcache Line + + * - ``address_tag`` + - logic [DCACHE_TAG_WIDTH-1:0] + - Tag of the Dcache Line + + * - ``data_wdata`` + - riscv::xlen_t + - Data to write in the Dcache + + * - ``data_wuser`` + - logic [DCACHE_USER_WIDTH-1:0] + - data_wuser + + * - ``data_req`` + - logic + - Data Request + + * - ``data_we`` + - logic + - Data Write enabled + + * - ``data_be`` + - logic [(riscv::XLEN/8)-1:0] + - Data Byte enable + + * - ``data_size`` + - logic [1:0] + - Size of data + + * - ``data_id`` + - logic [DCACHE_TID_WIDTH-1:0] + - Data ID + + * - ``kill_req`` + - logic + - Kill the D cache request + + * - ``tag_valid`` + - logic + - Indicate that teh tag is valid + +.. raw:: html + +Table 14: D Cache Request Struct (dcache_req_o_t)
+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``data_gnt`` + - logic + - Grant of data is given in response to the data request + + * - ``data_rvalid`` + - logic + - Indicate that data is valid which is sent by D cache + + * - ``data_rid`` + - logic [DCACHE_TID_WIDTH-1:0] + - Requested data ID + + * - ``data_rdata`` + - riscv::xlen_t + - Data from D cache + + * - ``data_ruser`` + - logic [DCACHE_USER_WIDTH-1:0] + - Requested data user + +.. raw:: html + + PTW State Machine + +Page Table Walker is implemented as a finite state machine. It listens to shared TLB for incoming translation requests. If there is a shared TLB miss, it saves the virtual address and starts the page table walk. Page table walker transition between 7 states in CVA6. + +* **IDLE:** The initial state where the PTW is awaiting a trigger, often a Shared TLB miss, to initiate a memory access request. +* **WAIT_GRANT:** Request memory access and wait for data grant +* **PTE_LOOKUP:** Once granted access, the PTW examines the valid Page Table Entry (PTE), checking attributes to determine the appropriate course of action. +* **PROPOGATE_ERROR:** If the PTE is invalid, this state handles the propagation of an error, often leading to a page-fault exception due to non-compliance with access conditions +* **PROPOGATE_ACCESS_ERROR:** Propagate access fault if access is not allowed from a PMP perspective +* **WAIT_RVALID:** After processing a PTE, the PTW waits for a valid data signal, indicating that relevant data is ready for further processing. +* **LATENCY:** Introduces a delay to account for synchronization or timing requirements between states. + +.. figure:: ../images/ptw_state_diagram.png + :name: **Figure 20:** State Machine Diagram of CVA6 PTW + :align: center + :width: 95% + :alt: ptw_state_diagram + + **Figure 20:** State Machine Diagram of CVA6 PTW + +.. raw:: html + + IDLE state + +In the IDLE state of the Page Table Walker (PTW) finite state machine, the system awaits a trigger to initiate the page table walk process. This trigger is often prompted by a Shared Translation Lookaside Buffer (TLB) miss, indicating that the required translation is not present in the shared TLB cache. The PTW's behavior in this state is explained as follows: + +1. The top-most page table is selected for the page table walk. In the case of SV32, which implements a two-level page table, the level 1 page table is chosen. +2. In the IDLE state, translations are assumed to be invalid in all addressing spaces. +3. The signal indicating the instruction page table walk is set to 0. +4. A conditional check is performed: if there is a shared TLB access request and the entry is not found in the shared TLB (indicating a shared TLB miss), the following steps are executed: + + a. The address of the desired Page Table Entry within the level 1 page table is calculated by multiplying the Physical Page Number (PPN) of the level 1 page table from the SATP register by the page size (4kB). This result is then added to the product of the Virtual Page Number (VPN1), and the size of a page table entry(4 bytes). + +.. figure:: ../images/ptw_idle.png + :name: **Figure 21:** Address of Desired PTE at Level 1 + :align: center + :width: 68% + :alt: ptw_idle + + **Figure 21:** Address of Desired PTE at Level 1 + +.. _example: + + b. The signal indicating whether it's an instruction page table walk is updated based on the ITLB miss. + c. The ASID and virtual address are saved for the page table walk. + d. A shared TLB miss is indicated. + +.. raw:: html + + WAIT GRANT state + +In the **WAIT_GRANT** state of the Page Table Walker's finite state machine, a data request is sent to retrieve memory information. It waits for a data grant signal from the Dcache controller, remaining in this state until granted. Once granted, it activates a tag valid signal, marking data validity. The state then transitions to "PTE_LOOKUP" for page table entry lookup. + +.. raw:: html + + PTE LOOKUP state + +In the **PTE_LOOKUP** state of the Page Table Walker (PTW) finite state machine, the PTW performs the actual lookup and evaluation of the page table entry (PTE) based on the virtual address translation. The behavior and operations performed in this state are detailed as follows: + +1. The state waits for a valid signal indicating that the data from the memory subsystem, specifically the page table entry, is available for processing. +2. Upon receiving the valid signal, the PTW proceeds with examining the retrieved page table entry to determine its properties and validity. +3. The state checks if the global mapping bit in the PTE is set, and if so, sets the global mapping signal to indicate that the translation applies globally across all address spaces. +4. The state distinguishes between two cases: Invalid PTE and Valid PTE. + + a. If the valid bit of the PTE is not set, or if the PTE has reserved RWX field encodings, it signifies an Invalid PTE. In such cases, the state transitions to the "PROPAGATE_ERROR" state, indicating a page-fault exception due to an invalid translation. + +.. figure:: ../images/ptw_pte_1.png + :name: **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault + :align: center + :width: 70% + :alt: ptw_pte_1 + + **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault + +.. _example1: + + b. If the PTE is valid, the state advances to the "LATENCY" state, indicating a period of processing latency. Additionally, if the "read" flag (pte.r) or the "execute" flag (pte.x) is set, the PTE is considered valid. + +5. Within the Valid PTE scenario, the state performs further checks based on whether the translation is intended for instruction fetching or data access: + + a. For instruction page table walk, if the page is not executable (pte.x is not set) or not marked as accessible (pte.a is not set), the state transitions to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_iptw.png + :name: **Figure 23:** For Instruction Page Table Walk + :align: center + :width: 70% + :alt: ptw_iptw + + **Figure 23:** For Instruction Page Table Walk + +.. _example2: + + b. For data page table walk, the state checks if the page is readable (pte.r is set) or if the page is executable only but made readable by setting the MXR bit in xSTATUS CSR register. If either condition is met, it indicates a valid translation. If not, the state transitions to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_dptw.png + :name: **Figure 24:** Data Access Page Table Walk + :width: 70% + :alt: ptw_dptw + + **Figure 24:** Data Access Page Table Walk + +.. _example3: + + c. If the access is intended for storing data, additional checks are performed: If the page is not writable (pte.w is not set) or if it is not marked as dirty (pte.d is not set), the state transitions to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_dptw_s.png + :name: **Figure 25:** Data Access Page Table Walk, Store requested + :align: center + :width: 70% + :alt: ptw_dptw_s + + **Figure 25:** Data Access Page Table Walk, Store requested + +6. The state also checks for potential misalignment issues in the translation: If the current page table level is the first level (LVL1) and if the PPN0 of in PTE is not zero, it indicates a misaligned superpage, leading to a transition to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_mis_sup.png + :name: **Figure 26:** Misaligned Superpage Check + :align: center + :width: 70% + :alt: ptw_mis_sup + + **Figure 26:** Misaligned Superpage Check + +7. If the PTE is valid but the page is neither readable nor executable, the PTW recognizes the PTE as a pointer to the next level of the page table, indicating that additional translation information can be found in the referenced page table at a lower level. +8. If the current page table level is the first level (LVL1), the PTW proceeds to switch to the second level (LVL2) page table, updating the next level pointer and calculating the address for the next page table entry using the Physical Page Number from the PTE and the index of the level 2 page table from virtual address. + +.. figure:: ../images/ptw_nlvl.png + :name: **Figure 27:** Address of desired PTE at next level of Page Table + :align: center + :width: 70% + :alt: ptw_nlvl + + **Figure 27:** Address of desired PTE at next level of Page Table + +9. The state then transitions to the "WAIT_GRANT" state, indicating that the PTW is awaiting the grant signal to proceed with requesting the next level page table entry. +10. If the current level is already the second level (LVL2), an error is flagged, and the state transitions to the "PROPAGATE_ERROR" state, signifying an unexpected situation where the PTW is already at the last level page table. +11. If the translation access is found to be restricted by the Physical Memory Protection (PMP) settings (allow_access is false), the state updates the shared TLB update signal to indicate that the TLB entry should not be updated. Additionally, the saved address for the page table walk is restored to its previous value, and the state transitions to the "PROPAGATE_ACCESS_ERROR" state. +12. Lastly, if the data request for the page table entry was granted, the state indicates to the cache subsystem that the tag associated with the data is now valid. + +.. figure:: ../images/ptw_pte_flowchart.png + :name: **Figure 28:** Flow Chart of PTE LOOKUP State + :align: center + :alt: ptw_pte_flowchart + + **Figure 28:** Flow Chart of PTE LOOKUP State + +.. raw:: html + + PROPAGATE ERROR state + +This state indicates a detected error in the page table walk process, and an error signal is asserted to indicate the Page Table Walker's error condition, triggering a transition to the "LATENCY" state for error signal propagation. + +.. raw:: html + + PROPAGATE ACCESS ERROR state + +This state indicates a detected access error in the page table walk process, and an access error signal is asserted to indicate the Page Table Walker's access error condition, triggering a transition to the "LATENCY" state for access error signal propagation. + +.. raw:: html + + WAIT RVALID state + +This state waits until it gets the "read valid" signal, and when it does, it's ready to start a new page table walk. + +.. raw:: html + + LATENCY state + +The LATENCY state introduces a latency period to allow for necessary system actions or signals to stabilize. After the latency period, the FSM transitions back to the IDLE state, indicating that the system is prepared for a new translation request. + +.. raw:: html + + Flush Scenario + +The first step when a flush is triggered is to check whether the Page Table Entry (PTE) lookup process is currently in progress. If the PTW (Page Table Walker) module is indeed in the middle of a PTE lookup operation, the code then proceeds to evaluate a specific aspect of this operation. + +* **Check for Data Validity (rvalid):** Within the PTE lookup operation, it's important to ensure that the data being used for the translation is valid. In other words, the code checks whether the "rvalid" signal (which likely indicates the validity of the data) is not active. If the data is not yet valid, it implies that the PTW module is waiting for the data to become valid before completing the lookup. In such a case, the code takes appropriate action to wait for the data to become valid before proceeding further. + +* **Check for Waiting on Grant:** The second condition the code checks for during a flush scenario is whether the PTW module is currently waiting for a "grant." This "grant" signal is typically used to indicate permission or authorization to proceed with an operation. If the PTW module is indeed in a state of waiting for this grant signal, it implies that it requires authorization before continuing its task. + + * **Waiting for Grant:** If the PTW module is in a state of waiting for the grant signal, the code ensures that it continues to wait for the grant signal to be asserted before proceeding further. + +* **Return to Idle State if Neither Condition is Met:** After evaluating the above two conditions, the code determines whether either of these conditions is true. If neither of these conditions applies, it suggests that the PTW module can return to its idle state, indicating that it can continue normal operations without any dependencies on the flush condition. + +PMA/PMP Checks +============== + +Multipler +========= + +CSR Buffer +========== \ No newline at end of file diff --git a/docs/04_cv32a6_design/source/cv32a6_subsystem.rst b/docs/04_cv32a6_design/source/cv32a6_subsystem.rst index bec3a02756b..6ec928b628b 100644 --- a/docs/04_cv32a6_design/source/cv32a6_subsystem.rst +++ b/docs/04_cv32a6_design/source/cv32a6_subsystem.rst @@ -32,8 +32,8 @@ Instantiation - Value - Description - * - ``ArianeCfg`` - - ariane_pkg::ariane_cfg_t + * - ``CVA6Cfg`` + - ariane_pkg::cva6_cfg_t - ariane_pkg::v0.1.0_Config - CVA6 v0.1.0 configuration diff --git a/docs/04_cv32a6_design/source/index.rst b/docs/04_cv32a6_design/source/index.rst index ae5a2f1eec5..63162cd0c5f 100644 --- a/docs/04_cv32a6_design/source/index.rst +++ b/docs/04_cv32a6_design/source/index.rst @@ -20,10 +20,11 @@ CV32A6 Design Document Editor: **Jean Roch Coulon** .. toctree:: - :maxdepth: 3 + :maxdepth: 4 :caption: Contents: cv32a6_intro cv32a6_subsystem cv32a6_frontend + cv32a6_execute cv32a6_glossary diff --git a/vendor/patches/riscv/riscv-isa-sim/0007-SPIKE-Fix-decoder-cvxif.patch b/vendor/patches/riscv/riscv-isa-sim/0007-SPIKE-Fix-decoder-cvxif.patch new file mode 100644 index 00000000000..230c11450b4 --- /dev/null +++ b/vendor/patches/riscv/riscv-isa-sim/0007-SPIKE-Fix-decoder-cvxif.patch @@ -0,0 +1,13 @@ +diff --git a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc +index b1bef8e6..20aea89c 100644 +--- a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc ++++ b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc +@@ -101,7 +101,7 @@ class cvxif_t : public cvxif_extn_t + case FUNC3_0: + switch (r_insn.funct7 & 0x1) { + case NO_RS3: +- switch (r_insn.funct7 & 0xe) { ++ switch (r_insn.funct7 & 0x7e) { + case CUS_NOP: + break; + case CUS_U_ADD: diff --git a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc index b1bef8e646b..20aea89cb45 100644 --- a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc +++ b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc @@ -101,7 +101,7 @@ class cvxif_t : public cvxif_extn_t case FUNC3_0: switch (r_insn.funct7 & 0x1) { case NO_RS3: - switch (r_insn.funct7 & 0xe) { + switch (r_insn.funct7 & 0x7e) { case CUS_NOP: break; case CUS_U_ADD: diff --git a/verif/docs/VerifPlans/csr_access/VP_IP000.yml b/verif/docs/VerifPlans/csr_access/VP_IP000.yml index 47fd5143dc7..664f24fee50 100644 --- a/verif/docs/VerifPlans/csr_access/VP_IP000.yml +++ b/verif/docs/VerifPlans/csr_access/VP_IP000.yml @@ -1,67 +1,111 @@ !Feature -next_elt_id: 1 -name: machineScratch(MSCRATCH) +next_elt_id: 4 +name: CVA6_Machine_mode_RW_CSRs(mstatus, misa, mideleg, medeleg, mie, mtvec, mcounteren, + mepc, mcause, mtval, mip,pmpaddr[0..7], pmpcfg[0..1]) id: 0 display_order: 0 subfeatures: !!omap -- 000_MSCRATCH: !Subfeature - name: 000_MSCRATCH - tag: VP_csr-test-ident_F000_S000 - next_elt_id: 3 +- 000_Power-on-reset (POR) values of CSR: !Subfeature + name: 000_Power-on-reset (POR) values of CSR + tag: VP_CSR_VERIFICATION_F000_S000 + next_elt_id: 1 display_order: 0 items: !!omap - '000': !VerifItem name: '000' - tag: VP_csr-test-ident_F000_S000_I000 - description: "To verify the Power-on Reset value for MSCRATCH CSR.\n \nAddress\ - \ Offset : 0x340\nWidth (bits) : 32\nAccess Type : RW\nReset Value : 0x00000000\n\ - priviliged mode : Machine" - reqt_doc: riscv-privileged-20211203 - ref_mode: section + tag: VP_CSR_VERIFICATION_F000_S000_I000 + description: Upon reset, RISC-V CVA6 Machine mode RW CSRs must initialize + to their respective POR value. + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page ref_page: '' - ref_section: 3.1.13 + ref_section: '' ref_viewer: firefox - verif_goals: Read MSCRATCH CSR to check default POR value that should be equal - to 0x00000000. - pfc: 3 + verif_goals: Verify that the Machine Mode RW CSR POR value must match with + the value specified in the RISC-V CVA6 user manual. + pfc: 1 test_type: 1 - cov_method: 10 + cov_method: 1 cores: 8 coverage_loc: '' comments: '' - - '001': !VerifItem - name: '001' - tag: VP_csr-test-ident_F000_S000_I001 - description: Verifying R/W access of a MSCRATCH CSR by writing random valid - data like 0xFFFFFFFF, 0XA5A5A5A5, 0X5A5A5A5A ... and Read back CSR values - to check correctness. - reqt_doc: riscv-privileged-20211203 - ref_mode: section +- ? "001_Testing CSR with inverted reset value\n\n" + : !Subfeature + name: "001_Testing CSR with inverted reset value\n\n" + tag: VP_csr-access_F000_S003 + next_elt_id: 1 + display_order: 1 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_csr-access_F000_S003_I000 + description: Check the behaviour of the RISC-V Machine mode CVA6 CSRs,when + reset inverted values are written to respective CSRs. + reqt_doc: '' + ref_mode: page ref_page: '' - ref_section: 3.1.13 + ref_section: '' ref_viewer: firefox - verif_goals: The read values of MSCRATCH CSR should matches with written random - data values. - pfc: -1 - test_type: -1 - cov_method: -1 + verif_goals: "1. Verify CSR reading post write operation.\n2. Verify if the + core correctly handles inverted reset values or not." + pfc: 1 + test_type: 1 + cov_method: 1 cores: 8 coverage_loc: '' comments: '' - - '002': !VerifItem - name: '002' - tag: VP_csr-test-ident_F000_S000_I002 - description: Verifying MSCRATCH CSR in other privilige modes(supervisor, user) - reqt_doc: '' +- 002_CSR write and read operations: !Subfeature + name: 002_CSR write and read operations + tag: VP_CSR_VERIFICATION_F000_S001 + next_elt_id: 1 + display_order: 2 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F000_S001_I000 + description: check the correctness of RISCV CVA6 Machine Mode RW CSRs by writing + random values like 0xa5a5a5a5, 0x5a5a5a5a, 0xffa1ae40.. and read using the + CSR instructions defined in the instruction set architecture (ISA). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Verify that CSR can be written using the appropriate CSR write + instructions.\n\n2.Ensure correct read operations using CSR read instructions.\n + \n3.Ensure that read values of the CSR should be as per CVA6 user manual" + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 003_CSR access in different privilege modes: !Subfeature + name: 003_CSR access in different privilege modes + tag: VP_CSR_VERIFICATION_F000_S002 + next_elt_id: 1 + display_order: 3 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F000_S002_I000 + description: Accessing RISC-V CVA6 Machine Mode CSRs in different privilege + modes (User, Supervisor and Machine modes). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html ref_mode: page ref_page: '' ref_section: '' ref_viewer: firefox - verif_goals: It is expected that accessing Machine Mode CSRs in lower privilige - modes will raise an exception. - pfc: 3 + verif_goals: "1.Ensure that Machine mode CSRs can only be accessed in the + Machine mode according to the RISCV specification.\n\n2.Verify that trying + to access Machine Mode CSRs in lower privilege mode raises an illegal instruction + exception." + pfc: 1 test_type: 1 - cov_method: 10 + cov_method: 1 cores: 8 coverage_loc: '' comments: '' diff --git a/verif/docs/VerifPlans/csr_access/VP_IP001.yml b/verif/docs/VerifPlans/csr_access/VP_IP001.yml new file mode 100644 index 00000000000..4e72a8156cf --- /dev/null +++ b/verif/docs/VerifPlans/csr_access/VP_IP001.yml @@ -0,0 +1,89 @@ +!Feature +next_elt_id: 4 +name: CVA6_Machine_mode_RO_CSRs(mvendorid, marchid, mimpid, mhartid) +id: 1 +display_order: 1 +subfeatures: !!omap +- 000_Power-on-reset (POR) values of CSR: !Subfeature + name: 000_Power-on-reset (POR) values of CSR + tag: VP_CSR_VERIFICATION_F001_S000 + next_elt_id: 1 + display_order: 0 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F001_S000_I000 + description: Upon reset,RISC-V CVA6 Machine RO(read only) CSR must initialize + to their respective POR value. + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: Verify that the Machine RO(Read only) CSR POR value must match + with the value specified in the RISC-V CVA6 User Manual. + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 001_CSR write and read operations: !Subfeature + name: 001_CSR write and read operations + tag: VP_CSR_VERIFICATION_F001_S001 + next_elt_id: 1 + display_order: 1 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F001_S001_I000 + description: Check the correctness of RISCV CVA6 read only CSR by writing + random values like 0xa5a5a5a5, 0x5a5a5a5a, 0xffa1ae40.. and confirm whether + write into RO CSRs is possible or not. + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Attempt to write a RO CSR.\n2.Check to see that an illegal + instruction exception occurred.\n3.Immediately after returning from the + exception handler, check to see that the CSR value is not changed." + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 002_CSR access in different privilege modes: !Subfeature + name: 002_CSR access in different privilege modes + tag: VP_CSR_VERIFICATION_F001_S002 + next_elt_id: 1 + display_order: 2 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F001_S002_I000 + description: Accessing RISC-V Machine read only CSRs in different privilege + modes (User, Supervisor and Machine modes). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Ensure that Machine mode read only CSRs can only be accessed + in Machine mode according to the RISC-V specification and does not alter + the value of the CSR.\n\n2.Verify that trying to access a Machine read only + CSRs in an lower privilege mode raises an illegal instruction exception." + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $' +io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $' +config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $' +ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $' diff --git a/verif/docs/VerifPlans/csr_access/VP_IP002.yml b/verif/docs/VerifPlans/csr_access/VP_IP002.yml new file mode 100644 index 00000000000..c615ae16e4a --- /dev/null +++ b/verif/docs/VerifPlans/csr_access/VP_IP002.yml @@ -0,0 +1,114 @@ +!Feature +next_elt_id: 4 +name: CVA6_Supervisor_mode_RW_CSRs(sstatus,stvec, sip, sie, scounteren, sscratch, + sepc, scause, stval, satp) +id: 2 +display_order: 4 +subfeatures: !!omap +- 000_Power-on-reset (POR) values of CSR: !Subfeature + name: 000_Power-on-reset (POR) values of CSR + tag: VP_CSR_VERIFICATION_F004_S000 + next_elt_id: 1 + display_order: 0 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F004_S000_I000 + description: Upon reset, RISC-V CVA6 Supervisor mode RW CSRs must initialize + to their respective POR value. + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: Verify that the Supervisor Mode RW CSRs POR value must match + with the value specified in the RISC-V CVA6 user manual. + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 001_Testing CSR with inverted reset value: !Subfeature + name: 001_Testing CSR with inverted reset value + tag: VP_csr-access_F004_S003 + next_elt_id: 1 + display_order: 1 + items: !!omap + - '000': !VerifItem + name: '000' + tag: Inverted PoR value + description: Check the behaviour of the RISC-V Supervisor mode CVA6 CSRs,when + reset inverted values are written to respective CSRs. + reqt_doc: '' + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: Ensure that the written value can be read back (that is, the + R/W CSR actually stored the value of ~PoR). + pfc: 3 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 002_CSR write and read operations: !Subfeature + name: 002_CSR write and read operations + tag: VP_CSR_VERIFICATION_F004_S001 + next_elt_id: 1 + display_order: 2 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F004_S001_I000 + description: Check the correctness of RISCV CVA6 Supervisor Mode RW CSR by + writing random values like 0xa5a5a5a5, 0x5a5a5a5a, 0xffa1ae40.. and read + using the CSR instructions defined in the instruction set architecture (ISA). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Verify that CSR can be written using the appropriate CSR write + instructions.\n2.Ensure correct read operations using CSR read instructions.\n + 3.Ensure that read values of the CSR should be as per CVA6 user manual." + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 003_CSR access in different privilege modes: !Subfeature + name: 003_CSR access in different privilege modes + tag: VP_CSR_VERIFICATION_F004_S002 + next_elt_id: 1 + display_order: 3 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F004_S002_I000 + description: Accessing RISC-V CVA6 Supervisor Mode CSRs in different privilege + modes (User,Supervisor and Machine modes). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Ensure that Supervisor Mode CSRs can only be accessed in supervisor + mode and in higher privilege mode according to the RISCV specification.\n + 2.Verify that trying to access a Supervisor Mode CSR in an lower privilege + mode raises an illegal instruction exception." + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $' +io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $' +config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $' +ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $' diff --git a/verif/docs/VerifPlans/csr_access/VP_IP003.yml b/verif/docs/VerifPlans/csr_access/VP_IP003.yml new file mode 100644 index 00000000000..3267c6030f7 --- /dev/null +++ b/verif/docs/VerifPlans/csr_access/VP_IP003.yml @@ -0,0 +1,125 @@ +!Feature +next_elt_id: 4 +name: CVA6_User_Mode_Counter_CSRs(cycle, instret, cycleh, instreth) +id: 3 +display_order: 3 +subfeatures: !!omap +- 000_Power-on-reset (POR) values of CSR: !Subfeature + name: 000_Power-on-reset (POR) values of CSR + tag: VP_CSR_VERIFICATION_F003_S000 + next_elt_id: 1 + display_order: 0 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F003_S000_I000 + description: Upon reset, RISC-V CVA6 User mode counter CSRs must initialize + to their respective POR value. + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "Verify that the User Mode counter CSR POR value must match with + the value specified in the RISC-V CVA6 user manual.\nAs cycle will increment + on the posedge of each clock and instret will increment after every instruction + is retired. For these CSRs, the best technique to check reset value is by + \"visual inspection\"" + pfc: 1 + test_type: 1 + cov_method: -1 + cores: 8 + coverage_loc: '' + comments: '' +- 001_Counter _CSRs_functionality_checking: !Subfeature + name: 001_Counter _CSRs_functionality_checking + tag: VP_CSR_VERIFICATION_F003_S001 + next_elt_id: 1 + display_order: 1 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F003_S001_I000 + description: "This feature pertains to the verification of functionality of + RISC-V cycle, cycleh, instret and instreth Control Status Register (CSR). + In a RISC-V architecture\n\n1.’cycle’ and ‘cycleh’ are user-level CSR that + hold low 32 bits and high 32 bits respectively of the count of clock cycles + executed by the processor.\n2.’instret’ and ‘instreth’ are also user-level + CSR that count the total number of instructions executed by the processor.\n + \nThe functionality of user mode counter CSR is being tested by performing + two continuous reads and checking whether the value in the second read is + greater than the value in the first read." + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Verify that these CSR are properly initialized.\n2.Initiate + a second read from the counter CSR immediately after the first read.\n3.Ensure + that the value of the second read from counter CSR is greater than the value + of the initial read.\n4.Confirm that user mode counter CSRs are incrementing.\n + \nNote: This algorithm is only an \"approximate test\" of the functionality + of these CSRs." + pfc: 1 + test_type: 1 + cov_method: -1 + cores: 8 + coverage_loc: '' + comments: '' +- 002_CSR access in different privilege modes: !Subfeature + name: 002_CSR access in different privilege modes + tag: VP_CSR_VERIFICATION_F003_S002 + next_elt_id: 1 + display_order: 2 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_CSR_VERIFICATION_F003_S002_I000 + description: Accessing RISC-V CVA6 user Mode counter CSR in different privilege + modes (User, Supervisor and Machine modes). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: Ensure that User mode counter CSRs can be accessed in user and + Supervisor modes by configuring MCOUNTEREN CSR. + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- ? "003_Verify the user mode counter CSRs behaviour after reaching maximum values\n" + : !Subfeature + name: "003_Verify the user mode counter CSRs behaviour after reaching maximum + values\n" + tag: VP_csr-access_F003_S003 + next_elt_id: 1 + display_order: 3 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_csr-access_F003_S003_I000 + description: check the behaviour of the RISC-V User mode counter CSRs when + it reaches to maximum value. + reqt_doc: '' + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: Ensure that user mode counter CSRs is updated to reset value + as mentioned in CVA6 user manual after reaching to maximum value. + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $' +io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $' +config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $' +ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $' diff --git a/verif/docs/VerifPlans/csr_access/VP_IP004.yml b/verif/docs/VerifPlans/csr_access/VP_IP004.yml new file mode 100644 index 00000000000..8c7d5b88710 --- /dev/null +++ b/verif/docs/VerifPlans/csr_access/VP_IP004.yml @@ -0,0 +1,127 @@ +!Feature +next_elt_id: 4 +name: CVA6_Machine_mode_counter_csr(mcycle,mcycleh,minstret,minstreth) +id: 4 +display_order: 2 +subfeatures: !!omap +- 000_Power-on-reset (POR) values of CSR: !Subfeature + name: 000_Power-on-reset (POR) values of CSR + tag: VP_csr-access_F002_S000 + next_elt_id: 1 + display_order: 0 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_csr-access_F002_S000_I000 + description: Upon reset, RISC-V CVA6 Machine mode counter CSRs must initialize + to their respective POR value. + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "Verify that the Machine Mode counter CSR POR value must match + with the value specified in the RISC-V CVA6 user manual.\nAs mcycle will + increment on the posedge of each clock and minstret will increment after + every instruction is retired. For these CSRs, the best technique to check + reset value is by \"visual inspection\"" + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- ? "001_Counter _CSRs_functionality_checking\n" + : !Subfeature + name: "001_Counter _CSRs_functionality_checking\n" + tag: VP_csr-access_F002_S001 + next_elt_id: 1 + display_order: 1 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_csr-access_F002_S001_I000 + description: "This feature pertains to the verification of functionality of + RISC-V mcycle, mcycleh, minstret and minstreth Control Status Register (CSR). + In a RISC-V architecture\n\n1.’mcycle’ and ‘mcycleh’ are machine-level CSRs + that hold low 32 bits and high 32 bits respectively of the count of clock + cycles executed by the processor.\n\n2.’minstret’ and ‘minstreth’ are also + machine-level CSR that count the total number of instructions executed by + the processor.\n\nThe functionality of machine mode counter CSR is being + tested by performing two continuous reads and checking whether the value + in the second read is greater than the value in the first read." + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Verify that these CSR are properly initialized.\n2.Initiate + a second read from the counter CSR immediately after the first read.\n3.Ensure + that the value of the second read from counter CSR is greater than the value + of the initial read.\n4.Confirm that Machine Mode counter CSRs are incrementing.\n + \nNote: This algorithm is only an \"approximate test\" of the functionality + of these CSRs." + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 002_CSR access in different privilege modes: !Subfeature + name: 002_CSR access in different privilege modes + tag: VP_csr-access_F002_S002 + next_elt_id: 1 + display_order: 2 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_csr-access_F002_S002_I000 + description: Accessing RISC-V CVA6 user Machine mode counter CSRs in different + privilege modes (User, Supervisor and Machine modes). + reqt_doc: + https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/CV32A6_Control_Status_Registers.html + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: "1.Ensure that Machine mode CSRs can only be accessed in the + Machine mode according to the RISC-V specification.\n2.Verify that trying + to access Machine Mode CSRs in lower privilege mode raises an illegal instruction + exception." + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +- 003_Verify the Machine mode counter CSRs behaviour after reaching maximum value: !Subfeature + name: 003_Verify the Machine mode counter CSRs behaviour after reaching maximum + value + tag: VP_csr-access_F002_S003 + next_elt_id: 1 + display_order: 3 + items: !!omap + - '000': !VerifItem + name: '000' + tag: VP_csr-access_F002_S003_I000 + description: check the behaviour of the RISC-V Machine mode counter CSRs when + it reaches to maximum value. + reqt_doc: '' + ref_mode: page + ref_page: '' + ref_section: '' + ref_viewer: firefox + verif_goals: Ensure that Machine mode counter CSRs is updated to reset value + as mentioned in CVA6 user manual after reaching it to maximum value. + pfc: 1 + test_type: 1 + cov_method: 1 + cores: 8 + coverage_loc: '' + comments: '' +vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $' +io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $' +config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $' +ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $' diff --git a/verif/docs/VerifPlans/csr_access/dvplan_csr-access.md b/verif/docs/VerifPlans/csr_access/dvplan_csr-access.md new file mode 100644 index 00000000000..60e8d9e63cb --- /dev/null +++ b/verif/docs/VerifPlans/csr_access/dvplan_csr-access.md @@ -0,0 +1,730 @@ + CORE-V CV32A6-step1 Design Verification Plan documentation + +[CORE-V CV32A6-step1 Design Verification Plan ![Logo](_static/openhw-landscape.svg)](#) + +Contents: + +* [Introduction](index.html#document-dvplan_intro) +* [Module: CSR ACCESS VERIFICATION](index.html#document-dvplan_csr-access) + +[CORE-V CV32A6-step1 Design Verification Plan](#) + +* [](#) +* CORE-V CV32A6-step1 Design Verification Plan documentation + +* * * + +CV32A6-step1 Design Verification Plan[](#cv32a6-step1-design-verification-plan "Permalink to this headline") +============================================================================================================= + +Introduction[](#introduction "Permalink to this headline") +----------------------------------------------------------- + +The objective of this document is to describe what must be covered to verify CVA6 RISC-V processor. + +### License[](#license "Permalink to this headline") + +Copyright 2022 Thales + +SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file except in compliance with the License, or, at your option, the Apache License version 2.0. You may obtain a copy of the License at [https://solderpad.org/licenses/SHL-2.1/](https://solderpad.org/licenses/SHL-2.1/). + +Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +### Standards Compliance[](#standards-compliance "Permalink to this headline") + +To ease the reading, the reference to these specifications can be implicit in the requirements below. For the sake of precision, the requirements identify the versions of RISC-V extensions from these specifications. + +* **\[CVA6req\]** “CVA6 requirement specification”, [https://github.com/openhwgroup/cva6/blob/master/docs/specifications/cva6\_requirement\_specification.rst](https://github.com/openhwgroup/cva6/blob/master/docs/specifications/cva6_requirement_specification.rst), HASH#767c465. + +* **\[CVA6design\]** “CVA6 design document”, TO BE COMPLETED + +* **\[RVunpriv\]** “The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document Version 20191213”, Editors Andrew Waterman and Krste Asanović, RISC-V Foundation, December 13, 2019. + +* **\[RVpriv\]** “The RISC-V Instruction Set Manual, Volume II: Privileged Architecture, Document Version 20211203”, Editors Andrew Waterman, Krste Asanović and John Hauser, RISC-V Foundation, December 4, 2021. + +* **\[RVdbg\]** “RISC-V External Debug Support, Document Version 0.13.2”, Editors Tim Newsome and Megan Wachs, RISC-V Foundation, March 22, 2019. + +* **\[RVcompat\]** “RISC-V Architectural Compatibility Test Framework”, [https://github.com/riscv-non-isa/riscv-arch-test](https://github.com/riscv-non-isa/riscv-arch-test). + +* **\[AXI\]** AXI Specification, [https://developer.arm.com/documentation/ihi0022/hc](https://developer.arm.com/documentation/ihi0022/hc). + +* **\[CV-X-IF\]** Placeholder for the CV-X-IF coprocessor interface currently prepared at OpenHW Group; current version in [https://docs.openhwgroup.org/projects/openhw-group-core-v-xif/](https://docs.openhwgroup.org/projects/openhw-group-core-v-xif/). + +* **\[OpenPiton\]** “OpenPiton Microarchitecture Specification”, Princeton University, [https://parallel.princeton.edu/openpiton/docs/micro\_arch.pdf](https://parallel.princeton.edu/openpiton/docs/micro_arch.pdf). + + +CV32A6 is a 32-bit processor fully compliant with RISC-V specifications: \[RVunpriv\], \[RVpriv\] and \[RVdbg\] and passes \[RVcompat\] compatibility tests, as requested by \[GEN-10\] in \[CVA6req\]. + +### Getting start verification[](#getting-start-verification "Permalink to this headline") + +\[TO BE COMPLETED\] + +### Documentation framework[](#documentation-framework "Permalink to this headline") + +The framework of this document is aligned with the CVA6 design document \[CVA6design\]. + +Description of the framework: + +* Processor is a subsystem + +* Processor subsystems are split into several modules + +* Modules are verified separately + + +### Contributors[](#contributors "Permalink to this headline") + +Jean-Roch Coulon - Thales + +\[TO BE COMPLETED\] + +Module: CSR ACCESS VERIFICATION[](#module-csr-access-verification "Permalink to this headline") +------------------------------------------------------------------------------------------------ + +### Feature: CVA6\_Machine\_mode\_RW\_CSRs(mstatus, misa, mideleg, medeleg, mie, mtvec, mcounteren, mepc, mcause, mtval, mip,pmpaddr\[0..7\], pmpcfg\[0..1\])[](#feature-cva6-machine-mode-rw-csrs-mstatus-misa-mideleg-medeleg-mie-mtvec-mcounteren-mepc-mcause-mtval-mip-pmpaddr-0-7-pmpcfg-0-1 "Permalink to this headline") + +#### Sub-feature: 000\_Power-on-reset (POR) values of CSR[](#sub-feature-000-power-on-reset-por-values-of-csr "Permalink to this headline") + +##### Item: 000[](#item-000 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Upon reset, RISC-V CVA6 Machine mode RW CSRs must initialize to their respective POR value. + +* **Verification Goals** + + Verify that the Machine Mode RW CSR POR value must match with the value specified in the RISC-V CVA6 user manual. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F000\_S000\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 001\_Testing CSR with inverted reset value[](#sub-feature-001-testing-csr-with-inverted-reset-value "Permalink to this headline") + +##### Item: 000[](#id1 "Permalink to this headline") + +* **Requirement location:** + +* **Feature Description** + + Check the behaviour of the RISC-V Machine mode CVA6 CSRs,when reset inverted values are written to respective CSRs. + +* **Verification Goals** + + 1. Verify CSR reading post write operation. + + 2. Verify if the core correctly handles inverted reset values or not. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_csr-access\_F000\_S003\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 002\_CSR write and read operations[](#sub-feature-002-csr-write-and-read-operations "Permalink to this headline") + +##### Item: 000[](#id2 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + check the correctness of RISCV CVA6 Machine Mode RW CSRs by writing random values like 0xa5a5a5a5, 0x5a5a5a5a, 0xffa1ae40.. and read using the CSR instructions defined in the instruction set architecture (ISA). + +* **Verification Goals** + + 1.Verify that CSR can be written using the appropriate CSR write instructions. + + 2.Ensure correct read operations using CSR read instructions. + + 3.Ensure that read values of the CSR should be as per CVA6 user manual + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F000\_S001\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 003\_CSR access in different privilege modes[](#sub-feature-003-csr-access-in-different-privilege-modes "Permalink to this headline") + +##### Item: 000[](#id3 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Accessing RISC-V CVA6 Machine Mode CSRs in different privilege modes (User, Supervisor and Machine modes). + +* **Verification Goals** + + 1.Ensure that Machine mode CSRs can only be accessed in the Machine mode according to the RISCV specification. + + 2.Verify that trying to access Machine Mode CSRs in lower privilege mode raises an illegal instruction exception. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F000\_S002\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +### Feature: CVA6\_Machine\_mode\_RO\_CSRs(mvendorid, marchid, mimpid, mhartid)[](#feature-cva6-machine-mode-ro-csrs-mvendorid-marchid-mimpid-mhartid "Permalink to this headline") + +#### Sub-feature: 000\_Power-on-reset (POR) values of CSR[](#id4 "Permalink to this headline") + +##### Item: 000[](#id5 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Upon reset,RISC-V CVA6 Machine RO(read only) CSR must initialize to their respective POR value. + +* **Verification Goals** + + Verify that the Machine RO(Read only) CSR POR value must match with the value specified in the RISC-V CVA6 User Manual. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F001\_S000\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 001\_CSR write and read operations[](#sub-feature-001-csr-write-and-read-operations "Permalink to this headline") + +##### Item: 000[](#id6 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Check the correctness of RISCV CVA6 read only CSR by writing random values like 0xa5a5a5a5, 0x5a5a5a5a, 0xffa1ae40.. and confirm whether write into RO CSRs is possible or not. + +* **Verification Goals** + + 1.Attempt to write a RO CSR. + 2.Check to see that an illegal instruction exception occurred. + 3.Immediately after returning from the exception handler, check to see that the CSR value is not changed. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F001\_S001\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 002\_CSR access in different privilege modes[](#sub-feature-002-csr-access-in-different-privilege-modes "Permalink to this headline") + +##### Item: 000[](#id7 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Accessing RISC-V Machine read only CSRs in different privilege modes (User, Supervisor and Machine modes). + +* **Verification Goals** + + 1.Ensure that Machine mode read only CSRs can only be accessed in Machine mode according to the RISC-V specification and does not alter the value of the CSR. + + 2.Verify that trying to access a Machine read only CSRs in an lower privilege mode raises an illegal instruction exception. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F001\_S002\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +### Feature: CVA6\_Supervisor\_mode\_RW\_CSRs(sstatus,stvec, sip, sie, scounteren, sscratch, sepc, scause, stval, satp)[](#feature-cva6-supervisor-mode-rw-csrs-sstatus-stvec-sip-sie-scounteren-sscratch-sepc-scause-stval-satp "Permalink to this headline") + +#### Sub-feature: 000\_Power-on-reset (POR) values of CSR[](#id8 "Permalink to this headline") + +##### Item: 000[](#id9 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Upon reset, RISC-V CVA6 Supervisor mode RW CSRs must initialize to their respective POR value. + +* **Verification Goals** + + Verify that the Supervisor Mode RW CSRs POR value must match with the value specified in the RISC-V CVA6 user manual. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F004\_S000\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 001\_Testing CSR with inverted reset value[](#id10 "Permalink to this headline") + +##### Item: 000[](#id11 "Permalink to this headline") + +* **Requirement location:** + +* **Feature Description** + + Check the behaviour of the RISC-V Supervisor mode CVA6 CSRs,when reset inverted values are written to respective CSRs. + +* **Verification Goals** + + Ensure that the written value can be read back (that is, the R/W CSR actually stored the value of ~PoR). + +* **Pass/Fail Criteria:** Check RM + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** Inverted PoR value + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 002\_CSR write and read operations[](#id12 "Permalink to this headline") + +##### Item: 000[](#id13 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Check the correctness of RISCV CVA6 Supervisor Mode RW CSR by writing random values like 0xa5a5a5a5, 0x5a5a5a5a, 0xffa1ae40.. and read using the CSR instructions defined in the instruction set architecture (ISA). + +* **Verification Goals** + + 1.Verify that CSR can be written using the appropriate CSR write instructions. + 2.Ensure correct read operations using CSR read instructions. + 3.Ensure that read values of the CSR should be as per CVA6 user manual. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F004\_S001\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 003\_CSR access in different privilege modes[](#id14 "Permalink to this headline") + +##### Item: 000[](#id15 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Accessing RISC-V CVA6 Supervisor Mode CSRs in different privilege modes (User,Supervisor and Machine modes). + +* **Verification Goals** + + 1.Ensure that Supervisor Mode CSRs can only be accessed in supervisor mode and in higher privilege mode according to the RISCV specification. + 2.Verify that trying to access a Supervisor Mode CSR in an lower privilege mode raises an illegal instruction exception. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F004\_S002\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +### Feature: CVA6\_User\_Mode\_Counter\_CSRs(cycle, instret, cycleh, instreth)[](#feature-cva6-user-mode-counter-csrs-cycle-instret-cycleh-instreth "Permalink to this headline") + +#### Sub-feature: 000\_Power-on-reset (POR) values of CSR[](#id16 "Permalink to this headline") + +##### Item: 000[](#id17 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Upon reset, RISC-V CVA6 User mode counter CSRs must initialize to their respective POR value. + +* **Verification Goals** + + Verify that the User Mode counter CSR POR value must match with the value specified in the RISC-V CVA6 user manual. + As cycle will increment on the posedge of each clock and instret will increment after every instruction is retired. For these CSRs, the best technique to check reset value is by “visual inspection” + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** NDY (Not Defined Yet) + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F003\_S000\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 001\_Counter \_CSRs\_functionality\_checking[](#sub-feature-001-counter-csrs-functionality-checking "Permalink to this headline") + +##### Item: 000[](#id18 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + This feature pertains to the verification of functionality of RISC-V cycle, cycleh, instret and instreth Control Status Register (CSR). In a RISC-V architecture + + 1.’cycle’ and ‘cycleh’ are user-level CSR that hold low 32 bits and high 32 bits respectively of the count of clock cycles executed by the processor. + 2.’instret’ and ‘instreth’ are also user-level CSR that count the total number of instructions executed by the processor. + + The functionality of user mode counter CSR is being tested by performing two continuous reads and checking whether the value in the second read is greater than the value in the first read. + +* **Verification Goals** + + 1.Verify that these CSR are properly initialized. + 2.Initiate a second read from the counter CSR immediately after the first read. + 3.Ensure that the value of the second read from counter CSR is greater than the value of the initial read. + 4.Confirm that user mode counter CSRs are incrementing. + + Note: This algorithm is only an “approximate test” of the functionality of these CSRs. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** NDY (Not Defined Yet) + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F003\_S001\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 002\_CSR access in different privilege modes[](#id19 "Permalink to this headline") + +##### Item: 000[](#id20 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Accessing RISC-V CVA6 user Mode counter CSR in different privilege modes (User, Supervisor and Machine modes). + +* **Verification Goals** + + Ensure that User mode counter CSRs can be accessed in user and Supervisor modes by configuring MCOUNTEREN CSR. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_CSR\_VERIFICATION\_F003\_S002\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 003\_Verify the user mode counter CSRs behaviour after reaching maximum values[](#sub-feature-003-verify-the-user-mode-counter-csrs-behaviour-after-reaching-maximum-values "Permalink to this headline") + +##### Item: 000[](#id21 "Permalink to this headline") + +* **Requirement location:** + +* **Feature Description** + + check the behaviour of the RISC-V User mode counter CSRs when it reaches to maximum value. + +* **Verification Goals** + + Ensure that user mode counter CSRs is updated to reset value as mentioned in CVA6 user manual after reaching to maximum value. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_csr-access\_F003\_S003\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +### Feature: CVA6\_Machine\_mode\_counter\_csr(mcycle,mcycleh,minstret,minstreth)[](#feature-cva6-machine-mode-counter-csr-mcycle-mcycleh-minstret-minstreth "Permalink to this headline") + +#### Sub-feature: 000\_Power-on-reset (POR) values of CSR[](#id22 "Permalink to this headline") + +##### Item: 000[](#id23 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Upon reset, RISC-V CVA6 Machine mode counter CSRs must initialize to their respective POR value. + +* **Verification Goals** + + Verify that the Machine Mode counter CSR POR value must match with the value specified in the RISC-V CVA6 user manual. + As mcycle will increment on the posedge of each clock and minstret will increment after every instruction is retired. For these CSRs, the best technique to check reset value is by “visual inspection” + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_csr-access\_F002\_S000\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 001\_Counter \_CSRs\_functionality\_checking[](#id24 "Permalink to this headline") + +##### Item: 000[](#id25 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + This feature pertains to the verification of functionality of RISC-V mcycle, mcycleh, minstret and minstreth Control Status Register (CSR). In a RISC-V architecture + + 1.’mcycle’ and ‘mcycleh’ are machine-level CSRs that hold low 32 bits and high 32 bits respectively of the count of clock cycles executed by the processor. + + 2.’minstret’ and ‘minstreth’ are also machine-level CSR that count the total number of instructions executed by the processor. + + The functionality of machine mode counter CSR is being tested by performing two continuous reads and checking whether the value in the second read is greater than the value in the first read. + +* **Verification Goals** + + 1.Verify that these CSR are properly initialized. + 2.Initiate a second read from the counter CSR immediately after the first read. + 3.Ensure that the value of the second read from counter CSR is greater than the value of the initial read. + 4.Confirm that Machine Mode counter CSRs are incrementing. + + Note: This algorithm is only an “approximate test” of the functionality of these CSRs. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_csr-access\_F002\_S001\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 002\_CSR access in different privilege modes[](#id26 "Permalink to this headline") + +##### Item: 000[](#id27 "Permalink to this headline") + +* **Requirement location:** https://docs.openhwgroup.org/projects/cva6-user-manual/01\_cva6\_user/CV32A6\_Control\_Status\_Registers.html + +* **Feature Description** + + Accessing RISC-V CVA6 user Machine mode counter CSRs in different privilege modes (User, Supervisor and Machine modes). + +* **Verification Goals** + + 1.Ensure that Machine mode CSRs can only be accessed in the Machine mode according to the RISC-V specification. + 2.Verify that trying to access Machine Mode CSRs in lower privilege mode raises an illegal instruction exception. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_csr-access\_F002\_S002\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +#### Sub-feature: 003\_Verify the Machine mode counter CSRs behaviour after reaching maximum value[](#sub-feature-003-verify-the-machine-mode-counter-csrs-behaviour-after-reaching-maximum-value "Permalink to this headline") + +##### Item: 000[](#id28 "Permalink to this headline") + +* **Requirement location:** + +* **Feature Description** + + check the behaviour of the RISC-V Machine mode counter CSRs when it reaches to maximum value. + +* **Verification Goals** + + Ensure that Machine mode counter CSRs is updated to reset value as mentioned in CVA6 user manual after reaching it to maximum value. + +* **Pass/Fail Criteria:** Self-Check + +* **Test Type:** Directed SelfChk + +* **Coverage Method:** Functional Coverage + +* **Applicable Cores:** CV32A6\_v0.1.0 + +* **Unique verification tag:** VP\_csr-access\_F002\_S003\_I000 + +* **Link to Coverage:** + +* **Comments** + + _(none)_ + + +* * * + +© Copyright 2022, Thales Group. + +Built with [Sphinx](https://www.sphinx-doc.org/) using a [theme](https://github.com/readthedocs/sphinx_rtd_theme) provided by [Read the Docs](https://readthedocs.org). + +jQuery(function () { SphinxRtdTheme.Navigation.enable(true); }); \ No newline at end of file diff --git a/verif/env/corev-dv/custom/cvxif_custom_instr.sv b/verif/env/corev-dv/custom/cvxif_custom_instr.sv index 573e801bcf9..b92295cf722 100644 --- a/verif/env/corev-dv/custom/cvxif_custom_instr.sv +++ b/verif/env/corev-dv/custom/cvxif_custom_instr.sv @@ -119,8 +119,8 @@ class cvxif_custom_instr extends riscv_custom_instr; `DV_CHECK_FATAL($cast(cfg_cva6, cfg), "Could not cast cfg into cfg_cva6") return cfg_cva6.enable_x_extension && ( instr_name inside { - CUS_ADD_MULTI,CUS_NOP,CUS_ADD_RS3, - CUS_EXC,CUS_U_ADD,CUS_S_ADD + CUS_ADD, CUS_ADD_MULTI, CUS_NOP, CUS_ADD_RS3, + CUS_EXC, CUS_U_ADD, CUS_S_ADD }); endfunction diff --git a/verif/sim/Makefile b/verif/sim/Makefile index 95540274d25..6eedbcb6bf2 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -186,7 +186,7 @@ ALL_UVM_FLAGS = -lca -sverilog +incdir+$(VCS_HOME)/etc/uvm/src \ $(if $(DEBUG), -debug_access+all $(if $(VERDI), -kdb) $(if $(TRACE_COMPACT),+vcs+fsdbon))\ -cm_seqnoconst -diag noconst -ALL_SIMV_UVM_FLAGS = -licwait 20 $(issrun_opts) \ +ALL_SIMV_UVM_FLAGS = +vcs+lic+wait $(issrun_opts) \ -sv_lib $(CVA6_REPO_DIR)/verif/core-v-verif/lib/dpi_dasm/lib/Linux64/libdpi_dasm +signature=I-ADD-01.signature_output \ +UVM_TESTNAME=uvmt_cva6_firmware_test_c diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index 128129c5cfb..e5eb48533a9 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -65,9 +65,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( cva6 #( .CVA6Cfg ( CVA6Cfg ), - .IsRVFI ( IsRVFI ), - // - .ArianeCfg ( ariane_soc::ArianeSocCfg ) + .IsRVFI ( IsRVFI ) ) i_cva6 ( .clk_i ( clk_i ), .rst_ni ( rst_ni ),