diff --git a/common/local/util/ex_trace_item.svh b/common/local/util/ex_trace_item.svh index 5705e59ce..2b2c7baf2 100644 --- a/common/local/util/ex_trace_item.svh +++ b/common/local/util/ex_trace_item.svh @@ -14,7 +14,9 @@ `ifndef VERILATOR class ex_trace_item #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter type interrupts_t = logic, + parameter interrupts_t INTERRUPTS = '0 ); // contains a human readable form of the cause value @@ -42,12 +44,12 @@ class ex_trace_item #( riscv::INSTR_PAGE_FAULT: this.cause_s = "Instruction Page Fault"; riscv::LOAD_PAGE_FAULT: this.cause_s = "Load Page Fault"; riscv::STORE_PAGE_FAULT: this.cause_s = "Store Page Fault"; - riscv::S_SW_INTERRUPT: this.cause_s = "Supervisor Software Interrupt"; - riscv::M_SW_INTERRUPT: this.cause_s = "Machine Software Interrupt"; - riscv::S_TIMER_INTERRUPT: this.cause_s = "Supervisor Timer Interrupt"; - riscv::M_TIMER_INTERRUPT: this.cause_s = "Machine Timer Interrupt"; - riscv::S_EXT_INTERRUPT: this.cause_s = "Supervisor External Interrupt"; - riscv::M_EXT_INTERRUPT: this.cause_s = "Machine External Interrupt"; + INTERRUPTS.S_SW: this.cause_s = "Supervisor Software Interrupt"; + INTERRUPTS.M_SW: this.cause_s = "Machine Software Interrupt"; + INTERRUPTS.S_TIMER: this.cause_s = "Supervisor Timer Interrupt"; + INTERRUPTS.M_TIMER: this.cause_s = "Machine Timer Interrupt"; + INTERRUPTS.S_EXT: this.cause_s = "Supervisor External Interrupt"; + INTERRUPTS.M_EXT: this.cause_s = "Machine External Interrupt"; riscv::DEBUG_REQUEST: this.cause_s = "Request Debug Mode"; default: this.cause_s = "Interrupt"; endcase @@ -64,12 +66,12 @@ class ex_trace_item #( riscv::ENV_CALL_MMODE, riscv::ENV_CALL_SMODE, riscv::ENV_CALL_UMODE, - riscv::S_SW_INTERRUPT, - riscv::M_SW_INTERRUPT, - riscv::S_TIMER_INTERRUPT, - riscv::M_TIMER_INTERRUPT, - riscv::S_EXT_INTERRUPT, - riscv::M_EXT_INTERRUPT + INTERRUPTS.S_SW, + INTERRUPTS.M_SW, + INTERRUPTS.S_TIMER, + INTERRUPTS.M_TIMER, + INTERRUPTS.S_EXT, + INTERRUPTS.M_EXT })) s = $sformatf("%s, \n\t\t\t\ttval: %h", s, this.tval); return s; diff --git a/common/local/util/instr_tracer.sv b/common/local/util/instr_tracer.sv index e7c6eb5ee..f7dc27e02 100644 --- a/common/local/util/instr_tracer.sv +++ b/common/local/util/instr_tracer.sv @@ -20,7 +20,9 @@ module instr_tracer #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type bp_resolve_t = logic, - parameter type scoreboard_entry_t = logic + parameter type scoreboard_entry_t = logic, + parameter type interrupts_t = logic, + parameter interrupts_t INTERRUPTS = '0 )( instr_tracer_if tracer_if, input logic[riscv::XLEN-1:0] hart_id_i @@ -206,7 +208,9 @@ module instr_tracer #( function void printException(logic [riscv::VLEN-1:0] pc, logic [63:0] cause, logic [63:0] tval); automatic ex_trace_item #( - .CVA6Cfg(CVA6Cfg) + .CVA6Cfg(CVA6Cfg), + .interrupts_t(interrupts_t), + .INTERRUPTS(INTERRUPTS) ) eti = new (pc, cause, tval); automatic string print_ex = eti.printException(); $fwrite(f, {print_ex, "\n"}); diff --git a/core/acc_dispatcher.sv b/core/acc_dispatcher.sv index fa3c4ad53..3ee68361b 100644 --- a/core/acc_dispatcher.sv +++ b/core/acc_dispatcher.sv @@ -24,34 +24,34 @@ module acc_dispatcher parameter type fu_data_t = logic, parameter type scoreboard_entry_t = logic, localparam type accelerator_req_t = struct packed { - logic req_valid; - logic resp_ready; - riscv::instruction_t insn; - logic [riscv::XLEN-1:0] rs1; - logic [riscv::XLEN-1:0] rs2; - fpnew_pkg::roundmode_e frm; - logic [ariane_pkg::TRANS_ID_BITS-1:0] trans_id; - logic store_pending; + logic req_valid; + logic resp_ready; + riscv::instruction_t insn; + logic [riscv::XLEN-1:0] rs1; + logic [riscv::XLEN-1:0] rs2; + fpnew_pkg::roundmode_e frm; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; + logic store_pending; // Invalidation interface - logic acc_cons_en; - logic inval_ready; + logic acc_cons_en; + logic inval_ready; }, parameter type acc_req_t = accelerator_req_t, parameter type acc_resp_t = struct packed { - logic req_ready; - logic resp_valid; - logic [riscv::XLEN-1:0] result; - logic [ariane_pkg::TRANS_ID_BITS-1:0] trans_id; - logic error; + logic req_ready; + logic resp_valid; + logic [riscv::XLEN-1:0] result; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; + logic error; // Metadata - logic store_pending; - logic store_complete; - logic load_complete; - logic [4:0] fflags; - logic fflags_valid; + logic store_pending; + logic store_complete; + logic load_complete; + logic [4:0] fflags; + logic fflags_valid; // Invalidation interface - logic inval_valid; - logic [63:0] inval_addr; + logic inval_valid; + logic [63:0] inval_addr; }, parameter type acc_cfg_t = logic, parameter acc_cfg_t AccCfg = '0 @@ -75,7 +75,7 @@ module acc_dispatcher output logic issue_stall_o, input fu_data_t fu_data_i, input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i, - output logic [TRANS_ID_BITS-1:0] acc_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] acc_trans_id_o, output logic [riscv::XLEN-1:0] acc_result_o, output logic acc_valid_o, output exception_t acc_exception_o, @@ -161,14 +161,15 @@ module acc_dispatcher logic acc_insn_queue_empty; logic [idx_width(InstructionQueueDepth)-1:0] acc_insn_queue_usage; logic acc_commit; - logic [ TRANS_ID_BITS-1:0] acc_commit_trans_id; + logic [ CVA6Cfg.TRANS_ID_BITS-1:0] acc_commit_trans_id; assign acc_data = acc_valid_ex_o ? fu_data_i : '0; fifo_v3 #( .DEPTH (InstructionQueueDepth), .FALL_THROUGH(1'b1), - .dtype (fu_data_t) + .dtype (fu_data_t), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_acc_insn_queue ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -191,13 +192,13 @@ module acc_dispatcher **********************************/ // Keep track of the instructions that were received by the dispatcher. - logic [NR_SB_ENTRIES-1:0] insn_pending_d, insn_pending_q; + logic [CVA6Cfg.NR_SB_ENTRIES-1:0] insn_pending_d, insn_pending_q; `FF(insn_pending_q, insn_pending_d, '0) // Only non-speculative instructions can be issued to the accelerators. // The following block keeps track of which transaction IDs reached the // top of the scoreboard, and are therefore no longer speculative. - logic [NR_SB_ENTRIES-1:0] insn_ready_d, insn_ready_q; + logic [CVA6Cfg.NR_SB_ENTRIES-1:0] insn_ready_d, insn_ready_q; `FF(insn_ready_q, insn_ready_d, '0) always_comb begin : p_non_speculative_ff diff --git a/core/amo_buffer.sv b/core/amo_buffer.sv index f01b3eb7f..c594adbeb 100644 --- a/core/amo_buffer.sv +++ b/core/amo_buffer.sv @@ -63,8 +63,9 @@ module amo_buffer #( assign flush_amo_buffer = flush_i & !amo_valid_commit_i; fifo_v3 #( - .DEPTH(1), - .dtype(amo_op_t) + .DEPTH (1), + .dtype (amo_op_t), + .FPGA_EN(CVA6Cfg.FPGA_EN) ) i_amo_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), diff --git a/core/cache_subsystem/cache_ctrl.sv b/core/cache_subsystem/cache_ctrl.sv index 70ff5c3da..c30c57814 100644 --- a/core/cache_subsystem/cache_ctrl.sv +++ b/core/cache_subsystem/cache_ctrl.sv @@ -37,15 +37,15 @@ module cache_ctrl input dcache_req_i_t req_port_i, output dcache_req_o_t req_port_o, // SRAM interface - output logic [DCACHE_SET_ASSOC-1:0] req_o, // req is valid - output logic [DCACHE_INDEX_WIDTH-1:0] addr_o, // address into cache array + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] req_o, // req is valid + output logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] addr_o, // address into cache array input logic gnt_i, output cache_line_t data_o, output cl_be_t be_o, - output logic [DCACHE_TAG_WIDTH-1:0] tag_o, //valid one cycle later - input cache_line_t [DCACHE_SET_ASSOC-1:0] data_i, + output logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag_o, //valid one cycle later + input cache_line_t [CVA6Cfg.DCACHE_SET_ASSOC-1:0] data_i, output logic we_o, - input logic [DCACHE_SET_ASSOC-1:0] hit_way_i, + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] hit_way_i, // Miss handling output miss_req_t miss_req_o, // return @@ -79,29 +79,30 @@ module cache_ctrl state_d, state_q; typedef struct packed { - logic [DCACHE_INDEX_WIDTH-1:0] index; - logic [DCACHE_TAG_WIDTH-1:0] tag; - logic [DCACHE_TID_WIDTH-1:0] id; - logic [7:0] be; - logic [1:0] size; - logic we; - logic [63:0] wdata; - logic bypass; - logic killed; + logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] index; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag; + logic [DCACHE_TID_WIDTH-1:0] id; + logic [7:0] be; + logic [1:0] size; + logic we; + logic [63:0] wdata; + logic bypass; + logic killed; } mem_req_t; - logic [DCACHE_SET_ASSOC-1:0] hit_way_d, hit_way_q; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] hit_way_d, hit_way_q; mem_req_t mem_req_d, mem_req_q; assign busy_o = (state_q != IDLE); assign tag_o = mem_req_d.tag; - logic [DCACHE_LINE_WIDTH-1:0] cl_i; + logic [CVA6Cfg.DCACHE_LINE_WIDTH-1:0] cl_i; always_comb begin : way_select cl_i = '0; - for (int unsigned i = 0; i < DCACHE_SET_ASSOC; i++) if (hit_way_i[i]) cl_i = data_i[i].data; + for (int unsigned i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) + if (hit_way_i[i]) cl_i = data_i[i].data; // cl_i = data_i[one_hot_to_bin(hit_way_i)].data; end @@ -110,10 +111,10 @@ module cache_ctrl // Cache FSM // -------------- always_comb begin : cache_ctrl_fsm - automatic logic [$clog2(DCACHE_LINE_WIDTH)-1:0] cl_offset; + automatic logic [$clog2(CVA6Cfg.DCACHE_LINE_WIDTH)-1:0] cl_offset; // incoming cache-line -> this is needed as synthesis is not supporting +: indexing in a multi-dimensional array // cache-line offset -> multiple of 64 - cl_offset = mem_req_q.index[DCACHE_BYTE_OFFSET-1:3] << 6; // shift by 6 to the left + cl_offset = mem_req_q.index[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:3] << 6; // shift by 6 to the left // default assignments state_d = state_q; mem_req_d = mem_req_q; @@ -256,7 +257,7 @@ module cache_ctrl // Check for cache-ability // ------------------------- if (!config_pkg::is_inside_cacheable_regions( - CVA6Cfg, {{{64 - riscv::PLEN} {1'b0}}, tag_o, {DCACHE_INDEX_WIDTH{1'b0}}} + CVA6Cfg, {{{64 - riscv::PLEN} {1'b0}}, tag_o, {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}}} )) begin mem_req_d.bypass = 1'b1; state_d = WAIT_REFILL_GNT; @@ -460,7 +461,7 @@ module cache_ctrl //pragma translate_off `ifndef VERILATOR initial begin - assert (DCACHE_LINE_WIDTH == 128) + assert (CVA6Cfg.DCACHE_LINE_WIDTH == 128) else $error( "Cacheline width has to be 128 for the moment. But only small changes required in data select logic" diff --git a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv index 7f27d61b1..bf0b15039 100644 --- a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv +++ b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv @@ -67,9 +67,9 @@ module cva6_hpdcache_if_adapter assign hpdcache_req_is_uncacheable = !config_pkg::is_inside_cacheable_regions( CVA6Cfg, { - {64 - ariane_pkg::DCACHE_TAG_WIDTH{1'b0}} + {64 - CVA6Cfg.DCACHE_TAG_WIDTH{1'b0}} , cva6_req_i.address_tag - , {ariane_pkg::DCACHE_INDEX_WIDTH{1'b0}} + , {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} } ); @@ -140,9 +140,9 @@ module cva6_hpdcache_if_adapter assign hpdcache_req_is_uncacheable = !config_pkg::is_inside_cacheable_regions( CVA6Cfg, { - {64 - ariane_pkg::DCACHE_TAG_WIDTH{1'b0}} + {64 - CVA6Cfg.DCACHE_TAG_WIDTH{1'b0}} , hpdcache_req_o.addr_tag, - {ariane_pkg::DCACHE_INDEX_WIDTH{1'b0}} + {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} } ); diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem.sv b/core/cache_subsystem/cva6_hpdcache_subsystem.sv index aef74cc9f..581916199 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem.sv @@ -520,8 +520,7 @@ module cva6_hpdcache_subsystem // AXI arbiter instantiation // {{{ cva6_hpdcache_subsystem_axi_arbiter #( - .HPDcacheMemIdWidth (CVA6Cfg.MEM_TID_WIDTH), - .HPDcacheMemDataWidth (CVA6Cfg.AxiDataWidth), + .CVA6Cfg (CVA6Cfg), .hpdcache_mem_req_t (hpdcache_mem_req_t), .hpdcache_mem_req_w_t (hpdcache_mem_req_w_t), .hpdcache_mem_resp_r_t(hpdcache_mem_resp_r_t), diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv b/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv index 5af3ae6f6..8368f1f54 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem_axi_arbiter.sv @@ -16,8 +16,7 @@ module cva6_hpdcache_subsystem_axi_arbiter // Parameters // {{{ #( - parameter int HPDcacheMemIdWidth = 8, - parameter int HPDcacheMemDataWidth = 512, + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type hpdcache_mem_req_t = logic, parameter type hpdcache_mem_req_w_t = logic, parameter type hpdcache_mem_resp_r_t = logic, @@ -37,7 +36,7 @@ module cva6_hpdcache_subsystem_axi_arbiter parameter type axi_req_t = logic, parameter type axi_rsp_t = logic, - localparam type hpdcache_mem_id_t = logic [HPDcacheMemIdWidth-1:0] + localparam type hpdcache_mem_id_t = logic [CVA6Cfg.MEM_TID_WIDTH-1:0] ) // }}} @@ -117,23 +116,23 @@ module cva6_hpdcache_subsystem_axi_arbiter // Internal type definitions // {{{ - localparam int MEM_RESP_RT_DEPTH = (1 << HPDcacheMemIdWidth); + localparam int MEM_RESP_RT_DEPTH = (1 << CVA6Cfg.MEM_TID_WIDTH); typedef hpdcache_mem_id_t [MEM_RESP_RT_DEPTH-1:0] mem_resp_rt_t; - typedef logic [ariane_pkg::ICACHE_LINE_WIDTH-1:0] icache_resp_data_t; + typedef logic [CVA6Cfg.ICACHE_LINE_WIDTH-1:0] icache_resp_data_t; // }}} // Adapt the I$ interface to the HPDcache memory interface // {{{ - localparam int ICACHE_CL_WORDS = ariane_pkg::ICACHE_LINE_WIDTH / 64; + localparam int ICACHE_CL_WORDS = CVA6Cfg.ICACHE_LINE_WIDTH / 64; localparam int ICACHE_CL_WORD_INDEX = $clog2(ICACHE_CL_WORDS); - localparam int ICACHE_CL_SIZE = $clog2(ariane_pkg::ICACHE_LINE_WIDTH / 8); + localparam int ICACHE_CL_SIZE = $clog2(CVA6Cfg.ICACHE_LINE_WIDTH / 8); localparam int ICACHE_WORD_SIZE = 3; localparam int ICACHE_MEM_REQ_CL_LEN = - (ariane_pkg::ICACHE_LINE_WIDTH + HPDcacheMemDataWidth - 1)/HPDcacheMemDataWidth; + (CVA6Cfg.ICACHE_LINE_WIDTH + CVA6Cfg.AxiDataWidth - 1)/CVA6Cfg.AxiDataWidth; localparam int ICACHE_MEM_REQ_CL_SIZE = - (HPDcacheMemDataWidth <= ariane_pkg::ICACHE_LINE_WIDTH) ? + (CVA6Cfg.AxiDataWidth <= CVA6Cfg.ICACHE_LINE_WIDTH) ? $clog2( - HPDcacheMemDataWidth / 8 + CVA6Cfg.AxiDataWidth / 8 ) : ICACHE_CL_SIZE; // I$ request @@ -192,7 +191,7 @@ module cva6_hpdcache_subsystem_axi_arbiter icache_resp_data_t icache_miss_rdata; generate - if (HPDcacheMemDataWidth < ariane_pkg::ICACHE_LINE_WIDTH) begin + if (CVA6Cfg.AxiDataWidth < CVA6Cfg.ICACHE_LINE_WIDTH) begin hpdcache_fifo_reg #( .FIFO_DEPTH (1), .fifo_data_t(hpdcache_mem_id_t) @@ -210,8 +209,8 @@ module cva6_hpdcache_subsystem_axi_arbiter ); hpdcache_data_upsize #( - .WR_WIDTH(HPDcacheMemDataWidth), - .RD_WIDTH(ariane_pkg::ICACHE_LINE_WIDTH), + .WR_WIDTH(CVA6Cfg.AxiDataWidth), + .RD_WIDTH(CVA6Cfg.ICACHE_LINE_WIDTH), .DEPTH (1) ) i_icache_hpdcache_data_upsize ( .clk_i, @@ -252,7 +251,7 @@ module cva6_hpdcache_subsystem_axi_arbiter automatic logic [63:0] icache_miss_word; icache_miss_word_index = icache_miss_req_rdata.mem_req_addr[3+:ICACHE_CL_WORD_INDEX]; icache_miss_word = icache_miss_resp_data_rdata[icache_miss_word_index*64+:64]; - icache_miss_rdata = {{ariane_pkg::ICACHE_LINE_WIDTH - 64{1'b0}}, icache_miss_word}; + icache_miss_rdata = {{CVA6Cfg.ICACHE_LINE_WIDTH - 64{1'b0}}, icache_miss_word}; end else begin icache_miss_rdata = icache_miss_resp_data_rdata; end @@ -547,26 +546,26 @@ module cva6_hpdcache_subsystem_axi_arbiter // {{{ // pragma translate_off initial - assert (HPDcacheMemIdWidth <= AxiIdWidth) - else $fatal("HPDcacheMemIdWidth shall be less or equal to AxiIdWidth"); + assert (CVA6Cfg.MEM_TID_WIDTH <= AxiIdWidth) + else $fatal("MEM_TID_WIDTH shall be less or equal to AxiIdWidth"); initial - assert (HPDcacheMemIdWidth >= (hpdcache_pkg::HPDCACHE_MSHR_SET_WIDTH + hpdcache_pkg::HPDCACHE_MSHR_WAY_WIDTH + 1)) + assert (CVA6Cfg.MEM_TID_WIDTH >= (hpdcache_pkg::HPDCACHE_MSHR_SET_WIDTH + hpdcache_pkg::HPDCACHE_MSHR_WAY_WIDTH + 1)) else $fatal( - "HPDcacheMemIdWidth shall be wide enough to identify all pending HPDcache misses and Icache misses" + "MEM_TID_WIDTH shall be wide enough to identify all pending HPDcache misses and Icache misses" ); initial - assert (HPDcacheMemIdWidth >= (hpdcache_pkg::HPDCACHE_WBUF_DIR_PTR_WIDTH + 1)) + assert (CVA6Cfg.MEM_TID_WIDTH >= (hpdcache_pkg::HPDCACHE_WBUF_DIR_PTR_WIDTH + 1)) else $fatal( - "HPDcacheMemIdWidth shall be wide enough to identify all pending HPDcache cacheable writes and uncacheable writes" + "MEM_TID_WIDTH shall be wide enough to identify all pending HPDcache cacheable writes and uncacheable writes" ); initial - assert (HPDcacheMemDataWidth <= ariane_pkg::ICACHE_LINE_WIDTH) - else $fatal("HPDcacheMemDataWidth shall be less or equal to the width of a Icache line"); + assert (CVA6Cfg.AxiDataWidth <= CVA6Cfg.ICACHE_LINE_WIDTH) + else $fatal("AxiDataWidth shall be less or equal to the width of a Icache line"); initial - assert (HPDcacheMemDataWidth <= ariane_pkg::DCACHE_LINE_WIDTH) - else $fatal("HPDcacheMemDataWidth shall be less or equal to the width of a Dcache line"); + assert (CVA6Cfg.AxiDataWidth <= CVA6Cfg.DCACHE_LINE_WIDTH) + else $fatal("AxiDataWidth shall be less or equal to the width of a Dcache line"); // pragma translate_on // }}} diff --git a/core/cache_subsystem/cva6_icache.sv b/core/cache_subsystem/cva6_icache.sv index 95e366b5c..54c485ee3 100644 --- a/core/cache_subsystem/cva6_icache.sv +++ b/core/cache_subsystem/cva6_icache.sv @@ -62,14 +62,14 @@ module cva6_icache output icache_req_t mem_data_o ); - localparam ICACHE_OFFSET_WIDTH = $clog2(ariane_pkg::ICACHE_LINE_WIDTH / 8); - localparam ICACHE_NUM_WORDS = 2 ** (ariane_pkg::ICACHE_INDEX_WIDTH - ICACHE_OFFSET_WIDTH); + localparam ICACHE_OFFSET_WIDTH = $clog2(CVA6Cfg.ICACHE_LINE_WIDTH / 8); + localparam ICACHE_NUM_WORDS = 2 ** (CVA6Cfg.ICACHE_INDEX_WIDTH - ICACHE_OFFSET_WIDTH); localparam ICACHE_CL_IDX_WIDTH = $clog2(ICACHE_NUM_WORDS); // excluding byte offset // functions - function automatic logic [ariane_pkg::ICACHE_SET_ASSOC-1:0] icache_way_bin2oh( - input logic [L1I_WAY_WIDTH-1:0] in); - logic [ariane_pkg::ICACHE_SET_ASSOC-1:0] out; + function automatic logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] icache_way_bin2oh( + input logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] in); + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] out; out = '0; out[in] = 1'b1; return out; @@ -78,21 +78,21 @@ module cva6_icache // signals logic cache_en_d, cache_en_q; // cache is enabled logic [riscv::VLEN-1:0] vaddr_d, vaddr_q; - logic paddr_is_nc; // asserted if physical address is non-cacheable - logic [ICACHE_SET_ASSOC-1:0] cl_hit; // hit from tag compare - logic cache_rden; // triggers cache lookup - logic cache_wren; // triggers write to cacheline + logic paddr_is_nc; // asserted if physical address is non-cacheable + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] cl_hit; // hit from tag compare + logic cache_rden; // triggers cache lookup + logic cache_wren; // triggers write to cacheline logic cmp_en_d, cmp_en_q; // enable tag comparison in next cycle. used to cut long path due to NC signal. logic flush_d, flush_q; // used to register and signal pending flushes // replacement strategy - logic update_lfsr; // shift the LFSR - logic [$clog2(ICACHE_SET_ASSOC)-1:0] inv_way; // first non-valid encountered - logic [$clog2(ICACHE_SET_ASSOC)-1:0] rnd_way; // random index for replacement - logic [$clog2(ICACHE_SET_ASSOC)-1:0] repl_way; // way to replace - logic [ICACHE_SET_ASSOC-1:0] repl_way_oh_d, repl_way_oh_q; // way to replace (onehot) + logic update_lfsr; // shift the LFSR + logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] inv_way; // first non-valid encountered + logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] rnd_way; // random index for replacement + logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] repl_way; // way to replace + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] repl_way_oh_d, repl_way_oh_q; // way to replace (onehot) logic all_ways_valid; // we need to switch repl strategy since all are valid // invalidations / flushing @@ -102,20 +102,20 @@ module cva6_icache logic [ICACHE_CL_IDX_WIDTH-1:0] flush_cnt_d, flush_cnt_q; // used to flush cache entries // mem arrays - logic cl_we; // write enable to memory array - logic [ ICACHE_SET_ASSOC-1:0] cl_req; // request to memory array - logic [ICACHE_CL_IDX_WIDTH-1:0] cl_index; // this is a cache-line index, to memory array + logic cl_we; // write enable to memory array + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] cl_req; // request to memory array + logic [ ICACHE_CL_IDX_WIDTH-1:0] cl_index; // this is a cache-line index, to memory array logic [ICACHE_OFFSET_WIDTH-1:0] cl_offset_d, cl_offset_q; // offset in cache line - logic [ICACHE_TAG_WIDTH-1:0] cl_tag_d, cl_tag_q; // this is the cache tag - logic [ICACHE_TAG_WIDTH-1:0] cl_tag_rdata [ICACHE_SET_ASSOC-1:0]; // these are the tags coming from the tagmem - logic [ICACHE_LINE_WIDTH-1:0] cl_rdata [ICACHE_SET_ASSOC-1:0]; // these are the cachelines coming from the cache - logic [ICACHE_USER_LINE_WIDTH-1:0] cl_ruser[ICACHE_SET_ASSOC-1:0]; // these are the cachelines coming from the user cache - logic [ICACHE_SET_ASSOC-1:0][FETCH_WIDTH-1:0] cl_sel; // selected word from each cacheline - logic [ICACHE_SET_ASSOC-1:0][FETCH_USER_WIDTH-1:0] cl_user; // selected word from each cacheline - logic [ICACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs + logic [CVA6Cfg.ICACHE_TAG_WIDTH-1:0] cl_tag_d, cl_tag_q; // this is the cache tag + logic [CVA6Cfg.ICACHE_TAG_WIDTH-1:0] cl_tag_rdata [CVA6Cfg.ICACHE_SET_ASSOC-1:0]; // these are the tags coming from the tagmem + logic [CVA6Cfg.ICACHE_LINE_WIDTH-1:0] cl_rdata [CVA6Cfg.ICACHE_SET_ASSOC-1:0]; // these are the cachelines coming from the cache + logic [CVA6Cfg.ICACHE_USER_LINE_WIDTH-1:0] cl_ruser[CVA6Cfg.ICACHE_SET_ASSOC-1:0]; // these are the cachelines coming from the user cache + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0][CVA6Cfg.FETCH_WIDTH-1:0] cl_sel; // selected word from each cacheline + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0][CVA6Cfg.FETCH_USER_WIDTH-1:0] cl_user; // selected word from each cacheline + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs logic vld_we; // valid bits write enable - logic [ICACHE_SET_ASSOC-1:0] vld_wdata; // valid bits to write - logic [ICACHE_SET_ASSOC-1:0] vld_rdata; // valid bits coming from valid regs + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] vld_wdata; // valid bits to write + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] vld_rdata; // valid bits coming from valid regs logic [ICACHE_CL_IDX_WIDTH-1:0] vld_addr; // valid bit // cpmtroller FSM @@ -134,11 +134,11 @@ module cva6_icache /////////////////////////////////////////////////////// // extract tag from physical address, check if NC - 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; + assign cl_tag_d = (areq_i.fetch_valid) ? areq_i.fetch_paddr[CVA6Cfg.ICACHE_TAG_WIDTH+CVA6Cfg.ICACHE_INDEX_WIDTH-1:CVA6Cfg.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) | (~config_pkg::is_inside_cacheable_regions( - CVA6Cfg, {{64 - riscv::PLEN{1'b0}}, cl_tag_d, {ICACHE_INDEX_WIDTH{1'b0}}} + CVA6Cfg, {{64 - riscv::PLEN{1'b0}}, cl_tag_d, {CVA6Cfg.ICACHE_INDEX_WIDTH{1'b0}}} )); // pass exception through @@ -150,7 +150,7 @@ module cva6_icache assign areq_o.fetch_vaddr = {vaddr_q[riscv::VLEN-1:2], 2'b0}; // split virtual address into index and offset to address cache arrays - assign cl_index = vaddr_d[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH]; + assign cl_index = vaddr_d[CVA6Cfg.ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH]; if (CVA6Cfg.NOCType == config_pkg::NOC_TYPE_AXI4_ATOP) begin : gen_axi_offset @@ -159,16 +159,16 @@ module cva6_icache ( paddr_is_nc & mem_data_req_o ) ? {{ICACHE_OFFSET_WIDTH-1{1'b0}}, cl_offset_q[2]}<<2 : // needed since we transfer 32bit over a 64bit AXI bus in this case cl_offset_q; // request word address instead of cl address in case of NC access - assign mem_data_o.paddr = (paddr_is_nc) ? {cl_tag_d, vaddr_q[ICACHE_INDEX_WIDTH-1:3], 3'b0} : // align to 64bit - {cl_tag_d, vaddr_q[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH], {ICACHE_OFFSET_WIDTH{1'b0}}}; // align to cl + assign mem_data_o.paddr = (paddr_is_nc) ? {cl_tag_d, vaddr_q[CVA6Cfg.ICACHE_INDEX_WIDTH-1:3], 3'b0} : // align to 64bit + {cl_tag_d, vaddr_q[CVA6Cfg.ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH], {ICACHE_OFFSET_WIDTH{1'b0}}}; // align to cl end else begin : gen_piton_offset // icache fills are either cachelines or 4byte fills, depending on whether they go to the Piton I/O space or not. // since the piton cache system replicates the data, we can always index the full CL assign cl_offset_d = (dreq_o.ready & dreq_i.req) ? {dreq_i.vaddr >> 2, 2'b0} : cl_offset_q; // request word address instead of cl address in case of NC access - assign mem_data_o.paddr = (paddr_is_nc) ? {cl_tag_d, vaddr_q[ICACHE_INDEX_WIDTH-1:2], 2'b0} : // align to 32bit - {cl_tag_d, vaddr_q[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH], {ICACHE_OFFSET_WIDTH{1'b0}}}; // align to cl + assign mem_data_o.paddr = (paddr_is_nc) ? {cl_tag_d, vaddr_q[CVA6Cfg.ICACHE_INDEX_WIDTH-1:2], 2'b0} : // align to 32bit + {cl_tag_d, vaddr_q[CVA6Cfg.ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH], {ICACHE_OFFSET_WIDTH{1'b0}}}; // align to cl end @@ -371,7 +371,7 @@ module cva6_icache // invalidation/clearing address // flushing takes precedence over invals assign vld_addr = (flush_en) ? flush_cnt_q : - (inv_en) ? mem_rtrn_i.inv.idx[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH] : + (inv_en) ? mem_rtrn_i.inv.idx[CVA6Cfg.ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH] : cl_index; assign vld_req = (flush_en || cache_rden) ? '1 : @@ -398,7 +398,7 @@ module cva6_icache // find invalid cache line lzc #( - .WIDTH(ICACHE_SET_ASSOC) + .WIDTH(CVA6Cfg.ICACHE_SET_ASSOC) ) i_lzc ( .in_i (~vld_rdata), .cnt_o (inv_way), @@ -408,7 +408,7 @@ module cva6_icache // generate random cacheline index lfsr #( .LfsrWidth(8), - .OutWidth ($clog2(ariane_pkg::ICACHE_SET_ASSOC)) + .OutWidth (CVA6Cfg.ICACHE_SET_ASSOC_WIDTH) ) i_lfsr ( .clk_i (clk_i), .rst_ni(rst_ni), @@ -421,17 +421,17 @@ module cva6_icache // tag comparison, hit generation /////////////////////////////////////////////////////// - logic [$clog2(ICACHE_SET_ASSOC)-1:0] hit_idx; + logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] hit_idx; - for (genvar i = 0; i < ICACHE_SET_ASSOC; i++) begin : gen_tag_cmpsel + for (genvar i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin : gen_tag_cmpsel assign cl_hit[i] = (cl_tag_rdata[i] == cl_tag_d) & vld_rdata[i]; - assign cl_sel[i] = cl_rdata[i][{cl_offset_q, 3'b0}+:FETCH_WIDTH]; - assign cl_user[i] = cl_ruser[i][{cl_offset_q, 3'b0}+:FETCH_USER_WIDTH]; + assign cl_sel[i] = cl_rdata[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_WIDTH]; + assign cl_user[i] = cl_ruser[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH]; end lzc #( - .WIDTH(ICACHE_SET_ASSOC) + .WIDTH(CVA6Cfg.ICACHE_SET_ASSOC) ) i_lzc_hit ( .in_i (cl_hit), .cnt_o (hit_idx), @@ -443,8 +443,8 @@ module cva6_icache dreq_o.data = cl_sel[hit_idx]; dreq_o.user = cl_user[hit_idx]; end else begin - dreq_o.data = mem_rtrn_i.data[{cl_offset_q, 3'b0}+:FETCH_WIDTH]; - dreq_o.user = mem_rtrn_i.user[{cl_offset_q, 3'b0}+:FETCH_USER_WIDTH]; + dreq_o.data = mem_rtrn_i.data[{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_WIDTH]; + dreq_o.user = mem_rtrn_i.user[{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH]; end end @@ -453,13 +453,13 @@ module cva6_icache /////////////////////////////////////////////////////// - logic [ICACHE_TAG_WIDTH:0] cl_tag_valid_rdata[ICACHE_SET_ASSOC-1:0]; + logic [CVA6Cfg.ICACHE_TAG_WIDTH:0] cl_tag_valid_rdata[CVA6Cfg.ICACHE_SET_ASSOC-1:0]; - for (genvar i = 0; i < ICACHE_SET_ASSOC; i++) begin : gen_sram + for (genvar i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin : gen_sram // Tag RAM sram #( // tag + valid bit - .DATA_WIDTH(ICACHE_TAG_WIDTH + 1), + .DATA_WIDTH(CVA6Cfg.ICACHE_TAG_WIDTH + 1), .NUM_WORDS (ICACHE_NUM_WORDS) ) tag_sram ( .clk_i (clk_i), @@ -476,14 +476,14 @@ module cva6_icache .rdata_o(cl_tag_valid_rdata[i]) ); - assign cl_tag_rdata[i] = cl_tag_valid_rdata[i][ICACHE_TAG_WIDTH-1:0]; - assign vld_rdata[i] = cl_tag_valid_rdata[i][ICACHE_TAG_WIDTH]; + assign cl_tag_rdata[i] = cl_tag_valid_rdata[i][CVA6Cfg.ICACHE_TAG_WIDTH-1:0]; + assign vld_rdata[i] = cl_tag_valid_rdata[i][CVA6Cfg.ICACHE_TAG_WIDTH]; // Data RAM sram #( - .USER_WIDTH(ICACHE_USER_LINE_WIDTH), - .DATA_WIDTH(ICACHE_LINE_WIDTH), - .USER_EN (ariane_pkg::FETCH_USER_EN), + .USER_WIDTH(CVA6Cfg.ICACHE_USER_LINE_WIDTH), + .DATA_WIDTH(CVA6Cfg.ICACHE_LINE_WIDTH), + .USER_EN (CVA6Cfg.FETCH_USER_EN), .NUM_WORDS (ICACHE_NUM_WORDS) ) data_sram ( .clk_i (clk_i), @@ -555,16 +555,16 @@ module cva6_icache else $fatal(1, "[l1 icache] cl_hit signal must be hot1"); // this is only used for verification! - logic vld_mirror[ICACHE_NUM_WORDS-1:0][ariane_pkg::ICACHE_SET_ASSOC-1:0]; - logic [ariane_pkg::ICACHE_TAG_WIDTH-1:0] tag_mirror[ICACHE_NUM_WORDS-1:0][ariane_pkg::ICACHE_SET_ASSOC-1:0]; - logic [ariane_pkg::ICACHE_SET_ASSOC-1:0] tag_write_duplicate_test; + logic vld_mirror[ICACHE_NUM_WORDS-1:0][CVA6Cfg.ICACHE_SET_ASSOC-1:0]; + logic [CVA6Cfg.ICACHE_TAG_WIDTH-1:0] tag_mirror[ICACHE_NUM_WORDS-1:0][CVA6Cfg.ICACHE_SET_ASSOC-1:0]; + logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] tag_write_duplicate_test; always_ff @(posedge clk_i or negedge rst_ni) begin : p_mirror if (!rst_ni) begin vld_mirror <= '{default: '0}; tag_mirror <= '{default: '0}; end else begin - for (int i = 0; i < ICACHE_SET_ASSOC; i++) begin + for (int i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin if (vld_req[i] & vld_we) begin vld_mirror[vld_addr][i] <= vld_wdata[i]; tag_mirror[vld_addr][i] <= cl_tag_q; @@ -573,7 +573,7 @@ module cva6_icache end end - for (genvar i = 0; i < ICACHE_SET_ASSOC; i++) begin : gen_tag_dupl + for (genvar i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin : gen_tag_dupl assign tag_write_duplicate_test[i] = (tag_mirror[vld_addr][i] == cl_tag_q) & vld_mirror[vld_addr][i] & (|vld_wdata); end @@ -585,7 +585,7 @@ module cva6_icache initial begin // assert wrong parameterizations - assert (ICACHE_INDEX_WIDTH <= 12) + assert (CVA6Cfg.ICACHE_INDEX_WIDTH <= 12) else $fatal(1, "[l1 icache] cache index width can be maximum 12bit since VM uses 4kB pages"); end `endif diff --git a/core/cache_subsystem/cva6_icache_axi_wrapper.sv b/core/cache_subsystem/cva6_icache_axi_wrapper.sv index 3557390cf..c16597e8b 100644 --- a/core/cache_subsystem/cva6_icache_axi_wrapper.sv +++ b/core/cache_subsystem/cva6_icache_axi_wrapper.sv @@ -45,8 +45,8 @@ module cva6_icache_axi_wrapper input axi_rsp_t axi_resp_i ); - localparam AxiNumWords = (ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (ICACHE_LINE_WIDTH > DCACHE_LINE_WIDTH) + - (DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (ICACHE_LINE_WIDTH <= DCACHE_LINE_WIDTH) ; + localparam AxiNumWords = (CVA6Cfg.ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (CVA6Cfg.ICACHE_LINE_WIDTH > CVA6Cfg.DCACHE_LINE_WIDTH) + + (CVA6Cfg.DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (CVA6Cfg.ICACHE_LINE_WIDTH <= CVA6Cfg.DCACHE_LINE_WIDTH) ; logic icache_mem_rtrn_vld; icache_rtrn_t icache_mem_rtrn; @@ -71,7 +71,7 @@ module cva6_icache_axi_wrapper logic req_valid_d, req_valid_q; icache_req_t req_data_d, req_data_q; logic first_d, first_q; - logic [ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:0][CVA6Cfg.AxiDataWidth-1:0] + logic [CVA6Cfg.ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:0][CVA6Cfg.AxiDataWidth-1:0] rd_shift_d, rd_shift_q; // Keep read request asserted until we have an AXI grant. This is not guaranteed by icache (but @@ -86,7 +86,7 @@ module cva6_icache_axi_wrapper assign axi_rd_addr = CVA6Cfg.AxiAddrWidth'(req_data_d.paddr); // Fetch a full cache line on a cache miss, or a single word on a bypassed access - assign axi_rd_blen = (req_data_d.nc) ? '0 : ariane_pkg::ICACHE_LINE_WIDTH / 64 - 1; + assign axi_rd_blen = (req_data_d.nc) ? '0 : CVA6Cfg.ICACHE_LINE_WIDTH / 64 - 1; assign axi_rd_size = $clog2(CVA6Cfg.AxiDataWidth / 8); // Maximum assign axi_rd_id_in = req_data_d.tid; assign axi_rd_rdy = 1'b1; @@ -183,10 +183,10 @@ module cva6_icache_axi_wrapper if (axi_rd_valid) begin first_d = axi_rd_last; - if (ICACHE_LINE_WIDTH == CVA6Cfg.AxiDataWidth) begin + if (CVA6Cfg.ICACHE_LINE_WIDTH == CVA6Cfg.AxiDataWidth) begin rd_shift_d = axi_rd_data; end else begin - rd_shift_d = {axi_rd_data, rd_shift_q[ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:1]}; + rd_shift_d = {axi_rd_data, rd_shift_q[CVA6Cfg.ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:1]}; end // If this is a single word transaction, we need to make sure that word is placed at offset 0 diff --git a/core/cache_subsystem/miss_handler.sv b/core/cache_subsystem/miss_handler.sv index 346b6804e..ae072c7c6 100644 --- a/core/cache_subsystem/miss_handler.sv +++ b/core/cache_subsystem/miss_handler.sv @@ -60,11 +60,11 @@ module miss_handler input amo_req_t amo_req_i, output amo_resp_t amo_resp_o, // Port to SRAMs, for refill and eviction - output logic [DCACHE_SET_ASSOC-1:0] req_o, - output logic [DCACHE_INDEX_WIDTH-1:0] addr_o, // address into cache array + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] req_o, + output logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] addr_o, // address into cache array output cache_line_t data_o, output cl_be_t be_o, - input cache_line_t [DCACHE_SET_ASSOC-1:0] data_i, + input cache_line_t [CVA6Cfg.DCACHE_SET_ASSOC-1:0] data_i, output logic we_o ); @@ -72,18 +72,18 @@ module miss_handler parameter NR_BYPASS_PORTS = NR_PORTS + 1; // convert one hot to bin for -> needed for cache replacement - function automatic logic [std_cache_pkg::DCACHE_SET_ASSOC_WIDTH-1:0] one_hot_to_bin( - input logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] in); - for (int unsigned i = 0; i < ariane_pkg::DCACHE_SET_ASSOC; i++) begin + function automatic logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] one_hot_to_bin( + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] in); + for (int unsigned i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin if (in[i]) return i; end endfunction // get the first bit set, returns one hot value - function automatic logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] get_victim_cl( - input logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] valid_dirty); + function automatic logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] get_victim_cl( + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] valid_dirty); // one-hot return vector - logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] oh = '0; - for (int unsigned i = 0; i < ariane_pkg::DCACHE_SET_ASSOC; i++) begin + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] oh = '0; + for (int unsigned i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin if (valid_dirty[i]) begin oh[i] = 1'b1; return oh; @@ -112,61 +112,61 @@ module miss_handler // Registers mshr_t mshr_d, mshr_q; - logic [DCACHE_INDEX_WIDTH-1:0] cnt_d, cnt_q; - logic [DCACHE_SET_ASSOC-1:0] evict_way_d, evict_way_q; + logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] cnt_d, cnt_q; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] evict_way_d, evict_way_q; // cache line to evict cache_line_t evict_cl_d, evict_cl_q; logic serve_amo_d, serve_amo_q; // Request from one FSM - logic [ NR_PORTS-1:0] miss_req_valid; - logic [ NR_PORTS-1:0] miss_req_bypass; - logic [ NR_PORTS-1:0][63:0] miss_req_addr; - logic [ NR_PORTS-1:0][63:0] miss_req_wdata; - logic [ NR_PORTS-1:0] miss_req_we; - logic [ NR_PORTS-1:0][ 7:0] miss_req_be; - logic [ NR_PORTS-1:0][ 1:0] miss_req_size; + logic [ NR_PORTS-1:0] miss_req_valid; + logic [ NR_PORTS-1:0] miss_req_bypass; + logic [ NR_PORTS-1:0][63:0] miss_req_addr; + logic [ NR_PORTS-1:0][63:0] miss_req_wdata; + logic [ NR_PORTS-1:0] miss_req_we; + logic [ NR_PORTS-1:0][ 7:0] miss_req_be; + logic [ NR_PORTS-1:0][ 1:0] miss_req_size; // Bypass AMO port - bypass_req_t amo_bypass_req; - bypass_rsp_t amo_bypass_rsp; + bypass_req_t amo_bypass_req; + bypass_rsp_t amo_bypass_rsp; // Bypass ports <-> Arbiter - bypass_req_t [ NR_BYPASS_PORTS-1:0] bypass_ports_req; - bypass_rsp_t [ NR_BYPASS_PORTS-1:0] bypass_ports_rsp; + bypass_req_t [ NR_BYPASS_PORTS-1:0] bypass_ports_req; + bypass_rsp_t [ NR_BYPASS_PORTS-1:0] bypass_ports_rsp; // Arbiter <-> Bypass AXI adapter - bypass_req_t bypass_adapter_req; - bypass_rsp_t bypass_adapter_rsp; + bypass_req_t bypass_adapter_req; + bypass_rsp_t bypass_adapter_rsp; // Cache Line Refill <-> AXI - logic req_fsm_miss_valid; - logic [ 63:0] req_fsm_miss_addr; - logic [ DCACHE_LINE_WIDTH-1:0] req_fsm_miss_wdata; - logic req_fsm_miss_we; - logic [ (DCACHE_LINE_WIDTH/8)-1:0] req_fsm_miss_be; - ariane_pkg::ad_req_t req_fsm_miss_req; - logic [ 1:0] req_fsm_miss_size; + logic req_fsm_miss_valid; + logic [ 63:0] req_fsm_miss_addr; + logic [ CVA6Cfg.DCACHE_LINE_WIDTH-1:0] req_fsm_miss_wdata; + logic req_fsm_miss_we; + logic [ (CVA6Cfg.DCACHE_LINE_WIDTH/8)-1:0] req_fsm_miss_be; + ariane_pkg::ad_req_t req_fsm_miss_req; + logic [ 1:0] req_fsm_miss_size; - logic gnt_miss_fsm; - logic valid_miss_fsm; - logic [ (DCACHE_LINE_WIDTH/64)-1:0][63:0] data_miss_fsm; + logic gnt_miss_fsm; + logic valid_miss_fsm; + logic [ (CVA6Cfg.DCACHE_LINE_WIDTH/64)-1:0][63:0] data_miss_fsm; // Cache Management <-> LFSR - logic lfsr_enable; - logic [ DCACHE_SET_ASSOC-1:0] lfsr_oh; - logic [$clog2(DCACHE_SET_ASSOC-1)-1:0] lfsr_bin; + logic lfsr_enable; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] lfsr_oh; + logic [$clog2(CVA6Cfg.DCACHE_SET_ASSOC-1)-1:0] lfsr_bin; // AMOs - ariane_pkg::amo_t amo_op; - logic [ 63:0] amo_operand_b; + ariane_pkg::amo_t amo_op; + logic [ 63:0] amo_operand_b; // ------------------------------ // Cache Management // ------------------------------ always_comb begin : cache_management - automatic logic [DCACHE_SET_ASSOC-1:0] evict_way, valid_way; + automatic logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] evict_way, valid_way; - for (int unsigned i = 0; i < DCACHE_SET_ASSOC; i++) begin + for (int unsigned i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin evict_way[i] = data_i[i].valid & data_i[i].dirty; valid_way[i] = data_i[i].valid; end @@ -242,16 +242,16 @@ module miss_handler for (int unsigned i = 0; i < NR_PORTS; i++) begin // here comes the refill portion of code if (miss_req_valid[i] && !miss_req_bypass[i]) begin - state_d = MISS; + state_d = MISS; // we are taking another request so don't take the AMO - serve_amo_d = 1'b0; + serve_amo_d = 1'b0; // save to MSHR mshr_d.valid = 1'b1; - mshr_d.we = miss_req_we[i]; - mshr_d.id = i; - mshr_d.addr = miss_req_addr[i][DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:0]; + mshr_d.we = miss_req_we[i]; + mshr_d.id = i; + mshr_d.addr = miss_req_addr[i][CVA6Cfg.DCACHE_TAG_WIDTH+CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; mshr_d.wdata = miss_req_wdata[i]; - mshr_d.be = miss_req_be[i]; + mshr_d.be = miss_req_be[i]; break; end end @@ -262,7 +262,7 @@ module miss_handler // 1. Check if there is an empty cache-line // 2. If not -> evict one req_o = '1; - addr_o = mshr_q.addr[DCACHE_INDEX_WIDTH-1:0]; + addr_o = mshr_q.addr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; state_d = MISS_REPL; miss_o = 1'b1; end @@ -278,7 +278,7 @@ module miss_handler state_d = WB_CACHELINE_MISS; evict_cl_d.tag = data_i[lfsr_bin].tag; evict_cl_d.data = data_i[lfsr_bin].data; - cnt_d = mshr_q.addr[DCACHE_INDEX_WIDTH-1:0]; + cnt_d = mshr_q.addr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; // no - we can request a cache line now end else state_d = REQ_CACHELINE; // we have at least one free way @@ -303,18 +303,18 @@ module miss_handler // ~> replace the cacheline SAVE_CACHELINE: begin // calculate cacheline offset - automatic logic [$clog2(DCACHE_LINE_WIDTH)-1:0] cl_offset; - cl_offset = mshr_q.addr[DCACHE_BYTE_OFFSET-1:3] << 6; + automatic logic [$clog2(CVA6Cfg.DCACHE_LINE_WIDTH)-1:0] cl_offset; + cl_offset = mshr_q.addr[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:3] << 6; // we've got a valid response from refill unit if (valid_miss_fsm) begin - addr_o = mshr_q.addr[DCACHE_INDEX_WIDTH-1:0]; - req_o = evict_way_q; - we_o = 1'b1; - be_o = '1; - be_o.vldrty = evict_way_q; - data_o.tag = mshr_q.addr[DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:DCACHE_INDEX_WIDTH]; - data_o.data = data_miss_fsm; + addr_o = mshr_q.addr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; + req_o = evict_way_q; + we_o = 1'b1; + be_o = '1; + be_o.vldrty = evict_way_q; + data_o.tag = mshr_q.addr[CVA6Cfg.DCACHE_TAG_WIDTH+CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_INDEX_WIDTH]; + data_o.data = data_miss_fsm; data_o.valid = 1'b1; data_o.dirty = 1'b0; @@ -344,8 +344,8 @@ module miss_handler req_fsm_miss_valid = 1'b1; req_fsm_miss_addr = { evict_cl_q.tag, - cnt_q[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET], - {{DCACHE_BYTE_OFFSET} {1'b0}} + cnt_q[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH], + {{CVA6Cfg.DCACHE_OFFSET_WIDTH} {1'b0}} }; req_fsm_miss_be = '1; req_fsm_miss_we = 1'b1; @@ -386,14 +386,14 @@ module miss_handler // not dirty ~> increment and continue end else begin // increment and re-request - cnt_d = cnt_q + (1'b1 << DCACHE_BYTE_OFFSET); + cnt_d = cnt_q + (1'b1 << CVA6Cfg.DCACHE_OFFSET_WIDTH); state_d = FLUSH_REQ_STATUS; addr_o = cnt_q; req_o = 1'b1; be_o.vldrty = INVALIDATE_ON_FLUSH ? '1 : '0; we_o = 1'b1; // finished with flushing operation, go back to idle - if (cnt_q[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] == DCACHE_NUM_WORDS - 1) begin + if (cnt_q[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == CVA6Cfg.DCACHE_NUM_WORDS - 1) begin // only acknowledge if the flush wasn't triggered by an atomic flush_ack_o = ~serve_amo_q; // if we are flushing because of an AMO go to serve it @@ -415,9 +415,10 @@ module miss_handler we_o = 1'b1; // only write the dirty array be_o.vldrty = '1; - cnt_d = cnt_q + (1'b1 << DCACHE_BYTE_OFFSET); + cnt_d = cnt_q + (1'b1 << CVA6Cfg.DCACHE_OFFSET_WIDTH); // finished initialization - if (cnt_q[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] == DCACHE_NUM_WORDS - 1) state_d = IDLE; + if (cnt_q[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == CVA6Cfg.DCACHE_NUM_WORDS - 1) + state_d = IDLE; end // ---------------------- // AMOs @@ -501,12 +502,12 @@ module miss_handler for (int i = 0; i < NR_PORTS; i++) begin // check mshr for potential matching of other units, exclude the unit currently being served - if (mshr_q.valid && mshr_addr_i[i][55:DCACHE_BYTE_OFFSET] == mshr_q.addr[55:DCACHE_BYTE_OFFSET]) begin + if (mshr_q.valid && mshr_addr_i[i][55:CVA6Cfg.DCACHE_OFFSET_WIDTH] == mshr_q.addr[55:CVA6Cfg.DCACHE_OFFSET_WIDTH]) begin mshr_addr_matches_o[i] = 1'b1; end // same as previous, but checking only the index - if (mshr_q.valid && mshr_addr_i[i][DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] == mshr_q.addr[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET]) begin + if (mshr_q.valid && mshr_addr_i[i][CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == mshr_q.addr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) begin mshr_index_matches_o[i] = 1'b1; end end @@ -597,7 +598,7 @@ module miss_handler axi_adapter #( .CVA6Cfg (CVA6Cfg), .DATA_WIDTH (64), - .CACHELINE_BYTE_OFFSET(DCACHE_BYTE_OFFSET), + .CACHELINE_BYTE_OFFSET(CVA6Cfg.DCACHE_OFFSET_WIDTH), .axi_req_t (axi_req_t), .axi_rsp_t (axi_rsp_t) ) i_bypass_axi_adapter ( @@ -631,8 +632,8 @@ module miss_handler axi_adapter #( .CVA6Cfg (CVA6Cfg), - .DATA_WIDTH (DCACHE_LINE_WIDTH), - .CACHELINE_BYTE_OFFSET(DCACHE_BYTE_OFFSET), + .DATA_WIDTH (CVA6Cfg.DCACHE_LINE_WIDTH), + .CACHELINE_BYTE_OFFSET(CVA6Cfg.DCACHE_OFFSET_WIDTH), .axi_req_t (axi_req_t), .axi_rsp_t (axi_rsp_t) ) i_miss_axi_adapter ( @@ -661,7 +662,7 @@ module miss_handler // Replacement LFSR // ----------------- lfsr_8bit #( - .WIDTH(DCACHE_SET_ASSOC) + .WIDTH(CVA6Cfg.DCACHE_SET_ASSOC) ) i_lfsr ( .en_i (lfsr_enable), .refill_way_oh (lfsr_oh), diff --git a/core/cache_subsystem/std_cache_subsystem.sv b/core/cache_subsystem/std_cache_subsystem.sv index e5d077c7c..8ece88a36 100644 --- a/core/cache_subsystem/std_cache_subsystem.sv +++ b/core/cache_subsystem/std_cache_subsystem.sv @@ -183,7 +183,8 @@ module std_cache_subsystem .DATA_WIDTH (2), // we can have a maximum of 4 oustanding transactions as each port is blocking .DEPTH (4), - .FALL_THROUGH(1'b1) + .FALL_THROUGH(1'b1), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_fifo_w_channel ( .clk_i (clk_i), .rst_ni (rst_ni), diff --git a/core/cache_subsystem/std_nbdcache.sv b/core/cache_subsystem/std_nbdcache.sv index 466feaf20..d068e743b 100644 --- a/core/cache_subsystem/std_nbdcache.sv +++ b/core/cache_subsystem/std_nbdcache.sv @@ -46,16 +46,18 @@ module std_nbdcache import std_cache_pkg::*; + localparam DCACHE_DIRTY_WIDTH = CVA6Cfg.DCACHE_SET_ASSOC * 2; + localparam type cache_line_t = struct packed { - logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] tag; // tag array - logic [ariane_pkg::DCACHE_LINE_WIDTH-1:0] data; // data array - logic valid; // state array - logic dirty; // state array + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag; // tag array + logic [CVA6Cfg.DCACHE_LINE_WIDTH-1:0] data; // data array + logic valid; // state array + logic dirty; // state array }; localparam type cl_be_t = struct packed { - logic [(ariane_pkg::DCACHE_TAG_WIDTH+7)/8-1:0] tag; // byte enable into tag array - logic [(ariane_pkg::DCACHE_LINE_WIDTH+7)/8-1:0] data; // byte enable into data array - logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] vldrty; // bit enable into state array (valid for a pair of dirty/valid bits) + logic [(CVA6Cfg.DCACHE_TAG_WIDTH+7)/8-1:0] tag; // byte enable into tag array + logic [(CVA6Cfg.DCACHE_LINE_WIDTH+7)/8-1:0] data; // byte enable into data array + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] vldrty; // bit enable into state array (valid for a pair of dirty/valid bits) }; // ------------------------------- @@ -66,42 +68,42 @@ module std_nbdcache // 3. Load Unit // 4. Accelerator // 5. Store unit - logic [ NumPorts:0][ DCACHE_SET_ASSOC-1:0] req; - logic [ NumPorts:0][DCACHE_INDEX_WIDTH-1:0] addr; - logic [ NumPorts:0] gnt; - cache_line_t [ DCACHE_SET_ASSOC-1:0] rdata; - logic [ NumPorts:0][ DCACHE_TAG_WIDTH-1:0] tag; + logic [ NumPorts:0][ CVA6Cfg.DCACHE_SET_ASSOC-1:0] req; + logic [ NumPorts:0][CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] addr; + logic [ NumPorts:0] gnt; + cache_line_t [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] rdata; + logic [ NumPorts:0][ CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag; - cache_line_t [ NumPorts:0] wdata; - logic [ NumPorts:0] we; - cl_be_t [ NumPorts:0] be; - logic [ DCACHE_SET_ASSOC-1:0] hit_way; + cache_line_t [ NumPorts:0] wdata; + logic [ NumPorts:0] we; + cl_be_t [ NumPorts:0] be; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] hit_way; // ------------------------------- // Controller <-> Miss unit // ------------------------------- - logic [ NumPorts-1:0] busy; - logic [ NumPorts-1:0][ 55:0] mshr_addr; - logic [ NumPorts-1:0] mshr_addr_matches; - logic [ NumPorts-1:0] mshr_index_matches; - logic [ 63:0] critical_word; - logic critical_word_valid; + logic [ NumPorts-1:0] busy; + logic [ NumPorts-1:0][ 55:0] mshr_addr; + logic [ NumPorts-1:0] mshr_addr_matches; + logic [ NumPorts-1:0] mshr_index_matches; + logic [ 63:0] critical_word; + logic critical_word_valid; - logic [ NumPorts-1:0][ $bits(miss_req_t)-1:0] miss_req; - logic [ NumPorts-1:0] miss_gnt; - logic [ NumPorts-1:0] active_serving; + logic [ NumPorts-1:0][ $bits(miss_req_t)-1:0] miss_req; + logic [ NumPorts-1:0] miss_gnt; + logic [ NumPorts-1:0] active_serving; - logic [ NumPorts-1:0] bypass_gnt; - logic [ NumPorts-1:0] bypass_valid; - logic [ NumPorts-1:0][ 63:0] bypass_data; + logic [ NumPorts-1:0] bypass_gnt; + logic [ NumPorts-1:0] bypass_valid; + logic [ NumPorts-1:0][ 63:0] bypass_data; // ------------------------------- // Arbiter <-> Datram, // ------------------------------- - logic [ DCACHE_SET_ASSOC-1:0] req_ram; - logic [DCACHE_INDEX_WIDTH-1:0] addr_ram; - logic we_ram; - cache_line_t wdata_ram; - cache_line_t [ DCACHE_SET_ASSOC-1:0] rdata_ram; - cl_be_t be_ram; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] req_ram; + logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] addr_ram; + logic we_ram; + cache_line_t wdata_ram; + cache_line_t [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] rdata_ram; + cl_be_t be_ram; // ------------------ // Cache Controller @@ -193,15 +195,15 @@ module std_nbdcache // -------------- // Memory Arrays // -------------- - for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin : sram_block + for (genvar i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin : sram_block sram #( - .DATA_WIDTH(DCACHE_LINE_WIDTH), - .NUM_WORDS (DCACHE_NUM_WORDS) + .DATA_WIDTH(CVA6Cfg.DCACHE_LINE_WIDTH), + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) data_sram ( .req_i (req_ram[i]), .rst_ni (rst_ni), .we_i (we_ram), - .addr_i (addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET]), + .addr_i (addr_ram[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]), .wuser_i('0), .wdata_i(wdata_ram.data), .be_i (be_ram.data), @@ -211,13 +213,13 @@ module std_nbdcache ); sram #( - .DATA_WIDTH(DCACHE_TAG_WIDTH), - .NUM_WORDS (DCACHE_NUM_WORDS) + .DATA_WIDTH(CVA6Cfg.DCACHE_TAG_WIDTH), + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) tag_sram ( .req_i (req_ram[i]), .rst_ni (rst_ni), .we_i (we_ram), - .addr_i (addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET]), + .addr_i (addr_ram[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]), .wuser_i('0), .wdata_i(wdata_ram.tag), .be_i (be_ram.tag), @@ -237,7 +239,7 @@ module std_nbdcache // you can use it here to save the extra 4x overhead introduced by this workaround. logic [4*DCACHE_DIRTY_WIDTH-1:0] dirty_wdata, dirty_rdata; - for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin + for (genvar i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin assign dirty_wdata[8*i] = wdata_ram.dirty; assign dirty_wdata[8*i+1] = wdata_ram.valid; assign rdata_ram[i].dirty = dirty_rdata[8*i]; @@ -247,13 +249,13 @@ module std_nbdcache sram #( .USER_WIDTH(1), .DATA_WIDTH(4 * DCACHE_DIRTY_WIDTH), - .NUM_WORDS (DCACHE_NUM_WORDS) + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) valid_dirty_sram ( .clk_i (clk_i), .rst_ni (rst_ni), .req_i (|req_ram), .we_i (we_ram), - .addr_i (addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET]), + .addr_i (addr_ram[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]), .wuser_i('0), .wdata_i(dirty_wdata), .be_i (be_ram.vldrty), @@ -265,12 +267,11 @@ module std_nbdcache // Tag Comparison and memory arbitration // ------------------------------------------------ tag_cmp #( - .CVA6Cfg (CVA6Cfg), - .NR_PORTS (NumPorts + 1), - .ADDR_WIDTH (DCACHE_INDEX_WIDTH), - .l_data_t (cache_line_t), - .l_be_t (cl_be_t), - .DCACHE_SET_ASSOC(DCACHE_SET_ASSOC) + .CVA6Cfg (CVA6Cfg), + .NR_PORTS (NumPorts + 1), + .ADDR_WIDTH(CVA6Cfg.DCACHE_INDEX_WIDTH), + .l_data_t (cache_line_t), + .l_be_t (cl_be_t) ) i_tag_cmp ( .req_i (req), .gnt_o (gnt), @@ -294,7 +295,7 @@ module std_nbdcache //pragma translate_off initial begin - assert (DCACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth inside {2, 4, 8, 16}) + assert (CVA6Cfg.DCACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth inside {2, 4, 8, 16}) else $fatal(1, "Cache line size needs to be a power of two multiple of AxiDataWidth"); end //pragma translate_on diff --git a/core/cache_subsystem/tag_cmp.sv b/core/cache_subsystem/tag_cmp.sv index f5d2d9e81..ff7b805fd 100644 --- a/core/cache_subsystem/tag_cmp.sv +++ b/core/cache_subsystem/tag_cmp.sv @@ -16,46 +16,45 @@ // checks for hit or miss on cache // module tag_cmp #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter int unsigned NR_PORTS = 3, - parameter int unsigned ADDR_WIDTH = 64, - parameter type l_data_t = logic, - parameter type l_be_t = logic, - parameter int unsigned DCACHE_SET_ASSOC = 8 + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter int unsigned NR_PORTS = 3, + parameter int unsigned ADDR_WIDTH = 64, + parameter type l_data_t = logic, + parameter type l_be_t = logic ) ( input logic clk_i, input logic rst_ni, - input logic [NR_PORTS-1:0][DCACHE_SET_ASSOC-1:0] req_i, + input logic [NR_PORTS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] req_i, output logic [NR_PORTS-1:0] gnt_o, input logic [NR_PORTS-1:0][ADDR_WIDTH-1:0] addr_i, input l_data_t [NR_PORTS-1:0] wdata_i, input logic [NR_PORTS-1:0] we_i, input l_be_t [NR_PORTS-1:0] be_i, - output l_data_t [DCACHE_SET_ASSOC-1:0] rdata_o, - input logic [NR_PORTS-1:0][ariane_pkg::DCACHE_TAG_WIDTH-1:0] tag_i, // tag in - comes one cycle later - output logic [DCACHE_SET_ASSOC-1:0] hit_way_o, // we've got a hit on the corresponding way + output l_data_t [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rdata_o, + input logic [NR_PORTS-1:0][CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag_i, // tag in - comes one cycle later + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] hit_way_o, // we've got a hit on the corresponding way - output logic [DCACHE_SET_ASSOC-1:0] req_o, - output logic [ ADDR_WIDTH-1:0] addr_o, - output l_data_t wdata_o, - output logic we_o, - output l_be_t be_o, - input l_data_t [DCACHE_SET_ASSOC-1:0] rdata_i + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] req_o, + output logic [ ADDR_WIDTH-1:0] addr_o, + output l_data_t wdata_o, + output logic we_o, + output l_be_t be_o, + input l_data_t [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rdata_i ); assign rdata_o = rdata_i; // one hot encoded logic [NR_PORTS-1:0] id_d, id_q; - logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] sel_tag; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] sel_tag; always_comb begin : tag_sel sel_tag = '0; for (int unsigned i = 0; i < NR_PORTS; i++) if (id_q[i]) sel_tag = tag_i[i]; end - for (genvar j = 0; j < DCACHE_SET_ASSOC; j++) begin : tag_cmp + for (genvar j = 0; j < CVA6Cfg.DCACHE_SET_ASSOC; j++) begin : tag_cmp assign hit_way_o[j] = (sel_tag == rdata_i[j].tag) ? rdata_i[j].valid : 1'b0; end diff --git a/core/cache_subsystem/wt_axi_adapter.sv b/core/cache_subsystem/wt_axi_adapter.sv index 0de7033b4..9ad41aa3d 100644 --- a/core/cache_subsystem/wt_axi_adapter.sv +++ b/core/cache_subsystem/wt_axi_adapter.sv @@ -59,11 +59,11 @@ module wt_axi_adapter ); // support up to 512bit cache lines - localparam AxiNumWords = (ariane_pkg::ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (ariane_pkg::ICACHE_LINE_WIDTH > ariane_pkg::DCACHE_LINE_WIDTH) + - (ariane_pkg::DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (ariane_pkg::ICACHE_LINE_WIDTH <= ariane_pkg::DCACHE_LINE_WIDTH) ; + localparam AxiNumWords = (CVA6Cfg.ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (CVA6Cfg.ICACHE_LINE_WIDTH > CVA6Cfg.DCACHE_LINE_WIDTH) + + (CVA6Cfg.DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth) * (CVA6Cfg.ICACHE_LINE_WIDTH <= CVA6Cfg.DCACHE_LINE_WIDTH) ; localparam MaxNumWords = $clog2(CVA6Cfg.AxiDataWidth / 8); - localparam AxiRdBlenIcache = ariane_pkg::ICACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth - 1; - localparam AxiRdBlenDcache = ariane_pkg::DCACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth - 1; + localparam AxiRdBlenIcache = CVA6Cfg.ICACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth - 1; + localparam AxiRdBlenDcache = CVA6Cfg.DCACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth - 1; /////////////////////////////////////////////////////// // request path @@ -311,8 +311,9 @@ module wt_axi_adapter end fifo_v3 #( - .dtype(icache_req_t), - .DEPTH(ReqFifoDepth) + .dtype (icache_req_t), + .DEPTH (ReqFifoDepth), + .FPGA_EN(CVA6Cfg.FPGA_EN) ) i_icache_data_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -328,8 +329,9 @@ module wt_axi_adapter ); fifo_v3 #( - .dtype(dcache_req_t), - .DEPTH(ReqFifoDepth) + .dtype (dcache_req_t), + .DEPTH (ReqFifoDepth), + .FPGA_EN(CVA6Cfg.FPGA_EN) ) i_dcache_data_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -353,7 +355,8 @@ module wt_axi_adapter fifo_v3 #( .DATA_WIDTH(CVA6Cfg.MEM_TID_WIDTH), - .DEPTH (MetaFifoDepth) + .DEPTH (MetaFifoDepth), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_rd_icache_id ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -370,7 +373,8 @@ module wt_axi_adapter fifo_v3 #( .DATA_WIDTH(CVA6Cfg.MEM_TID_WIDTH), - .DEPTH (MetaFifoDepth) + .DEPTH (MetaFifoDepth), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_rd_dcache_id ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -387,7 +391,8 @@ module wt_axi_adapter fifo_v3 #( .DATA_WIDTH(CVA6Cfg.MEM_TID_WIDTH), - .DEPTH (MetaFifoDepth) + .DEPTH (MetaFifoDepth), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_wr_dcache_id ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -417,7 +422,8 @@ module wt_axi_adapter fifo_v3 #( .DATA_WIDTH (CVA6Cfg.AxiIdWidth + 1), .DEPTH (MetaFifoDepth), - .FALL_THROUGH(1'b1) + .FALL_THROUGH(1'b1), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_b_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -434,13 +440,13 @@ module wt_axi_adapter // buffer read responses in shift regs logic icache_first_d, icache_first_q, dcache_first_d, dcache_first_q; - logic [ICACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:0][CVA6Cfg.AxiUserWidth-1:0] + logic [CVA6Cfg.ICACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:0][CVA6Cfg.AxiUserWidth-1:0] icache_rd_shift_user_d, icache_rd_shift_user_q; - logic [DCACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:0][CVA6Cfg.AxiUserWidth-1:0] + logic [CVA6Cfg.DCACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:0][CVA6Cfg.AxiUserWidth-1:0] dcache_rd_shift_user_d, dcache_rd_shift_user_q; - logic [ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:0][CVA6Cfg.AxiDataWidth-1:0] + logic [CVA6Cfg.ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:0][CVA6Cfg.AxiDataWidth-1:0] icache_rd_shift_d, icache_rd_shift_q; - logic [DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:0][CVA6Cfg.AxiDataWidth-1:0] + logic [CVA6Cfg.DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:0][CVA6Cfg.AxiDataWidth-1:0] dcache_rd_shift_d, dcache_rd_shift_q; wt_cache_pkg::dcache_in_t dcache_rtrn_type_d, dcache_rtrn_type_q; dcache_inval_t dcache_rtrn_inv_d, dcache_rtrn_inv_q; @@ -473,15 +479,15 @@ module wt_axi_adapter if (icache_rtrn_rd_en) begin icache_first_d = axi_rd_last; - if (ICACHE_LINE_WIDTH == CVA6Cfg.AxiDataWidth) begin + if (CVA6Cfg.ICACHE_LINE_WIDTH == CVA6Cfg.AxiDataWidth) begin icache_rd_shift_d[0] = axi_rd_data; end else begin icache_rd_shift_d = { - axi_rd_data, icache_rd_shift_q[ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:1] + axi_rd_data, icache_rd_shift_q[CVA6Cfg.ICACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:1] }; end icache_rd_shift_user_d = { - axi_rd_user, icache_rd_shift_user_q[ICACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:1] + axi_rd_user, icache_rd_shift_user_q[CVA6Cfg.ICACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:1] }; // if this is a single word transaction, we need to make sure that word is placed at offset 0 if (icache_first_q) begin @@ -492,15 +498,15 @@ module wt_axi_adapter if (dcache_rtrn_rd_en) begin dcache_first_d = axi_rd_last; - if (DCACHE_LINE_WIDTH == CVA6Cfg.AxiDataWidth) begin + if (CVA6Cfg.DCACHE_LINE_WIDTH == CVA6Cfg.AxiDataWidth) begin dcache_rd_shift_d[0] = axi_rd_data; end else begin dcache_rd_shift_d = { - axi_rd_data, dcache_rd_shift_q[DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:1] + axi_rd_data, dcache_rd_shift_q[CVA6Cfg.DCACHE_LINE_WIDTH/CVA6Cfg.AxiDataWidth-1:1] }; end dcache_rd_shift_user_d = { - axi_rd_user, dcache_rd_shift_user_q[DCACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:1] + axi_rd_user, dcache_rd_shift_user_q[CVA6Cfg.DCACHE_USER_LINE_WIDTH/CVA6Cfg.AxiUserWidth-1:1] }; // if this is a single word transaction, we need to make sure that word is placed at offset 0 if (dcache_first_q) begin @@ -549,7 +555,7 @@ module wt_axi_adapter dcache_rtrn_type_d = wt_cache_pkg::DCACHE_INV_REQ; dcache_rtrn_vld_d = 1'b1; dcache_rtrn_inv_d.all = 1'b1; - dcache_rtrn_inv_d.idx = inval_addr_i[ariane_pkg::DCACHE_INDEX_WIDTH-1:0]; + dcache_rtrn_inv_d.idx = inval_addr_i[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; ////////////////////////////////////// // dcache needs some special treatment // for arbitration and decoding of atomics @@ -563,7 +569,7 @@ module wt_axi_adapter dcache_rtrn_vld_d = 1'b1; dcache_rtrn_inv_d.all = 1'b1; - dcache_rtrn_inv_d.idx = dcache_data.paddr[ariane_pkg::DCACHE_INDEX_WIDTH-1:0]; + dcache_rtrn_inv_d.idx = dcache_data.paddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; ////////////////////////////////////// // read responses // note that in case of atomics, the dcache sequentializes requests and diff --git a/core/cache_subsystem/wt_cache_subsystem.sv b/core/cache_subsystem/wt_cache_subsystem.sv index 4145c2be6..fc5407008 100644 --- a/core/cache_subsystem/wt_cache_subsystem.sv +++ b/core/cache_subsystem/wt_cache_subsystem.sv @@ -55,7 +55,7 @@ module wt_cache_subsystem output logic dcache_flush_ack_o, // send a single cycle acknowledge signal when the cache is flushed output logic dcache_miss_o, // we missed on a ld/st // For Performance Counter - output logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, + output logic [NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // AMO interface input amo_req_t dcache_amo_req_i, output amo_resp_t dcache_amo_resp_o, @@ -79,17 +79,17 @@ module wt_cache_subsystem localparam type dcache_inval_t = struct packed { logic vld; // invalidate only affected way logic all; // invalidate all ways - logic [ariane_pkg::DCACHE_INDEX_WIDTH-1:0] idx; // physical address to invalidate - logic [L15_WAY_WIDTH-1:0] way; // way to invalidate + logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] idx; // physical address to invalidate + logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] way; // way to invalidate }; localparam type dcache_req_t = struct packed { wt_cache_pkg::dcache_out_t rtype; // see definitions above logic [2:0] size; // transaction size: 000=Byte 001=2Byte; 010=4Byte; 011=8Byte; 111=Cache line (16/32Byte) - logic [L1D_WAY_WIDTH-1:0] way; // way to replace + logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] way; // way to replace logic [riscv::PLEN-1:0] paddr; // physical address logic [riscv::XLEN-1:0] data; // word width of processor (no block stores at the moment) - logic [ariane_pkg::DATA_USER_WIDTH-1:0] user; // user width of processor (no block stores at the moment) + logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] user; // user width of processor (no block stores at the moment) logic nc; // noncacheable logic [CVA6Cfg.MEM_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane) ariane_pkg::amo_t amo_op; // amo opcode @@ -97,8 +97,8 @@ module wt_cache_subsystem localparam type dcache_rtrn_t = struct packed { wt_cache_pkg::dcache_in_t rtype; // see definitions above - logic [ariane_pkg::DCACHE_LINE_WIDTH-1:0] data; // full cache line width - logic [ariane_pkg::DCACHE_USER_LINE_WIDTH-1:0] user; // user bits + logic [CVA6Cfg.DCACHE_LINE_WIDTH-1:0] data; // full cache line width + logic [CVA6Cfg.DCACHE_USER_LINE_WIDTH-1:0] user; // user bits dcache_inval_t inv; // invalidation vector logic [CVA6Cfg.MEM_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane) }; diff --git a/core/cache_subsystem/wt_dcache.sv b/core/cache_subsystem/wt_dcache.sv index c2249f036..669d9ea45 100644 --- a/core/cache_subsystem/wt_dcache.sv +++ b/core/cache_subsystem/wt_dcache.sv @@ -46,7 +46,7 @@ module wt_dcache input dcache_req_i_t [NumPorts-1:0] req_ports_i, output dcache_req_o_t [NumPorts-1:0] req_ports_o, - output logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, + output logic [NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, input logic mem_rtrn_vld_i, input dcache_rtrn_t mem_rtrn_i, @@ -55,72 +55,74 @@ module wt_dcache output dcache_req_t mem_data_o ); + localparam DCACHE_CL_IDX_WIDTH = $clog2(CVA6Cfg.DCACHE_NUM_WORDS); + localparam type wbuffer_t = struct packed { - logic [ariane_pkg::DCACHE_TAG_WIDTH+(ariane_pkg::DCACHE_INDEX_WIDTH-riscv::XLEN_ALIGN_BYTES)-1:0] wtag; + logic [CVA6Cfg.DCACHE_TAG_WIDTH+(CVA6Cfg.DCACHE_INDEX_WIDTH-CVA6Cfg.XLEN_ALIGN_BYTES)-1:0] wtag; logic [riscv::XLEN-1:0] data; - logic [ariane_pkg::DCACHE_USER_WIDTH-1:0] user; + logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] user; logic [(riscv::XLEN/8)-1:0] dirty; // byte is dirty logic [(riscv::XLEN/8)-1:0] valid; // byte is valid logic [(riscv::XLEN/8)-1:0] txblock; // byte is part of transaction in-flight logic checked; // if cache state of this word has been checked - logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] hit_oh; // valid way in the cache + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] hit_oh; // valid way in the cache }; // miss unit <-> read controllers - logic cache_en; + logic cache_en; // miss unit <-> memory - logic wr_cl_vld; - logic wr_cl_nc; - logic [ DCACHE_SET_ASSOC-1:0] wr_cl_we; - logic [ DCACHE_TAG_WIDTH-1:0] wr_cl_tag; - logic [ DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx; - logic [ DCACHE_OFFSET_WIDTH-1:0] wr_cl_off; - logic [ DCACHE_LINE_WIDTH-1:0] wr_cl_data; - logic [DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user; - logic [ DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be; - logic [ DCACHE_SET_ASSOC-1:0] wr_vld_bits; - logic [ DCACHE_SET_ASSOC-1:0] wr_req; - logic wr_ack; - logic [ DCACHE_CL_IDX_WIDTH-1:0] wr_idx; - logic [ DCACHE_OFFSET_WIDTH-1:0] wr_off; - logic [ riscv::XLEN-1:0] wr_data; - logic [ (riscv::XLEN/8)-1:0] wr_data_be; - logic [ DCACHE_USER_WIDTH-1:0] wr_user; + logic wr_cl_vld; + logic wr_cl_nc; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_cl_we; + logic [ CVA6Cfg.DCACHE_TAG_WIDTH-1:0] wr_cl_tag; + logic [ DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx; + logic [ CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] wr_cl_off; + logic [ CVA6Cfg.DCACHE_LINE_WIDTH-1:0] wr_cl_data; + logic [CVA6Cfg.DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user; + logic [ CVA6Cfg.DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_vld_bits; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_req; + logic wr_ack; + logic [ DCACHE_CL_IDX_WIDTH-1:0] wr_idx; + logic [ CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] wr_off; + logic [ riscv::XLEN-1:0] wr_data; + logic [ (riscv::XLEN/8)-1:0] wr_data_be; + logic [ CVA6Cfg.DCACHE_USER_WIDTH-1:0] wr_user; // miss unit <-> controllers/wbuffer - logic [ NumPorts-1:0] miss_req; - logic [ NumPorts-1:0] miss_ack; - logic [ NumPorts-1:0] miss_nc; - logic [ NumPorts-1:0] miss_we; - logic [ NumPorts-1:0][ riscv::XLEN-1:0] miss_wdata; - logic [ NumPorts-1:0][ DCACHE_USER_WIDTH-1:0] miss_wuser; - logic [ NumPorts-1:0][ riscv::PLEN-1:0] miss_paddr; - logic [ NumPorts-1:0][ 2:0] miss_size; - logic [ NumPorts-1:0][CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id; - logic [ NumPorts-1:0] miss_replay; - logic [ NumPorts-1:0] miss_rtrn_vld; - logic [ CVA6Cfg.MEM_TID_WIDTH-1:0] miss_rtrn_id; + logic [ NumPorts-1:0] miss_req; + logic [ NumPorts-1:0] miss_ack; + logic [ NumPorts-1:0] miss_nc; + logic [ NumPorts-1:0] miss_we; + logic [ NumPorts-1:0][ riscv::XLEN-1:0] miss_wdata; + logic [ NumPorts-1:0][ CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser; + logic [ NumPorts-1:0][ riscv::PLEN-1:0] miss_paddr; + logic [ NumPorts-1:0][ 2:0] miss_size; + logic [ NumPorts-1:0][ CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id; + logic [ NumPorts-1:0] miss_replay; + logic [ NumPorts-1:0] miss_rtrn_vld; + logic [ CVA6Cfg.MEM_TID_WIDTH-1:0] miss_rtrn_id; // memory <-> read controllers/miss unit - logic [ NumPorts-1:0] rd_prio; - logic [ NumPorts-1:0] rd_tag_only; - logic [ NumPorts-1:0] rd_req; - logic [ NumPorts-1:0] rd_ack; - logic [ NumPorts-1:0][ DCACHE_TAG_WIDTH-1:0] rd_tag; - logic [ NumPorts-1:0][ DCACHE_CL_IDX_WIDTH-1:0] rd_idx; - logic [ NumPorts-1:0][ DCACHE_OFFSET_WIDTH-1:0] rd_off; - logic [ riscv::XLEN-1:0] rd_data; - logic [ DCACHE_USER_WIDTH-1:0] rd_user; - logic [ DCACHE_SET_ASSOC-1:0] rd_vld_bits; - logic [ DCACHE_SET_ASSOC-1:0] rd_hit_oh; + logic [ NumPorts-1:0] rd_prio; + logic [ NumPorts-1:0] rd_tag_only; + logic [ NumPorts-1:0] rd_req; + logic [ NumPorts-1:0] rd_ack; + logic [ NumPorts-1:0][ CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag; + logic [ NumPorts-1:0][ DCACHE_CL_IDX_WIDTH-1:0] rd_idx; + logic [ NumPorts-1:0][CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] rd_off; + logic [ riscv::XLEN-1:0] rd_data; + logic [ CVA6Cfg.DCACHE_USER_WIDTH-1:0] rd_user; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_vld_bits; + logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh; // miss unit <-> wbuffer - logic [ CVA6Cfg.DCACHE_MAX_TX-1:0][ riscv::PLEN-1:0] tx_paddr; - logic [ CVA6Cfg.DCACHE_MAX_TX-1:0] tx_vld; + logic [ CVA6Cfg.DCACHE_MAX_TX-1:0][ riscv::PLEN-1:0] tx_paddr; + logic [ CVA6Cfg.DCACHE_MAX_TX-1:0] tx_vld; // wbuffer <-> memory - wbuffer_t [ DCACHE_WBUF_DEPTH-1:0] wbuffer_data; + wbuffer_t [ DCACHE_WBUF_DEPTH-1:0] wbuffer_data; /////////////////////////////////////////////////////// @@ -129,6 +131,7 @@ module wt_dcache wt_dcache_missunit #( .CVA6Cfg(CVA6Cfg), + .DCACHE_CL_IDX_WIDTH(DCACHE_CL_IDX_WIDTH), .dcache_req_t(dcache_req_t), .dcache_rtrn_t(dcache_rtrn_t), .AmoTxId(RdAmoTxId), @@ -192,6 +195,7 @@ module wt_dcache assign rd_prio[k] = 1'b1; wt_dcache_ctrl #( .CVA6Cfg(CVA6Cfg), + .DCACHE_CL_IDX_WIDTH(DCACHE_CL_IDX_WIDTH), .dcache_req_i_t(dcache_req_i_t), .dcache_req_o_t(dcache_req_o_t), .RdTxId(RdAmoTxId) @@ -235,15 +239,15 @@ module wt_dcache assign miss_req[k] = 1'b0; assign miss_we[k] = 1'b0; assign miss_wdata[k] = {{riscv::XLEN} {1'b0}}; - assign miss_wuser[k] = {{DCACHE_USER_WIDTH} {1'b0}}; - assign miss_vld_bits_o[k] = {{DCACHE_SET_ASSOC} {1'b0}}; + assign miss_wuser[k] = {{CVA6Cfg.DCACHE_USER_WIDTH} {1'b0}}; + assign miss_vld_bits_o[k] = {{CVA6Cfg.DCACHE_SET_ASSOC} {1'b0}}; assign miss_paddr[k] = {{riscv::PLEN} {1'b0}}; assign miss_nc[k] = 1'b0; assign miss_size[k] = 3'b0; assign miss_id[k] = {{CVA6Cfg.MEM_TID_WIDTH} {1'b0}}; - assign rd_tag[k] = {{DCACHE_TAG_WIDTH} {1'b0}}; + assign rd_tag[k] = {{CVA6Cfg.DCACHE_TAG_WIDTH} {1'b0}}; assign rd_idx[k] = {{DCACHE_CL_IDX_WIDTH} {1'b0}}; - assign rd_off[k] = {{DCACHE_OFFSET_WIDTH} {1'b0}}; + assign rd_off[k] = {{CVA6Cfg.DCACHE_OFFSET_WIDTH} {1'b0}}; assign rd_req[k] = 1'b0; assign rd_tag_only[k] = 1'b0; end @@ -258,6 +262,7 @@ module wt_dcache wt_dcache_wbuffer #( .CVA6Cfg(CVA6Cfg), + .DCACHE_CL_IDX_WIDTH(DCACHE_CL_IDX_WIDTH), .dcache_req_i_t(dcache_req_i_t), .dcache_req_o_t(dcache_req_o_t), .wbuffer_t(wbuffer_t) @@ -317,9 +322,10 @@ module wt_dcache /////////////////////////////////////////////////////// wt_dcache_mem #( - .CVA6Cfg (CVA6Cfg), + .CVA6Cfg(CVA6Cfg), + .DCACHE_CL_IDX_WIDTH(DCACHE_CL_IDX_WIDTH), .wbuffer_t(wbuffer_t), - .NumPorts (NumPorts) + .NumPorts(NumPorts) ) i_wt_dcache_mem ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -374,7 +380,7 @@ module wt_dcache initial begin // assert wrong parameterizations - assert (DCACHE_INDEX_WIDTH <= 12) + assert (CVA6Cfg.DCACHE_INDEX_WIDTH <= 12) else $fatal(1, "[l1 dcache] cache index width can be maximum 12bit since VM uses 4kB pages"); end `endif diff --git a/core/cache_subsystem/wt_dcache_ctrl.sv b/core/cache_subsystem/wt_dcache_ctrl.sv index 84c4c6665..bdd27399d 100644 --- a/core/cache_subsystem/wt_dcache_ctrl.sv +++ b/core/cache_subsystem/wt_dcache_ctrl.sv @@ -18,6 +18,7 @@ module wt_dcache_ctrl import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter DCACHE_CL_IDX_WIDTH = 0, parameter type dcache_req_i_t = logic, parameter type dcache_req_o_t = logic, parameter logic [CVA6Cfg.MEM_TID_WIDTH-1:0] RdTxId = 1 @@ -33,8 +34,8 @@ module wt_dcache_ctrl input logic miss_ack_i, output logic miss_we_o, // unused (set to 0) output logic [riscv::XLEN-1:0] miss_wdata_o, // unused (set to 0) - output logic [DCACHE_USER_WIDTH-1:0] miss_wuser_o, // unused (set to 0) - output logic [DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // valid bits at the missed index + output logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser_o, // unused (set to 0) + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // valid bits at the missed index output logic [riscv::PLEN-1:0] miss_paddr_o, output logic miss_nc_o, // request to I/O space output logic [2:0] miss_size_o, // 00: 1byte, 01: 2byte, 10: 4byte, 11: 8byte, 111: cacheline @@ -44,16 +45,16 @@ module wt_dcache_ctrl // used to detect readout mux collisions input logic wr_cl_vld_i, // cache memory interface - output logic [DCACHE_TAG_WIDTH-1:0] rd_tag_o, // tag in - comes one cycle later + output logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag_o, // tag in - comes one cycle later output logic [DCACHE_CL_IDX_WIDTH-1:0] rd_idx_o, - output logic [DCACHE_OFFSET_WIDTH-1:0] rd_off_o, + output logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] rd_off_o, output logic rd_req_o, // read the word at offset off_i[:3] in all ways output logic rd_tag_only_o, // set to zero here input logic rd_ack_i, input logic [riscv::XLEN-1:0] rd_data_i, - input logic [DCACHE_USER_WIDTH-1:0] rd_user_i, - input logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits_i, - input logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_i + input logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] rd_user_i, + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_vld_bits_i, + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh_i ); // controller FSM @@ -69,11 +70,11 @@ module wt_dcache_ctrl } state_e; state_e state_d, state_q; - logic [DCACHE_TAG_WIDTH-1:0] address_tag_d, address_tag_q; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] address_tag_d, address_tag_q; logic [DCACHE_CL_IDX_WIDTH-1:0] address_idx_d, address_idx_q; - logic [DCACHE_OFFSET_WIDTH-1:0] address_off_d, address_off_q; + logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] address_off_d, address_off_q; logic [DCACHE_TID_WIDTH-1:0] id_d, id_q; - logic [DCACHE_SET_ASSOC-1:0] vld_data_d, vld_data_q; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] vld_data_d, vld_data_q; logic save_tag, rd_req_d, rd_req_q, rd_ack_d, rd_ack_q; logic [1:0] data_size_d, data_size_q; @@ -84,8 +85,8 @@ module wt_dcache_ctrl // map address to tag/idx/offset and save assign vld_data_d = (rd_req_q) ? rd_vld_bits_i : vld_data_q; assign address_tag_d = (save_tag) ? req_port_i.address_tag : address_tag_q; - assign address_idx_d = (req_port_o.data_gnt) ? req_port_i.address_index[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH] : address_idx_q; - assign address_off_d = (req_port_o.data_gnt) ? req_port_i.address_index[DCACHE_OFFSET_WIDTH-1:0] : address_off_q; + assign address_idx_d = (req_port_o.data_gnt) ? req_port_i.address_index[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] : address_idx_q; + assign address_off_d = (req_port_o.data_gnt) ? req_port_i.address_index[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] : address_off_q; assign id_d = (req_port_o.data_gnt) ? req_port_i.data_id : id_q; assign data_size_d = (req_port_o.data_gnt) ? req_port_i.data_size : data_size_q; assign rd_tag_o = address_tag_d; @@ -104,7 +105,7 @@ module wt_dcache_ctrl // noncacheable if request goes to I/O space, or if cache is disabled 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}}} + {{{64-CVA6Cfg.DCACHE_TAG_WIDTH-CVA6Cfg.DCACHE_INDEX_WIDTH}{1'b0}}, address_tag_q, {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}}} )); @@ -291,7 +292,7 @@ module wt_dcache_ctrl initial begin // assert wrong parameterizations - assert (DCACHE_INDEX_WIDTH <= 12) + assert (CVA6Cfg.DCACHE_INDEX_WIDTH <= 12) else $fatal(1, "[l1 dcache ctrl] cache index width can be maximum 12bit since VM uses 4kB pages"); end diff --git a/core/cache_subsystem/wt_dcache_mem.sv b/core/cache_subsystem/wt_dcache_mem.sv index 627889871..0cace0394 100644 --- a/core/cache_subsystem/wt_dcache_mem.sv +++ b/core/cache_subsystem/wt_dcache_mem.sv @@ -30,52 +30,53 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter type wbuffer_t = logic, - parameter int unsigned NumPorts = 3 + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter DCACHE_CL_IDX_WIDTH = 0, + parameter type wbuffer_t = logic, + parameter int unsigned NumPorts = 3 ) ( input logic clk_i, input logic rst_ni, // ports - input logic [NumPorts-1:0][DCACHE_TAG_WIDTH-1:0] rd_tag_i, // tag in - comes one cycle later + input logic [NumPorts-1:0][CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag_i, // tag in - comes one cycle later input logic [NumPorts-1:0][DCACHE_CL_IDX_WIDTH-1:0] rd_idx_i, - input logic [NumPorts-1:0][DCACHE_OFFSET_WIDTH-1:0] rd_off_i, + input logic [NumPorts-1:0][CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] rd_off_i, input logic [NumPorts-1:0] rd_req_i, // read the word at offset off_i[:3] in all ways input logic [NumPorts-1:0] rd_tag_only_i, // only do a tag/valid lookup, no access to data arrays input logic [NumPorts-1:0] rd_prio_i, // 0: low prio, 1: high prio output logic [NumPorts-1:0] rd_ack_o, - output logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits_o, - output logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_o, + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_vld_bits_o, + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh_o, output logic [riscv::XLEN-1:0] rd_data_o, - output logic [DCACHE_USER_WIDTH-1:0] rd_user_o, + output logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] rd_user_o, // only available on port 0, uses address signals of port 0 - input logic wr_cl_vld_i, - input logic wr_cl_nc_i, // noncacheable access - input logic [ DCACHE_SET_ASSOC-1:0] wr_cl_we_i, // writes a full cacheline - input logic [ DCACHE_TAG_WIDTH-1:0] wr_cl_tag_i, - input logic [ DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_i, - input logic [ DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_i, - input logic [ DCACHE_LINE_WIDTH-1:0] wr_cl_data_i, - input logic [DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user_i, - input logic [ DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be_i, - input logic [ DCACHE_SET_ASSOC-1:0] wr_vld_bits_i, + input logic wr_cl_vld_i, + input logic wr_cl_nc_i, // noncacheable access + input logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_cl_we_i, // writes a full cacheline + input logic [ CVA6Cfg.DCACHE_TAG_WIDTH-1:0] wr_cl_tag_i, + input logic [ DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_i, + input logic [ CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_i, + input logic [ CVA6Cfg.DCACHE_LINE_WIDTH-1:0] wr_cl_data_i, + input logic [CVA6Cfg.DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user_i, + input logic [ CVA6Cfg.DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be_i, + input logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_vld_bits_i, // separate port for single word write, no tag access - input logic [DCACHE_SET_ASSOC-1:0] wr_req_i, // write a single word to offset off_i[:3] + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_req_i, // write a single word to offset off_i[:3] output logic wr_ack_o, input logic [DCACHE_CL_IDX_WIDTH-1:0] wr_idx_i, - input logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_i, + input logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] wr_off_i, input logic [riscv::XLEN-1:0] wr_data_i, - input logic [DCACHE_USER_WIDTH-1:0] wr_user_i, + input logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] wr_user_i, input logic [(riscv::XLEN/8)-1:0] wr_data_be_i, // forwarded wbuffer input wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data_i ); - localparam DCACHE_NUM_BANKS = ariane_pkg::DCACHE_LINE_WIDTH / riscv::XLEN; + localparam DCACHE_NUM_BANKS = CVA6Cfg.DCACHE_LINE_WIDTH / riscv::XLEN; localparam DCACHE_NUM_BANKS_WIDTH = $clog2(DCACHE_NUM_BANKS); // functions @@ -95,25 +96,25 @@ module wt_dcache_mem CVA6Cfg.AxiDataWidth / 8 ); - logic [DCACHE_NUM_BANKS-1:0] bank_req; - logic [DCACHE_NUM_BANKS-1:0] bank_we; - logic [DCACHE_NUM_BANKS-1:0][ DCACHE_SET_ASSOC-1:0][(riscv::XLEN/8)-1:0] bank_be; - logic [DCACHE_NUM_BANKS-1:0][DCACHE_CL_IDX_WIDTH-1:0] bank_idx; + logic [DCACHE_NUM_BANKS-1:0] bank_req; + logic [DCACHE_NUM_BANKS-1:0] bank_we; + logic [DCACHE_NUM_BANKS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0][(riscv::XLEN/8)-1:0] bank_be; + logic [DCACHE_NUM_BANKS-1:0][ DCACHE_CL_IDX_WIDTH-1:0] bank_idx; logic [DCACHE_CL_IDX_WIDTH-1:0] bank_idx_d, bank_idx_q; - logic [DCACHE_OFFSET_WIDTH-1:0] bank_off_d, bank_off_q; + logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] bank_off_d, bank_off_q; - logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_wdata; // - logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_rdata; // - logic [DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] rdata_cl; // selected word from each cacheline - logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][DCACHE_USER_WIDTH-1:0] bank_wuser; // - logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][DCACHE_USER_WIDTH-1:0] bank_ruser; // - logic [DCACHE_SET_ASSOC-1:0][DCACHE_USER_WIDTH-1:0] ruser_cl; // selected word from each cacheline + logic [DCACHE_NUM_BANKS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_wdata; // + logic [DCACHE_NUM_BANKS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_rdata; // + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] rdata_cl; // selected word from each cacheline + logic [DCACHE_NUM_BANKS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0][CVA6Cfg.DCACHE_USER_WIDTH-1:0] bank_wuser; // + logic [DCACHE_NUM_BANKS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0][CVA6Cfg.DCACHE_USER_WIDTH-1:0] bank_ruser; // + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0][CVA6Cfg.DCACHE_USER_WIDTH-1:0] ruser_cl; // selected word from each cacheline - logic [DCACHE_TAG_WIDTH-1:0] rd_tag; - logic [DCACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs logic vld_we; // valid bits write enable - logic [DCACHE_SET_ASSOC-1:0] vld_wdata; // valid bits to write - logic [DCACHE_SET_ASSOC-1:0][DCACHE_TAG_WIDTH-1:0] tag_rdata; // these are the tags coming from the tagmem + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] vld_wdata; // valid bits to write + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0][CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag_rdata; // these are the tags coming from the tagmem logic [DCACHE_CL_IDX_WIDTH-1:0] vld_addr; // valid bit logic [$clog2(NumPorts)-1:0] vld_sel_d, vld_sel_q; @@ -121,7 +122,7 @@ module wt_dcache_mem logic [DCACHE_WBUF_DEPTH-1:0] wbuffer_hit_oh; logic [ (riscv::XLEN/8)-1:0] wbuffer_be; logic [riscv::XLEN-1:0] wbuffer_rdata, rdata; - logic [DCACHE_USER_WIDTH-1:0] wbuffer_ruser, ruser; + logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] wbuffer_ruser, ruser; logic [riscv::PLEN-1:0] wbuffer_cmp_addr; logic cmp_en_d, cmp_en_q; @@ -141,13 +142,13 @@ module wt_dcache_mem // byte enable mapping for (genvar k = 0; k < DCACHE_NUM_BANKS; k++) begin : gen_bank - for (genvar j = 0; j < DCACHE_SET_ASSOC; j++) begin : gen_bank_way + for (genvar j = 0; j < CVA6Cfg.DCACHE_SET_ASSOC; j++) begin : gen_bank_way assign bank_be[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_data_be_i[k*(riscv::XLEN/8) +: (riscv::XLEN/8)] : (wr_req_i[j] & wr_ack_o) ? wr_data_be_i : '0; assign bank_wdata[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_data_i[k*riscv::XLEN +: riscv::XLEN] : wr_data_i; - assign bank_wuser[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_user_i[k*DCACHE_USER_WIDTH +: DCACHE_USER_WIDTH] : + assign bank_wuser[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_user_i[k*CVA6Cfg.DCACHE_USER_WIDTH +: CVA6Cfg.DCACHE_USER_WIDTH] : wr_user_i; end end @@ -193,7 +194,7 @@ module wt_dcache_mem bank_idx = '{default: wr_idx_i}; for (int k = 0; k < NumPorts; k++) begin - bank_collision[k] = rd_off_i[k][DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES] == wr_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]; + bank_collision[k] = rd_off_i[k][CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES] == wr_off_i[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]; end if (wr_cl_vld_i & |wr_cl_we_i) begin @@ -203,17 +204,20 @@ module wt_dcache_mem end else begin if (rd_acked) begin if (!rd_tag_only_i[vld_sel_d]) begin - bank_req = - dcache_cl_bin2oh(rd_off_i[vld_sel_d][DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]); - bank_idx[rd_off_i[vld_sel_d][DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]] = rd_idx_i[vld_sel_d]; + bank_req = dcache_cl_bin2oh( + rd_off_i[vld_sel_d][CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]); + bank_idx[rd_off_i[vld_sel_d][CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]] = rd_idx_i[vld_sel_d]; end end if (|wr_req_i) begin if (rd_tag_only_i[vld_sel_d] || !(rd_ack_o[vld_sel_d] && bank_collision[vld_sel_d])) begin wr_ack_o = 1'b1; - bank_req |= dcache_cl_bin2oh(wr_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]); - bank_we = dcache_cl_bin2oh(wr_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]); + bank_req |= dcache_cl_bin2oh( + wr_off_i[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES] + ); + bank_we = + dcache_cl_bin2oh(wr_off_i[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]); end end end @@ -223,10 +227,10 @@ module wt_dcache_mem // tag comparison, hit generatio, readoud muxes /////////////////////////////////////////////////////// - logic [DCACHE_OFFSET_WIDTH-riscv::XLEN_ALIGN_BYTES-1:0] wr_cl_off; - logic [DCACHE_OFFSET_WIDTH-riscv::XLEN_ALIGN_BYTES-1:0] wr_cl_nc_off; - logic [ $clog2(DCACHE_WBUF_DEPTH)-1:0] wbuffer_hit_idx; - logic [ $clog2(DCACHE_SET_ASSOC)-1:0] rd_hit_idx; + logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-CVA6Cfg.XLEN_ALIGN_BYTES-1:0] wr_cl_off; + logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-CVA6Cfg.XLEN_ALIGN_BYTES-1:0] wr_cl_nc_off; + logic [ $clog2(DCACHE_WBUF_DEPTH)-1:0] wbuffer_hit_idx; + logic [ $clog2(CVA6Cfg.DCACHE_SET_ASSOC)-1:0] rd_hit_idx; assign cmp_en_d = (|vld_req) & ~vld_we; @@ -234,16 +238,16 @@ module wt_dcache_mem assign wbuffer_cmp_addr = (wr_cl_vld_i) ? {wr_cl_tag_i, wr_cl_idx_i, wr_cl_off_i} : {rd_tag, bank_idx_q, bank_off_q}; // hit generation - for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin : gen_tag_cmpsel + for (genvar i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin : gen_tag_cmpsel // tag comparison of ways >0 assign rd_hit_oh_o[i] = (rd_tag == tag_rdata[i]) & rd_vld_bits_o[i] & cmp_en_q; // byte offset mux of ways >0 - assign rdata_cl[i] = bank_rdata[bank_off_q[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]][i]; - assign ruser_cl[i] = bank_ruser[bank_off_q[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]][i]; + assign rdata_cl[i] = bank_rdata[bank_off_q[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]][i]; + assign ruser_cl[i] = bank_ruser[bank_off_q[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]][i]; end for (genvar k = 0; k < DCACHE_WBUF_DEPTH; k++) begin : gen_wbuffer_hit - assign wbuffer_hit_oh[k] = (|wbuffer_data_i[k].valid) & ({{riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_data_i[k].wtag} == (wbuffer_cmp_addr >> riscv::XLEN_ALIGN_BYTES)); + assign wbuffer_hit_oh[k] = (|wbuffer_data_i[k].valid) & ({{CVA6Cfg.XLEN_ALIGN_BYTES{1'b0}}, wbuffer_data_i[k].wtag} == (wbuffer_cmp_addr >> CVA6Cfg.XLEN_ALIGN_BYTES)); end lzc #( @@ -255,7 +259,7 @@ module wt_dcache_mem ); lzc #( - .WIDTH(DCACHE_SET_ASSOC) + .WIDTH(CVA6Cfg.DCACHE_SET_ASSOC) ) i_lzc_rd_hit ( .in_i (rd_hit_oh_o), .cnt_o (rd_hit_idx), @@ -269,16 +273,16 @@ module wt_dcache_mem 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 : - {{DCACHE_OFFSET_WIDTH-AXI_OFFSET_WIDTH{1'b0}}, wr_cl_off_i[AXI_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]} : - wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]; + {{CVA6Cfg.DCACHE_OFFSET_WIDTH-AXI_OFFSET_WIDTH{1'b0}}, wr_cl_off_i[AXI_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]} : + wr_cl_off_i[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]; end else begin : gen_piton_offset - assign wr_cl_off = wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:3]; + assign wr_cl_off = wr_cl_off_i[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:3]; end always_comb begin if (wr_cl_vld_i) begin rdata = wr_cl_data_i[wr_cl_off*riscv::XLEN+:riscv::XLEN]; - ruser = wr_cl_user_i[wr_cl_off*DCACHE_USER_WIDTH+:DCACHE_USER_WIDTH]; + ruser = wr_cl_user_i[wr_cl_off*CVA6Cfg.DCACHE_USER_WIDTH+:CVA6Cfg.DCACHE_USER_WIDTH]; end else begin rdata = rdata_cl[rd_hit_idx]; ruser = ruser_cl[rd_hit_idx]; @@ -289,7 +293,7 @@ module wt_dcache_mem for (genvar k = 0; k < (riscv::XLEN / 8); k++) begin : gen_rd_data assign rd_data_o[8*k+:8] = (wbuffer_be[k]) ? wbuffer_rdata[8*k+:8] : rdata[8*k+:8]; end - for (genvar k = 0; k < DCACHE_USER_WIDTH / 8; k++) begin : gen_rd_user + for (genvar k = 0; k < CVA6Cfg.DCACHE_USER_WIDTH / 8; k++) begin : gen_rd_user assign rd_user_o[8*k+:8] = (wbuffer_be[k]) ? wbuffer_ruser[8*k+:8] : ruser[8*k+:8]; end @@ -297,15 +301,15 @@ module wt_dcache_mem // memory arrays and regs /////////////////////////////////////////////////////// - logic [DCACHE_TAG_WIDTH:0] vld_tag_rdata[DCACHE_SET_ASSOC-1:0]; + logic [CVA6Cfg.DCACHE_TAG_WIDTH:0] vld_tag_rdata[CVA6Cfg.DCACHE_SET_ASSOC-1:0]; for (genvar k = 0; k < DCACHE_NUM_BANKS; k++) begin : gen_data_banks // Data RAM sram #( - .USER_WIDTH(ariane_pkg::DCACHE_SET_ASSOC * DATA_USER_WIDTH), - .DATA_WIDTH(ariane_pkg::DCACHE_SET_ASSOC * riscv::XLEN), - .USER_EN (ariane_pkg::DATA_USER_EN), - .NUM_WORDS (wt_cache_pkg::DCACHE_NUM_WORDS) + .USER_WIDTH(CVA6Cfg.DCACHE_SET_ASSOC * CVA6Cfg.DCACHE_USER_WIDTH), + .DATA_WIDTH(CVA6Cfg.DCACHE_SET_ASSOC * riscv::XLEN), + .USER_EN (CVA6Cfg.DATA_USER_EN), + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) i_data_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -320,16 +324,16 @@ module wt_dcache_mem ); end - for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin : gen_tag_srams + for (genvar i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin : gen_tag_srams - assign tag_rdata[i] = vld_tag_rdata[i][DCACHE_TAG_WIDTH-1:0]; - assign rd_vld_bits_o[i] = vld_tag_rdata[i][DCACHE_TAG_WIDTH]; + assign tag_rdata[i] = vld_tag_rdata[i][CVA6Cfg.DCACHE_TAG_WIDTH-1:0]; + assign rd_vld_bits_o[i] = vld_tag_rdata[i][CVA6Cfg.DCACHE_TAG_WIDTH]; // Tag RAM sram #( // tag + valid bit - .DATA_WIDTH(ariane_pkg::DCACHE_TAG_WIDTH + 1), - .NUM_WORDS (wt_cache_pkg::DCACHE_NUM_WORDS) + .DATA_WIDTH(CVA6Cfg.DCACHE_TAG_WIDTH + 1), + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) i_tag_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -366,7 +370,7 @@ module wt_dcache_mem `ifndef VERILATOR initial begin cach_line_width_axi : - assert (DCACHE_LINE_WIDTH >= CVA6Cfg.AxiDataWidth) + assert (CVA6Cfg.DCACHE_LINE_WIDTH >= CVA6Cfg.AxiDataWidth) else $fatal(1, "[l1 dcache] cache line size needs to be greater or equal AXI data width"); end @@ -378,7 +382,7 @@ module wt_dcache_mem initial begin cach_line_width_xlen : - assert (DCACHE_LINE_WIDTH > riscv::XLEN) + assert (CVA6Cfg.DCACHE_LINE_WIDTH > riscv::XLEN) else $fatal(1, "[l1 dcache] cache_line_size needs to be greater than XLEN"); end @@ -399,16 +403,16 @@ module wt_dcache_mem else $fatal(1, "[l1 dcache] wbuffer_hit_oh signal must be hot1"); // this is only used for verification! - logic vld_mirror[wt_cache_pkg::DCACHE_NUM_WORDS-1:0][ariane_pkg::DCACHE_SET_ASSOC-1:0]; - logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] tag_mirror[wt_cache_pkg::DCACHE_NUM_WORDS-1:0][ariane_pkg::DCACHE_SET_ASSOC-1:0]; - logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] tag_write_duplicate_test; + logic vld_mirror[CVA6Cfg.DCACHE_NUM_WORDS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0]; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag_mirror[CVA6Cfg.DCACHE_NUM_WORDS-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0]; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] tag_write_duplicate_test; always_ff @(posedge clk_i or negedge rst_ni) begin : p_mirror if (!rst_ni) begin vld_mirror <= '{default: '0}; tag_mirror <= '{default: '0}; end else begin - for (int i = 0; i < DCACHE_SET_ASSOC; i++) begin + for (int i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin if (vld_req[i] & vld_we) begin vld_mirror[vld_addr][i] <= vld_wdata[i]; tag_mirror[vld_addr][i] <= wr_cl_tag_i; @@ -417,7 +421,7 @@ module wt_dcache_mem end end - for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin : gen_tag_dubl_test + for (genvar i = 0; i < CVA6Cfg.DCACHE_SET_ASSOC; i++) begin : gen_tag_dubl_test assign tag_write_duplicate_test[i] = (tag_mirror[vld_addr][i] == wr_cl_tag_i) & vld_mirror[vld_addr][i] & (|vld_wdata); end diff --git a/core/cache_subsystem/wt_dcache_missunit.sv b/core/cache_subsystem/wt_dcache_missunit.sv index 616b4cd67..e7d4b8962 100644 --- a/core/cache_subsystem/wt_dcache_missunit.sv +++ b/core/cache_subsystem/wt_dcache_missunit.sv @@ -19,6 +19,7 @@ module wt_dcache_missunit import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter DCACHE_CL_IDX_WIDTH = 0, parameter type dcache_req_t = logic, parameter type dcache_rtrn_t = logic, parameter logic [CVA6Cfg.MEM_TID_WIDTH-1:0] AmoTxId = 1, // TX id to be used for AMOs @@ -43,9 +44,9 @@ module wt_dcache_missunit input logic [NumPorts-1:0] miss_nc_i, input logic [NumPorts-1:0] miss_we_i, input logic [NumPorts-1:0][riscv::XLEN-1:0] miss_wdata_i, - input logic [NumPorts-1:0][DCACHE_USER_WIDTH-1:0] miss_wuser_i, + input logic [NumPorts-1:0][CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser_i, input logic [NumPorts-1:0][riscv::PLEN-1:0] miss_paddr_i, - input logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits_i, + input logic [NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_i, input logic [NumPorts-1:0][2:0] miss_size_i, input logic [NumPorts-1:0][CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id_i, // used as transaction ID // signals that the request collided with a pending read @@ -59,14 +60,14 @@ module wt_dcache_missunit // write interface to cache memory output logic wr_cl_vld_o, // writes a full cacheline output logic wr_cl_nc_o, // writes a full cacheline - output logic [DCACHE_SET_ASSOC-1:0] wr_cl_we_o, // writes a full cacheline - output logic [DCACHE_TAG_WIDTH-1:0] wr_cl_tag_o, + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_cl_we_o, // writes a full cacheline + output logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] wr_cl_tag_o, output logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_o, - output logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_o, - output logic [DCACHE_LINE_WIDTH-1:0] wr_cl_data_o, - output logic [DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user_o, - output logic [DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be_o, - output logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits_o, + output logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_o, + output logic [CVA6Cfg.DCACHE_LINE_WIDTH-1:0] wr_cl_data_o, + output logic [CVA6Cfg.DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user_o, + output logic [CVA6Cfg.DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be_o, + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_vld_bits_o, // memory interface input logic mem_rtrn_vld_i, input dcache_rtrn_t mem_rtrn_i, @@ -76,9 +77,9 @@ module wt_dcache_missunit ); // functions - function automatic logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] dcache_way_bin2oh( - input logic [L1D_WAY_WIDTH-1:0] in); - logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] out; + function automatic logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] dcache_way_bin2oh( + input logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] in); + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] out; out = '0; out[in] = 1'b1; return out; @@ -98,7 +99,7 @@ module wt_dcache_missunit 3'b001: out[0:0] = '0; 3'b010: out[1:0] = '0; 3'b011: out[2:0] = '0; - 3'b111: out[DCACHE_OFFSET_WIDTH-1:0] = '0; + 3'b111: out[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] = '0; default: ; endcase return out; @@ -118,17 +119,17 @@ module wt_dcache_missunit // MSHR for reads typedef struct packed { - logic [riscv::PLEN-1:0] paddr; - logic [2:0] size; - logic [DCACHE_SET_ASSOC-1:0] vld_bits; - logic [CVA6Cfg.MEM_TID_WIDTH-1:0] id; - logic nc; - logic [$clog2(DCACHE_SET_ASSOC)-1:0] repl_way; - logic [$clog2(NumPorts)-1:0] miss_port_idx; + logic [riscv::PLEN-1:0] paddr; + logic [2:0] size; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] vld_bits; + logic [CVA6Cfg.MEM_TID_WIDTH-1:0] id; + logic nc; + logic [$clog2(CVA6Cfg.DCACHE_SET_ASSOC)-1:0] repl_way; + logic [$clog2(NumPorts)-1:0] miss_port_idx; } mshr_t; mshr_t mshr_d, mshr_q; - logic [$clog2(DCACHE_SET_ASSOC)-1:0] repl_way, inv_way, rnd_way; + logic [$clog2(CVA6Cfg.DCACHE_SET_ASSOC)-1:0] repl_way, inv_way, rnd_way; logic mshr_vld_d, mshr_vld_q, mshr_vld_q1; logic mshr_allocate; logic update_lfsr, all_ways_valid; @@ -141,7 +142,7 @@ module wt_dcache_missunit logic amo_req_d, amo_req_q; logic [63:0] amo_rtrn_mux; logic [riscv::XLEN-1:0] amo_data, amo_data_a, amo_data_b; - logic [riscv::XLEN-1:0] amo_user; //DCACHE USER ? DATA_USER_WIDTH + logic [riscv::XLEN-1:0] amo_user; //DCACHE USER ? CVA6Cfg.DCACHE_USER_WIDTH logic [riscv::PLEN-1:0] tmp_paddr; logic [$clog2(NumPorts)-1:0] miss_port_idx; logic [DCACHE_CL_IDX_WIDTH-1:0] cnt_d, cnt_q; @@ -160,7 +161,7 @@ module wt_dcache_missunit assign cache_en_o = enable_q; assign cnt_d = (flush_en) ? cnt_q + 1 : '0; - assign flush_done = (cnt_q == wt_cache_pkg::DCACHE_NUM_WORDS - 1); + assign flush_done = (cnt_q == CVA6Cfg.DCACHE_NUM_WORDS - 1); assign miss_req_masked_d = (lock_reqs) ? miss_req_masked_q : (mask_reads) ? miss_we_i & miss_req_i : miss_req_i; @@ -188,7 +189,7 @@ module wt_dcache_missunit // find invalid cache line lzc #( - .WIDTH(ariane_pkg::DCACHE_SET_ASSOC) + .WIDTH(CVA6Cfg.DCACHE_SET_ASSOC) ) i_lzc_inv ( .in_i (~miss_vld_bits_i[miss_port_idx]), .cnt_o (inv_way), @@ -198,7 +199,7 @@ module wt_dcache_missunit // generate random cacheline index lfsr #( .LfsrWidth(8), - .OutWidth ($clog2(ariane_pkg::DCACHE_SET_ASSOC)) + .OutWidth ($clog2(CVA6Cfg.DCACHE_SET_ASSOC)) ) i_lfsr_inv ( .clk_i (clk_i), .rst_ni(rst_ni), @@ -223,19 +224,19 @@ module wt_dcache_missunit for (genvar k = 0; k < NumPorts; k++) begin : gen_rdrd_collision - assign mshr_rdrd_collision[k] = (mshr_q.paddr[riscv::PLEN-1:DCACHE_OFFSET_WIDTH] == miss_paddr_i[k][riscv::PLEN-1:DCACHE_OFFSET_WIDTH]) && (mshr_vld_q | mshr_vld_q1); + assign mshr_rdrd_collision[k] = (mshr_q.paddr[riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == miss_paddr_i[k][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && (mshr_vld_q | mshr_vld_q1); assign mshr_rdrd_collision_d[k] = (!miss_req_i[k]) ? 1'b0 : mshr_rdrd_collision_q[k] | mshr_rdrd_collision[k]; end // read/write collision, stalls the corresponding request // write port[NumPorts-1] collides with MSHR_Q - assign mshr_rdwr_collision = (mshr_q.paddr[riscv::PLEN-1:DCACHE_OFFSET_WIDTH] == miss_paddr_i[NumPorts-1][riscv::PLEN-1:DCACHE_OFFSET_WIDTH]) && mshr_vld_q; + assign mshr_rdwr_collision = (mshr_q.paddr[riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == miss_paddr_i[NumPorts-1][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && mshr_vld_q; // read collides with inflight TX always_comb begin : p_tx_coll tx_rdwr_collision = 1'b0; for (int k = 0; k < CVA6Cfg.DCACHE_MAX_TX; k++) begin - tx_rdwr_collision |= (miss_paddr_i[miss_port_idx][riscv::PLEN-1:DCACHE_OFFSET_WIDTH] == tx_paddr_i[k][riscv::PLEN-1:DCACHE_OFFSET_WIDTH]) && tx_vld_i[k]; + tx_rdwr_collision |= (miss_paddr_i[miss_port_idx][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == tx_paddr_i[k][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && tx_vld_i[k]; end end @@ -265,7 +266,7 @@ module wt_dcache_missunit end else begin amo_data = amo_data_a; end - if (ariane_pkg::DATA_USER_EN) begin + if (CVA6Cfg.DATA_USER_EN) begin amo_user = amo_data; end else begin amo_user = '0; @@ -284,7 +285,7 @@ module wt_dcache_missunit assign amo_rtrn_mux = mem_rtrn_i.data[0+:64]; end end else begin : gen_piton_rtrn_mux - assign amo_rtrn_mux = mem_rtrn_i.data[amo_req_i.operand_a[DCACHE_OFFSET_WIDTH-1:3]*64+:64]; + assign amo_rtrn_mux = mem_rtrn_i.data[amo_req_i.operand_a[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:3]*64+:64]; end // always sign extend 32bit values @@ -410,11 +411,11 @@ module wt_dcache_missunit ) : '0; assign wr_cl_idx_o = (flush_en) ? cnt_q : - (inv_vld) ? mem_rtrn_i.inv.idx[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH] : - mshr_q.paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH]; + (inv_vld) ? mem_rtrn_i.inv.idx[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] : + mshr_q.paddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]; - assign wr_cl_tag_o = mshr_q.paddr[DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:DCACHE_INDEX_WIDTH]; - assign wr_cl_off_o = mshr_q.paddr[DCACHE_OFFSET_WIDTH-1:0]; + assign wr_cl_tag_o = mshr_q.paddr[CVA6Cfg.DCACHE_TAG_WIDTH+CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_INDEX_WIDTH]; + assign wr_cl_off_o = mshr_q.paddr[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0]; assign wr_cl_data_o = mem_rtrn_i.data; assign wr_cl_user_o = mem_rtrn_i.user; assign wr_cl_data_be_o = (cl_write_en) ? '1 : '0;// we only write complete cachelines into the memory diff --git a/core/cache_subsystem/wt_dcache_wbuffer.sv b/core/cache_subsystem/wt_dcache_wbuffer.sv index ffa3aeb3d..7eb29ced2 100644 --- a/core/cache_subsystem/wt_dcache_wbuffer.sv +++ b/core/cache_subsystem/wt_dcache_wbuffer.sv @@ -54,6 +54,7 @@ module wt_dcache_wbuffer import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter DCACHE_CL_IDX_WIDTH = 0, parameter type dcache_req_i_t = logic, parameter type dcache_req_o_t = logic, parameter type wbuffer_t = logic @@ -73,8 +74,8 @@ module wt_dcache_wbuffer output logic miss_req_o, output logic miss_we_o, // always 1 here output logic [riscv::XLEN-1:0] miss_wdata_o, - output logic [DCACHE_USER_WIDTH-1:0] miss_wuser_o, - output logic [DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // unused here (set to 0) + output logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser_o, + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // unused here (set to 0) output logic miss_nc_o, // request to I/O space output logic [2:0] miss_size_o, // output logic [CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id_o, // ID of this transaction (wbuffer uses all IDs from 0 to DCACHE_MAX_TX-1) @@ -82,26 +83,26 @@ module wt_dcache_wbuffer input logic miss_rtrn_vld_i, input logic [CVA6Cfg.MEM_TID_WIDTH-1:0] miss_rtrn_id_i, // transaction ID to clear // cache read interface - output logic [DCACHE_TAG_WIDTH-1:0] rd_tag_o, // tag in - comes one cycle later + output logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag_o, // tag in - comes one cycle later output logic [DCACHE_CL_IDX_WIDTH-1:0] rd_idx_o, - output logic [DCACHE_OFFSET_WIDTH-1:0] rd_off_o, + output logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] rd_off_o, output logic rd_req_o, // read the word at offset off_i[:3] in all ways output logic rd_tag_only_o, // set to 1 here as we do not have to read the data arrays input logic rd_ack_i, input logic [riscv::XLEN-1:0] rd_data_i, // unused - input logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits_i, // unused - input logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_i, + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_vld_bits_i, // unused + input logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh_i, // cacheline writes input logic wr_cl_vld_i, input logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_i, // cache word write interface - output logic [DCACHE_SET_ASSOC-1:0] wr_req_o, + output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] wr_req_o, input logic wr_ack_i, output logic [DCACHE_CL_IDX_WIDTH-1:0] wr_idx_o, - output logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_o, + output logic [CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0] wr_off_o, output logic [riscv::XLEN-1:0] wr_data_o, output logic [(riscv::XLEN/8)-1:0] wr_data_be_o, - output logic [DCACHE_USER_WIDTH-1:0] wr_user_o, + output logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] wr_user_o, // to forwarding logic and miss unit output wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data_o, output logic [CVA6Cfg.DCACHE_MAX_TX-1:0][riscv::PLEN-1:0] tx_paddr_o, // used to check for address collisions with read operations @@ -109,7 +110,7 @@ module wt_dcache_wbuffer ); function automatic logic [(riscv::XLEN/8)-1:0] to_byte_enable8( - input logic [riscv::XLEN_ALIGN_BYTES-1:0] offset, input logic [1:0] size); + input logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] offset, input logic [1:0] size); logic [(riscv::XLEN/8)-1:0] be; be = '0; unique case (size) @@ -122,7 +123,7 @@ module wt_dcache_wbuffer endfunction : to_byte_enable8 function automatic logic [(riscv::XLEN/8)-1:0] to_byte_enable4( - input logic [riscv::XLEN_ALIGN_BYTES-1:0] offset, input logic [1:0] size); + input logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] offset, input logic [1:0] size); logic [3:0] be; be = '0; unique case (size) @@ -135,7 +136,7 @@ module wt_dcache_wbuffer // openpiton requires the data to be replicated in case of smaller sizes than dwords function automatic logic [riscv::XLEN-1:0] repData64( - input logic [riscv::XLEN-1:0] data, input logic [riscv::XLEN_ALIGN_BYTES-1:0] offset, + input logic [riscv::XLEN-1:0] data, input logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] offset, input logic [1:0] size); logic [riscv::XLEN-1:0] out; unique case (size) @@ -148,7 +149,7 @@ module wt_dcache_wbuffer endfunction : repData64 function automatic logic [riscv::XLEN-1:0] repData32( - input logic [riscv::XLEN-1:0] data, input logic [riscv::XLEN_ALIGN_BYTES-1:0] offset, + input logic [riscv::XLEN-1:0] data, input logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] offset, input logic [1:0] size); logic [riscv::XLEN-1:0] out; unique case (size) @@ -178,11 +179,11 @@ module wt_dcache_wbuffer next_ptr, dirty_ptr, hit_ptr, wr_ptr, check_ptr_d, check_ptr_q, check_ptr_q1, rtrn_ptr; logic [CVA6Cfg.MEM_TID_WIDTH-1:0] tx_id, rtrn_id; - logic [riscv::XLEN_ALIGN_BYTES-1:0] bdirty_off; + logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] bdirty_off; logic [(riscv::XLEN/8)-1:0] tx_be; logic [riscv::PLEN-1:0] wr_paddr, rd_paddr, extract_tag; - logic [DCACHE_TAG_WIDTH-1:0] rd_tag_d, rd_tag_q; - logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_d, rd_hit_oh_q; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag_d, rd_tag_q; + logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh_d, rd_hit_oh_q; logic check_en_d, check_en_q, check_en_q1; logic full, dirty_rd_en, rdy; logic rtrn_empty, evict; @@ -200,14 +201,16 @@ module wt_dcache_wbuffer /////////////////////////////////////////////////////// // misc /////////////////////////////////////////////////////// - logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] miss_tag; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] miss_tag; logic is_nc_miss; logic is_ni; - assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH]; + assign miss_tag = miss_paddr_o[CVA6Cfg.DCACHE_INDEX_WIDTH+:CVA6Cfg.DCACHE_TAG_WIDTH]; 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}} + {64 - CVA6Cfg.DCACHE_TAG_WIDTH - CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}}, + miss_tag, + {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} } ); assign miss_nc_o = !cache_en_i || is_nc_miss; @@ -215,9 +218,9 @@ module wt_dcache_wbuffer assign is_ni = config_pkg::is_inside_nonidempotent_regions( CVA6Cfg, { - {64 - DCACHE_TAG_WIDTH - DCACHE_INDEX_WIDTH{1'b0}}, + {64 - CVA6Cfg.DCACHE_TAG_WIDTH - CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}}, req_port_i.address_tag, - {DCACHE_INDEX_WIDTH{1'b0}} + {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}} } ); @@ -228,7 +231,7 @@ module wt_dcache_wbuffer for (genvar k = 0; k < CVA6Cfg.DCACHE_MAX_TX; k++) begin : gen_tx_vld assign tx_vld_o[k] = tx_stat_q[k].vld; assign tx_paddr_o[k] = { - {riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[tx_stat_q[k].ptr].wtag << riscv::XLEN_ALIGN_BYTES + {CVA6Cfg.XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[tx_stat_q[k].ptr].wtag << CVA6Cfg.XLEN_ALIGN_BYTES }; end @@ -275,7 +278,7 @@ module wt_dcache_wbuffer ) : repData32( wbuffer_dirty_mux.data, bdirty_off, miss_size_o[1:0] ); - if (ariane_pkg::DATA_USER_EN) begin + if (CVA6Cfg.DATA_USER_EN) begin assign miss_wuser_o = riscv::IS_XLEN64 ? repData64( wbuffer_dirty_mux.user, bdirty_off, miss_size_o[1:0] ) : repData32( @@ -299,7 +302,8 @@ module wt_dcache_wbuffer fifo_v3 #( .FALL_THROUGH(1'b0), .DATA_WIDTH ($clog2(CVA6Cfg.DCACHE_MAX_TX)), - .DEPTH (CVA6Cfg.DCACHE_MAX_TX) + .DEPTH (CVA6Cfg.DCACHE_MAX_TX), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_rtrn_id_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -368,18 +372,18 @@ module wt_dcache_wbuffer // cache readout & update /////////////////////////////////////////////////////// - assign extract_tag = rd_paddr >> DCACHE_INDEX_WIDTH; - assign rd_tag_d = extract_tag[DCACHE_TAG_WIDTH-1:0]; + assign extract_tag = rd_paddr >> CVA6Cfg.DCACHE_INDEX_WIDTH; + assign rd_tag_d = extract_tag[CVA6Cfg.DCACHE_TAG_WIDTH-1:0]; // trigger TAG readout in cache assign rd_tag_only_o = 1'b1; assign rd_paddr = { - {riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_check_mux.wtag << riscv::XLEN_ALIGN_BYTES + {CVA6Cfg.XLEN_ALIGN_BYTES{1'b0}}, wbuffer_check_mux.wtag << CVA6Cfg.XLEN_ALIGN_BYTES }; assign rd_req_o = |tocheck; assign rd_tag_o = rd_tag_q; //delay by one cycle - assign rd_idx_o = rd_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH]; - assign rd_off_o = rd_paddr[DCACHE_OFFSET_WIDTH-1:0]; + assign rd_idx_o = rd_paddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]; + assign rd_off_o = rd_paddr[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0]; assign check_en_d = rd_req_o & rd_ack_i; // cache update port @@ -388,10 +392,10 @@ module wt_dcache_wbuffer // when the TX returns assign wr_data_be_o = tx_stat_q[rtrn_id].be & (~wbuffer_q[rtrn_ptr].dirty); assign wr_paddr = { - {riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[rtrn_ptr].wtag << riscv::XLEN_ALIGN_BYTES + {CVA6Cfg.XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[rtrn_ptr].wtag << CVA6Cfg.XLEN_ALIGN_BYTES }; - assign wr_idx_o = wr_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH]; - assign wr_off_o = wr_paddr[DCACHE_OFFSET_WIDTH-1:0]; + assign wr_idx_o = wr_paddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]; + assign wr_off_o = wr_paddr[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:0]; assign wr_data_o = wbuffer_q[rtrn_ptr].data; assign wr_user_o = wbuffer_q[rtrn_ptr].user; @@ -409,7 +413,7 @@ module wt_dcache_wbuffer // only for debug, will be pruned if (CVA6Cfg.DebugEn) begin assign debug_paddr[k] = { - {riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[k].wtag << riscv::XLEN_ALIGN_BYTES + {CVA6Cfg.XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[k].wtag << CVA6Cfg.XLEN_ALIGN_BYTES }; end @@ -421,12 +425,12 @@ module wt_dcache_wbuffer assign dirty[k] = |bdirty[k]; assign valid[k] = |wbuffer_q[k].valid; - assign wbuffer_hit_oh[k] = valid[k] & (wbuffer_q[k].wtag == {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:riscv::XLEN_ALIGN_BYTES]}); + assign wbuffer_hit_oh[k] = valid[k] & (wbuffer_q[k].wtag == {req_port_i.address_tag, req_port_i.address_index[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES]}); // checks if an invalidation/cache refill hits a particular word // note: an invalidation can hit multiple words! // need to respect previous cycle, too, since we add a cycle of latency to the rd_hit_oh_i signal... - assign wtag_comp[k] = wbuffer_q[k].wtag[DCACHE_INDEX_WIDTH-riscv::XLEN_ALIGN_BYTES-1:DCACHE_OFFSET_WIDTH-riscv::XLEN_ALIGN_BYTES]; + assign wtag_comp[k] = wbuffer_q[k].wtag[CVA6Cfg.DCACHE_INDEX_WIDTH-CVA6Cfg.XLEN_ALIGN_BYTES-1:CVA6Cfg.DCACHE_OFFSET_WIDTH-CVA6Cfg.XLEN_ALIGN_BYTES]; assign inval_hit[k] = (wr_cl_vld_d & valid[k] & (wtag_comp[k] == wr_cl_idx_d)) | (wr_cl_vld_q & valid[k] & (wtag_comp[k] == wr_cl_idx_q)); @@ -579,7 +583,7 @@ module wt_dcache_wbuffer wbuffer_d[wr_ptr].checked = 1'b0; wbuffer_d[wr_ptr].wtag = { req_port_i.address_tag, - req_port_i.address_index[DCACHE_INDEX_WIDTH-1:riscv::XLEN_ALIGN_BYTES] + req_port_i.address_index[CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.XLEN_ALIGN_BYTES] }; // mark bytes as dirty @@ -588,7 +592,7 @@ module wt_dcache_wbuffer wbuffer_d[wr_ptr].valid[k] = 1'b1; wbuffer_d[wr_ptr].dirty[k] = 1'b1; wbuffer_d[wr_ptr].data[k*8+:8] = req_port_i.data_wdata[k*8+:8]; - if (ariane_pkg::DATA_USER_EN) begin + if (CVA6Cfg.DATA_USER_EN) begin wbuffer_d[wr_ptr].user[k*8+:8] = req_port_i.data_wuser[k*8+:8]; end else begin wbuffer_d[wr_ptr].user[k*8+:8] = '0; diff --git a/core/cache_subsystem/wt_l15_adapter.sv b/core/cache_subsystem/wt_l15_adapter.sv index b3e906c71..cd1ca2296 100644 --- a/core/cache_subsystem/wt_l15_adapter.sv +++ b/core/cache_subsystem/wt_l15_adapter.sv @@ -94,7 +94,7 @@ module wt_l15_adapter logic l15_invalidate_cacheline; // unused by Ariane as L1 has no ECC at the moment logic l15_blockstore; // unused in openpiton logic l15_blockinitstore; // unused in openpiton - logic [wt_cache_pkg::L15_WAY_WIDTH-1:0] l15_l1rplway; // way to replace + logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] l15_l1rplway; // way to replace logic [39:0] l15_address; // physical address logic [63:0] l15_data; // word to write logic [63:0] l15_data_next_entry; // unused in Ariane (only used for CAS atomic requests) @@ -121,10 +121,10 @@ module wt_l15_adapter logic l15_inval_dcache_all_way; // unused in openpiton logic [15:4] l15_inval_address_15_4; // invalidate selected cacheline logic l15_cross_invalidate; // unused in openpiton - logic [wt_cache_pkg::L15_WAY_WIDTH-1:0] l15_cross_invalidate_way; // unused in openpiton + logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] l15_cross_invalidate_way; // unused in openpiton logic l15_inval_dcache_inval; // invalidate selected cacheline and way logic l15_inval_icache_inval; // unused in openpiton - logic [wt_cache_pkg::L15_WAY_WIDTH-1:0] l15_inval_way; // way to invalidate + logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] l15_inval_way; // way to invalidate logic l15_blockinitstore; // unused in openpiton }; @@ -153,7 +153,7 @@ module wt_l15_adapter // logic [2:0] l15_req_o.l15_size; // transaction size: 000=Byte 001=2Byte; 010=4Byte; 011=8Byte; 111=Cache line (16/32Byte) // logic [CVA6Cfg.MEM_TID_WIDTH-1:0] l15_req_o.l15_threadid; // currently 0 or 1 // logic l15_req_o.l15_invalidate_cacheline; // unused by Ariane as L1 has no ECC at the moment - // logic [L15_WAY_WIDTH-1:0] l15_req_o.l15_l1rplway; // way to replace + // logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] l15_req_o.l15_l1rplway; // way to replace // logic [39:0] l15_req_o.l15_address; // physical address // logic [63:0] l15_req_o.l15_data; // word to write // logic [63:0] l15_req_o.l15_data_next_entry; // unused in Ariane (only used for CAS atomic requests) @@ -438,19 +438,19 @@ module wt_l15_adapter initial begin // assert wrong parameterizations - assert (L15_SET_ASSOC >= ICACHE_SET_ASSOC) + assert (CVA6Cfg.DCACHE_SET_ASSOC >= CVA6Cfg.ICACHE_SET_ASSOC) else $fatal( 1, "[l15_adapter] number of icache ways must be smaller or equal the number of L15 ways" ); // assert wrong parameterizations - assert (L15_SET_ASSOC >= DCACHE_SET_ASSOC) + assert (CVA6Cfg.DCACHE_SET_ASSOC >= CVA6Cfg.DCACHE_SET_ASSOC) else $fatal( 1, "[l15_adapter] number of dcache ways must be smaller or equal the number of L15 ways" ); // invalidation address returned by L1.5 is 16 bit - assert (16 >= DCACHE_INDEX_WIDTH && 16 >= ICACHE_INDEX_WIDTH) + assert (16 >= CVA6Cfg.DCACHE_INDEX_WIDTH && 16 >= CVA6Cfg.ICACHE_INDEX_WIDTH) else $fatal(1, "[l15_adapter] maximum number of index bits supported by L1.5 is 16"); end `endif diff --git a/core/commit_stage.sv b/core/commit_stage.sv index 1c80a51d9..cf047f83b 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -67,7 +67,7 @@ module commit_stage // Commit buffer of LSU is ready - EX_STAGE input logic commit_lsu_ready_i, // Transaction id of first commit port - ID_STAGE - output logic [TRANS_ID_BITS-1:0] commit_tran_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] commit_tran_id_o, // Valid AMO in commit stage - EX_STAGE output logic amo_valid_commit_o, // no store is pending - EX_STAGE diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 94ac1a9b2..b7d8a2a7a 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -98,7 +98,7 @@ module csr_regfile // Make Executable Readable - EX_STAGE output logic mxr_o, // TO_BE_COMPLETED - EX_STAGE - output logic [riscv::PPNW-1:0] satp_ppn_o, + output logic [CVA6Cfg.PPNW-1:0] satp_ppn_o, // TO_BE_COMPLETED - EX_STAGE output logic [AsidWidth-1:0] asid_o, // external interrupt in - SUBSYSTEM @@ -144,10 +144,12 @@ module csr_regfile output rvfi_probes_csr_t rvfi_csr_o ); + localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg); + typedef struct packed { - logic [riscv::ModeW-1:0] mode; - logic [riscv::ASIDW-1:0] asid; - logic [riscv::PPNW-1:0] ppn; + logic [CVA6Cfg.ModeW-1:0] mode; + logic [CVA6Cfg.ASIDW-1:0] asid; + logic [CVA6Cfg.PPNW-1:0] ppn; } satp_t; // internal signal to keep track of access exceptions @@ -298,8 +300,7 @@ module csr_regfile riscv::CSR_TDATA3: read_access_exception = 1'b1; // not implemented // supervisor registers riscv::CSR_SSTATUS: begin - if (CVA6Cfg.RVS) - csr_rdata = mstatus_extended & ariane_pkg::SMODE_STATUS_READ_MASK[riscv::XLEN-1:0]; + if (CVA6Cfg.RVS) csr_rdata = mstatus_extended & SMODE_STATUS_READ_MASK[riscv::XLEN-1:0]; else read_access_exception = 1'b1; end riscv::CSR_SIE: @@ -829,10 +830,10 @@ module csr_regfile else begin satp = satp_t'(csr_wdata); // only make ASID_LEN - 1 bit stick, that way software can figure out how many ASID bits are supported - satp.asid = satp.asid & {{(riscv::ASIDW - AsidWidth) {1'b0}}, {AsidWidth{1'b1}}}; + satp.asid = satp.asid & {{(CVA6Cfg.ASIDW - AsidWidth) {1'b0}}, {AsidWidth{1'b1}}}; // only update if we actually support this mode - if (riscv::vm_mode_t'(satp.mode) == riscv::ModeOff || - riscv::vm_mode_t'(satp.mode) == riscv::MODE_SV) + if (config_pkg::vm_mode_t'(satp.mode) == config_pkg::ModeOff || + config_pkg::vm_mode_t'(satp.mode) == CVA6Cfg.MODE_SV) satp_d = satp; end // changing the mode can have side-effects on address translation (e.g.: other instructions), re-fetch @@ -1306,7 +1307,7 @@ module csr_regfile // ------------------------------ // Set the address translation at which the load and stores should occur // we can use the previous values since changing the address translation will always involve a pipeline flush - if (ariane_pkg::MMU_PRESENT && mprv && CVA6Cfg.RVS && riscv::vm_mode_t'(satp_q.mode) == riscv::MODE_SV && (mstatus_q.mpp != riscv::PRIV_LVL_M)) + if (ariane_pkg::MMU_PRESENT && mprv && CVA6Cfg.RVS && config_pkg::vm_mode_t'(satp_q.mode) == CVA6Cfg.MODE_SV && (mstatus_q.mpp != riscv::PRIV_LVL_M)) en_ld_st_translation_d = 1'b1; else // otherwise we go with the regular settings en_ld_st_translation_d = en_translation_o; @@ -1553,7 +1554,7 @@ module csr_regfile assign asid_o = satp_q.asid[AsidWidth-1:0]; assign sum_o = mstatus_q.sum; // we support bare memory addressing and SV39 - assign en_translation_o = ((CVA6Cfg.RVS && riscv::vm_mode_t'(satp_q.mode) == riscv::MODE_SV) && + assign en_translation_o = ((CVA6Cfg.RVS && config_pkg::vm_mode_t'(satp_q.mode) == CVA6Cfg.MODE_SV) && priv_lvl_o != riscv::PRIV_LVL_M) ? 1'b1 : 1'b0; diff --git a/core/cva6.sv b/core/cva6.sv index 1ab3c7aef..65aad6d49 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -66,12 +66,12 @@ module cva6 logic [riscv::VLEN-1:0] vaddr; // 1st cycle: 12 bit index is taken for lookup }, localparam type icache_drsp_t = struct packed { - logic ready; // icache is ready - logic valid; // signals a valid read - logic [ariane_pkg::FETCH_WIDTH-1:0] data; // 2+ cycle out: tag - logic [ariane_pkg::FETCH_USER_WIDTH-1:0] user; // User bits - logic [riscv::VLEN-1:0] vaddr; // virtual address out - exception_t ex; // we've encountered an exception + logic ready; // icache is ready + logic valid; // signals a valid read + logic [CVA6Cfg.FETCH_WIDTH-1:0] data; // 2+ cycle out: tag + logic [CVA6Cfg.FETCH_USER_WIDTH-1:0] user; // User bits + logic [riscv::VLEN-1:0] vaddr; // virtual address out + exception_t ex; // we've encountered an exception }, // IF/ID Stage @@ -86,8 +86,8 @@ module cva6 // ID/EX/WB Stage localparam type scoreboard_entry_t = struct packed { logic [riscv::VLEN-1:0] pc; // PC of instruction - logic [TRANS_ID_BITS-1:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry - // with the transaction id in any case make the width more generic + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry + // with the transaction id in any case make the width more generic fu_t fu; // functional unit to use fu_op op; // operation to perform in each functional unit logic [REG_ADDR_SIZE-1:0] rs1; // register source address 1 @@ -135,65 +135,65 @@ module cva6 }, localparam type lsu_ctrl_t = struct packed { - logic valid; - logic [riscv::VLEN-1:0] vaddr; - logic overflow; - logic [riscv::XLEN-1:0] data; - logic [(riscv::XLEN/8)-1:0] be; - fu_t fu; - fu_op operation; - logic [ariane_pkg::TRANS_ID_BITS-1:0] trans_id; + logic valid; + logic [riscv::VLEN-1:0] vaddr; + logic overflow; + logic [riscv::XLEN-1:0] data; + logic [(riscv::XLEN/8)-1:0] be; + fu_t fu; + fu_op operation; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; }, localparam type fu_data_t = struct packed { - fu_t fu; - fu_op operation; - logic [riscv::XLEN-1:0] operand_a; - logic [riscv::XLEN-1:0] operand_b; - logic [riscv::XLEN-1:0] imm; - logic [ariane_pkg::TRANS_ID_BITS-1:0] trans_id; + fu_t fu; + fu_op operation; + logic [riscv::XLEN-1:0] operand_a; + logic [riscv::XLEN-1:0] operand_b; + logic [riscv::XLEN-1:0] imm; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; }, localparam type icache_req_t = struct packed { - logic [$clog2(ariane_pkg::ICACHE_SET_ASSOC)-1:0] way; // way to replace + logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] way; // way to replace logic [riscv::PLEN-1:0] paddr; // physical address logic nc; // noncacheable logic [CVA6Cfg.MEM_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane) }, localparam type icache_rtrn_t = struct packed { wt_cache_pkg::icache_in_t rtype; // see definitions above - logic [ariane_pkg::ICACHE_LINE_WIDTH-1:0] data; // full cache line width - logic [ariane_pkg::ICACHE_USER_LINE_WIDTH-1:0] user; // user bits + logic [CVA6Cfg.ICACHE_LINE_WIDTH-1:0] data; // full cache line width + logic [CVA6Cfg.ICACHE_USER_LINE_WIDTH-1:0] user; // user bits struct packed { logic vld; // invalidate only affected way logic all; // invalidate all ways - logic [ariane_pkg::ICACHE_INDEX_WIDTH-1:0] idx; // physical address to invalidate - logic [wt_cache_pkg::L1I_WAY_WIDTH-1:0] way; // way to invalidate + logic [CVA6Cfg.ICACHE_INDEX_WIDTH-1:0] idx; // physical address to invalidate + logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] way; // way to invalidate } inv; // invalidation vector logic [CVA6Cfg.MEM_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane) }, // D$ data requests localparam type dcache_req_i_t = struct packed { - logic [DCACHE_INDEX_WIDTH-1:0] address_index; - logic [DCACHE_TAG_WIDTH-1:0] address_tag; - logic [riscv::XLEN-1:0] data_wdata; - logic [DCACHE_USER_WIDTH-1:0] data_wuser; - logic data_req; - logic data_we; - logic [(riscv::XLEN/8)-1:0] data_be; - logic [1:0] data_size; - logic [DCACHE_TID_WIDTH-1:0] data_id; - logic kill_req; - logic tag_valid; + logic [CVA6Cfg.DCACHE_INDEX_WIDTH-1:0] address_index; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] address_tag; + logic [riscv::XLEN-1:0] data_wdata; + logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] data_wuser; + logic data_req; + logic data_we; + logic [(riscv::XLEN/8)-1:0] data_be; + logic [1:0] data_size; + logic [DCACHE_TID_WIDTH-1:0] data_id; + logic kill_req; + logic tag_valid; }, localparam type dcache_req_o_t = struct packed { - logic data_gnt; - logic data_rvalid; - logic [DCACHE_TID_WIDTH-1:0] data_rid; - logic [riscv::XLEN-1:0] data_rdata; - logic [DCACHE_USER_WIDTH-1:0] data_ruser; + logic data_gnt; + logic data_rvalid; + logic [DCACHE_TID_WIDTH-1:0] data_rid; + logic [riscv::XLEN-1:0] data_rdata; + logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] data_ruser; }, // AXI types @@ -295,6 +295,24 @@ module cva6 input noc_resp_t noc_resp_i ); + localparam type interrupts_t = struct packed { + logic [riscv::XLEN-1:0] S_SW; + logic [riscv::XLEN-1:0] M_SW; + logic [riscv::XLEN-1:0] S_TIMER; + logic [riscv::XLEN-1:0] M_TIMER; + logic [riscv::XLEN-1:0] S_EXT; + logic [riscv::XLEN-1:0] M_EXT; + }; + + localparam interrupts_t INTERRUPTS = '{ + S_SW: (1 << (riscv::XLEN - 1)) | riscv::XLEN'(riscv::IRQ_S_SOFT), + M_SW: (1 << (riscv::XLEN - 1)) | riscv::XLEN'(riscv::IRQ_M_SOFT), + S_TIMER: (1 << (riscv::XLEN - 1)) | riscv::XLEN'(riscv::IRQ_S_TIMER), + M_TIMER: (1 << (riscv::XLEN - 1)) | riscv::XLEN'(riscv::IRQ_M_TIMER), + S_EXT: (1 << (riscv::XLEN - 1)) | riscv::XLEN'(riscv::IRQ_S_EXT), + M_EXT: (1 << (riscv::XLEN - 1)) | riscv::XLEN'(riscv::IRQ_M_EXT) + }; + // ------------------------------------------ // Global Signals // Signals connecting more than one module @@ -343,7 +361,7 @@ module cva6 logic is_compressed_instr_id_ex; // fixed latency units logic flu_ready_ex_id; - logic [TRANS_ID_BITS-1:0] flu_trans_id_ex_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] flu_trans_id_ex_id; logic flu_valid_ex_id; logic [riscv::XLEN-1:0] flu_result_ex_id; exception_t flu_exception_ex_id; @@ -358,13 +376,13 @@ module cva6 logic lsu_valid_id_ex; logic lsu_ready_ex_id; - logic [TRANS_ID_BITS-1:0] load_trans_id_ex_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] load_trans_id_ex_id; logic [riscv::XLEN-1:0] load_result_ex_id; logic load_valid_ex_id; exception_t load_exception_ex_id; logic [riscv::XLEN-1:0] store_result_ex_id; - logic [TRANS_ID_BITS-1:0] store_trans_id_ex_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] store_trans_id_ex_id; logic store_valid_ex_id; exception_t store_exception_ex_id; // MULT @@ -374,7 +392,7 @@ module cva6 logic fpu_valid_id_ex; logic [1:0] fpu_fmt_id_ex; logic [2:0] fpu_rm_id_ex; - logic [TRANS_ID_BITS-1:0] fpu_trans_id_ex_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] fpu_trans_id_ex_id; logic [riscv::XLEN-1:0] fpu_result_ex_id; logic fpu_valid_ex_id; exception_t fpu_exception_ex_id; @@ -382,7 +400,7 @@ module cva6 logic stall_acc_id; scoreboard_entry_t issue_instr_id_acc; logic issue_instr_hs_id_acc; - logic [TRANS_ID_BITS-1:0] acc_trans_id_ex_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] acc_trans_id_ex_id; logic [riscv::XLEN-1:0] acc_result_ex_id; logic acc_valid_ex_id; exception_t acc_exception_ex_id; @@ -393,7 +411,7 @@ module cva6 // CSR logic csr_valid_id_ex; // CVXIF - logic [TRANS_ID_BITS-1:0] x_trans_id_ex_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_ex_id; logic [riscv::XLEN-1:0] x_result_ex_id; logic x_valid_ex_id; exception_t x_exception_ex_id; @@ -411,7 +429,7 @@ module cva6 // LSU Commit logic lsu_commit_commit_ex; logic lsu_commit_ready_ex_commit; - logic [TRANS_ID_BITS-1:0] lsu_commit_trans_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_commit_trans_id; logic stall_st_pending_ex; logic no_st_pending_ex; logic no_st_pending_commit; @@ -425,8 +443,8 @@ module cva6 // -------------- // RVFI // -------------- - logic [TRANS_ID_BITS-1:0] rvfi_issue_pointer; - logic [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] rvfi_commit_pointer; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer; + logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer; // -------------- // COMMIT <-> ID // -------------- @@ -447,7 +465,7 @@ module cva6 riscv::priv_lvl_t ld_st_priv_lvl_csr_ex; logic sum_csr_ex; logic mxr_csr_ex; - logic [riscv::PPNW-1:0] satp_ppn_csr_ex; + logic [CVA6Cfg.PPNW-1:0] satp_ppn_csr_ex; logic [ASID_WIDTH-1:0] asid_csr_ex; logic [11:0] csr_addr_ex_csr; fu_op csr_op_commit_csr; @@ -472,66 +490,66 @@ module cva6 // ---------------------------- logic [11:0] addr_csr_perf; logic [riscv::XLEN-1:0] data_csr_perf, data_perf_csr; - logic we_csr_perf; + logic we_csr_perf; - logic icache_flush_ctrl_cache; - logic itlb_miss_ex_perf; - logic dtlb_miss_ex_perf; - logic dcache_miss_cache_perf; - logic icache_miss_cache_perf; - logic [ NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits; - logic stall_issue; + logic icache_flush_ctrl_cache; + logic itlb_miss_ex_perf; + logic dtlb_miss_ex_perf; + logic dcache_miss_cache_perf; + logic icache_miss_cache_perf; + logic [ NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits; + logic stall_issue; // -------------- // CTRL <-> * // -------------- - logic set_pc_ctrl_pcgen; - logic flush_csr_ctrl; - logic flush_unissued_instr_ctrl_id; - logic flush_ctrl_if; - logic flush_ctrl_id; - logic flush_ctrl_ex; - logic flush_ctrl_bp; - logic flush_tlb_ctrl_ex; - logic fence_i_commit_controller; - logic fence_commit_controller; - logic sfence_vma_commit_controller; - logic halt_ctrl; - logic halt_csr_ctrl; - logic dcache_flush_ctrl_cache; - logic dcache_flush_ack_cache_ctrl; - logic set_debug_pc; - logic flush_commit; - logic flush_acc; + logic set_pc_ctrl_pcgen; + logic flush_csr_ctrl; + logic flush_unissued_instr_ctrl_id; + logic flush_ctrl_if; + logic flush_ctrl_id; + logic flush_ctrl_ex; + logic flush_ctrl_bp; + logic flush_tlb_ctrl_ex; + logic fence_i_commit_controller; + logic fence_commit_controller; + logic sfence_vma_commit_controller; + logic halt_ctrl; + logic halt_csr_ctrl; + logic dcache_flush_ctrl_cache; + logic dcache_flush_ack_cache_ctrl; + logic set_debug_pc; + logic flush_commit; + logic flush_acc; - icache_areq_t icache_areq_ex_cache; - icache_arsp_t icache_areq_cache_ex; - icache_dreq_t icache_dreq_if_cache; - icache_drsp_t icache_dreq_cache_if; + icache_areq_t icache_areq_ex_cache; + icache_arsp_t icache_areq_cache_ex; + icache_dreq_t icache_dreq_if_cache; + icache_drsp_t icache_dreq_cache_if; - amo_req_t amo_req; - amo_resp_t amo_resp; - logic sb_full; + amo_req_t amo_req; + amo_resp_t amo_resp; + logic sb_full; // ---------------- // DCache <-> * // ---------------- - dcache_req_i_t [ 2:0] dcache_req_ports_ex_cache; - dcache_req_o_t [ 2:0] dcache_req_ports_cache_ex; - dcache_req_i_t [ 1:0] dcache_req_ports_acc_cache; - dcache_req_o_t [ 1:0] dcache_req_ports_cache_acc; - logic dcache_commit_wbuffer_empty; - logic dcache_commit_wbuffer_not_ni; + dcache_req_i_t [ 2:0] dcache_req_ports_ex_cache; + dcache_req_o_t [ 2:0] dcache_req_ports_cache_ex; + dcache_req_i_t [ 1:0] dcache_req_ports_acc_cache; + dcache_req_o_t [ 1:0] dcache_req_ports_cache_acc; + logic dcache_commit_wbuffer_empty; + logic dcache_commit_wbuffer_not_ni; //RVFI - lsu_ctrl_t rvfi_lsu_ctrl; - logic [riscv::PLEN-1:0] rvfi_mem_paddr; - logic rvfi_is_compressed; - rvfi_probes_csr_t rvfi_csr; + lsu_ctrl_t rvfi_lsu_ctrl; + logic [riscv::PLEN-1:0] rvfi_mem_paddr; + logic rvfi_is_compressed; + rvfi_probes_csr_t rvfi_csr; // Accelerator port - logic [ 63:0] inval_addr; - logic inval_valid; - logic inval_ready; + logic [ 63:0] inval_addr; + logic inval_valid; + logic inval_ready; // -------------- // Frontend @@ -573,7 +591,9 @@ module cva6 .exception_t(exception_t), .fetch_entry_t(fetch_entry_t), .irq_ctrl_t(irq_ctrl_t), - .scoreboard_entry_t(scoreboard_entry_t) + .scoreboard_entry_t(scoreboard_entry_t), + .interrupts_t(interrupts_t), + .INTERRUPTS(INTERRUPTS) ) id_stage_i ( .clk_i, .rst_ni, @@ -604,7 +624,7 @@ module cva6 .tsr_i (tsr_csr_id) ); - logic [CVA6Cfg.NrWbPorts-1:0][TRANS_ID_BITS-1:0] trans_id_ex_id; + logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_ex_id; logic [CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_ex_id; exception_t [CVA6Cfg.NrWbPorts-1:0] ex_ex_ex_id; // exception from execute, ex_stage to id_stage logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_ex_id; @@ -1373,7 +1393,8 @@ module cva6 for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin : gen_pc_fifo fifo_v3 #( .DATA_WIDTH(64), - .DEPTH(PC_QUEUE_DEPTH) + .DEPTH(PC_QUEUE_DEPTH), + .FPGA_EN(CVA6Cfg.FPGA_EN) ) i_pc_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -1455,7 +1476,9 @@ module cva6 instr_tracer #( .CVA6Cfg(CVA6Cfg), .bp_resolve_t(bp_resolve_t), - .scoreboard_entry_t(scoreboard_entry_t) + .scoreboard_entry_t(scoreboard_entry_t), + .interrupts_t(interrupts_t), + .INTERRUPTS(INTERRUPTS) ) instr_tracer_i ( .tracer_if(tracer_if), .hart_id_i diff --git a/core/cva6_rvfi.sv b/core/cva6_rvfi.sv index fdea33da6..af0ac64c5 100644 --- a/core/cva6_rvfi.sv +++ b/core/cva6_rvfi.sv @@ -54,14 +54,17 @@ module cva6_rvfi | ((riscv::XLEN == 64 ? 2 : 1) << riscv::XLEN - 2); // MXL localparam logic [riscv::XLEN-1:0] hart_id_i = '0; + + localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg); + logic flush; logic issue_instr_ack; logic fetch_entry_valid; logic [31:0] instruction; logic is_compressed; - logic [TRANS_ID_BITS-1:0] issue_pointer; - logic [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] issue_pointer; + logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] commit_pointer; logic flush_unissued_instr; logic decoded_instr_valid; @@ -71,7 +74,7 @@ module cva6_rvfi logic [riscv::XLEN-1:0] rs2_forwarding; logic [CVA6Cfg.NrCommitPorts-1:0][riscv::VLEN-1:0] commit_instr_pc; - fu_op [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_instr_op; + fu_op [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] commit_instr_op; logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rs1; logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rs2; logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rd; @@ -86,7 +89,7 @@ module cva6_rvfi logic [riscv::VLEN-1:0] lsu_ctrl_vaddr; fu_t lsu_ctrl_fu; logic [(riscv::XLEN/8)-1:0] lsu_ctrl_be; - logic [TRANS_ID_BITS-1:0] lsu_ctrl_trans_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_ctrl_trans_id; logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; @@ -97,7 +100,7 @@ module cva6_rvfi logic [riscv::VLEN-1:0] lsu_addr; logic [(riscv::XLEN/8)-1:0] lsu_rmask; logic [(riscv::XLEN/8)-1:0] lsu_wmask; - logic [TRANS_ID_BITS-1:0] lsu_addr_trans_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_addr_trans_id; riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d; @@ -201,7 +204,7 @@ module cva6_rvfi logic [riscv::XLEN-1:0] lsu_wdata; logic [31:0] instr; } sb_mem_t; - sb_mem_t [NR_SB_ENTRIES-1:0] mem_q, mem_n; + sb_mem_t [CVA6Cfg.NR_SB_ENTRIES-1:0] mem_q, mem_n; always_comb begin : issue_fifo mem_n = mem_q; @@ -311,8 +314,8 @@ module cva6_rvfi : '0; rvfi_csr_o.sstatus = CVA6Cfg.RVS ? '{ - rdata: csr.mstatus_extended & ariane_pkg::SMODE_STATUS_READ_MASK[riscv::XLEN-1:0], - wdata: csr.mstatus_extended & ariane_pkg::SMODE_STATUS_READ_MASK[riscv::XLEN-1:0], + rdata: csr.mstatus_extended & SMODE_STATUS_READ_MASK[riscv::XLEN-1:0], + wdata: csr.mstatus_extended & SMODE_STATUS_READ_MASK[riscv::XLEN-1:0], rmask: '1, wmask: '1 } diff --git a/core/cva6_rvfi_probes.sv b/core/cva6_rvfi_probes.sv index 1288a45e8..da5f746fd 100644 --- a/core/cva6_rvfi_probes.sv +++ b/core/cva6_rvfi_probes.sv @@ -28,8 +28,8 @@ module cva6_rvfi_probes input logic [31:0] instruction_i, input logic is_compressed_i, - input logic [TRANS_ID_BITS-1:0] issue_pointer_i, - input logic [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] issue_pointer_i, + input logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] commit_pointer_i, input logic flush_unissued_instr_i, input logic decoded_instr_valid_i, diff --git a/core/cvxif_example/cvxif_example_coprocessor.sv b/core/cvxif_example/cvxif_example_coprocessor.sv index 08e801c33..93edc8b3f 100644 --- a/core/cvxif_example/cvxif_example_coprocessor.sv +++ b/core/cvxif_example/cvxif_example_coprocessor.sv @@ -12,7 +12,9 @@ module cvxif_example_coprocessor import cvxif_pkg::*; import cvxif_instr_pkg::*; -( +#( + 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 input cvxif_req_t cvxif_req_i, @@ -109,10 +111,11 @@ module cvxif_example_coprocessor end fifo_v3 #( - .FALL_THROUGH(1), //data_o ready and pop in the same cycle + .FALL_THROUGH(1), //data_o ready and pop in the same cycle .DATA_WIDTH (64), .DEPTH (8), - .dtype (x_issue_t) + .dtype (x_issue_t), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) fifo_commit_i ( .clk_i (clk_i), .rst_ni (rst_ni), diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index c6a14296c..170c58ef8 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -18,38 +18,38 @@ module cvxif_fu parameter type fu_data_t = logic ) ( // Subsystem Clock - SUBSYSTEM - input logic clk_i, + input logic clk_i, // Asynchronous reset active low - SUBSYSTEM - input logic rst_ni, + input logic rst_ni, // FU data needed to execute instruction - ISSUE_STAGE - input fu_data_t fu_data_i, + input fu_data_t fu_data_i, // Current privilege mode - CSR_REGFILE - input riscv::priv_lvl_t priv_lvl_i, + input riscv::priv_lvl_t priv_lvl_i, // CVXIF instruction is valid - ISSUE_STAGE - input logic x_valid_i, + input logic x_valid_i, // CVXIF is ready - ISSUE_STAGE - output logic x_ready_o, + output logic x_ready_o, // Offloaded instruction - ISSUE_STAGE - input logic [ 31:0] x_off_instr_i, + input logic [ 31:0] x_off_instr_i, // CVXIF transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] x_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o, // CVXIF exception - ISSUE_STAGE - output exception_t x_exception_o, + output exception_t x_exception_o, // CVXIF FU result - ISSUE_STAGE - output logic [ riscv::XLEN-1:0] x_result_o, + output logic [ riscv::XLEN-1:0] x_result_o, // CVXIF result valid - ISSUE_STAGE - output logic x_valid_o, + output logic x_valid_o, // CVXIF write enable - ISSUE_STAGE - output logic x_we_o, + output logic x_we_o, // CVXIF request - SUBSYSTEM - output cvxif_pkg::cvxif_req_t cvxif_req_o, + output cvxif_pkg::cvxif_req_t cvxif_req_o, // CVXIF response - SUBSYSTEM - input cvxif_pkg::cvxif_resp_t cvxif_resp_i + input cvxif_pkg::cvxif_resp_t cvxif_resp_i ); localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS; logic illegal_n, illegal_q; - logic [TRANS_ID_BITS-1:0] illegal_id_n, illegal_id_q; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] illegal_id_n, illegal_id_q; logic [31:0] illegal_instr_n, illegal_instr_q; logic [X_NUM_RS-1:0] rs_valid; diff --git a/core/decoder.sv b/core/decoder.sv index a5a044e05..a05b55705 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -26,7 +26,9 @@ module decoder parameter type branchpredict_sbe_t = logic, parameter type exception_t = logic, parameter type irq_ctrl_t = logic, - parameter type scoreboard_entry_t = logic + parameter type scoreboard_entry_t = logic, + parameter type interrupts_t = logic, + parameter interrupts_t INTERRUPTS = '0 ) ( // Debug (async) request - SUBSYSTEM input logic debug_req_i, @@ -1397,29 +1399,29 @@ module decoder // for two privilege levels: Supervisor and Machine Mode // Supervisor Timer Interrupt if (irq_ctrl_i.mie[riscv::IRQ_S_TIMER] && irq_ctrl_i.mip[riscv::IRQ_S_TIMER]) begin - interrupt_cause = riscv::S_TIMER_INTERRUPT; + interrupt_cause = INTERRUPTS.S_TIMER; end // Supervisor Software Interrupt if (irq_ctrl_i.mie[riscv::IRQ_S_SOFT] && irq_ctrl_i.mip[riscv::IRQ_S_SOFT]) begin - interrupt_cause = riscv::S_SW_INTERRUPT; + interrupt_cause = INTERRUPTS.S_SW; end // Supervisor External Interrupt // The logical-OR of the software-writable bit and the signal from the external interrupt controller is // used to generate external interrupts to the supervisor if (irq_ctrl_i.mie[riscv::IRQ_S_EXT] && (irq_ctrl_i.mip[riscv::IRQ_S_EXT] | irq_i[ariane_pkg::SupervisorIrq])) begin - interrupt_cause = riscv::S_EXT_INTERRUPT; + interrupt_cause = INTERRUPTS.S_EXT; end // Machine Timer Interrupt if (irq_ctrl_i.mip[riscv::IRQ_M_TIMER] && irq_ctrl_i.mie[riscv::IRQ_M_TIMER]) begin - interrupt_cause = riscv::M_TIMER_INTERRUPT; + interrupt_cause = INTERRUPTS.M_TIMER; end // Machine Mode Software Interrupt if (irq_ctrl_i.mip[riscv::IRQ_M_SOFT] && irq_ctrl_i.mie[riscv::IRQ_M_SOFT]) begin - interrupt_cause = riscv::M_SW_INTERRUPT; + interrupt_cause = INTERRUPTS.M_SW; end // Machine Mode External Interrupt if (irq_ctrl_i.mip[riscv::IRQ_M_EXT] && irq_ctrl_i.mie[riscv::IRQ_M_EXT]) begin - interrupt_cause = riscv::M_EXT_INTERRUPT; + interrupt_cause = INTERRUPTS.M_EXT; end if (interrupt_cause[riscv::XLEN-1] && irq_ctrl_i.global_enable) begin diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 30d571451..c30915b36 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -52,7 +52,7 @@ module ex_stage // Fixed Latency Unit result - ISSUE_STAGE output logic [riscv::XLEN-1:0] flu_result_o, // ID of the scoreboard entry at which a=to write back - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] flu_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] flu_trans_id_o, // Fixed Latency Unit exception - ISSUE_STAGE output exception_t flu_exception_o, // FLU is ready - ISSUE_STAGE @@ -86,7 +86,7 @@ module ex_stage // Load result valid - ISSUE_STAGE output logic [riscv::XLEN-1:0] load_result_o, // Load instruction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] load_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] load_trans_id_o, // Exception generated by load instruction - ISSUE_STAGE output exception_t load_exception_o, // Store result is valid - ISSUe_STAGE @@ -94,7 +94,7 @@ module ex_stage // Store result - ISSUE_STAGE output logic [riscv::XLEN-1:0] store_result_o, // Store instruction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] store_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] store_trans_id_o, // Exception generated by store instruction - ISSUE_STAGE output exception_t store_exception_o, // LSU commit - COMMIT_STAGE @@ -102,7 +102,7 @@ module ex_stage // Commit queue ready to accept another commit request - COMMIT_STAGE output logic lsu_commit_ready_o, // Commit transaction ID - COMMIT_STAGE - input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] commit_tran_id_i, // TO_BE_COMPLETED - ACC_DISPATCHER input logic stall_st_pending_i, // TO_BE_COMPLETED - COMMIT_STAGE @@ -122,7 +122,7 @@ module ex_stage // FPU precision control - CSR_REGFILE input logic [6:0] fpu_prec_i, // FPU transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] fpu_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] fpu_trans_id_o, // FPU result - ISSUE_STAGE output logic [riscv::XLEN-1:0] fpu_result_o, // FPU valid - ISSUE_STAGE @@ -136,7 +136,7 @@ module ex_stage // undecoded instruction - ISSUE_STAGE input logic [31:0] x_off_instr_i, // CVXIF transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] x_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o, // CVXIF exception - ISSUE_STAGE output exception_t x_exception_o, // CVXIF result - ISSUE_STAGE @@ -166,7 +166,7 @@ module ex_stage // Make executable readable - CSR_REGFILE input logic mxr_i, // TO_BE_COMPLETED - CSR_REGFILE - input logic [riscv::PPNW-1:0] satp_ppn_i, + input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, // TO_BE_COMPLETED - CSR_REGFILE input logic [ASID_WIDTH-1:0] asid_i, // icache translation response - CACHE @@ -231,7 +231,7 @@ module ex_stage logic [riscv::XLEN-1:0] alu_result, csr_result, mult_result; logic [riscv::VLEN-1:0] branch_result; logic csr_ready, mult_ready; - logic [TRANS_ID_BITS-1:0] mult_trans_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] mult_trans_id; logic mult_valid; // 1. ALU (combinatorial) diff --git a/core/fpu_wrap.sv b/core/fpu_wrap.sv index 671ce177a..c319a5739 100644 --- a/core/fpu_wrap.sv +++ b/core/fpu_wrap.sv @@ -27,14 +27,14 @@ module fpu_wrap output logic fpu_ready_o, input fu_data_t fu_data_i, - input logic [ 1:0] fpu_fmt_i, - input logic [ 2:0] fpu_rm_i, - input logic [ 2:0] fpu_frm_i, - input logic [ 6:0] fpu_prec_i, - output logic [TRANS_ID_BITS-1:0] fpu_trans_id_o, - output logic [ CVA6Cfg.FLen-1:0] result_o, - output logic fpu_valid_o, - output exception_t fpu_exception_o + input logic [ 1:0] fpu_fmt_i, + input logic [ 2:0] fpu_rm_i, + input logic [ 2:0] fpu_frm_i, + input logic [ 6:0] fpu_prec_i, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] fpu_trans_id_o, + output logic [ CVA6Cfg.FLen-1:0] result_o, + output logic fpu_valid_o, + output exception_t fpu_exception_o ); // this is a workaround @@ -110,7 +110,7 @@ module fpu_wrap logic [2:0] fpu_rm_d, fpu_rm_q, fpu_rm; logic fpu_vec_op_d, fpu_vec_op_q, fpu_vec_op; - logic [TRANS_ID_BITS-1:0] fpu_tag_d, fpu_tag_q, fpu_tag; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] fpu_tag_d, fpu_tag_q, fpu_tag; logic fpu_in_ready, fpu_in_valid; logic fpu_out_ready, fpu_out_valid; @@ -531,7 +531,7 @@ module fpu_wrap fpnew_top #( .Features (FPU_FEATURES), .Implementation(FPU_IMPLEMENTATION), - .TagType (logic [TRANS_ID_BITS-1:0]) + .TagType (logic [CVA6Cfg.TRANS_ID_BITS-1:0]) ) i_fpnew_bulk ( .clk_i, .rst_ni, diff --git a/core/frontend/bht.sv b/core/frontend/bht.sv index 5e738c44b..9ea0395a9 100644 --- a/core/frontend/bht.sv +++ b/core/frontend/bht.sv @@ -36,15 +36,15 @@ module bht #( // Update bht with resolved address - EXECUTE input bht_update_t bht_update_i, // Prediction from bht - FRONTEND - output ariane_pkg::bht_prediction_t [ariane_pkg::INSTR_PER_FETCH-1:0] bht_prediction_o + output ariane_pkg::bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction_o ); // the last bit is always zero, we don't need it for indexing localparam OFFSET = CVA6Cfg.RVC == 1'b1 ? 1 : 2; // re-shape the branch history table - localparam NR_ROWS = NR_ENTRIES / ariane_pkg::INSTR_PER_FETCH; + localparam NR_ROWS = NR_ENTRIES / CVA6Cfg.INSTR_PER_FETCH; // number of bits needed to index the row - localparam ROW_ADDR_BITS = $clog2(ariane_pkg::INSTR_PER_FETCH); - localparam ROW_INDEX_BITS = CVA6Cfg.RVC == 1'b1 ? $clog2(ariane_pkg::INSTR_PER_FETCH) : 1; + localparam ROW_ADDR_BITS = $clog2(CVA6Cfg.INSTR_PER_FETCH); + localparam ROW_INDEX_BITS = CVA6Cfg.RVC == 1'b1 ? $clog2(CVA6Cfg.INSTR_PER_FETCH) : 1; // number of bits we should use for prediction localparam PREDICTION_BITS = $clog2(NR_ROWS) + OFFSET + ROW_ADDR_BITS; // we are not interested in all bits of the address @@ -54,8 +54,8 @@ module bht #( logic valid; logic [1:0] saturation_counter; } - bht_d[NR_ROWS-1:0][ariane_pkg::INSTR_PER_FETCH-1:0], - bht_q[NR_ROWS-1:0][ariane_pkg::INSTR_PER_FETCH-1:0]; + bht_d[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0], + bht_q[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0]; logic [$clog2(NR_ROWS)-1:0] index, update_pc; logic [ROW_INDEX_BITS-1:0] update_row_index; @@ -68,11 +68,11 @@ module bht #( assign update_row_index = '0; end - if (!ariane_pkg::FPGA_EN) begin : gen_asic_bht // ASIC TARGET + if (!CVA6Cfg.FPGA_EN) begin : gen_asic_bht // ASIC TARGET logic [1:0] saturation_counter; // prediction assignment - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_bht_output + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_bht_output assign bht_prediction_o[i].valid = bht_q[index][i].valid; assign bht_prediction_o[i].taken = bht_q[index][i].saturation_counter[1] == 1'b1; end @@ -104,7 +104,7 @@ module bht #( always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin for (int unsigned i = 0; i < NR_ROWS; i++) begin - for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin + for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin bht_q[i][j] <= '0; end end @@ -112,7 +112,7 @@ module bht #( // evict all entries if (flush_bp_i) begin for (int i = 0; i < NR_ROWS; i++) begin - for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin + for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin bht_q[i][j].valid <= 1'b0; bht_q[i][j].saturation_counter <= 2'b10; end @@ -127,17 +127,17 @@ module bht #( // number of bits par word in the bram localparam BRAM_WORD_BITS = $bits(ariane_pkg::bht_t); - logic [ ROW_INDEX_BITS-1:0] row_index; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] bht_ram_we; - logic [ariane_pkg::INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] bht_ram_read_address_0; - logic [ariane_pkg::INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] bht_ram_read_address_1; - logic [ariane_pkg::INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] bht_ram_write_address; - logic [ ariane_pkg::INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] bht_ram_wdata; - logic [ ariane_pkg::INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] bht_ram_rdata_0; - logic [ ariane_pkg::INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] bht_ram_rdata_1; + logic [ ROW_INDEX_BITS-1:0] row_index; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] bht_ram_we; + logic [CVA6Cfg.INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] bht_ram_read_address_0; + logic [CVA6Cfg.INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] bht_ram_read_address_1; + logic [CVA6Cfg.INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] bht_ram_write_address; + logic [ CVA6Cfg.INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] bht_ram_wdata; + logic [ CVA6Cfg.INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] bht_ram_rdata_0; + logic [ CVA6Cfg.INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] bht_ram_rdata_1; - ariane_pkg::bht_t [ ariane_pkg::INSTR_PER_FETCH-1:0] bht; - ariane_pkg::bht_t [ ariane_pkg::INSTR_PER_FETCH-1:0] bht_updated; + ariane_pkg::bht_t [ CVA6Cfg.INSTR_PER_FETCH-1:0] bht; + ariane_pkg::bht_t [ CVA6Cfg.INSTR_PER_FETCH-1:0] bht_updated; if (CVA6Cfg.RVC) begin : gen_row_index assign row_index = vpc_i[ROW_ADDR_BITS+OFFSET-1:OFFSET]; @@ -157,7 +157,7 @@ module bht #( bht_updated = '0; bht = '0; - for (int i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + for (int i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin if (row_index == i) begin bht_ram_read_address_0[i*$clog2(NR_ROWS)+:$clog2(NR_ROWS)] = index; bht_prediction_o[i].valid = bht_ram_rdata_0[i*BRAM_WORD_BITS+2]; @@ -166,7 +166,7 @@ module bht #( end if (bht_update_i.valid && !debug_mode_i) begin - for (int i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + for (int i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin if (update_row_index == i) begin bht_ram_read_address_1[i*$clog2(NR_ROWS)+:$clog2(NR_ROWS)] = update_pc; bht[i].saturation_counter = bht_ram_rdata_1[i*BRAM_WORD_BITS+:2]; @@ -201,7 +201,7 @@ module bht #( end end - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_bht_ram + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_bht_ram AsyncThreePortRam #( .ADDR_WIDTH($clog2(NR_ROWS)), .DATA_DEPTH(NR_ROWS), diff --git a/core/frontend/btb.sv b/core/frontend/btb.sv index f561a881a..b8acaee98 100644 --- a/core/frontend/btb.sv +++ b/core/frontend/btb.sv @@ -44,15 +44,15 @@ module btb #( // Update BTB with resolved address - EXECUTE input btb_update_t btb_update_i, // BTB Prediction - FRONTEND - output btb_prediction_t [ariane_pkg::INSTR_PER_FETCH-1:0] btb_prediction_o + output btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction_o ); // the last bit is always zero, we don't need it for indexing localparam OFFSET = CVA6Cfg.RVC == 1'b1 ? 1 : 2; // re-shape the branch history table - localparam NR_ROWS = NR_ENTRIES / ariane_pkg::INSTR_PER_FETCH; + localparam NR_ROWS = NR_ENTRIES / CVA6Cfg.INSTR_PER_FETCH; // number of bits needed to index the row - localparam ROW_ADDR_BITS = $clog2(ariane_pkg::INSTR_PER_FETCH); - localparam ROW_INDEX_BITS = CVA6Cfg.RVC == 1'b1 ? $clog2(ariane_pkg::INSTR_PER_FETCH) : 1; + localparam ROW_ADDR_BITS = $clog2(CVA6Cfg.INSTR_PER_FETCH); + localparam ROW_INDEX_BITS = CVA6Cfg.RVC == 1'b1 ? $clog2(CVA6Cfg.INSTR_PER_FETCH) : 1; // number of bits we should use for prediction localparam PREDICTION_BITS = $clog2(NR_ROWS) + OFFSET + ROW_ADDR_BITS; // prevent aliasing to degrade performance @@ -74,20 +74,20 @@ module btb #( assign update_row_index = '0; end - if (ariane_pkg::FPGA_EN) begin : gen_fpga_btb //FPGA TARGETS - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] btb_ram_csel_prediction; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] btb_ram_we_prediction; - logic [ariane_pkg::INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] btb_ram_addr_prediction; - logic [ ariane_pkg::INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] btb_ram_wdata_prediction; - logic [ ariane_pkg::INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] btb_ram_rdata_prediction; + if (CVA6Cfg.FPGA_EN) begin : gen_fpga_btb //FPGA TARGETS + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] btb_ram_csel_prediction; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] btb_ram_we_prediction; + logic [CVA6Cfg.INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] btb_ram_addr_prediction; + logic [ CVA6Cfg.INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] btb_ram_wdata_prediction; + logic [ CVA6Cfg.INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] btb_ram_rdata_prediction; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] btb_ram_csel_update; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] btb_ram_we_update; - logic [ariane_pkg::INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] btb_ram_addr_update; - logic [ ariane_pkg::INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] btb_ram_wdata_update; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] btb_ram_csel_update; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] btb_ram_we_update; + logic [CVA6Cfg.INSTR_PER_FETCH*$clog2(NR_ROWS)-1:0] btb_ram_addr_update; + logic [ CVA6Cfg.INSTR_PER_FETCH*BRAM_WORD_BITS-1:0] btb_ram_wdata_update; // output matching prediction - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_btb_output + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_btb_output assign btb_ram_csel_prediction[i] = 1'b1; assign btb_ram_we_prediction[i] = 1'b0; assign btb_ram_wdata_prediction = '0; @@ -106,7 +106,7 @@ module btb #( btb_ram_wdata_update = '0; if (btb_update_i.valid && !debug_mode_i) begin - for (int i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + for (int i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin if (update_row_index == i) begin btb_ram_csel_update[i] = 1'b1; btb_ram_we_update[i] = 1'b1; @@ -119,7 +119,7 @@ module btb #( end end - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_btb_ram + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_btb_ram SyncDpRam #( .ADDR_WIDTH($clog2(NR_ROWS)), .DATA_DEPTH(NR_ROWS), @@ -149,11 +149,11 @@ module btb #( // typedef for all branch target entries // we may want to try to put a tag field that fills the rest of the PC in-order to mitigate aliasing effects btb_prediction_t - btb_d[NR_ROWS-1:0][ariane_pkg::INSTR_PER_FETCH-1:0], - btb_q[NR_ROWS-1:0][ariane_pkg::INSTR_PER_FETCH-1:0]; + btb_d[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0], + btb_q[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0]; // output matching prediction - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_btb_output + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_btb_output assign btb_prediction_o[i] = btb_q[index][i]; // workaround end @@ -180,7 +180,7 @@ module btb #( // evict all entries if (flush_bp_i) begin for (int i = 0; i < NR_ROWS; i++) begin - for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin + for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin btb_q[i][j].valid <= 1'b0; end end diff --git a/core/frontend/frontend.sv b/core/frontend/frontend.sv index bde92b676..340c47dc0 100644 --- a/core/frontend/frontend.sv +++ b/core/frontend/frontend.sv @@ -89,30 +89,30 @@ module frontend }; // Instruction Cache Registers, from I$ - logic [ FETCH_WIDTH-1:0] icache_data_q; - logic icache_valid_q; - ariane_pkg::frontend_exception_t icache_ex_valid_q; - logic [ riscv::VLEN-1:0] icache_vaddr_q; - logic instr_queue_ready; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] instr_queue_consumed; + logic [ CVA6Cfg.FETCH_WIDTH-1:0] icache_data_q; + logic icache_valid_q; + ariane_pkg::frontend_exception_t icache_ex_valid_q; + logic [ riscv::VLEN-1:0] icache_vaddr_q; + logic instr_queue_ready; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_consumed; // upper-most branch-prediction from last cycle - btb_prediction_t btb_q; - bht_prediction_t bht_q; + btb_prediction_t btb_q; + bht_prediction_t bht_q; // instruction fetch is ready - logic if_ready; + logic if_ready; logic [riscv::VLEN-1:0] npc_d, npc_q; // next PC // indicates whether we come out of reset (then we need to load boot_addr_i) - logic npc_rst_load_q; + logic npc_rst_load_q; - logic replay; - logic [ riscv::VLEN-1:0] replay_addr; + logic replay; + logic [ riscv::VLEN-1:0] replay_addr; // shift amount - logic [$clog2(ariane_pkg::INSTR_PER_FETCH)-1:0] shamt; + logic [$clog2(CVA6Cfg.INSTR_PER_FETCH)-1:0] shamt; // address will always be 16 bit aligned, make this explicit here if (CVA6Cfg.RVC) begin : gen_shamt - assign shamt = icache_dreq_i.vaddr[$clog2(ariane_pkg::INSTR_PER_FETCH):1]; + assign shamt = icache_dreq_i.vaddr[$clog2(CVA6Cfg.INSTR_PER_FETCH):1]; end else begin assign shamt = 1'b0; end @@ -121,35 +121,35 @@ module frontend // Ctrl Flow Speculation // ----------------------- // RVI ctrl flow prediction - logic [INSTR_PER_FETCH-1:0] rvi_return, rvi_call, rvi_branch, rvi_jalr, rvi_jump; - logic [INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] rvi_imm; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] rvi_return, rvi_call, rvi_branch, rvi_jalr, rvi_jump; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] rvi_imm; // RVC branching - logic [INSTR_PER_FETCH-1:0] rvc_branch, rvc_jump, rvc_jr, rvc_return, rvc_jalr, rvc_call; - logic [INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] rvc_imm; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] rvc_branch, rvc_jump, rvc_jr, rvc_return, rvc_jalr, rvc_call; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] rvc_imm; // re-aligned instruction and address (coming from cache - combinationally) - logic [INSTR_PER_FETCH-1:0][ 31:0] instr; - logic [INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr; - logic [INSTR_PER_FETCH-1:0] instruction_valid; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0][ 31:0] instr; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instruction_valid; // BHT, BTB and RAS prediction - bht_prediction_t [INSTR_PER_FETCH-1:0] bht_prediction; - btb_prediction_t [INSTR_PER_FETCH-1:0] btb_prediction; - bht_prediction_t [INSTR_PER_FETCH-1:0] bht_prediction_shifted; - btb_prediction_t [INSTR_PER_FETCH-1:0] btb_prediction_shifted; - ras_t ras_predict; - logic [ riscv::VLEN-1:0] vpc_btb; + bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction; + btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction; + bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction_shifted; + btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction_shifted; + ras_t ras_predict; + logic [ riscv::VLEN-1:0] vpc_btb; // branch-predict update - logic is_mispredict; + logic is_mispredict; logic ras_push, ras_pop; - logic [ riscv::VLEN-1:0] ras_update; + logic [ riscv::VLEN-1:0] ras_update; // Instruction FIFO - logic [ riscv::VLEN-1:0] predict_address; - cf_t [ariane_pkg::INSTR_PER_FETCH-1:0] cf_type; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvi_cf; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvc_cf; + logic [ riscv::VLEN-1:0] predict_address; + cf_t [CVA6Cfg.INSTR_PER_FETCH-1:0] cf_type; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] taken_rvi_cf; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] taken_rvc_cf; - logic serving_unaligned; + logic serving_unaligned; // Re-align instructions instr_realign #( .CVA6Cfg(CVA6Cfg) @@ -174,17 +174,17 @@ module frontend // the prediction we saved from the previous fetch if (CVA6Cfg.RVC) begin : gen_btb_prediction_shifted assign bht_prediction_shifted[0] = (serving_unaligned) ? bht_q : bht_prediction[addr[0][$clog2( - INSTR_PER_FETCH + CVA6Cfg.INSTR_PER_FETCH ):1]]; assign btb_prediction_shifted[0] = (serving_unaligned) ? btb_q : btb_prediction[addr[0][$clog2( - INSTR_PER_FETCH + CVA6Cfg.INSTR_PER_FETCH ):1]]; // for all other predictions we can use the generated address to index // into the branch prediction data structures - for (genvar i = 1; i < INSTR_PER_FETCH; i++) begin : gen_prediction_address - assign bht_prediction_shifted[i] = bht_prediction[addr[i][$clog2(INSTR_PER_FETCH):1]]; - assign btb_prediction_shifted[i] = btb_prediction[addr[i][$clog2(INSTR_PER_FETCH):1]]; + for (genvar i = 1; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_prediction_address + assign bht_prediction_shifted[i] = bht_prediction[addr[i][$clog2(CVA6Cfg.INSTR_PER_FETCH):1]]; + assign btb_prediction_shifted[i] = btb_prediction[addr[i][$clog2(CVA6Cfg.INSTR_PER_FETCH):1]]; end end else begin assign bht_prediction_shifted[0] = (serving_unaligned) ? bht_q : bht_prediction[addr[0][1]]; @@ -196,13 +196,13 @@ module frontend // address of the call/return already logic bp_valid; - logic [INSTR_PER_FETCH-1:0] is_branch; - logic [INSTR_PER_FETCH-1:0] is_call; - logic [INSTR_PER_FETCH-1:0] is_jump; - logic [INSTR_PER_FETCH-1:0] is_return; - logic [INSTR_PER_FETCH-1:0] is_jalr; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] is_branch; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] is_call; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] is_jump; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] is_return; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] is_jalr; - for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin // branch history table -> BHT assign is_branch[i] = instruction_valid[i] & (rvi_branch[i] | rvc_branch[i]); // function calls -> RAS @@ -221,14 +221,14 @@ module frontend taken_rvc_cf = '0; predict_address = '0; - for (int i = 0; i < INSTR_PER_FETCH; i++) cf_type[i] = ariane_pkg::NoCF; + for (int i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) cf_type[i] = ariane_pkg::NoCF; ras_push = 1'b0; ras_pop = 1'b0; ras_update = '0; // lower most prediction gets precedence - for (int i = INSTR_PER_FETCH - 1; i >= 0; i--) begin + for (int i = CVA6Cfg.INSTR_PER_FETCH - 1; i >= 0; i--) begin unique case ({ is_branch[i], is_return[i], is_jump[i], is_jalr[i] }) @@ -297,7 +297,7 @@ module frontend // BP cannot be valid if we have a return instruction and the RAS is not giving a valid address // Check that we encountered a control flow and that for a return the RAS // contains a valid prediction. - for (int i = 0; i < INSTR_PER_FETCH; i++) + for (int i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) bp_valid |= ((cf_type[i] != NoCF & cf_type[i] != Return) | ((cf_type[i] == Return) & ras_predict.valid)); end assign is_mispredict = resolved_branch_i.valid & resolved_branch_i.is_mispredict; @@ -406,7 +406,7 @@ module frontend icache_dreq_o.vaddr = fetch_address; end - logic [FETCH_WIDTH-1:0] icache_data; + logic [CVA6Cfg.FETCH_WIDTH-1:0] icache_data; // re-align the cache line assign icache_data = icache_dreq_i.data >> {shamt, 4'b0}; @@ -438,8 +438,8 @@ module frontend icache_ex_valid_q <= ariane_pkg::FE_NONE; end // save the uppermost prediction - btb_q <= btb_prediction[INSTR_PER_FETCH-1]; - bht_q <= bht_prediction[INSTR_PER_FETCH-1]; + btb_q <= btb_prediction[CVA6Cfg.INSTR_PER_FETCH-1]; + bht_q <= bht_prediction[CVA6Cfg.INSTR_PER_FETCH-1]; end end end @@ -465,7 +465,7 @@ module frontend //For FPGA, BTB is implemented in read synchronous BRAM //while for ASIC, BTB is implemented in D flip-flop //and can be read at the same cycle. - assign vpc_btb = (ariane_pkg::FPGA_EN) ? icache_dreq_i.vaddr : icache_vaddr_q; + assign vpc_btb = (CVA6Cfg.FPGA_EN) ? icache_dreq_i.vaddr : icache_vaddr_q; if (CVA6Cfg.BTBEntries == 0) begin assign btb_prediction = '0; @@ -504,9 +504,9 @@ module frontend ); end - // we need to inspect up to INSTR_PER_FETCH instructions for branches + // we need to inspect up to CVA6Cfg.INSTR_PER_FETCH instructions for branches // and jumps - for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin : gen_instr_scan + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_instr_scan instr_scan #( .CVA6Cfg(CVA6Cfg) ) i_instr_scan ( @@ -553,7 +553,7 @@ module frontend // pragma translate_off `ifndef VERILATOR initial begin - assert (FETCH_WIDTH == 32 || FETCH_WIDTH == 64) + assert (CVA6Cfg.FETCH_WIDTH == 32 || CVA6Cfg.FETCH_WIDTH == 64) else $fatal(1, "[frontend] fetch width != not supported"); end `endif diff --git a/core/frontend/instr_queue.sv b/core/frontend/instr_queue.sv index 039484199..4daed4311 100644 --- a/core/frontend/instr_queue.sv +++ b/core/frontend/instr_queue.sv @@ -56,15 +56,15 @@ module instr_queue // Fetch flush request - CONTROLLER input logic flush_i, // Instruction - instr_realign - input logic [ariane_pkg::INSTR_PER_FETCH-1:0][31:0] instr_i, + input logic [CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] instr_i, // Instruction address - instr_realign - input logic [ariane_pkg::INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_i, + input logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_i, // Instruction is valid - instr_realign - input logic [ariane_pkg::INSTR_PER_FETCH-1:0] valid_i, + input logic [CVA6Cfg.INSTR_PER_FETCH-1:0] valid_i, // Handshake’s ready with CACHE - CACHE output logic ready_o, // Indicates instructions consummed, or popped by ID_STAGE - FRONTEND - output logic [ariane_pkg::INSTR_PER_FETCH-1:0] consumed_o, + output logic [CVA6Cfg.INSTR_PER_FETCH-1:0] consumed_o, // Exception (which is page-table fault) - CACHE input ariane_pkg::frontend_exception_t exception_i, // Exception address - CACHE @@ -72,7 +72,7 @@ module instr_queue // Branch predict - FRONTEND input logic [riscv::VLEN-1:0] predict_address_i, // Instruction predict address - FRONTEND - input ariane_pkg::cf_t [ariane_pkg::INSTR_PER_FETCH-1:0] cf_type_i, + input ariane_pkg::cf_t [CVA6Cfg.INSTR_PER_FETCH-1:0] cf_type_i, // Replay instruction because one of the FIFO was full - FRONTEND output logic replay_o, // Address at which to replay the fetch - FRONTEND @@ -92,16 +92,16 @@ module instr_queue logic [riscv::VLEN-1:0] ex_vaddr; // lower VLEN bits of tval for exception } instr_data_t; - logic [ariane_pkg::LOG2_INSTR_PER_FETCH-1:0] branch_index; + logic [CVA6Cfg.LOG2_INSTR_PER_FETCH-1:0] branch_index; // instruction queues - logic [ariane_pkg::INSTR_PER_FETCH-1:0][$clog2( + logic [CVA6Cfg.INSTR_PER_FETCH-1:0][$clog2( ariane_pkg::FETCH_FIFO_DEPTH )-1:0] instr_queue_usage; - instr_data_t [ariane_pkg::INSTR_PER_FETCH-1:0] instr_data_in, instr_data_out; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] push_instr, push_instr_fifo; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] pop_instr; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] instr_queue_full; - logic [ ariane_pkg::INSTR_PER_FETCH-1:0] instr_queue_empty; + instr_data_t [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_data_in, instr_data_out; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] push_instr, push_instr_fifo; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] pop_instr; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_full; + logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_empty; logic instr_overflow; // address queue logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)-1:0] address_queue_usage; @@ -112,42 +112,42 @@ ariane_pkg::FETCH_FIFO_DEPTH logic empty_address; logic address_overflow; // input stream counter - logic [ariane_pkg::LOG2_INSTR_PER_FETCH-1:0] idx_is_d, idx_is_q; + logic [CVA6Cfg.LOG2_INSTR_PER_FETCH-1:0] idx_is_d, idx_is_q; // Registers // output FIFO select, one-hot - logic [ariane_pkg::INSTR_PER_FETCH-1:0] idx_ds_d, idx_ds_q; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] idx_ds_d, idx_ds_q; logic [riscv::VLEN-1:0] pc_d, pc_q; // current PC logic reset_address_d, reset_address_q; // we need to re-set the address because of a flush - logic [ariane_pkg::INSTR_PER_FETCH*2-2:0] branch_mask_extended; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] branch_mask; + logic [CVA6Cfg.INSTR_PER_FETCH*2-2:0] branch_mask_extended; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] branch_mask; logic branch_empty; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] taken; // shift amount, e.g.: instructions we want to retire - logic [ariane_pkg::LOG2_INSTR_PER_FETCH:0] popcount; - logic [ariane_pkg::LOG2_INSTR_PER_FETCH-1:0] shamt; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] valid; - logic [ariane_pkg::INSTR_PER_FETCH*2-1:0] consumed_extended; + logic [CVA6Cfg.LOG2_INSTR_PER_FETCH:0] popcount; + logic [CVA6Cfg.LOG2_INSTR_PER_FETCH-1:0] shamt; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] valid; + logic [CVA6Cfg.INSTR_PER_FETCH*2-1:0] consumed_extended; // FIFO mask - logic [ariane_pkg::INSTR_PER_FETCH*2-1:0] fifo_pos_extended; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] fifo_pos; - logic [ariane_pkg::INSTR_PER_FETCH*2-1:0][31:0] instr; - ariane_pkg::cf_t [ariane_pkg::INSTR_PER_FETCH*2-1:0] cf; + logic [CVA6Cfg.INSTR_PER_FETCH*2-1:0] fifo_pos_extended; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] fifo_pos; + logic [CVA6Cfg.INSTR_PER_FETCH*2-1:0][31:0] instr; + ariane_pkg::cf_t [CVA6Cfg.INSTR_PER_FETCH*2-1:0] cf; // replay interface - logic [ariane_pkg::INSTR_PER_FETCH-1:0] instr_overflow_fifo; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_overflow_fifo; assign ready_o = ~(|instr_queue_full) & ~full_address; if (ariane_pkg::RVC) begin : gen_multiple_instr_per_fetch_with_C - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_unpack_taken + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_unpack_taken assign taken[i] = cf_type_i[i] != ariane_pkg::NoCF; end // calculate a branch mask, e.g.: get the first taken branch lzc #( - .WIDTH(ariane_pkg::INSTR_PER_FETCH), - .MODE (0) // count trailing zeros + .WIDTH(CVA6Cfg.INSTR_PER_FETCH), + .MODE (0) // count trailing zeros ) i_lzc_branch_index ( .in_i (taken), // we want to count trailing zeros .cnt_o (branch_index), // first branch on branch_index @@ -161,17 +161,17 @@ ariane_pkg::FETCH_FIFO_DEPTH // leading zero count = 1 // 0 0 0 1, 1 1 1 << 1 = 0 0 1 1, 1 1 0 // take the upper 4 bits: 0 0 1 1 - assign branch_mask_extended = {{{ariane_pkg::INSTR_PER_FETCH-1}{1'b0}}, {{ariane_pkg::INSTR_PER_FETCH}{1'b1}}} << branch_index; - assign branch_mask = branch_mask_extended[ariane_pkg::INSTR_PER_FETCH * 2 - 2:ariane_pkg::INSTR_PER_FETCH - 1]; + assign branch_mask_extended = {{{CVA6Cfg.INSTR_PER_FETCH-1}{1'b0}}, {{CVA6Cfg.INSTR_PER_FETCH}{1'b1}}} << branch_index; + assign branch_mask = branch_mask_extended[CVA6Cfg.INSTR_PER_FETCH * 2 - 2:CVA6Cfg.INSTR_PER_FETCH - 1]; // mask with taken branches to get the actual amount of instructions we want to push assign valid = valid_i & branch_mask; // rotate right again assign consumed_extended = {push_instr_fifo, push_instr_fifo} >> idx_is_q; - assign consumed_o = consumed_extended[ariane_pkg::INSTR_PER_FETCH-1:0]; + assign consumed_o = consumed_extended[CVA6Cfg.INSTR_PER_FETCH-1:0]; // count the numbers of valid instructions we've pushed from this package popcount #( - .INPUT_WIDTH(ariane_pkg::INSTR_PER_FETCH) + .INPUT_WIDTH(CVA6Cfg.INSTR_PER_FETCH) ) i_popcount ( .data_i (push_instr_fifo), .popcount_o(popcount) @@ -187,21 +187,21 @@ ariane_pkg::FETCH_FIFO_DEPTH // rotate left by the current position assign fifo_pos_extended = {valid, valid} << idx_is_q; // we just care about the upper bits - assign fifo_pos = fifo_pos_extended[ariane_pkg::INSTR_PER_FETCH*2-1:ariane_pkg::INSTR_PER_FETCH]; + assign fifo_pos = fifo_pos_extended[CVA6Cfg.INSTR_PER_FETCH*2-1:CVA6Cfg.INSTR_PER_FETCH]; // the fifo_position signal can directly be used to guide the push signal of each FIFO // make sure it is not full assign push_instr = fifo_pos & ~instr_queue_full; // duplicate the entries for easier selection e.g.: 3 2 1 0 3 2 1 0 - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_duplicate_instr_input + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_duplicate_instr_input assign instr[i] = instr_i[i]; - assign instr[i+ariane_pkg::INSTR_PER_FETCH] = instr_i[i]; + assign instr[i+CVA6Cfg.INSTR_PER_FETCH] = instr_i[i]; assign cf[i] = cf_type_i[i]; - assign cf[i+ariane_pkg::INSTR_PER_FETCH] = cf_type_i[i]; + assign cf[i+CVA6Cfg.INSTR_PER_FETCH] = cf_type_i[i]; end // shift the inputs - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_fifo_input_select + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_fifo_input_select /* verilator lint_off WIDTH */ assign instr_data_in[i].instr = instr[i+idx_is_q]; assign instr_data_in[i].cf = cf[i+idx_is_q]; @@ -287,7 +287,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.branch_predict.predict_address = address_out; fetch_entry_o.branch_predict.cf = ariane_pkg::NoCF; // output mux select - for (int unsigned i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + for (int unsigned i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin if (idx_ds_q[i]) begin if (instr_data_out[i].ex == ariane_pkg::FE_INSTR_ACCESS_FAULT) begin fetch_entry_o.ex.cause = riscv::INSTR_ACCESS_FAULT; @@ -306,9 +306,7 @@ ariane_pkg::FETCH_FIFO_DEPTH end // rotate the pointer left if (fetch_entry_ready_i) begin - idx_ds_d = { - idx_ds_q[ariane_pkg::INSTR_PER_FETCH-2:0], idx_ds_q[ariane_pkg::INSTR_PER_FETCH-1] - }; + idx_ds_d = {idx_ds_q[CVA6Cfg.INSTR_PER_FETCH-2:0], idx_ds_q[CVA6Cfg.INSTR_PER_FETCH-1]}; end end end else begin : gen_downstream_itf_without_c @@ -366,12 +364,13 @@ ariane_pkg::FETCH_FIFO_DEPTH end // FIFOs - for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_instr_fifo + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_instr_fifo // Make sure we don't save any instructions if we couldn't save the address assign push_instr_fifo[i] = push_instr[i] & ~address_overflow; fifo_v3 #( - .DEPTH(ariane_pkg::FETCH_FIFO_DEPTH), - .dtype(instr_data_t) + .DEPTH (ariane_pkg::FETCH_FIFO_DEPTH), + .dtype (instr_data_t), + .FPGA_EN(CVA6Cfg.FPGA_EN) ) i_fifo_instr_data ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -391,14 +390,15 @@ ariane_pkg::FETCH_FIFO_DEPTH always_comb begin push_address = 1'b0; // check if we are pushing a ctrl flow change, if so save the address - for (int i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + for (int i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin push_address |= push_instr[i] & (instr_data_in[i].cf != ariane_pkg::NoCF); end end fifo_v3 #( .DEPTH (ariane_pkg::FETCH_FIFO_DEPTH), // TODO(zarubaf): Fork out to separate param - .DATA_WIDTH(riscv::VLEN) + .DATA_WIDTH(riscv::VLEN), + .FPGA_EN (CVA6Cfg.FPGA_EN) ) i_fifo_address ( .clk_i (clk_i), .rst_ni (rst_ni), diff --git a/core/id_stage.sv b/core/id_stage.sv index 1ce879ba2..36c5a65dd 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -19,7 +19,9 @@ module id_stage #( parameter type exception_t = logic, parameter type fetch_entry_t = logic, parameter type irq_ctrl_t = logic, - parameter type scoreboard_entry_t = logic + parameter type scoreboard_entry_t = logic, + parameter type interrupts_t = logic, + parameter interrupts_t INTERRUPTS = '0 ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -149,7 +151,9 @@ module id_stage #( .branchpredict_sbe_t(branchpredict_sbe_t), .exception_t(exception_t), .irq_ctrl_t(irq_ctrl_t), - .scoreboard_entry_t(scoreboard_entry_t) + .scoreboard_entry_t(scoreboard_entry_t), + .interrupts_t(interrupts_t), + .INTERRUPTS(INTERRUPTS) ) decoder_i ( .debug_req_i, .irq_ctrl_i, diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index a49565a74..d74da567d 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -29,11 +29,6 @@ package ariane_pkg; // 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 - // to uniquely identify the entry in the scoreboard localparam ASID_WIDTH = (riscv::XLEN == 64) ? 16 : 1; localparam BITS_SATURATION_COUNTER = 2; @@ -51,8 +46,6 @@ package ariane_pkg; // allocate more space for the commit buffer to be on the save side, this needs to be a power of two localparam logic [2:0] DEPTH_COMMIT = 'd4; - localparam bit FPGA_EN = cva6_config_pkg::CVA6ConfigFPGAEn; // Is FPGA optimization of CV32A6 - localparam bit RVC = cva6_config_pkg::CVA6ConfigCExtEn; // Is C extension configuration // Transprecision float unit @@ -120,19 +113,22 @@ package ariane_pkg; `else localparam bit ZERO_TVAL = 1'b0; `endif + // read mask for SSTATUS over MMSTATUS - localparam logic [63:0] SMODE_STATUS_READ_MASK = riscv::SSTATUS_UIE - | riscv::SSTATUS_SIE - | riscv::SSTATUS_SPIE - | riscv::SSTATUS_SPP - | riscv::SSTATUS_FS - | riscv::SSTATUS_XS - | riscv::SSTATUS_SUM - | riscv::SSTATUS_MXR - | riscv::SSTATUS_UPIE - | riscv::SSTATUS_SPIE - | riscv::SSTATUS_UXL - | riscv::SSTATUS_SD; + function automatic logic [63:0] smode_status_read_mask(config_pkg::cva6_cfg_t Cfg); + return riscv::SSTATUS_UIE + | riscv::SSTATUS_SIE + | riscv::SSTATUS_SPIE + | riscv::SSTATUS_SPP + | riscv::SSTATUS_FS + | riscv::SSTATUS_XS + | riscv::SSTATUS_SUM + | riscv::SSTATUS_MXR + | riscv::SSTATUS_UPIE + | riscv::SSTATUS_SPIE + | riscv::SSTATUS_UXL + | riscv::sstatus_sd(riscv::IS_XLEN64); + endfunction localparam logic [63:0] SMODE_STATUS_WRITE_MASK = riscv::SSTATUS_SIE | riscv::SSTATUS_SPIE @@ -144,12 +140,8 @@ package ariane_pkg; // AXI // --------------- - localparam FETCH_USER_WIDTH = cva6_config_pkg::CVA6ConfigFetchUserWidth; - localparam DATA_USER_WIDTH = cva6_config_pkg::CVA6ConfigDataUserWidth; localparam AXI_USER_EN = cva6_config_pkg::CVA6ConfigDataUserEn | cva6_config_pkg::CVA6ConfigFetchUserEn; localparam AXI_USER_WIDTH = cva6_config_pkg::CVA6ConfigDataUserWidth; - localparam DATA_USER_EN = cva6_config_pkg::CVA6ConfigDataUserEn; - localparam FETCH_USER_EN = cva6_config_pkg::CVA6ConfigFetchUserEn; typedef enum logic { SINGLE_REQ, @@ -162,10 +154,6 @@ package ariane_pkg; // leave as is (fails with >8 entries and wider fetch width) localparam int unsigned FETCH_FIFO_DEPTH = 4; - localparam int unsigned FETCH_WIDTH = 32; - // maximum instructions we can fetch on one request (we support compressed instructions) - localparam int unsigned INSTR_PER_FETCH = RVC == 1'b1 ? (FETCH_WIDTH / 16) : 1; - localparam int unsigned LOG2_INSTR_PER_FETCH = RVC == 1'b1 ? $clog2(INSTR_PER_FETCH) : 1; typedef enum logic [2:0] { NoCF, // No control flow prediction @@ -251,29 +239,9 @@ package ariane_pkg; localparam int unsigned DCACHE_INDEX_WIDTH = $clog2(`CONFIG_L1D_SIZE / DCACHE_SET_ASSOC); localparam int unsigned DCACHE_TAG_WIDTH = riscv::PLEN - DCACHE_INDEX_WIDTH; localparam int unsigned DCACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : 128; // in bit - localparam int unsigned DCACHE_USER_WIDTH = DATA_USER_WIDTH; + localparam int unsigned DCACHE_USER_WIDTH = cva6_config_pkg::CVA6ConfigDataUserWidth; localparam int unsigned MEM_TID_WIDTH = `L15_THREADID_WIDTH; -`else - // I$ - localparam int unsigned CONFIG_L1I_SIZE = cva6_config_pkg::CVA6ConfigIcacheByteSize; // in byte - localparam int unsigned ICACHE_SET_ASSOC = cva6_config_pkg::CVA6ConfigIcacheSetAssoc; // number of ways - localparam int unsigned ICACHE_INDEX_WIDTH = $clog2( - CONFIG_L1I_SIZE / ICACHE_SET_ASSOC - ); // in bit, contains also offset width - localparam int unsigned ICACHE_TAG_WIDTH = riscv::PLEN - ICACHE_INDEX_WIDTH; // in bit - localparam int unsigned ICACHE_LINE_WIDTH = cva6_config_pkg::CVA6ConfigIcacheLineWidth; // in bit - localparam int unsigned ICACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : cva6_config_pkg::CVA6ConfigIcacheLineWidth; // in bit - // D$ - localparam int unsigned CONFIG_L1D_SIZE = cva6_config_pkg::CVA6ConfigDcacheByteSize; // in byte - localparam int unsigned DCACHE_SET_ASSOC = cva6_config_pkg::CVA6ConfigDcacheSetAssoc; // number of ways - localparam int unsigned DCACHE_INDEX_WIDTH = $clog2( - CONFIG_L1D_SIZE / DCACHE_SET_ASSOC - ); // in bit, contains also offset width - localparam int unsigned DCACHE_TAG_WIDTH = riscv::PLEN - DCACHE_INDEX_WIDTH; // in bit - localparam int unsigned DCACHE_LINE_WIDTH = cva6_config_pkg::CVA6ConfigDcacheLineWidth; // in bit - localparam int unsigned DCACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : cva6_config_pkg::CVA6ConfigDcacheLineWidth; // in bit - localparam int unsigned DCACHE_USER_WIDTH = DATA_USER_WIDTH; `endif localparam int unsigned DCACHE_TID_WIDTH = cva6_config_pkg::CVA6ConfigDcacheIdWidth; diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index aafcf783d..b7c5a08bd 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -21,8 +21,15 @@ package build_config_pkg; bit EnableAccelerator = CVA6Cfg.RVV; // Currently only used by V extension (Ara) int unsigned NrWbPorts = (CVA6Cfg.CvxifEn || EnableAccelerator) ? 5 : 4; + int unsigned ICACHE_INDEX_WIDTH = $clog2(CVA6Cfg.IcacheByteSize / CVA6Cfg.IcacheSetAssoc); + int unsigned DCACHE_INDEX_WIDTH = $clog2(CVA6Cfg.DcacheByteSize / CVA6Cfg.DcacheSetAssoc); + int unsigned DCACHE_OFFSET_WIDTH = $clog2(CVA6Cfg.DcacheLineWidth / 8); + config_pkg::cva6_cfg_t cfg; + cfg.XLEN_ALIGN_BYTES = $clog2(riscv::XLEN / 8); + + cfg.FPGA_EN = CVA6Cfg.FPGA_EN; cfg.NrCommitPorts = CVA6Cfg.NrCommitPorts; cfg.AxiAddrWidth = CVA6Cfg.AxiAddrWidth; cfg.AxiDataWidth = CVA6Cfg.AxiDataWidth; @@ -43,6 +50,8 @@ package build_config_pkg; cfg.XFVec = CVA6Cfg.XFVec; cfg.CvxifEn = CVA6Cfg.CvxifEn; cfg.ZiCondExtEn = CVA6Cfg.ZiCondExtEn; + cfg.NR_SB_ENTRIES = CVA6Cfg.NrScoreboardEntries; + cfg.TRANS_ID_BITS = $clog2(CVA6Cfg.NrScoreboardEntries); cfg.RVF = bit'(RVF); cfg.RVD = bit'(RVD); @@ -85,8 +94,38 @@ package build_config_pkg; cfg.NonIdemPotenceEn = CVA6Cfg.NrNonIdempotentRules && CVA6Cfg.NonIdempotentLength; cfg.AxiBurstWriteEn = CVA6Cfg.AxiBurstWriteEn; + cfg.ICACHE_SET_ASSOC = CVA6Cfg.IcacheSetAssoc; + cfg.ICACHE_SET_ASSOC_WIDTH = $clog2(CVA6Cfg.IcacheSetAssoc); + cfg.ICACHE_INDEX_WIDTH = ICACHE_INDEX_WIDTH; + cfg.ICACHE_TAG_WIDTH = riscv::PLEN - ICACHE_INDEX_WIDTH; + cfg.ICACHE_LINE_WIDTH = CVA6Cfg.IcacheLineWidth; + cfg.ICACHE_USER_LINE_WIDTH = (CVA6Cfg.AxiUserWidth == 1) ? 4 : CVA6Cfg.IcacheLineWidth; + cfg.DCACHE_SET_ASSOC = CVA6Cfg.DcacheSetAssoc; + cfg.DCACHE_SET_ASSOC_WIDTH = $clog2(CVA6Cfg.DcacheSetAssoc); + cfg.DCACHE_INDEX_WIDTH = DCACHE_INDEX_WIDTH; + cfg.DCACHE_TAG_WIDTH = riscv::PLEN - DCACHE_INDEX_WIDTH; + cfg.DCACHE_LINE_WIDTH = CVA6Cfg.DcacheLineWidth; + cfg.DCACHE_USER_LINE_WIDTH = (CVA6Cfg.AxiUserWidth == 1) ? 4 : CVA6Cfg.DcacheLineWidth; + cfg.DCACHE_USER_WIDTH = CVA6Cfg.AxiUserWidth; + cfg.DCACHE_OFFSET_WIDTH = DCACHE_OFFSET_WIDTH; + cfg.DCACHE_NUM_WORDS = 2 ** (DCACHE_INDEX_WIDTH - DCACHE_OFFSET_WIDTH); + cfg.DCACHE_MAX_TX = unsigned'(2 ** CVA6Cfg.MemTidWidth); + cfg.DATA_USER_EN = CVA6Cfg.DataUserEn; + cfg.FETCH_USER_WIDTH = CVA6Cfg.FetchUserWidth; + cfg.FETCH_USER_EN = CVA6Cfg.FetchUserEn; + + cfg.FETCH_WIDTH = 32; + cfg.INSTR_PER_FETCH = CVA6Cfg.RVC == 1'b1 ? (cfg.FETCH_WIDTH / 16) : 1; + cfg.LOG2_INSTR_PER_FETCH = CVA6Cfg.RVC == 1'b1 ? $clog2(cfg.INSTR_PER_FETCH) : 1; + + cfg.ModeW = (riscv::XLEN == 32) ? 1 : 4; + cfg.ASIDW = (riscv::XLEN == 32) ? 9 : 16; + cfg.PPNW = (riscv::XLEN == 32) ? 22 : 44; + cfg.MODE_SV = (riscv::XLEN == 32) ? config_pkg::ModeSv32 : config_pkg::ModeSv39; + cfg.SV = (cfg.MODE_SV == config_pkg::ModeSv32) ? 32 : 39; + return cfg; endfunction diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index da1972d05..9bc1f5326 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -33,9 +33,21 @@ package config_pkg; HPDCACHE = 2 } cache_type_t; + /// Data and Address length + typedef enum logic [3:0] { + ModeOff = 0, + ModeSv32 = 1, + ModeSv39 = 8, + ModeSv48 = 9, + ModeSv57 = 10, + ModeSv64 = 11 + } vm_mode_t; + localparam NrMaxRules = 16; typedef struct packed { + // Is FPGA optimization of CV32A6 + bit FPGA_EN; // Number of commit ports int unsigned NrCommitPorts; // AXI address width @@ -80,6 +92,8 @@ package config_pkg; bit RVS; // User mode bit RVU; + // Scoreboard length + int unsigned NrScoreboardEntries; // Address to jump when halt request logic [63:0] HaltAddress; // Address to jump when exception @@ -128,9 +142,30 @@ package config_pkg; bit DebugEn; // AXI burst in write bit AxiBurstWriteEn; + // Instruction cache size (in bytes) + int unsigned IcacheByteSize; + // Instruction cache associativity (number of ways) + int unsigned IcacheSetAssoc; + // Instruction line width + int unsigned IcacheLineWidth; + // Data cache size (in bytes) + int unsigned DcacheByteSize; + // Data cache associativity (number of ways) + int unsigned DcacheSetAssoc; + // Data line width + int unsigned DcacheLineWidth; + // TODO + int unsigned DataUserEn; + // TODO + int unsigned FetchUserWidth; + // TODO + int unsigned FetchUserEn; } cva6_user_cfg_t; typedef struct packed { + int unsigned XLEN_ALIGN_BYTES; + + bit FPGA_EN; /// 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 @@ -156,7 +191,10 @@ package config_pkg; bit XFVec; bit CvxifEn; bit ZiCondExtEn; - // Calculated + + int unsigned NR_SB_ENTRIES; + int unsigned TRANS_ID_BITS; + bit RVF; bit RVD; bit FpPresent; @@ -198,7 +236,37 @@ package config_pkg; bit NonIdemPotenceEn; // Currently only used by V extension (Ara) bit AxiBurstWriteEn; + int unsigned ICACHE_SET_ASSOC; + int unsigned ICACHE_SET_ASSOC_WIDTH; + int unsigned ICACHE_INDEX_WIDTH; + int unsigned ICACHE_TAG_WIDTH; + int unsigned ICACHE_LINE_WIDTH; + int unsigned ICACHE_USER_LINE_WIDTH; + int unsigned DCACHE_SET_ASSOC; + int unsigned DCACHE_SET_ASSOC_WIDTH; + int unsigned DCACHE_INDEX_WIDTH; + int unsigned DCACHE_TAG_WIDTH; + int unsigned DCACHE_LINE_WIDTH; + int unsigned DCACHE_USER_LINE_WIDTH; + int unsigned DCACHE_USER_WIDTH; + int unsigned DCACHE_OFFSET_WIDTH; + int unsigned DCACHE_NUM_WORDS; + int unsigned DCACHE_MAX_TX; + + int unsigned DATA_USER_EN; + int unsigned FETCH_USER_WIDTH; + int unsigned FETCH_USER_EN; + + int unsigned FETCH_WIDTH; + int unsigned INSTR_PER_FETCH; + int unsigned LOG2_INSTR_PER_FETCH; + + int unsigned ModeW; + int unsigned ASIDW; + int unsigned PPNW; + vm_mode_t MODE_SV; + int unsigned SV; } cva6_cfg_t; /// Empty configuration to sanity check proper parameter passing. Whenever diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index 9a467b7de..9718a74dc 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index badc9ce01..6410344ae 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -75,6 +75,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -95,6 +96,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(0), RVU: bit'(0), HaltAddress: 64'h800, @@ -120,7 +122,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(0), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv32a6_embedded_config_pkg.sv b/core/include/cv32a6_embedded_config_pkg.sv index 99ed450cf..f30c4d7f0 100644 --- a/core/include/cv32a6_embedded_config_pkg.sv +++ b/core/include/cv32a6_embedded_config_pkg.sv @@ -75,6 +75,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -95,6 +96,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(0), RVU: bit'(0), HaltAddress: 64'h800, @@ -132,7 +134,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(0), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index 84a342a5d..f0879b139 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index 49f2f78a9..2650d6beb 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -125,6 +127,15 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index 7c3968757..b2e9d7227 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index 80139cc8f..1c6213fe6 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv index 481a6b668..85b3a8964 100644 --- a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv +++ b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index 33696e1c3..fb4d0b06f 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv index ab62c714f..61a537b04 100644 --- a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv @@ -83,6 +83,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -103,6 +104,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -140,7 +142,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 64cb7ce69..e55ff14a2 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv index e3582147b..6b186c7a3 100644 --- a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,7 +135,16 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index f39dbd454..311e6c501 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam CVA6ConfigRvfiTrace = 1; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ + FPGA_EN: bit'(CVA6ConfigFPGAEn), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -96,6 +97,7 @@ package cva6_config_pkg; XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), + NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), RVS: bit'(1), RVU: bit'(1), HaltAddress: 64'h800, @@ -133,6 +135,15 @@ package cva6_config_pkg; CachedRegionLength: 1024'({64'h40000000}), MaxOutstandingStores: unsigned'(7), DebugEn: bit'(1), - AxiBurstWriteEn: bit'(0) + AxiBurstWriteEn: bit'(0), + IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize), + IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc), + IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth), + DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize), + DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc), + DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth), + DataUserEn: unsigned'(CVA6ConfigDataUserEn), + FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth), + FetchUserEn: unsigned'(CVA6ConfigFetchUserEn) }; endpackage diff --git a/core/include/cvxif_pkg.sv b/core/include/cvxif_pkg.sv index 39e77b447..57bd40b01 100644 --- a/core/include/cvxif_pkg.sv +++ b/core/include/cvxif_pkg.sv @@ -13,7 +13,7 @@ package cvxif_pkg; localparam X_DATAWIDTH = riscv::XLEN; localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS; //2 or 3 - localparam X_ID_WIDTH = ariane_pkg::TRANS_ID_BITS; + localparam X_ID_WIDTH = $clog2(cva6_config_pkg::CVA6ConfigNrScoreboardEntries); localparam X_MEM_WIDTH = 64; localparam X_RFR_WIDTH = riscv::XLEN; localparam X_RFW_WIDTH = riscv::XLEN; diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index acada1857..8a57b0077 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -22,18 +22,6 @@ package riscv; // ---------------------- localparam XLEN = cva6_config_pkg::CVA6ConfigXlen; - // ---------------------- - // Data and Address length - // ---------------------- - typedef enum logic [3:0] { - ModeOff = 0, - ModeSv32 = 1, - ModeSv39 = 8, - ModeSv48 = 9, - ModeSv57 = 10, - ModeSv64 = 11 - } vm_mode_t; - // Warning: When using STD_CACHE, configuration must be PLEN=56 and VLEN=64 // Warning: VLEN must be superior or equal to PLEN localparam VLEN = (XLEN == 32) ? 32 : 64; // virtual address length @@ -41,13 +29,6 @@ package riscv; localparam IS_XLEN32 = (XLEN == 32) ? 1'b1 : 1'b0; localparam IS_XLEN64 = (XLEN == 32) ? 1'b0 : 1'b1; - localparam ModeW = (XLEN == 32) ? 1 : 4; - localparam ASIDW = (XLEN == 32) ? 9 : 16; - localparam PPNW = (XLEN == 32) ? 22 : 44; - localparam vm_mode_t MODE_SV = (XLEN == 32) ? ModeSv32 : ModeSv39; - localparam SV = (MODE_SV == ModeSv32) ? 32 : 39; - localparam VPN2 = (VLEN - 31 < 8) ? VLEN - 31 : 8; - localparam XLEN_ALIGN_BYTES = $clog2(XLEN / 8); // -------------------- // Privilege Spec @@ -338,19 +319,12 @@ package riscv; localparam int unsigned IRQ_S_EXT = 9; localparam int unsigned IRQ_M_EXT = 11; - localparam logic [XLEN-1:0] MIP_SSIP = 1 << IRQ_S_SOFT; - localparam logic [XLEN-1:0] MIP_MSIP = 1 << IRQ_M_SOFT; - localparam logic [XLEN-1:0] MIP_STIP = 1 << IRQ_S_TIMER; - localparam logic [XLEN-1:0] MIP_MTIP = 1 << IRQ_M_TIMER; - localparam logic [XLEN-1:0] MIP_SEIP = 1 << IRQ_S_EXT; - localparam logic [XLEN-1:0] MIP_MEIP = 1 << IRQ_M_EXT; - - localparam logic [XLEN-1:0] S_SW_INTERRUPT = (1 << (XLEN - 1)) | XLEN'(IRQ_S_SOFT); - localparam logic [XLEN-1:0] M_SW_INTERRUPT = (1 << (XLEN - 1)) | XLEN'(IRQ_M_SOFT); - localparam logic [XLEN-1:0] S_TIMER_INTERRUPT = (1 << (XLEN - 1)) | XLEN'(IRQ_S_TIMER); - localparam logic [XLEN-1:0] M_TIMER_INTERRUPT = (1 << (XLEN - 1)) | XLEN'(IRQ_M_TIMER); - localparam logic [XLEN-1:0] S_EXT_INTERRUPT = (1 << (XLEN - 1)) | XLEN'(IRQ_S_EXT); - localparam logic [XLEN-1:0] M_EXT_INTERRUPT = (1 << (XLEN - 1)) | XLEN'(IRQ_M_EXT); + localparam logic [31:0] MIP_SSIP = 1 << IRQ_S_SOFT; + localparam logic [31:0] MIP_MSIP = 1 << IRQ_M_SOFT; + localparam logic [31:0] MIP_STIP = 1 << IRQ_S_TIMER; + localparam logic [31:0] MIP_MTIP = 1 << IRQ_M_TIMER; + localparam logic [31:0] MIP_SEIP = 1 << IRQ_S_EXT; + localparam logic [31:0] MIP_MEIP = 1 << IRQ_M_EXT; // ----- // CSRs @@ -608,7 +582,9 @@ package riscv; localparam logic [63:0] SSTATUS_MXR = 'h00080000; localparam logic [63:0] SSTATUS_UPIE = 'h00000010; localparam logic [63:0] SSTATUS_UXL = 64'h0000000300000000; - localparam logic [63:0] SSTATUS_SD = {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000}; + function automatic logic [63:0] sstatus_sd(logic IS_XLEN64); + return {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000}; + endfunction localparam logic [63:0] MSTATUS_UIE = 'h00000001; localparam logic [63:0] MSTATUS_SIE = 'h00000002; diff --git a/core/include/rvfi_types.svh b/core/include/rvfi_types.svh index d6094c46e..b58ffe294 100644 --- a/core/include/rvfi_types.svh +++ b/core/include/rvfi_types.svh @@ -93,8 +93,8 @@ // RVFI PROBES `define RVFI_PROBES_INSTR_T(Cfg) struct packed { \ - logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer; \ - logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] commit_pointer; \ + logic [Cfg.TRANS_ID_BITS-1:0] issue_pointer; \ + logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][Cfg.TRANS_ID_BITS-1:0] commit_pointer; \ logic flush_unissued_instr; \ logic decoded_instr_valid; \ logic decoded_instr_ack; \ @@ -106,7 +106,7 @@ logic [riscv::XLEN-1:0] rs1_forwarding; \ logic [riscv::XLEN-1:0] rs2_forwarding; \ logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][riscv::VLEN-1:0] commit_instr_pc; \ - ariane_pkg::fu_op [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] commit_instr_op; \ + ariane_pkg::fu_op [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][Cfg.TRANS_ID_BITS-1:0] commit_instr_op; \ logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rs1; \ logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rs2; \ logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rd; \ @@ -118,7 +118,7 @@ logic [riscv::VLEN-1:0] lsu_ctrl_vaddr; \ ariane_pkg::fu_t lsu_ctrl_fu; \ logic [(riscv::XLEN/8)-1:0] lsu_ctrl_be; \ - logic [ariane_pkg::TRANS_ID_BITS-1:0] lsu_ctrl_trans_id; \ + logic [Cfg.TRANS_ID_BITS-1:0] lsu_ctrl_trans_id; \ logic [((cva6_config_pkg::CVA6ConfigCvxifEn || cva6_config_pkg::CVA6ConfigVExtEn) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; \ logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0] commit_ack; \ logic [riscv::PLEN-1:0] mem_paddr; \ diff --git a/core/include/std_cache_pkg.sv b/core/include/std_cache_pkg.sv index a80ac1392..e6c337e1a 100644 --- a/core/include/std_cache_pkg.sv +++ b/core/include/std_cache_pkg.sv @@ -17,11 +17,6 @@ package std_cache_pkg; - // Calculated parameter - localparam DCACHE_BYTE_OFFSET = $clog2(ariane_pkg::DCACHE_LINE_WIDTH / 8); - localparam DCACHE_NUM_WORDS = 2 ** (ariane_pkg::DCACHE_INDEX_WIDTH - DCACHE_BYTE_OFFSET); - localparam DCACHE_DIRTY_WIDTH = ariane_pkg::DCACHE_SET_ASSOC * 2; - localparam DCACHE_SET_ASSOC_WIDTH = $clog2(ariane_pkg::DCACHE_SET_ASSOC); // localparam DECISION_BIT = 30; // bit on which to decide whether the request is cache-able or not typedef struct packed { diff --git a/core/include/wt_cache_pkg.sv b/core/include/wt_cache_pkg.sv index 1cd92ad0b..3482a47a9 100644 --- a/core/include/wt_cache_pkg.sv +++ b/core/include/wt_cache_pkg.sv @@ -37,23 +37,14 @@ package wt_cache_pkg; localparam L15_SET_ASSOC = `CONFIG_L15_ASSOCIATIVITY; localparam L15_TLB_CSM_WIDTH = `TLB_CSM_WIDTH; `else - localparam L15_SET_ASSOC = ariane_pkg::DCACHE_SET_ASSOC;// align with dcache for compatibility with the standard Ariane setup localparam L15_TLB_CSM_WIDTH = 33; `endif - localparam L15_WAY_WIDTH = $clog2(L15_SET_ASSOC); - localparam L1I_WAY_WIDTH = $clog2(ariane_pkg::ICACHE_SET_ASSOC); - localparam L1D_WAY_WIDTH = $clog2(ariane_pkg::DCACHE_SET_ASSOC); // FIFO depths of L15 adapter localparam ADAPTER_REQ_FIFO_DEPTH = 2; localparam ADAPTER_RTRN_FIFO_DEPTH = 2; - // Calculated parameter - localparam DCACHE_OFFSET_WIDTH = $clog2(ariane_pkg::DCACHE_LINE_WIDTH / 8); - localparam DCACHE_NUM_WORDS = 2 ** (ariane_pkg::DCACHE_INDEX_WIDTH - DCACHE_OFFSET_WIDTH); - localparam DCACHE_CL_IDX_WIDTH = $clog2(DCACHE_NUM_WORDS); // excluding byte offset - // write buffer parameterization localparam DCACHE_WBUF_DEPTH = ariane_pkg::WT_DCACHE_WBUF_DEPTH; diff --git a/core/instr_realign.sv b/core/instr_realign.sv index 31a99a556..c259f4cc9 100644 --- a/core/instr_realign.sv +++ b/core/instr_realign.sv @@ -38,18 +38,18 @@ module instr_realign // 32-bit block address - CACHE input logic [riscv::VLEN-1:0] address_i, // 32-bit block - CACHE - input logic [FETCH_WIDTH-1:0] data_i, + input logic [CVA6Cfg.FETCH_WIDTH-1:0] data_i, // instruction is valid - FRONTEND - output logic [INSTR_PER_FETCH-1:0] valid_o, + output logic [CVA6Cfg.INSTR_PER_FETCH-1:0] valid_o, // Instruction address - FRONTEND - output logic [INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_o, + output logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_o, // Instruction - instr_scan&instr_queue - output logic [INSTR_PER_FETCH-1:0][31:0] instr_o + output logic [CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] instr_o ); // as a maximum we support a fetch width of 64-bit, hence there can be 4 compressed instructions logic [3:0] instr_is_compressed; - for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin + for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin // LSB != 2'b11 assign instr_is_compressed[i] = ~&data_i[i*16+:2]; end @@ -64,7 +64,7 @@ module instr_realign assign serving_unaligned_o = unaligned_q; // Instruction re-alignment - if (FETCH_WIDTH == 32) begin : realign_bp_32 + if (CVA6Cfg.FETCH_WIDTH == 32) begin : realign_bp_32 always_comb begin : re_align unaligned_d = unaligned_q; unaligned_address_d = {address_i[riscv::VLEN-1:2], 2'b10}; @@ -109,12 +109,12 @@ module instr_realign unaligned_instr_d = data_i[15:0]; // the instruction isn't compressed but only the lower is ready end else begin - valid_o = {{INSTR_PER_FETCH - 1{1'b0}}, 1'b1}; + valid_o = {{CVA6Cfg.INSTR_PER_FETCH - 1{1'b0}}, 1'b1}; end end end - // TODO(zarubaf): Fix 64 bit FETCH_WIDTH, maybe generalize to arbitrary fetch width - end else if (FETCH_WIDTH == 64) begin : realign_bp_64 + // TODO(zarubaf): Fix 64 bit CVA6Cfg.FETCH_WIDTH, maybe generalize to arbitrary fetch width + end else if (CVA6Cfg.FETCH_WIDTH == 64) begin : realign_bp_64 initial begin $error("Not propperly implemented"); end diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 0402f2a45..27a708354 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -136,7 +136,7 @@ module issue_read_operands logic cvxif_valid_q; logic [31:0] cvxif_off_instr_q; - logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; fu_op operator_n, operator_q; // operation to perform fu_t fu_n, fu_q; // functional unit to use @@ -483,7 +483,7 @@ module issue_read_operands assign wdata_pack[i] = wdata_i[i]; assign we_pack[i] = we_gpr_i[i]; end - if (ariane_pkg::FPGA_EN) begin : gen_fpga_regfile + if (CVA6Cfg.FPGA_EN) begin : gen_fpga_regfile ariane_regfile_fpga #( .CVA6Cfg (CVA6Cfg), .DATA_WIDTH (riscv::XLEN), @@ -532,7 +532,7 @@ module issue_read_operands for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin : gen_fp_wdata_pack assign fp_wdata_pack[i] = {wdata_i[i][CVA6Cfg.FLen-1:0]}; end - if (ariane_pkg::FPGA_EN) begin : gen_fpga_fp_regfile + if (CVA6Cfg.FPGA_EN) begin : gen_fpga_fp_regfile ariane_regfile_fpga #( .CVA6Cfg (CVA6Cfg), .DATA_WIDTH (CVA6Cfg.FLen), diff --git a/core/issue_stage.sv b/core/issue_stage.sv index 4d9d5835c..9cf74f753 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -93,7 +93,7 @@ module issue_stage // TO_BE_COMPLETED - ACC_DISPATCHER output logic issue_instr_hs_o, // Transaction ID - EX_STAGE - input logic [CVA6Cfg.NrWbPorts-1:0][TRANS_ID_BITS-1:0] trans_id_i, + input logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_i, // The branch engine uses the write back from the ALU - EX_STAGE input bp_resolve_t resolved_branch_i, // TO_BE_COMPLETED - EX_STAGE @@ -119,9 +119,9 @@ module issue_stage // Issue stall - PERF_COUNTERS output logic stall_issue_o, // Information dedicated to RVFI - RVFI - output logic [TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, // Information dedicated to RVFI - RVFI - output logic [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] rvfi_commit_pointer_o + output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o ); // --------------------------------------------------- // Scoreboard (SB) <-> Issue and Read Operands (IRO) diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index e38949fc8..df4933fd6 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -48,7 +48,7 @@ module load_store_unit input logic lsu_valid_i, // Load transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] load_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] load_trans_id_o, // Load result - ISSUE_STAGE output logic [riscv::XLEN-1:0] load_result_o, // Load result is valid - ISSUE_STAGE @@ -57,7 +57,7 @@ module load_store_unit output exception_t load_exception_o, // Store transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] store_trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] store_trans_id_o, // Store result - ISSUE_STAGE output logic [riscv::XLEN-1:0] store_result_o, // Store result is valid - ISSUE_STAGE @@ -70,7 +70,7 @@ module load_store_unit // Commit queue is ready to accept another commit request - TO_BE_COMPLETED output logic commit_ready_o, // Commit transaction ID - TO_BE_COMPLETED - input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] commit_tran_id_i, // Enable virtual memory translation - TO_BE_COMPLETED input logic enable_translation_i, @@ -83,27 +83,27 @@ module load_store_unit output icache_areq_t icache_areq_o, // Current privilege mode - CSR_REGFILE - input riscv::priv_lvl_t priv_lvl_i, + input riscv::priv_lvl_t priv_lvl_i, // Privilege level at which load and stores should happen - CSR_REGFILE - input riscv::priv_lvl_t ld_st_priv_lvl_i, + input riscv::priv_lvl_t ld_st_priv_lvl_i, // Supervisor User Memory - CSR_REGFILE - input logic sum_i, + input logic sum_i, // Make Executable Readable - CSR_REGFILE - input logic mxr_i, + input logic mxr_i, // TO_BE_COMPLETED - TO_BE_COMPLETED - input logic [riscv::PPNW-1:0] satp_ppn_i, + input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, // TO_BE_COMPLETED - TO_BE_COMPLETED - input logic [ ASID_WIDTH-1:0] asid_i, + input logic [ ASID_WIDTH-1:0] asid_i, // TO_BE_COMPLETED - TO_BE_COMPLETED - input logic [ ASID_WIDTH-1:0] asid_to_be_flushed_i, + input logic [ ASID_WIDTH-1:0] asid_to_be_flushed_i, // TO_BE_COMPLETED - TO_BE_COMPLETED - input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i, + input logic [ riscv::VLEN-1:0] vaddr_to_be_flushed_i, // TLB flush - CONTROLLER - input logic flush_tlb_i, + input logic flush_tlb_i, // Instruction TLB miss - PERF_COUNTERS - output logic itlb_miss_o, + output logic itlb_miss_o, // Data TLB miss - PERF_COUNTERS - output logic dtlb_miss_o, + output logic dtlb_miss_o, // Data cache request output - CACHES input dcache_req_o_t [ 2:0] dcache_req_ports_i, @@ -152,7 +152,7 @@ module load_store_unit assign vaddr_xlen = $unsigned($signed(fu_data_i.imm) + $signed(fu_data_i.operand_a)); assign vaddr_i = vaddr_xlen[riscv::VLEN-1:0]; // we work with SV39 or SV32, so if VM is enabled, check that all bits [XLEN-1:38] or [XLEN-1:31] are equal - assign overflow = (riscv::IS_XLEN64 && (!((&vaddr_xlen[riscv::XLEN-1:riscv::SV-1]) == 1'b1 || (|vaddr_xlen[riscv::XLEN-1:riscv::SV-1]) == 1'b0))); + assign overflow = (riscv::IS_XLEN64 && (!((&vaddr_xlen[riscv::XLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|vaddr_xlen[riscv::XLEN-1:CVA6Cfg.SV-1]) == 1'b0))); logic st_valid_i; logic ld_valid_i; @@ -164,23 +164,23 @@ module load_store_unit logic translation_valid; logic [riscv::VLEN-1:0] mmu_vaddr; logic [riscv::PLEN-1:0] mmu_paddr, mmu_vaddr_plen, fetch_vaddr_plen; - exception_t mmu_exception; - logic dtlb_hit; - logic [ riscv::PPNW-1:0] dtlb_ppn; + exception_t mmu_exception; + logic dtlb_hit; + logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn; - logic ld_valid; - logic [TRANS_ID_BITS-1:0] ld_trans_id; - logic [ riscv::XLEN-1:0] ld_result; - logic st_valid; - logic [TRANS_ID_BITS-1:0] st_trans_id; - logic [ riscv::XLEN-1:0] st_result; + logic ld_valid; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id; + logic [ riscv::XLEN-1:0] ld_result; + logic st_valid; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id; + logic [ riscv::XLEN-1:0] st_result; - logic [ 11:0] page_offset; - logic page_offset_matches; + logic [ 11:0] page_offset; + logic page_offset_matches; - exception_t misaligned_exception; - exception_t ld_ex; - exception_t st_ex; + exception_t misaligned_exception; + exception_t ld_ex; + exception_t st_ex; // ------------------- // MMU e.g.: TLBs/PTW diff --git a/core/load_unit.sv b/core/load_unit.sv index 21403c915..c1519bdb6 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -42,7 +42,7 @@ module load_unit // Load unit result is valid - TO_BE_COMPLETED output logic valid_o, // Load transaction ID - TO_BE_COMPLETED - output logic [TRANS_ID_BITS-1:0] trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_o, // Load result - TO_BE_COMPLETED output logic [riscv::XLEN-1:0] result_o, // Load exception - TO_BE_COMPLETED @@ -58,7 +58,7 @@ module load_unit // Data TLB hit - lsu input logic dtlb_hit_i, // TO_BE_COMPLETED - TO_BE_COMPLETED - input logic [riscv::PPNW-1:0] dtlb_ppn_i, + input logic [CVA6Cfg.PPNW-1:0] dtlb_ppn_i, // TO_BE_COMPLETED - TO_BE_COMPLETED output logic [11:0] page_offset_o, // TO_BE_COMPLETED - TO_BE_COMPLETED @@ -66,7 +66,7 @@ module load_unit // Store buffer is empty - TO_BE_COMPLETED input logic store_buffer_empty_i, // TO_BE_COMPLETED - TO_BE_COMPLETED - input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] commit_tran_id_i, // Data cache request out - CACHES input dcache_req_o_t req_port_i, // Data cache request in - CACHES @@ -90,9 +90,9 @@ module load_unit // in order to decouple the response interface from the request interface, // we need a a buffer which can hold all inflight memory load requests typedef struct packed { - logic [TRANS_ID_BITS-1:0] trans_id; // scoreboard identifier - logic [riscv::XLEN_ALIGN_BYTES-1:0] address_offset; // least significant bits of the address - fu_op operation; // type of load + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; // scoreboard identifier + logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] address_offset; // least significant bits of the address + fu_op operation; // type of load } ldbuf_t; @@ -188,15 +188,15 @@ module load_unit assign req_port_o.data_wdata = '0; // compose the load buffer write data, control is handled in the FSM assign ldbuf_wdata = { - lsu_ctrl_i.trans_id, lsu_ctrl_i.vaddr[riscv::XLEN_ALIGN_BYTES-1:0], lsu_ctrl_i.operation + lsu_ctrl_i.trans_id, lsu_ctrl_i.vaddr[CVA6Cfg.XLEN_ALIGN_BYTES-1:0], lsu_ctrl_i.operation }; // output address // we can now output the lower 12 bit as the index to the cache - assign req_port_o.address_index = lsu_ctrl_i.vaddr[ariane_pkg::DCACHE_INDEX_WIDTH-1:0]; + assign req_port_o.address_index = lsu_ctrl_i.vaddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; // translation from last cycle, again: control is handled in the FSM - assign req_port_o.address_tag = paddr_i[ariane_pkg::DCACHE_TAG_WIDTH + - ariane_pkg::DCACHE_INDEX_WIDTH-1 : - ariane_pkg::DCACHE_INDEX_WIDTH]; + assign req_port_o.address_tag = paddr_i[CVA6Cfg.DCACHE_TAG_WIDTH + + CVA6Cfg.DCACHE_INDEX_WIDTH-1 : + CVA6Cfg.DCACHE_INDEX_WIDTH]; // request id = index of the load buffer's entry assign req_port_o.data_id = ldbuf_windex; // directly forward exception fields (valid bit is set below) @@ -209,7 +209,7 @@ module load_unit logic inflight_stores; logic stall_ni; assign paddr_ni = config_pkg::is_inside_nonidempotent_regions( - CVA6Cfg, {{52 - riscv::PPNW{1'b0}}, dtlb_ppn_i, 12'd0} + CVA6Cfg, {{52 - CVA6Cfg.PPNW{1'b0}}, 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); @@ -473,8 +473,8 @@ module load_unit end */ // result mux fast - logic [ (riscv::XLEN/8)-1:0] rdata_sign_bits; - logic [riscv::XLEN_ALIGN_BYTES-1:0] rdata_offset; + logic [ (riscv::XLEN/8)-1:0] rdata_sign_bits; + logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] rdata_offset; logic rdata_sign_bit, rdata_is_signed, rdata_is_fp_signed; diff --git a/core/mmu_sv32/cva6_mmu_sv32.sv b/core/mmu_sv32/cva6_mmu_sv32.sv index 1f452423f..7fa0b4f60 100644 --- a/core/mmu_sv32/cva6_mmu_sv32.sv +++ b/core/mmu_sv32/cva6_mmu_sv32.sv @@ -59,7 +59,7 @@ module cva6_mmu_sv32 // if we need to walk the page table we can't grant in the same cycle // Cycle 0 output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB - output logic [riscv::PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit) + output logic [CVA6Cfg.PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit) // Cycle 1 output logic lsu_valid_o, // translation is valid output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address @@ -70,7 +70,7 @@ module cva6_mmu_sv32 input logic sum_i, input logic mxr_i, // input logic flag_mprv_i, - input logic [riscv::PPNW-1:0] satp_ppn_i, + input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, input logic [ASID_WIDTH-1:0] asid_i, input logic [ASID_WIDTH-1:0] asid_to_be_flushed_i, input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i, @@ -303,8 +303,8 @@ module cva6_mmu_sv32 // AXI decode error), or when PTW performs walk due to ITLB miss and raises // an error. if (enable_translation_i) begin - // we work with SV32, so if VM is enabled, check that all bits [riscv::VLEN-1:riscv::SV-1] are equal - if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[riscv::VLEN-1:riscv::SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[riscv::VLEN-1:riscv::SV-1]) == 1'b0)) begin + // we work with SV32, so if VM is enabled, check that all bits [riscv::VLEN-1:CVA6Cfg.SV-1] are equal + if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -415,7 +415,7 @@ module cva6_mmu_sv32 // Wires to PMP checks riscv::pmp_access_t pmp_access_type; logic pmp_data_allow; - localparam PPNWMin = (riscv::PPNW - 1 > 29) ? 29 : riscv::PPNW - 1; + localparam PPNWMin = (CVA6Cfg.PPNW - 1 > 29) ? 29 : CVA6Cfg.PPNW - 1; // The data interface is simpler and only consists of a request/response interface always_comb begin : data_interface // save request and DTLB response @@ -432,7 +432,7 @@ module cva6_mmu_sv32 lsu_dtlb_ppn_o = {{riscv::PLEN - riscv::VLEN{1'b0}}, lsu_vaddr_n[riscv::VLEN-1:12]}; end else begin lsu_paddr_o = {2'b00, lsu_vaddr_q[riscv::VLEN-1:0]}; - lsu_dtlb_ppn_o = lsu_vaddr_n[riscv::PPNW-1:0]; + lsu_dtlb_ppn_o = lsu_vaddr_n[CVA6Cfg.PPNW-1:0]; end lsu_valid_o = lsu_req_q; lsu_exception_o = misaligned_ex_q; diff --git a/core/mmu_sv32/cva6_ptw_sv32.sv b/core/mmu_sv32/cva6_ptw_sv32.sv index 76bfe3bd8..74bb2cce1 100644 --- a/core/mmu_sv32/cva6_ptw_sv32.sv +++ b/core/mmu_sv32/cva6_ptw_sv32.sv @@ -64,8 +64,8 @@ module cva6_ptw_sv32 input logic itlb_req_i, // from CSR file - input logic [riscv::PPNW-1:0] satp_ppn_i, // ppn from satp - input logic mxr_i, + input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, // ppn from satp + input logic mxr_i, // Performance counters output logic shared_tlb_miss_o, @@ -122,8 +122,8 @@ module cva6_ptw_sv32 //assign walking_instr_o = is_instr_ptw_q; assign walking_instr_o = is_instr_ptw_q; // directly output the correct physical address - assign req_port_o.address_index = ptw_pptr_q[DCACHE_INDEX_WIDTH-1:0]; - assign req_port_o.address_tag = ptw_pptr_q[DCACHE_INDEX_WIDTH+DCACHE_TAG_WIDTH-1:DCACHE_INDEX_WIDTH]; + assign req_port_o.address_index = ptw_pptr_q[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; + assign req_port_o.address_tag = ptw_pptr_q[CVA6Cfg.DCACHE_INDEX_WIDTH+CVA6Cfg.DCACHE_TAG_WIDTH-1:CVA6Cfg.DCACHE_INDEX_WIDTH]; // we are never going to kill this request assign req_port_o.kill_req = '0; // we are never going to write with the HPTW @@ -134,7 +134,7 @@ module cva6_ptw_sv32 // ----------- // Shared TLB Update // ----------- - assign shared_tlb_update_o.vpn = vaddr_q[riscv::SV-1:12]; + assign shared_tlb_update_o.vpn = vaddr_q[CVA6Cfg.SV-1:12]; // update the correct page table level assign shared_tlb_update_o.is_4M = (ptw_lvl_q == LVL1); // output the correct ASID @@ -223,7 +223,7 @@ module cva6_ptw_sv32 // if we got a Shared TLB miss if (shared_tlb_access_i & ~shared_tlb_hit_i) begin ptw_pptr_n = { - satp_ppn_i, shared_tlb_vaddr_i[riscv::SV-1:22], 2'b0 + satp_ppn_i, shared_tlb_vaddr_i[CVA6Cfg.SV-1:22], 2'b0 }; // SATP.PPN * PAGESIZE + VPN*PTESIZE = SATP.PPN * 2^(12) + VPN*4 is_instr_ptw_n = itlb_req_i; tlb_update_asid_n = asid_i; diff --git a/core/mmu_sv32/cva6_shared_tlb_sv32.sv b/core/mmu_sv32/cva6_shared_tlb_sv32.sv index 98e2a044a..20b322267 100644 --- a/core/mmu_sv32/cva6_shared_tlb_sv32.sv +++ b/core/mmu_sv32/cva6_shared_tlb_sv32.sv @@ -243,8 +243,8 @@ module cva6_shared_tlb_sv32 dtlb_req_q <= '0; shared_tag_valid <= '0; end else begin - itlb_vpn_q <= itlb_vaddr_i[riscv::SV-1:12]; - dtlb_vpn_q <= dtlb_vaddr_i[riscv::SV-1:12]; + itlb_vpn_q <= itlb_vaddr_i[CVA6Cfg.SV-1:12]; + dtlb_vpn_q <= dtlb_vaddr_i[CVA6Cfg.SV-1:12]; tlb_update_asid_q <= tlb_update_asid_d; shared_tlb_access_q <= shared_tlb_access_d; shared_tlb_vaddr_q <= shared_tlb_vaddr_d; diff --git a/core/mmu_sv39/mmu.sv b/core/mmu_sv39/mmu.sv index 6aecb2b39..83066dea0 100644 --- a/core/mmu_sv39/mmu.sv +++ b/core/mmu_sv39/mmu.sv @@ -48,7 +48,7 @@ module mmu // if we need to walk the page table we can't grant in the same cycle // Cycle 0 output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB - output logic [riscv::PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit) + output logic [CVA6Cfg.PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit) // Cycle 1 output logic lsu_valid_o, // translation is valid output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address @@ -59,7 +59,7 @@ module mmu input logic sum_i, input logic mxr_i, // input logic flag_mprv_i, - input logic [riscv::PPNW-1:0] satp_ppn_i, + input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, input logic [ASID_WIDTH-1:0] asid_i, input logic [ASID_WIDTH-1:0] asid_to_be_flushed_i, input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i, @@ -241,8 +241,8 @@ module mmu // AXI decode error), or when PTW performs walk due to ITLB miss and raises // an error. if (enable_translation_i) begin - // we work with SV39 or SV32, so if VM is enabled, check that all bits [riscv::VLEN-1:riscv::SV-1] are equal - if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[riscv::VLEN-1:riscv::SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[riscv::VLEN-1:riscv::SV-1]) == 1'b0)) begin + // we work with SV39 or SV32, so if VM is enabled, check that all bits [riscv::VLEN-1:CVA6Cfg.SV-1] are equal + if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -359,7 +359,7 @@ module mmu // Wires to PMP checks riscv::pmp_access_t pmp_access_type; logic pmp_data_allow; - localparam PPNWMin = (riscv::PPNW - 1 > 29) ? 29 : riscv::PPNW - 1; + localparam PPNWMin = (CVA6Cfg.PPNW - 1 > 29) ? 29 : CVA6Cfg.PPNW - 1; // The data interface is simpler and only consists of a request/response interface always_comb begin : data_interface // save request and DTLB response diff --git a/core/mmu_sv39/ptw.sv b/core/mmu_sv39/ptw.sv index 27c1346f2..cd2c8d55a 100644 --- a/core/mmu_sv39/ptw.sv +++ b/core/mmu_sv39/ptw.sv @@ -55,15 +55,15 @@ module ptw input logic itlb_hit_i, input logic [riscv::VLEN-1:0] itlb_vaddr_i, - input logic dtlb_access_i, - input logic dtlb_hit_i, - input logic [riscv::VLEN-1:0] dtlb_vaddr_i, + input logic dtlb_access_i, + input logic dtlb_hit_i, + input logic [ riscv::VLEN-1:0] dtlb_vaddr_i, // from CSR file - input logic [riscv::PPNW-1:0] satp_ppn_i, // ppn from satp - input logic mxr_i, + input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, // ppn from satp + input logic mxr_i, // Performance counters - output logic itlb_miss_o, - output logic dtlb_miss_o, + output logic itlb_miss_o, + output logic dtlb_miss_o, // PMP input riscv::pmpcfg_t [15:0] pmpcfg_i, @@ -115,8 +115,8 @@ module ptw assign ptw_active_o = (state_q != IDLE); assign walking_instr_o = is_instr_ptw_q; // directly output the correct physical address - assign req_port_o.address_index = ptw_pptr_q[DCACHE_INDEX_WIDTH-1:0]; - assign req_port_o.address_tag = ptw_pptr_q[DCACHE_INDEX_WIDTH+DCACHE_TAG_WIDTH-1:DCACHE_INDEX_WIDTH]; + assign req_port_o.address_index = ptw_pptr_q[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; + assign req_port_o.address_tag = ptw_pptr_q[CVA6Cfg.DCACHE_INDEX_WIDTH+CVA6Cfg.DCACHE_TAG_WIDTH-1:CVA6Cfg.DCACHE_INDEX_WIDTH]; // we are never going to kill this request assign req_port_o.kill_req = '0; // we are never going to write with the HPTW @@ -126,8 +126,8 @@ module ptw // ----------- // TLB Update // ----------- - assign itlb_update_o.vpn = {{39 - riscv::SV{1'b0}}, vaddr_q[riscv::SV-1:12]}; - assign dtlb_update_o.vpn = {{39 - riscv::SV{1'b0}}, vaddr_q[riscv::SV-1:12]}; + assign itlb_update_o.vpn = {{39 - CVA6Cfg.SV{1'b0}}, vaddr_q[CVA6Cfg.SV-1:12]}; + assign dtlb_update_o.vpn = {{39 - CVA6Cfg.SV{1'b0}}, vaddr_q[CVA6Cfg.SV-1:12]}; // update the correct page table level assign itlb_update_o.is_2M = (ptw_lvl_q == LVL2); assign itlb_update_o.is_1G = (ptw_lvl_q == LVL1); @@ -219,7 +219,7 @@ module ptw is_instr_ptw_n = 1'b0; // if we got an ITLB miss if (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) begin - ptw_pptr_n = {satp_ppn_i, itlb_vaddr_i[riscv::SV-1:30], 3'b0}; + ptw_pptr_n = {satp_ppn_i, itlb_vaddr_i[CVA6Cfg.SV-1:30], 3'b0}; is_instr_ptw_n = 1'b1; tlb_update_asid_n = asid_i; vaddr_n = itlb_vaddr_i; @@ -227,7 +227,7 @@ module ptw itlb_miss_o = 1'b1; // we got an DTLB miss end else if (en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) begin - ptw_pptr_n = {satp_ppn_i, dtlb_vaddr_i[riscv::SV-1:30], 3'b0}; + ptw_pptr_n = {satp_ppn_i, dtlb_vaddr_i[CVA6Cfg.SV-1:30], 3'b0}; tlb_update_asid_n = asid_i; vaddr_n = dtlb_vaddr_i; state_d = WAIT_GRANT; diff --git a/core/mmu_sv39/tlb.sv b/core/mmu_sv39/tlb.sv index 06d10d81e..ef70f4ad9 100644 --- a/core/mmu_sv39/tlb.sv +++ b/core/mmu_sv39/tlb.sv @@ -40,10 +40,12 @@ module tlb output logic lu_hit_o ); + localparam VPN2 = (riscv::VLEN - 31 < 8) ? riscv::VLEN - 31 : 8; + // SV39 defines three levels of page tables struct packed { logic [ASID_WIDTH-1:0] asid; - logic [riscv::VPN2:0] vpn2; + logic [VPN2:0] vpn2; logic [8:0] vpn1; logic [8:0] vpn0; logic is_2M; @@ -54,7 +56,7 @@ module tlb riscv::pte_t [TLB_ENTRIES-1:0] content_q, content_n; logic [8:0] vpn0, vpn1; - logic [ riscv::VPN2:0] vpn2; + logic [VPN2:0] vpn2; logic [TLB_ENTRIES-1:0] lu_hit; // to replacement logic logic [TLB_ENTRIES-1:0] replace_en; // replace the following entry, set by replacement strategy //------------- @@ -63,7 +65,7 @@ module tlb always_comb begin : translation vpn0 = lu_vaddr_i[20:12]; vpn1 = lu_vaddr_i[29:21]; - vpn2 = lu_vaddr_i[30+riscv::VPN2:30]; + vpn2 = lu_vaddr_i[30+VPN2:30]; // default assignment lu_hit = '{default: 0}; @@ -119,7 +121,7 @@ module tlb vaddr_vpn0_match[i] = (vaddr_to_be_flushed_i[20:12] == tags_q[i].vpn0); vaddr_vpn1_match[i] = (vaddr_to_be_flushed_i[29:21] == tags_q[i].vpn1); - vaddr_vpn2_match[i] = (vaddr_to_be_flushed_i[30+riscv::VPN2:30] == tags_q[i].vpn2); + vaddr_vpn2_match[i] = (vaddr_to_be_flushed_i[30+VPN2:30] == tags_q[i].vpn2); if (flush_i) begin // invalidate logic @@ -139,7 +141,7 @@ module tlb // update tag array tags_n[i] = '{ asid: update_i.asid, - vpn2: update_i.vpn[18+riscv::VPN2:18], + vpn2: update_i.vpn[18+VPN2:18], vpn1: update_i.vpn[17:9], vpn0: update_i.vpn[8:0], is_1G: update_i.is_1G, diff --git a/core/mult.sv b/core/mult.sv index b13b8e78d..4f7d2a1db 100644 --- a/core/mult.sv +++ b/core/mult.sv @@ -7,29 +7,29 @@ module mult parameter type fu_data_t = logic ) ( // Subsystem Clock - SUBSYSTEM - input logic clk_i, + input logic clk_i, // Asynchronous reset active low - SUBSYSTEM - input logic rst_ni, + input logic rst_ni, // Flush - CONTROLLER - input logic flush_i, + input logic flush_i, // FU data needed to execute instruction - ISSUE_STAGE - input fu_data_t fu_data_i, + input fu_data_t fu_data_i, // Mult instruction is valid - ISSUE_STAGE - input logic mult_valid_i, + input logic mult_valid_i, // Mult result - ISSUE_STAGE - output logic [ riscv::XLEN-1:0] result_o, + output logic [ riscv::XLEN-1:0] result_o, // Mult result is valid - ISSUE_STAGE - output logic mult_valid_o, + output logic mult_valid_o, // Mutl is ready - ISSUE_STAGE - output logic mult_ready_o, + output logic mult_ready_o, // Mult transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] mult_trans_id_o + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] mult_trans_id_o ); logic mul_valid; logic div_valid; logic div_ready_i; // receiver of division result is able to accept the result - logic [TRANS_ID_BITS-1:0] mul_trans_id; - logic [TRANS_ID_BITS-1:0] div_trans_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] mul_trans_id; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] div_trans_id; logic [riscv::XLEN-1:0] mul_result; logic [riscv::XLEN-1:0] div_result; diff --git a/core/multiplier.sv b/core/multiplier.sv index 53503bc9b..5e28e4c23 100644 --- a/core/multiplier.sv +++ b/core/multiplier.sv @@ -21,27 +21,27 @@ module multiplier parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( // Subsystem Clock - SUBSYSTEM - input logic clk_i, + input logic clk_i, // Asynchronous reset active low - SUBSYSTEM - input logic rst_ni, + input logic rst_ni, // Multiplier transaction ID - Mult - input logic [TRANS_ID_BITS-1:0] trans_id_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_i, // Multiplier instruction is valid - Mult - input logic mult_valid_i, + input logic mult_valid_i, // Multiplier operation - Mult - input fu_op operation_i, + input fu_op operation_i, // A operand - Mult - input logic [ riscv::XLEN-1:0] operand_a_i, + input logic [ riscv::XLEN-1:0] operand_a_i, // B operand - Mult - input logic [ riscv::XLEN-1:0] operand_b_i, + input logic [ riscv::XLEN-1:0] operand_b_i, // Multiplier result - Mult - output logic [ riscv::XLEN-1:0] result_o, + output logic [ riscv::XLEN-1:0] result_o, // Mutliplier result is valid - Mult - output logic mult_valid_o, + output logic mult_valid_o, // Multiplier FU is ready - Mult - output logic mult_ready_o, + output logic mult_ready_o, // Multiplier transaction ID - Mult - output logic [TRANS_ID_BITS-1:0] mult_trans_id_o + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] mult_trans_id_o ); // Carry-less multiplication logic [riscv::XLEN-1:0] @@ -78,8 +78,8 @@ module multiplier end // Pipeline register - logic [TRANS_ID_BITS-1:0] trans_id_q; - logic mult_valid_q; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_q; + logic mult_valid_q; fu_op operator_d, operator_q; logic [riscv::XLEN*2-1:0] mult_result_d, mult_result_q; diff --git a/core/perf_counters.sv b/core/perf_counters.sv index 0e710176d..2e13dab4c 100644 --- a/core/perf_counters.sv +++ b/core/perf_counters.sv @@ -54,7 +54,7 @@ module perf_counters input exception_t branch_exceptions_i, //Branch exceptions->execute unit-> branch_exception_o input icache_dreq_t l1_icache_access_i, input dcache_req_i_t [2:0] l1_dcache_access_i, - input logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0]miss_vld_bits_i, //For Cache eviction (3ports-LOAD,STORE,PTW) + input logic [NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0]miss_vld_bits_i, //For Cache eviction (3ports-LOAD,STORE,PTW) input logic i_tlb_flush_i, input logic stall_issue_i, //stall-read operands input logic [31:0] mcountinhibit_i diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 5fe030f69..dfd1a4bfb 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -87,7 +87,7 @@ module scoreboard #( // TO_BE_COMPLETED - TO_BE_COMPLETED input bp_resolve_t resolved_branch_i, // Transaction ID at which to write the result back - TO_BE_COMPLETED - input logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] trans_id_i, + input logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_i, // Results to write back - TO_BE_COMPLETED input logic [CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, // Exception from a functional unit (e.g.: ld/st exception) - TO_BE_COMPLETED @@ -98,9 +98,9 @@ module scoreboard #( input logic x_we_i, // TO_BE_COMPLETED - RVFI - output logic [ariane_pkg::TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, // TO_BE_COMPLETED - RVFI - output logic [CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] rvfi_commit_pointer_o + output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o ); // this is the FIFO struct of the issue queue @@ -109,18 +109,17 @@ module scoreboard #( logic is_rd_fpr_flag; // redundant meta info, added for speed scoreboard_entry_t sbe; // this is the score board entry we will send to ex } sb_mem_t; - sb_mem_t [ariane_pkg::NR_SB_ENTRIES-1:0] mem_q, mem_n; + sb_mem_t [CVA6Cfg.NR_SB_ENTRIES-1:0] mem_q, mem_n; logic issue_full, issue_en; - logic [ariane_pkg::TRANS_ID_BITS:0] issue_cnt_n, issue_cnt_q; - logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer_n, issue_pointer_q; - logic [CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] - commit_pointer_n, commit_pointer_q; + logic [CVA6Cfg.TRANS_ID_BITS:0] issue_cnt_n, issue_cnt_q; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] issue_pointer_n, issue_pointer_q; + logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] commit_pointer_n, commit_pointer_q; logic [$clog2(CVA6Cfg.NrCommitPorts):0] num_commit; // the issue queue is full don't issue any new instructions // works since aligned to power of 2 - assign issue_full = (issue_cnt_q[ariane_pkg::TRANS_ID_BITS] == 1'b1); + assign issue_full = (issue_cnt_q[CVA6Cfg.TRANS_ID_BITS] == 1'b1); assign sb_full_o = issue_full; @@ -173,7 +172,7 @@ module scoreboard #( // ------------ // FU NONE // ------------ - for (int unsigned i = 0; i < ariane_pkg::NR_SB_ENTRIES; i++) begin + for (int unsigned i = 0; i < CVA6Cfg.NR_SB_ENTRIES; i++) begin // The FU is NONE -> this instruction is valid immediately if (mem_q[i].sbe.fu == ariane_pkg::NONE && mem_q[i].issued) mem_n[i].sbe.valid = 1'b1; end @@ -228,7 +227,7 @@ module scoreboard #( // Flush // ------ if (flush_i) begin - for (int unsigned i = 0; i < ariane_pkg::NR_SB_ENTRIES; i++) begin + for (int unsigned i = 0; i < CVA6Cfg.NR_SB_ENTRIES; i++) begin // set all valid flags for all entries to zero mem_n[i].issued = 1'b0; mem_n[i].sbe.valid = 1'b0; @@ -244,9 +243,9 @@ module scoreboard #( assign num_commit = commit_ack_i[0]; end - assign issue_cnt_n = (flush_i) ? '0 : issue_cnt_q - {{ariane_pkg::TRANS_ID_BITS - $clog2( + assign issue_cnt_n = (flush_i) ? '0 : issue_cnt_q - {{CVA6Cfg.TRANS_ID_BITS - $clog2( CVA6Cfg.NrCommitPorts - ) {1'b0}}, num_commit} + {{ariane_pkg::TRANS_ID_BITS - 1{1'b0}}, issue_en}; + ) {1'b0}}, num_commit} + {{CVA6Cfg.TRANS_ID_BITS - 1{1'b0}}, issue_en}; assign commit_pointer_n[0] = (flush_i) ? '0 : commit_pointer_q[0] + num_commit; assign issue_pointer_n = (flush_i) ? '0 : issue_pointer_q + issue_en; @@ -259,23 +258,23 @@ module scoreboard #( // RD clobber process // ------------------- // rd_clobber output: output currently clobbered destination registers - logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][ariane_pkg::NR_SB_ENTRIES:0] gpr_clobber_vld; - logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][ariane_pkg::NR_SB_ENTRIES:0] fpr_clobber_vld; - ariane_pkg::fu_t [ ariane_pkg::NR_SB_ENTRIES:0] clobber_fu; + logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][CVA6Cfg.NR_SB_ENTRIES:0] gpr_clobber_vld; + logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][CVA6Cfg.NR_SB_ENTRIES:0] fpr_clobber_vld; + ariane_pkg::fu_t [ CVA6Cfg.NR_SB_ENTRIES:0] clobber_fu; always_comb begin : clobber_assign gpr_clobber_vld = '0; fpr_clobber_vld = '0; // default (highest entry hast lowest prio in arbiter tree below) - clobber_fu[ariane_pkg::NR_SB_ENTRIES] = ariane_pkg::NONE; + clobber_fu[CVA6Cfg.NR_SB_ENTRIES] = ariane_pkg::NONE; for (int unsigned i = 0; i < 2 ** ariane_pkg::REG_ADDR_SIZE; i++) begin - gpr_clobber_vld[i][ariane_pkg::NR_SB_ENTRIES] = 1'b1; - fpr_clobber_vld[i][ariane_pkg::NR_SB_ENTRIES] = 1'b1; + gpr_clobber_vld[i][CVA6Cfg.NR_SB_ENTRIES] = 1'b1; + fpr_clobber_vld[i][CVA6Cfg.NR_SB_ENTRIES] = 1'b1; end // check for all valid entries and set the clobber accordingly - for (int unsigned i = 0; i < ariane_pkg::NR_SB_ENTRIES; i++) begin + for (int unsigned i = 0; i < CVA6Cfg.NR_SB_ENTRIES; i++) begin gpr_clobber_vld[mem_q[i].sbe.rd][i] = mem_q[i].issued & ~mem_q[i].is_rd_fpr_flag; fpr_clobber_vld[mem_q[i].sbe.rd][i] = mem_q[i].issued & mem_q[i].is_rd_fpr_flag; clobber_fu[i] = mem_q[i].sbe.fu; @@ -288,7 +287,7 @@ module scoreboard #( for (genvar k = 0; k < 2 ** ariane_pkg::REG_ADDR_SIZE; k++) begin : gen_sel_clobbers // get fu that is going to clobber this register (there should be only one) rr_arb_tree #( - .NumIn(ariane_pkg::NR_SB_ENTRIES + 1), + .NumIn(CVA6Cfg.NR_SB_ENTRIES + 1), .DataType(ariane_pkg::fu_t), .ExtPrio(1'b1), .AxiVldRdy(1'b1) @@ -307,7 +306,7 @@ module scoreboard #( ); if (CVA6Cfg.FpPresent) begin rr_arb_tree #( - .NumIn(ariane_pkg::NR_SB_ENTRIES + 1), + .NumIn(CVA6Cfg.NR_SB_ENTRIES + 1), .DataType(ariane_pkg::fu_t), .ExtPrio(1'b1), .AxiVldRdy(1'b1) @@ -331,8 +330,8 @@ module scoreboard #( // Read Operands (a.k.a forwarding) // ---------------------------------- // read operand interface: same logic as register file - logic [ariane_pkg::NR_SB_ENTRIES+CVA6Cfg.NrWbPorts-1:0] rs1_fwd_req, rs2_fwd_req, rs3_fwd_req; - logic [ariane_pkg::NR_SB_ENTRIES+CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] rs_data; + logic [CVA6Cfg.NR_SB_ENTRIES+CVA6Cfg.NrWbPorts-1:0] rs1_fwd_req, rs2_fwd_req, rs3_fwd_req; + logic [CVA6Cfg.NR_SB_ENTRIES+CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] rs_data; logic rs1_valid, rs2_valid, rs3_valid; // WB ports have higher prio than entries @@ -348,7 +347,7 @@ module scoreboard #( ))); assign rs_data[k] = wbdata_i[k]; end - for (genvar k = 0; unsigned'(k) < ariane_pkg::NR_SB_ENTRIES; k++) begin : gen_rs_entries + for (genvar k = 0; unsigned'(k) < CVA6Cfg.NR_SB_ENTRIES; k++) begin : gen_rs_entries assign rs1_fwd_req[k+CVA6Cfg.NrWbPorts] = (mem_q[k].sbe.rd == rs1_i) & mem_q[k].issued & mem_q[k].sbe.valid & (mem_q[k].is_rd_fpr_flag == (CVA6Cfg.FpPresent && ariane_pkg::is_rs1_fpr( issue_instr_o.op ))); @@ -375,7 +374,7 @@ module scoreboard #( // use fixed prio here // this implicitly gives higher prio to WB ports rr_arb_tree #( - .NumIn(ariane_pkg::NR_SB_ENTRIES + CVA6Cfg.NrWbPorts), + .NumIn(CVA6Cfg.NR_SB_ENTRIES + CVA6Cfg.NrWbPorts), .DataWidth(riscv::XLEN), .ExtPrio(1'b1), .AxiVldRdy(1'b1) @@ -394,7 +393,7 @@ module scoreboard #( ); rr_arb_tree #( - .NumIn(ariane_pkg::NR_SB_ENTRIES + CVA6Cfg.NrWbPorts), + .NumIn(CVA6Cfg.NR_SB_ENTRIES + CVA6Cfg.NrWbPorts), .DataWidth(riscv::XLEN), .ExtPrio(1'b1), .AxiVldRdy(1'b1) @@ -415,7 +414,7 @@ module scoreboard #( logic [riscv::XLEN-1:0] rs3; rr_arb_tree #( - .NumIn(ariane_pkg::NR_SB_ENTRIES + CVA6Cfg.NrWbPorts), + .NumIn(CVA6Cfg.NR_SB_ENTRIES + CVA6Cfg.NrWbPorts), .DataWidth(riscv::XLEN), .ExtPrio(1'b1), .AxiVldRdy(1'b1) @@ -461,7 +460,7 @@ module scoreboard #( //pragma translate_off initial begin - assert (ariane_pkg::NR_SB_ENTRIES == 2 ** ariane_pkg::TRANS_ID_BITS) + assert (CVA6Cfg.NR_SB_ENTRIES == 2 ** CVA6Cfg.TRANS_ID_BITS) else $fatal(1, "Scoreboard size needs to be a power of two."); end diff --git a/core/serdiv.sv b/core/serdiv.sv index 328cfc720..7e53ab608 100644 --- a/core/serdiv.sv +++ b/core/serdiv.sv @@ -27,7 +27,7 @@ module serdiv // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, // Serdiv translation ID - Mult - input logic [TRANS_ID_BITS-1:0] id_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] id_i, // A operand - Mult input logic [WIDTH-1:0] op_a_i, // B operand - Mult @@ -45,7 +45,7 @@ module serdiv // Serdiv is ready - Mult input logic out_rdy_i, // Serdiv transaction ID - Mult - output logic [TRANS_ID_BITS-1:0] id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] id_o, // Serdiv result - Mult output logic [WIDTH-1:0] res_o ); @@ -68,7 +68,7 @@ module serdiv logic op_b_zero, op_b_zero_q, op_b_zero_d; logic op_b_neg_one, op_b_neg_one_q, op_b_neg_one_d; - logic [TRANS_ID_BITS-1:0] id_q, id_d; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] id_q, id_d; logic rem_sel_d, rem_sel_q; logic comp_inv_d, comp_inv_q; diff --git a/core/store_buffer.sv b/core/store_buffer.sv index e9b258f1c..419129861 100644 --- a/core/store_buffer.sv +++ b/core/store_buffer.sv @@ -141,11 +141,11 @@ module store_buffer // we do not require an acknowledgement for writes, thus we do not need to identify uniquely the responses assign req_port_o.data_id = '0; // those signals can directly be output to the memory - assign req_port_o.address_index = commit_queue_q[commit_read_pointer_q].address[ariane_pkg::DCACHE_INDEX_WIDTH-1:0]; + assign req_port_o.address_index = commit_queue_q[commit_read_pointer_q].address[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; // if we got a new request we already saved the tag from the previous cycle - assign req_port_o.address_tag = commit_queue_q[commit_read_pointer_q].address[ariane_pkg::DCACHE_TAG_WIDTH + - ariane_pkg::DCACHE_INDEX_WIDTH-1 : - ariane_pkg::DCACHE_INDEX_WIDTH]; + assign req_port_o.address_tag = commit_queue_q[commit_read_pointer_q].address[CVA6Cfg.DCACHE_TAG_WIDTH + + CVA6Cfg.DCACHE_INDEX_WIDTH-1 : + CVA6Cfg.DCACHE_INDEX_WIDTH]; assign req_port_o.data_wdata = commit_queue_q[commit_read_pointer_q].data; assign req_port_o.data_be = commit_queue_q[commit_read_pointer_q].be; assign req_port_o.data_size = commit_queue_q[commit_read_pointer_q].data_size; diff --git a/core/store_unit.sv b/core/store_unit.sv index 6a8d30f1e..c9f509e58 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -49,7 +49,7 @@ module store_unit // Store result is valid - ISSUE_STAGE output logic valid_o, // Transaction ID - ISSUE_STAGE - output logic [TRANS_ID_BITS-1:0] trans_id_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_o, // Store result - ISSUE_STAGE output logic [riscv::XLEN-1:0] result_o, // Store exception output - TO_BE_COMPLETED @@ -124,7 +124,7 @@ module store_unit logic [1:0] st_data_size_n, st_data_size_q; amo_t amo_op_d, amo_op_q; - logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; // output assignments assign vaddr_o = lsu_ctrl_i.vaddr; // virtual address diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index 0c07b0189..237eac61c 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -80,7 +80,9 @@ module ariane import ariane_pkg::*; #( ); if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor - cvxif_example_coprocessor i_cvxif_coprocessor ( + cvxif_example_coprocessor #( + .CVA6Cfg ( CVA6Cfg ) + ) i_cvxif_coprocessor ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .cvxif_req_i ( cvxif_req ), diff --git a/corev_apu/tb/common/spike.sv b/corev_apu/tb/common/spike.sv index 87dd224ce..804692e75 100644 --- a/corev_apu/tb/common/spike.sv +++ b/corev_apu/tb/common/spike.sv @@ -19,31 +19,7 @@ import uvma_cva6pkg_utils_pkg::*; module spike #( parameter config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg, - parameter type rvfi_instr_t = struct packed { - logic [config_pkg::NRET-1:0] valid; - logic [config_pkg::NRET*64-1:0] order; - logic [config_pkg::NRET*config_pkg::ILEN-1:0] insn; - logic [config_pkg::NRET-1:0] trap; - logic [config_pkg::NRET*riscv::XLEN-1:0] cause; - logic [config_pkg::NRET-1:0] halt; - logic [config_pkg::NRET-1:0] intr; - logic [config_pkg::NRET*2-1:0] mode; - logic [config_pkg::NRET*2-1:0] ixl; - logic [config_pkg::NRET*5-1:0] rs1_addr; - logic [config_pkg::NRET*5-1:0] rs2_addr; - logic [config_pkg::NRET*riscv::XLEN-1:0] rs1_rdata; - logic [config_pkg::NRET*riscv::XLEN-1:0] rs2_rdata; - logic [config_pkg::NRET*5-1:0] rd_addr; - logic [config_pkg::NRET*riscv::XLEN-1:0] rd_wdata; - logic [config_pkg::NRET*riscv::XLEN-1:0] pc_rdata; - logic [config_pkg::NRET*riscv::XLEN-1:0] pc_wdata; - logic [config_pkg::NRET*riscv::VLEN-1:0] mem_addr; - logic [config_pkg::NRET*riscv::PLEN-1:0] mem_paddr; - logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_rmask; - logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_wmask; - logic [config_pkg::NRET*riscv::XLEN-1:0] mem_rdata; - logic [config_pkg::NRET*riscv::XLEN-1:0] mem_wdata; - }, + parameter type rvfi_instr_t = logic, parameter longint unsigned DramBase = 'h8000_0000, parameter int unsigned Size = 64 * 1024 * 1024 // 64 Mega Byte )( diff --git a/corev_apu/tb/common/tb_readport.sv b/corev_apu/tb/common/tb_readport.sv index 49796725f..35b993061 100644 --- a/corev_apu/tb/common/tb_readport.sv +++ b/corev_apu/tb/common/tb_readport.sv @@ -64,8 +64,8 @@ program tb_readport import tb_pkg::*; import ariane_pkg::*; #( logic [63:0] paddr; logic seq_end_req, seq_end_ack, prog_end; - logic [DCACHE_TAG_WIDTH-1:0] tag_q; - logic [DCACHE_TAG_WIDTH-1:0] tag_vld_q; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag_q; + logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] tag_vld_q; /////////////////////////////////////////////////////////////////////////////// @@ -93,7 +93,7 @@ program tb_readport import tb_pkg::*; import ariane_pkg::*; #( if(cnt==0) begin if(tmp_vld) begin tmp_vld = 0; - tag_q <= tmp_paddr[DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:DCACHE_INDEX_WIDTH]; + tag_q <= tmp_paddr[CVA6Cfg.DCACHE_TAG_WIDTH+CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_INDEX_WIDTH]; tag_vld_q <= 1'b1; end else begin tag_vld_q <= 1'b0; @@ -126,7 +126,7 @@ program tb_readport import tb_pkg::*; import ariane_pkg::*; #( assign dut_req_port_o.address_tag = tag_q; assign dut_req_port_o.tag_valid = tag_vld_q; - assign dut_req_port_o.address_index = paddr[DCACHE_INDEX_WIDTH-1:0]; + assign dut_req_port_o.address_index = paddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; assign exp_paddr_o = paddr; /////////////////////////////////////////////////////////////////////////////// @@ -221,11 +221,11 @@ program tb_readport import tb_pkg::*; import ariane_pkg::*; #( // Generate a sequence of reads to the same set (constant index) task automatic genSetSeqRead(); automatic logic [63:0] val, rnd; - paddr = CachedAddrBeg + 2 ** DCACHE_INDEX_WIDTH; + paddr = CachedAddrBeg + 2 ** CVA6Cfg.DCACHE_INDEX_WIDTH; dut_req_port_o.data_req = '0; dut_req_port_o.data_size = '0; dut_req_port_o.kill_req = '0; - val = CachedAddrBeg + 2 ** DCACHE_INDEX_WIDTH; + val = CachedAddrBeg + 2 ** CVA6Cfg.DCACHE_INDEX_WIDTH; while(~seq_end_req) begin void'(randomize(rnd) with {rnd > 0; rnd <= 100;}); if(rnd < req_rate_i) begin @@ -235,7 +235,7 @@ program tb_readport import tb_pkg::*; import ariane_pkg::*; #( // generate linear read `APPL_WAIT_COMB_SIG(clk_i, dut_req_port_i.data_gnt) // increment by set size - val = (val + 2 ** DCACHE_INDEX_WIDTH) % (MemWords<<3); + val = (val + 2 ** CVA6Cfg.DCACHE_INDEX_WIDTH) % (MemWords<<3); end `APPL_WAIT_CYC(clk_i,1) dut_req_port_o.data_req = '0; diff --git a/corev_apu/tb/common/tb_writeport.sv b/corev_apu/tb/common/tb_writeport.sv index babadd91c..beae49ed0 100644 --- a/corev_apu/tb/common/tb_writeport.sv +++ b/corev_apu/tb/common/tb_writeport.sv @@ -49,8 +49,8 @@ program tb_writeport import tb_pkg::*; import ariane_pkg::*; #( logic [63:0] paddr; - assign dut_req_port_o.address_tag = paddr[DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:DCACHE_INDEX_WIDTH]; - assign dut_req_port_o.address_index = paddr[DCACHE_INDEX_WIDTH-1:0]; + assign dut_req_port_o.address_tag = paddr[CVA6Cfg.DCACHE_TAG_WIDTH+CVA6Cfg.DCACHE_INDEX_WIDTH-1:CVA6Cfg.DCACHE_INDEX_WIDTH]; + assign dut_req_port_o.address_index = paddr[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; assign dut_req_port_o.data_we = dut_req_port_o.data_req; /////////////////////////////////////////////////////////////////////////////// diff --git a/corev_apu/tb/tb_cva6_icache/hdl/mem_emul.sv b/corev_apu/tb/tb_cva6_icache/hdl/mem_emul.sv index 181e5811c..994190e31 100644 --- a/corev_apu/tb/tb_cva6_icache/hdl/mem_emul.sv +++ b/corev_apu/tb/tb_cva6_icache/hdl/mem_emul.sv @@ -154,7 +154,7 @@ module mem_emul import ariane_pkg::*; import wt_cache_pkg::*; #( // we allways invalidate all ways of the aliased index. // this is not entirely correct and will produce // too many invalidations - infifo_data.inv.idx = rand_addr_q[ICACHE_INDEX_WIDTH-1:0]; + infifo_data.inv.idx = rand_addr_q[CVA6Cfg.ICACHE_INDEX_WIDTH-1:0]; infifo_data.inv.all = '1; infifo_push = 1'b1; diff --git a/corev_apu/tb/tb_cva6_icache/hdl/tb.sv b/corev_apu/tb/tb_cva6_icache/hdl/tb.sv index c6a18698b..624f1b9f9 100644 --- a/corev_apu/tb/tb_cva6_icache/hdl/tb.sv +++ b/corev_apu/tb/tb_cva6_icache/hdl/tb.sv @@ -32,7 +32,7 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); timeprecision 1ps; // number of 32bit words - parameter MemBytes = 2**ICACHE_INDEX_WIDTH * 4 * 32; + parameter MemBytes = 2**CVA6Cfg.ICACHE_INDEX_WIDTH * 4 * 32; parameter MemWords = MemBytes>>2; parameter logic [63:0] CachedAddrBeg = MemBytes/4; parameter logic [63:0] CachedAddrEnd = MemBytes; diff --git a/corev_apu/tb/tb_wb_dcache/hdl/tb.sv b/corev_apu/tb/tb_wb_dcache/hdl/tb.sv index 0b4550fec..8634a60c2 100644 --- a/corev_apu/tb/tb_wb_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wb_dcache/hdl/tb.sv @@ -24,7 +24,7 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()() timeprecision 1ps; // memory configuration (64bit words) - parameter MemBytes = 2**DCACHE_INDEX_WIDTH * 4 * 32; + parameter MemBytes = 2**CVA6Cfg.DCACHE_INDEX_WIDTH * 4 * 32; parameter MemWords = MemBytes>>3; // noncacheable portion @@ -849,9 +849,9 @@ axi_riscv_atomics_wrap #( seq_type = '{IDLE_SEQ, IDLE_SEQ, LINEAR_SEQ}; req_rate = '{default:100}; - runSeq((CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); + runSeq((CachedAddrBeg>>3)+(2**(CVA6Cfg.DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); seq_type = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ}; - runSeq(0,(CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); + runSeq(0,(CachedAddrBeg>>3)+(2**(CVA6Cfg.DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); flushCache(); tb_mem_port_t::check_mem(); 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 ea5a8371c..f3279f343 100644 --- a/corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv @@ -24,7 +24,7 @@ module tb import ariane_pkg::*; import wt_cache_pkg::*; import tb_pkg::*; #()(); timeprecision 1ps; // memory configuration (64bit words) - parameter MemBytes = 2**DCACHE_INDEX_WIDTH * 4 * 32; + parameter MemBytes = 2**CVA6Cfg.DCACHE_INDEX_WIDTH * 4 * 32; parameter MemWords = MemBytes>>3; // noncacheable portion @@ -809,9 +809,9 @@ axi_riscv_atomics_wrap #( seq_type = '{IDLE_SEQ, IDLE_SEQ, LINEAR_SEQ}; req_rate = '{default:100}; - runSeq((CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); + runSeq((CachedAddrBeg>>3)+(2**(CVA6Cfg.DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); seq_type = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ}; - runSeq(0,(CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); + runSeq(0,(CachedAddrBeg>>3)+(2**(CVA6Cfg.DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); flushCache(); tb_mem_port_t::check_mem(); diff --git a/corev_apu/tb/tb_wt_dcache/hdl/tb.sv b/corev_apu/tb/tb_wt_dcache/hdl/tb.sv index 031f89187..6939308de 100644 --- a/corev_apu/tb/tb_wt_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wt_dcache/hdl/tb.sv @@ -32,7 +32,7 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); timeprecision 1ps; // memory configuration (64bit words) - parameter MemBytes = 2**DCACHE_INDEX_WIDTH * 4 * 32; + parameter MemBytes = 2**CVA6Cfg.DCACHE_INDEX_WIDTH * 4 * 32; parameter MemWords = MemBytes>>3; // noncacheable portion parameter logic [63:0] CachedAddrBeg = MemBytes>>3;//1/8th of the memory is NC @@ -546,9 +546,9 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()(); inv_rand_en = 0; seq_type = '{IDLE_SEQ, IDLE_SEQ, LINEAR_SEQ}; req_rate = '{default:100}; - runSeq((CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC,0); + runSeq((CachedAddrBeg>>3)+(2**(CVA6Cfg.DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC,0); seq_type = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ}; - runSeq(0,(CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); + runSeq(0,(CachedAddrBeg>>3)+(2**(CVA6Cfg.DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC); flushCache(); memCheck(); /////////////////////////////////////////////// diff --git a/corev_apu/tb/tb_wt_dcache/hdl/tb_mem.sv b/corev_apu/tb/tb_wt_dcache/hdl/tb_mem.sv index 867f777c6..f7094bcc7 100644 --- a/corev_apu/tb/tb_wt_dcache/hdl/tb_mem.sv +++ b/corev_apu/tb/tb_wt_dcache/hdl/tb_mem.sv @@ -208,7 +208,7 @@ module tb_mem import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*;#( // we allways invalidate all ways of the aliased index. // this is not entirely correct and will produce // too many invalidations - infifo_data.inv.idx = rand_addr_q[DCACHE_INDEX_WIDTH-1:0]; + infifo_data.inv.idx = rand_addr_q[CVA6Cfg.DCACHE_INDEX_WIDTH-1:0]; infifo_data.inv.all = '1; infifo_push = 1'b1; diff --git a/vendor/pulp-platform/common_cells/src/fifo_v3.sv b/vendor/pulp-platform/common_cells/src/fifo_v3.sv index 11b77e025..eacc8840d 100644 --- a/vendor/pulp-platform/common_cells/src/fifo_v3.sv +++ b/vendor/pulp-platform/common_cells/src/fifo_v3.sv @@ -15,6 +15,7 @@ module fifo_v3 #( parameter int unsigned DATA_WIDTH = 32, // default data width if the fifo is of type logic parameter int unsigned DEPTH = 8, // depth can be arbitrary from 0 to 2**32 parameter type dtype = logic [DATA_WIDTH-1:0], + parameter bit FPGA_EN = 1'b0, // DO NOT OVERWRITE THIS PARAMETER parameter int unsigned ADDR_DEPTH = (DEPTH > 1) ? $clog2(DEPTH) : 1 )( @@ -70,7 +71,7 @@ module fifo_v3 #( read_pointer_n = read_pointer_q; write_pointer_n = write_pointer_q; status_cnt_n = status_cnt_q; - if (ariane_pkg::FPGA_EN) begin + if (FPGA_EN) begin fifo_ram_we = '0; fifo_ram_read_address = read_pointer_q; fifo_ram_write_address = '0; @@ -84,7 +85,7 @@ module fifo_v3 #( // push a new element to the queue if (push_i && ~full_o) begin - if (ariane_pkg::FPGA_EN) begin + if (FPGA_EN) begin fifo_ram_we = 1'b1; fifo_ram_write_address = write_pointer_q; fifo_ram_wdata = data_i; @@ -149,7 +150,7 @@ module fifo_v3 #( end end - if (ariane_pkg::FPGA_EN) begin : gen_fpga_queue + if (FPGA_EN) begin : gen_fpga_queue AsyncDpRam #( .ADDR_WIDTH (ADDR_DEPTH), .DATA_DEPTH (DEPTH),