diff --git a/Bender.yml b/Bender.yml index 5ef388dad7..292149edeb 100644 --- a/Bender.yml +++ b/Bender.yml @@ -1,5 +1,5 @@ package: - name: ariane + name: cva6 authors: - "Florian Zaruba " - "Michael Schaffner " @@ -68,6 +68,7 @@ sources: - target: any(cv64a6_imafdcv_sv39, cv64a6_imafdc_sv39, cv64a6_imafdc_sv39_wb, cv64a6_imafdch_sv39, cv64a6_imafdch_sv39_wb, cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32) files: - core/cva6_mmu/cva6_tlb.sv + - core/cva6_mmu/cva6_shared_tlb.sv - core/cva6_mmu/cva6_mmu.sv - core/cva6_mmu/cva6_ptw.sv @@ -78,6 +79,8 @@ sources: # Extension Interface - core/cvxif_example/include/cvxif_instr_pkg.sv - core/cvxif_fu.sv + - core/cvxif_issue_register_commit_if_driver.sv + - core/cvxif_compressed_if_driver.sv - core/cvxif_example/cvxif_example_coprocessor.sv - core/cvxif_example/instr_decoder.sv @@ -95,6 +98,7 @@ sources: - core/csr_regfile.sv - core/decoder.sv - core/ex_stage.sv + - core/acc_dispatcher.sv - core/instr_realign.sv - core/id_stage.sv - core/issue_read_operands.sv @@ -142,6 +146,7 @@ sources: # Physical Memory Protection - core/pmp/src/pmp.sv - core/pmp/src/pmp_entry.sv + - core/pmp/src/pmp_data_if.sv - include_dirs: - common/local/util @@ -153,12 +158,15 @@ sources: - common/local/util files: - common/local/util/tc_sram_wrapper.sv + - common/local/util/sram_cache.sv - target: all(fpga, xilinx) include_dirs: - common/local/util files: + - common/local/util/sram_cache.sv - common/local/util/tc_sram_fpga_wrapper.sv + - vendor/pulp-platform/fpga-support/rtl/SyncSpRamBeNx64.sv - target: not(synthesis) include_dirs: diff --git a/common/local/util/instr_tracer.sv b/common/local/util/instr_tracer.sv index 9083664069..850465c690 100644 --- a/common/local/util/instr_tracer.sv +++ b/common/local/util/instr_tracer.sv @@ -25,32 +25,32 @@ module instr_tracer #( parameter type exception_t = logic, parameter interrupts_t INTERRUPTS = '0 )( - input logic pck, - input logic rstn, - input logic flush_unissued, - input logic flush_all, - input logic [31:0] instruction, - input logic fetch_valid, - input logic fetch_ack, - input logic issue_ack, // issue acknowledged - input scoreboard_entry_t issue_sbe, // issue scoreboard entry - input logic [1:0][4:0] waddr, // WB stage - input logic [1:0][63:0] wdata, - input logic [1:0] we_gpr, - input logic [1:0] we_fpr, - input scoreboard_entry_t [1:0] commit_instr, // commit instruction - input logic [1:0] commit_ack, - input logic st_valid, // stores - address translation - input logic [CVA6Cfg.PLEN-1:0] st_paddr, - input logic ld_valid, // loads - input logic ld_kill, - input logic [CVA6Cfg.PLEN-1:0] ld_paddr, - input bp_resolve_t resolve_branch, // misprediction - input exception_t commit_exception, - input riscv::priv_lvl_t priv_lvl, // current privilege level - input logic debug_mode, + input logic pck, + input logic rstn, + input logic flush_unissued, + input logic flush_all, + input logic [31:0] instruction, + input logic fetch_valid, + input logic fetch_ack, + input logic issue_ack, // issue acknowledged + input scoreboard_entry_t issue_sbe, // issue scoreboard entry + input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr, // WB stage + input logic [CVA6Cfg.NrCommitPorts-1:0][63:0] wdata, + input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr, + input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr, + input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr, // commit instruction + input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack, + input logic st_valid, // stores - address translation + input logic [CVA6Cfg.PLEN-1:0] st_paddr, + input logic ld_valid, // loads + input logic ld_kill, + input logic [CVA6Cfg.PLEN-1:0] ld_paddr, + input bp_resolve_t resolve_branch, // misprediction + input exception_t commit_exception, + input riscv::priv_lvl_t priv_lvl, // current privilege level + input logic debug_mode, - input logic[CVA6Cfg.XLEN-1:0] hart_id_i + input logic[CVA6Cfg.XLEN-1:0] hart_id_i ); // keep the decoded instructions in a queue diff --git a/core/acc_dispatcher.sv b/core/acc_dispatcher.sv index d00e7eb5f0..aa526951e6 100644 --- a/core/acc_dispatcher.sv +++ b/core/acc_dispatcher.sv @@ -23,36 +23,12 @@ module acc_dispatcher parameter type exception_t = logic, 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 [CVA6Cfg.XLEN-1:0] rs1; - logic [CVA6Cfg.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; - }, - parameter type acc_req_t = accelerator_req_t, - parameter type acc_resp_t = struct packed { - logic req_ready; - logic resp_valid; - logic [CVA6Cfg.XLEN-1:0] result; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; - exception_t exception; - // Metadata - 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; - }, + parameter type acc_req_t = logic, + parameter type acc_resp_t = logic, + parameter type accelerator_req_t = logic, + parameter type accelerator_resp_t = logic, + parameter type acc_mmu_req_t = logic, + parameter type acc_mmu_resp_t = logic, parameter type acc_cfg_t = logic, parameter acc_cfg_t AccCfg = '0 ) ( @@ -65,10 +41,11 @@ module acc_dispatcher // Interface with the CSRs input priv_lvl_t ld_st_priv_lvl_i, input logic sum_i, - input pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, input logic [2:0] fcsr_frm_i, output logic dirty_v_state_o, + input logic acc_mmu_en_i, // Interface with the issue stage input scoreboard_entry_t issue_instr_i, input logic issue_instr_hs_i, @@ -88,6 +65,9 @@ module acc_dispatcher output logic acc_stall_st_pending_o, input logic acc_no_st_pending_i, input dcache_req_i_t [2:0] dcache_req_ports_i, + // Interface with the MMU + output acc_mmu_req_t acc_mmu_req_o, + input acc_mmu_resp_t acc_mmu_resp_i, // Interface with the controller output logic ctrl_halt_o, input logic [11:0] csr_addr_i, @@ -219,7 +199,7 @@ module acc_dispatcher end // An accelerator instruction was issued. - if (acc_req_o.req_valid) insn_ready_d[acc_req_o.trans_id] = 1'b0; + if (acc_req_o.acc_req.req_valid) insn_ready_d[acc_req_o.acc_req.trans_id] = 1'b0; end : p_non_speculative_ff /************************* @@ -231,29 +211,31 @@ module acc_dispatcher logic acc_req_ready; accelerator_req_t acc_req_int; - fall_through_register #( + spill_register #( .T(accelerator_req_t) ) i_accelerator_req_register ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (1'b0), - .testmode_i(1'b0), - .data_i (acc_req), - .valid_i (acc_req_valid), - .ready_o (acc_req_ready), - .data_o (acc_req_int), - .valid_o (acc_req_o.req_valid), - .ready_i (acc_resp_i.req_ready) + .clk_i (clk_i), + .rst_ni (rst_ni), + .data_i (acc_req), + .valid_i(acc_req_valid), + .ready_o(acc_req_ready), + .data_o (acc_req_int), + .valid_o(acc_req_o.acc_req.req_valid), + .ready_i(acc_resp_i.acc_resp.req_ready) ); - assign acc_req_o.insn = acc_req_int.insn; - assign acc_req_o.rs1 = acc_req_int.rs1; - assign acc_req_o.rs2 = acc_req_int.rs2; - assign acc_req_o.frm = acc_req_int.frm; - assign acc_req_o.trans_id = acc_req_int.trans_id; - assign acc_req_o.store_pending = !acc_no_st_pending_i && acc_cons_en_i; - assign acc_req_o.acc_cons_en = acc_cons_en_i; - assign acc_req_o.inval_ready = inval_ready_i; + assign acc_req_o.acc_req.insn = acc_req_int.insn; + assign acc_req_o.acc_req.rs1 = acc_req_int.rs1; + assign acc_req_o.acc_req.rs2 = acc_req_int.rs2; + assign acc_req_o.acc_req.frm = acc_req_int.frm; + assign acc_req_o.acc_req.trans_id = acc_req_int.trans_id; + assign acc_req_o.acc_req.store_pending = !acc_no_st_pending_i && acc_cons_en_i; + assign acc_req_o.acc_req.acc_cons_en = acc_cons_en_i; + assign acc_req_o.acc_req.inval_ready = inval_ready_i; + + // MMU interface + assign acc_req_o.acc_mmu_resp = acc_mmu_resp_i; + assign acc_req_o.acc_mmu_en = acc_mmu_en_i; always_comb begin : accelerator_req_dispatcher // Do not fetch from the instruction queue @@ -263,7 +245,7 @@ module acc_dispatcher acc_req = '0; acc_req_valid = 1'b0; - // Unpack fu_data_t into accelerator_req_t + // Unpack fu_data_t into acc_req_t if (!acc_insn_queue_empty) begin acc_req = '{ // Instruction is forwarded from the decoder as an immediate @@ -297,23 +279,27 @@ module acc_dispatcher logic acc_ld_disp; logic acc_st_disp; - assign acc_trans_id_o = acc_resp_i.trans_id; - assign acc_result_o = acc_resp_i.result; - assign acc_valid_o = acc_resp_i.resp_valid; - assign acc_exception_o = acc_resp_i.exception; + assign acc_trans_id_o = acc_resp_i.acc_resp.trans_id; + assign acc_result_o = acc_resp_i.acc_resp.result; + assign acc_valid_o = acc_resp_i.acc_resp.resp_valid; + assign acc_exception_o = acc_resp_i.acc_resp.exception; // Unpack the accelerator response - assign acc_fflags_valid_o = acc_resp_i.fflags_valid; - assign acc_fflags_o = acc_resp_i.fflags; + assign acc_fflags_valid_o = acc_resp_i.acc_resp.fflags_valid; + assign acc_fflags_o = acc_resp_i.acc_resp.fflags; + + // MMU interface + assign acc_mmu_req_o = acc_resp_i.acc_mmu_req; + // Always ready to receive responses - assign acc_req_o.resp_ready = 1'b1; + assign acc_req_o.acc_req.resp_ready = 1'b1; // Signal dispatched load/store to issue stage - assign acc_ld_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_LOAD); - assign acc_st_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_STORE); + assign acc_ld_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_LOAD); + assign acc_st_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_STORE); // Cache invalidation - assign inval_valid_o = acc_resp_i.inval_valid; - assign inval_addr_o = acc_resp_i.inval_addr; + assign inval_valid_o = acc_resp_i.acc_resp.inval_valid; + assign inval_addr_o = acc_resp_i.acc_resp.inval_addr; /************************** * Accelerator commit * @@ -351,8 +337,8 @@ module acc_dispatcher `FF(wait_acc_store_q, wait_acc_store_d, '0) // Set on store barrier. Clear when no store is pending. - assign wait_acc_store_d = (wait_acc_store_q | commit_st_barrier_i) & acc_resp_i.store_pending; - assign ctrl_halt_o = wait_acc_store_q; + assign wait_acc_store_d = (wait_acc_store_q | commit_st_barrier_i) & acc_resp_i.acc_resp.store_pending; + assign ctrl_halt_o = wait_acc_store_q; /************************** * Load/Store tracking * @@ -390,9 +376,9 @@ module acc_dispatcher .clk_i (clk_i), .rst_ni (rst_ni), .clear_i (1'b0), - .en_i (acc_ld_disp ^ acc_resp_i.load_complete), + .en_i (acc_ld_disp ^ acc_resp_i.acc_resp.load_complete), .load_i (1'b0), - .down_i (acc_resp_i.load_complete), + .down_i (acc_resp_i.acc_resp.load_complete), .d_i ('0), .q_o (acc_disp_loads_pending), .overflow_o(acc_disp_loads_overflow) @@ -435,9 +421,9 @@ module acc_dispatcher .clk_i (clk_i), .rst_ni (rst_ni), .clear_i (1'b0), - .en_i (acc_st_disp ^ acc_resp_i.store_complete), + .en_i (acc_st_disp ^ acc_resp_i.acc_resp.store_complete), .load_i (1'b0), - .down_i (acc_resp_i.store_complete), + .down_i (acc_resp_i.acc_resp.store_complete), .d_i ('0), .q_o (acc_disp_stores_pending), .overflow_o(acc_disp_stores_overflow) diff --git a/core/cache_subsystem/cva6_icache.sv b/core/cache_subsystem/cva6_icache.sv index d97fed369a..a173af54ce 100644 --- a/core/cache_subsystem/cva6_icache.sv +++ b/core/cache_subsystem/cva6_icache.sv @@ -426,7 +426,7 @@ module cva6_icache 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}+:CVA6Cfg.FETCH_WIDTH]; - assign cl_user[i] = cl_ruser[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH]; + assign cl_user[i] = CVA6Cfg.FETCH_USER_EN ? cl_ruser[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH] : '0; end @@ -441,10 +441,10 @@ module cva6_icache always_comb begin if (cmp_en_q) begin dreq_o.data = cl_sel[hit_idx]; - dreq_o.user = cl_user[hit_idx]; + dreq_o.user = CVA6Cfg.FETCH_USER_EN ? cl_user[hit_idx] : '0; end else begin 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]; + dreq_o.user = CVA6Cfg.FETCH_USER_EN ? mem_rtrn_i.user[{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH] : '0; end end diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index d6e965f2f6..69ecf1a66d 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -161,9 +161,9 @@ module csr_regfile // TO_BE_COMPLETED - PERF_COUNTERS output logic perf_we_o, // PMP configuration containing pmpcfg for max 64 PMPs - ACC_DISPATCHER - output riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_o, + output riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_o, // PMP addresses - ACC_DISPATCHER - output logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_o, + output logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_o, // TO_BE_COMPLETED - PERF_COUNTERS output logic [31:0] mcountinhibit_o, // RVFI @@ -773,11 +773,13 @@ module csr_regfile riscv::CSR_PMPCFG14, riscv::CSR_PMPCFG15: begin // index is calculated using PMPCFG0 as the offset - automatic logic [11:0] index = csr_addr.address[11:0] - riscv::CSR_PMPCFG0; + automatic logic [3:0] index = csr_addr.address[11:0] - riscv::CSR_PMPCFG0; // if index is not even and XLEN==64, raise exception if (CVA6Cfg.XLEN == 64 && index[0] == 1'b1) read_access_exception = 1'b1; else begin + // The following line has no effect. It's here just to prevent the synthesizer from crashing + if (CVA6Cfg.XLEN == 64) index = (index >> 1) << 1; csr_rdata = pmpcfg_q[index*4+:CVA6Cfg.XLEN/8]; end end diff --git a/core/cva6.sv b/core/cva6.sv index d395b4f5ca..19648c1227 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -39,7 +39,7 @@ module cva6 logic [CVA6Cfg.VLEN-1:0] predict_address; // target address at which to jump, or not }, - localparam type exception_t = struct packed { + parameter type exception_t = struct packed { logic [CVA6Cfg.XLEN-1:0] cause; // cause of exception logic [CVA6Cfg.XLEN-1:0] tval; // additional information of causing exception (e.g.: instruction causing it), // address of LD/ST fault @@ -211,6 +211,14 @@ module cva6 logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] data_ruser; }, + // Accelerator - CVA6 + parameter type accelerator_req_t = logic, + parameter type accelerator_resp_t = logic, + + // Accelerator - CVA6's MMU + parameter type acc_mmu_req_t = logic, + parameter type acc_mmu_resp_t = logic, + // AXI types parameter type axi_ar_chan_t = struct packed { logic [CVA6Cfg.AxiIdWidth-1:0] id; @@ -500,6 +508,11 @@ module cva6 // ACCEL Commit logic acc_valid_acc_ex; // -------------- + // EX <-> ACC_DISP + // -------------- + acc_mmu_req_t acc_mmu_req; + acc_mmu_resp_t acc_mmu_resp; + // -------------- // ID <-> COMMIT // -------------- scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_id_commit; @@ -560,8 +573,8 @@ module cva6 logic acc_cons_en_csr; logic debug_mode; logic single_step_csr_commit; - riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg; - logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr; + riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg; + logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr; logic [31:0] mcountinhibit_csr_perf; // ---------------------------- // Performance Counters <-> * @@ -744,16 +757,17 @@ module cva6 assign ex_ex_ex_id[FPU_WB] = fpu_exception_ex_id; assign wt_valid_ex_id[FPU_WB] = fpu_valid_ex_id; - always_comb begin : gen_cvxif_input_assignement - x_compressed_ready = cvxif_resp_i.compressed_ready; - x_compressed_resp = cvxif_resp_i.compressed_resp; - x_issue_ready = cvxif_resp_i.issue_ready; - x_issue_resp = cvxif_resp_i.issue_resp; - x_register_ready = cvxif_resp_i.register_ready; - x_result_valid = cvxif_resp_i.result_valid; - x_result = cvxif_resp_i.result; - end if (CVA6Cfg.CvxifEn) begin + always_comb begin : gen_cvxif_input_assignement + x_compressed_ready = cvxif_resp_i.compressed_ready; + x_compressed_resp = cvxif_resp_i.compressed_resp; + x_issue_ready = cvxif_resp_i.issue_ready; + x_issue_resp = cvxif_resp_i.issue_resp; + x_register_ready = cvxif_resp_i.register_ready; + x_result_valid = cvxif_resp_i.result_valid; + x_result = cvxif_resp_i.result; + end + always_comb begin : gen_cvxif_output_assignement cvxif_req.compressed_valid = x_compressed_valid; cvxif_req.compressed_req = x_compressed_req; @@ -898,7 +912,9 @@ module cva6 .icache_dreq_t(icache_dreq_t), .icache_drsp_t(icache_drsp_t), .lsu_ctrl_t(lsu_ctrl_t), - .x_result_t(x_result_t) + .x_result_t(x_result_t), + .acc_mmu_req_t(acc_mmu_req_t), + .acc_mmu_resp_t(acc_mmu_resp_t) ) ex_stage_i ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -981,6 +997,9 @@ module cva6 .x_result_ready_o (x_result_ready), // Accelerator .acc_valid_i (acc_valid_acc_ex), + // Accelerator MMU access + .acc_mmu_req_i (acc_mmu_req), + .acc_mmu_resp_o (acc_mmu_resp), // Performance counters .itlb_miss_o (itlb_miss_ex_perf), .dtlb_miss_o (dtlb_miss_ex_perf), @@ -1464,7 +1483,11 @@ module cva6 .acc_cfg_t (acc_cfg_t), .AccCfg (AccCfg), .acc_req_t (cvxif_req_t), - .acc_resp_t (cvxif_resp_t) + .acc_resp_t (cvxif_resp_t), + .accelerator_req_t (accelerator_req_t), + .accelerator_resp_t(accelerator_resp_t), + .acc_mmu_req_t (acc_mmu_req_t), + .acc_mmu_resp_t (acc_mmu_resp_t) ) i_acc_dispatcher ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -1480,6 +1503,7 @@ module cva6 .pmpcfg_i (pmpcfg), .pmpaddr_i (pmpaddr), .fcsr_frm_i (frm_csr_id_issue_ex), + .acc_mmu_en_i (enable_translation_csr_ex), .dirty_v_state_o (dirty_v_state), .issue_instr_i (issue_instr_id_acc), .issue_instr_hs_i (issue_instr_hs_id_acc), @@ -1496,6 +1520,8 @@ module cva6 .acc_stall_st_pending_o(stall_st_pending_ex), .acc_no_st_pending_i (no_st_pending_commit), .dcache_req_ports_i (dcache_req_ports_ex_cache), + .acc_mmu_req_o (acc_mmu_req), + .acc_mmu_resp_i (acc_mmu_resp), .ctrl_halt_o (halt_acc_ctrl), .csr_addr_i (csr_addr_ex_csr), .acc_dcache_req_ports_o(dcache_req_ports_acc_cache), @@ -1525,6 +1551,9 @@ module cva6 // D$ connection is unused assign dcache_req_ports_acc_cache = '0; + // MMU access is unused + assign acc_mmu_req = '0; + // No invalidation interface assign inval_valid = '0; assign inval_addr = '0; diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 5382279938..579b858d9f 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -100,8 +100,8 @@ module cva6_mmu // PMP - input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, - input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i + input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i ); // memory management, pte for cva6 diff --git a/core/cva6_mmu/cva6_ptw.sv b/core/cva6_mmu/cva6_ptw.sv index a5fef76fcc..4e2307c033 100644 --- a/core/cva6_mmu/cva6_ptw.sv +++ b/core/cva6_mmu/cva6_ptw.sv @@ -16,7 +16,7 @@ // Date: 26/02/2024 // Description: Hardware-PTW (Page-Table-Walker) for CVA6 supporting sv32, sv39 and sv39x4. // This module is an merge of the PTW Sv39 developed by Florian Zaruba, -// the PTW Sv32 developed by Sebastien Jacq and the PTW Sv39x4 by Bruno Sá. +// the PTW Sv32 developed by Sebastien Jacq and the PTW Sv39x4 by Bruno Sá. /* verilator lint_off WIDTH */ @@ -83,8 +83,8 @@ module cva6_ptw output logic shared_tlb_miss_o, // PMP - input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, - input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, output logic [CVA6Cfg.PLEN-1:0] bad_paddr_o, output logic [CVA6Cfg.GPLEN-1:0] bad_gpaddr_o ); @@ -258,8 +258,8 @@ module cva6_ptw // PAGESIZE=2^12 and LEVELS=3.) // 2. Let pte be the value of the PTE at address a+va.vpn[i]×PTESIZE. (For // Sv32, PTESIZE=4.) - // 3. If pte.v = 0, or if pte.r = 0 and pte.w = 1, or if any bits or encodings - // that are reserved for future standard use are set within pte, stop and raise + // 3. If pte.v = 0, or if pte.r = 0 and pte.w = 1, or if any bits or encodings + // that are reserved for future standard use are set within pte, stop and raise // a page-fault exception corresponding to the original access type. // 4. Otherwise, the PTE is valid. If pte.r = 1 or pte.x = 1, go to step 5. // Otherwise, this PTE is a pointer to the next level of the page table. diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 3095a2c736..b03f68062b 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -29,7 +29,9 @@ module ex_stage parameter type icache_dreq_t = logic, parameter type icache_drsp_t = logic, parameter type lsu_ctrl_t = logic, - parameter type x_result_t = logic + parameter type x_result_t = logic, + parameter type acc_mmu_req_t = logic, + parameter type acc_mmu_resp_t = logic ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -159,6 +161,9 @@ module ex_stage input logic x_transaction_rejected_i, // accelerate port result is valid - ACC_DISPATCHER input logic acc_valid_i, + // Accelerator MMU access + input acc_mmu_req_t acc_mmu_req_i, + output acc_mmu_resp_t acc_mmu_resp_o, // Enable virtual memory translation - CSR_REGFILE input logic enable_translation_i, // Enable G-Stage memory translation - CSR_REGFILE @@ -222,9 +227,9 @@ module ex_stage // To count the data TLB misses - PERF_COUNTERS output logic dtlb_miss_o, // Report the PMP configuration - CSR_REGFILE - input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, + input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i, // Report the PMP addresses - CSR_REGFILE - input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, // Information dedicated to RVFI - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, // Information dedicated to RVFI - RVFI @@ -526,7 +531,9 @@ module ex_stage .icache_arsp_t(icache_arsp_t), .icache_dreq_t(icache_dreq_t), .icache_drsp_t(icache_drsp_t), - .lsu_ctrl_t(lsu_ctrl_t) + .lsu_ctrl_t(lsu_ctrl_t), + .acc_mmu_req_t(acc_mmu_req_t), + .acc_mmu_resp_t(acc_mmu_resp_t) ) lsu_i ( .clk_i, .rst_ni, @@ -551,6 +558,8 @@ module ex_stage .enable_g_translation_i, .en_ld_st_translation_i, .en_ld_st_g_translation_i, + .acc_mmu_req_i, + .acc_mmu_resp_o, .icache_areq_i, .icache_areq_o, .priv_lvl_i, diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 9e2e0aa80c..c4bed6ab3b 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -809,4 +809,12 @@ package ariane_pkg; return gppn; endfunction : make_gppn + // ---------------------- + // Helper functions + // ---------------------- + // Avoid negative array slices when defining parametrized sizes + function automatic int unsigned avoid_neg(int n); + return (n < 0) ? 0 : n; + endfunction : avoid_neg + endpackage diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index 5b0917fed2..b9a3d5d1bc 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -12,6 +12,8 @@ package cva6_config_pkg; localparam CVA6ConfigXlen = 64; + localparam CVA6ConfigNrCommitPorts = 2; + localparam CVA6ConfigRVF = 1; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; @@ -32,16 +34,16 @@ package cva6_config_pkg; localparam CVA6ConfigAxiAddrWidth = 64; localparam CVA6ConfigAxiDataWidth = 64; localparam CVA6ConfigFetchUserEn = 0; - localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen; + localparam CVA6ConfigFetchUserWidth = 1; // Just not to raise warnings localparam CVA6ConfigDataUserEn = 0; localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen; - localparam CVA6ConfigIcacheByteSize = 16384; + localparam CVA6ConfigIcacheByteSize = 4096; localparam CVA6ConfigIcacheSetAssoc = 4; localparam CVA6ConfigIcacheLineWidth = 128; - localparam CVA6ConfigDcacheByteSize = 16384; + localparam CVA6ConfigDcacheByteSize = 8192; localparam CVA6ConfigDcacheSetAssoc = 4; - localparam CVA6ConfigDcacheLineWidth = 128; + localparam CVA6ConfigDcacheLineWidth = 256; localparam CVA6ConfigDcacheFlushOnFence = 1'b0; localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0; @@ -80,7 +82,7 @@ package cva6_config_pkg; FpgaAlteraEn: bit'(0), // for Altera (only) TechnoCut: bit'(0), SuperscalarEn: bit'(0), - NrCommitPorts: unsigned'(1), + NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth), diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 0fec645319..ccce630112 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -25,7 +25,9 @@ module load_store_unit parameter type icache_arsp_t = logic, parameter type icache_dreq_t = logic, parameter type icache_drsp_t = logic, - parameter type lsu_ctrl_t = logic + parameter type lsu_ctrl_t = logic, + parameter type acc_mmu_req_t = logic, + parameter type acc_mmu_resp_t = logic ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -82,6 +84,10 @@ module load_store_unit // Enable G-Stage memory translation for load/stores - TO_BE_COMPLETED input logic en_ld_st_g_translation_i, + // Accelerator request for CVA6's MMU + input acc_mmu_req_t acc_mmu_req_i, + output acc_mmu_resp_t acc_mmu_resp_o, + // Instruction cache input request - CACHES input icache_arsp_t icache_areq_i, // Instruction cache output request - CACHES @@ -148,9 +154,9 @@ module load_store_unit input amo_resp_t amo_resp_i, // PMP configuration - CSR_REGFILE - input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, + input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i, // PMP address - CSR_REGFILE - input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, // RVFI inforamtion - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, @@ -159,26 +165,26 @@ module load_store_unit ); // data is misaligned - logic data_misaligned; + logic data_misaligned; // -------------------------------------- // 1st register stage - (stall registers) // -------------------------------------- // those are the signals which are always correct // e.g.: they keep the value in the stall case - lsu_ctrl_t lsu_ctrl; + lsu_ctrl_t lsu_ctrl, lsu_ctrl_byp; - logic pop_st; - logic pop_ld; + logic pop_st; + logic pop_ld; // ------------------------------ // Address Generation Unit (AGU) // ------------------------------ // virtual address as calculated by the AGU in the first cycle - logic [ CVA6Cfg.VLEN-1:0] vaddr_i; - logic [ CVA6Cfg.XLEN-1:0] vaddr_xlen; - logic overflow; - logic g_overflow; - logic [(CVA6Cfg.XLEN/8)-1:0] be_i; + logic [ CVA6Cfg.VLEN-1:0] vaddr_i; + logic [ CVA6Cfg.XLEN-1:0] vaddr_xlen; + logic overflow; + logic g_overflow; + logic [(CVA6Cfg.XLEN/8)-1:0] be_i; assign vaddr_xlen = $unsigned($signed(fu_data_i.imm) + $signed(fu_data_i.operand_a)); assign vaddr_i = vaddr_xlen[CVA6Cfg.VLEN-1:0]; @@ -190,10 +196,10 @@ module load_store_unit assign g_overflow = 1'b0; end - logic st_valid_i; - logic ld_valid_i; - logic ld_translation_req; - logic st_translation_req; + logic st_valid_i; + logic ld_valid_i; + logic ld_translation_req; + logic st_translation_req, cva6_st_translation_req, acc_st_translation_req; logic [CVA6Cfg.VLEN-1:0] ld_vaddr; logic [ 31:0] ld_tinst; logic ld_hs_ld_st_inst; @@ -202,41 +208,41 @@ module load_store_unit logic [ 31:0] st_tinst; logic st_hs_ld_st_inst; logic st_hlvx_inst; - logic translation_req; - logic translation_valid; - logic [CVA6Cfg.VLEN-1:0] mmu_vaddr; - logic [CVA6Cfg.PLEN-1:0] mmu_paddr, lsu_paddr; - logic [ 31:0] mmu_tinst; - logic mmu_hs_ld_st_inst; - logic mmu_hlvx_inst; - exception_t mmu_exception; - exception_t pmp_exception; - icache_areq_t pmp_icache_areq_i; - logic pmp_translation_valid; - logic dtlb_hit; - logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn; - - logic ld_valid; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id; - logic [ CVA6Cfg.XLEN-1:0] ld_result; - logic st_valid; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id; - logic [ CVA6Cfg.XLEN-1:0] st_result; - - logic [ 11:0] page_offset; - logic page_offset_matches; - - exception_t misaligned_exception; - exception_t ld_ex; - exception_t st_ex; - - logic hs_ld_st_inst; - logic hlvx_inst; - + logic translation_req, cva6_translation_req, acc_translation_req; + logic translation_valid, cva6_translation_valid, acc_translataion_valid; + logic [CVA6Cfg.VLEN-1:0] mmu_vaddr, cva6_mmu_vaddr, acc_mmu_vaddr; + logic [CVA6Cfg.PLEN-1:0] mmu_paddr, cva6_mmu_paddr, acc_mmu_paddr, lsu_paddr; + logic [31:0] mmu_tinst; + logic mmu_hs_ld_st_inst; + logic mmu_hlvx_inst; + exception_t mmu_exception, cva6_mmu_exception, acc_mmu_exception; + exception_t pmp_exception; + icache_areq_t pmp_icache_areq_i; + logic pmp_translation_valid; + logic dtlb_hit, cva6_dtlb_hit, acc_dtlb_hit; + logic [CVA6Cfg.PPNW-1:0] dtlb_ppn, cva6_dtlb_ppn, acc_dtlb_ppn; + + logic ld_valid; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id; + logic [ CVA6Cfg.XLEN-1:0] ld_result; + logic st_valid; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id; + logic [ CVA6Cfg.XLEN-1:0] st_result; + + logic [ 11:0] page_offset; + logic page_offset_matches; + + exception_t misaligned_exception, cva6_misaligned_exception, acc_misaligned_exception; + exception_t ld_ex; + exception_t st_ex; + + logic hs_ld_st_inst; + logic hlvx_inst; logic [1:0] sum, mxr; logic [CVA6Cfg.PPNW-1:0] satp_ppn[2:0]; logic [CVA6Cfg.ASID_WIDTH-1:0] asid[2:0], asid_to_be_flushed[1:0]; logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed[1:0]; + // ------------------- // MMU e.g.: TLBs/PTW // ------------------- @@ -387,6 +393,108 @@ module load_store_unit .pmpaddr_i (pmpaddr_i) ); + // ------------------ + // External MMU port + // ------------------ + + if (CVA6Cfg.EnableAccelerator) begin + // The MMU can be connected to CVA6 or the ACCELERATOR + enum logic { + CVA6, + ACC + } + mmu_state_d, mmu_state_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + mmu_state_q <= CVA6; + end else begin + mmu_state_q <= mmu_state_d; + end + end + // Straightforward and slow-reactive MMU arbitration logic + // This logic can be optimized to reduce answer latency and contention + always_comb begin + // Maintain state + mmu_state_d = mmu_state_q; + // Serve CVA6 and gate the accelerator by default + // MMU input + misaligned_exception = cva6_misaligned_exception; + st_translation_req = cva6_st_translation_req; + translation_req = cva6_translation_req; + mmu_vaddr = cva6_mmu_vaddr; + // MMU output + cva6_translation_valid = translation_valid; + cva6_mmu_paddr = mmu_paddr; + cva6_mmu_exception = mmu_exception; + cva6_dtlb_hit = dtlb_hit; + cva6_dtlb_ppn = dtlb_ppn; + acc_mmu_resp_o.acc_mmu_valid = '0; + acc_mmu_resp_o.acc_mmu_paddr = '0; + acc_mmu_resp_o.acc_mmu_exception = '0; + acc_mmu_resp_o.acc_mmu_dtlb_hit = '0; + acc_mmu_resp_o.acc_mmu_dtlb_ppn = '0; + unique case (mmu_state_q) + CVA6: begin + // Only the accelerator is requesting, and the lsu bypass queue is empty. + if (acc_mmu_req_i.acc_mmu_req && !lsu_valid_i && lsu_ready_o) begin + // Lock the MMU to the accelerator. + // If the issue stage is firing a mem op in this cycle, + // the bypass queue will buffer it. + mmu_state_d = ACC; + end + // Make this a mealy FSM to cut some latency. + // It should be okay timing-wise since cva6's requests already + // depend on lsu_valid_i. Moreover, lsu_ready_o is sequentially + // generated by the bypass and, in this first implementation, + // the acc request already depends combinatorially upon acc_mmu_req_i.acc_mmu_req. + end + ACC: begin + // MMU input + misaligned_exception = acc_mmu_req_i.acc_mmu_misaligned_ex; + st_translation_req = acc_mmu_req_i.acc_mmu_is_store; + translation_req = acc_mmu_req_i.acc_mmu_req; + mmu_vaddr = acc_mmu_req_i.acc_mmu_vaddr; + // MMU output + acc_mmu_resp_o.acc_mmu_valid = translation_valid; + acc_mmu_resp_o.acc_mmu_paddr = mmu_paddr; + acc_mmu_resp_o.acc_mmu_exception = mmu_exception; + acc_mmu_resp_o.acc_mmu_dtlb_hit = dtlb_hit; + acc_mmu_resp_o.acc_mmu_dtlb_ppn = dtlb_ppn; + cva6_translation_valid = '0; + cva6_mmu_paddr = '0; + cva6_mmu_exception = '0; + cva6_dtlb_hit = '0; + cva6_dtlb_ppn = '0; + // Get back to CVA6 after the translation + if (translation_valid) mmu_state_d = CVA6; + end + default: mmu_state_d = CVA6; + endcase + end + always_comb begin + // Feed forward + lsu_ctrl = lsu_ctrl_byp; + // Mask the lsu valid so that cva6's req gets buffered in the + // bypass queue when the MMU is being used by the accelerator. + lsu_ctrl.valid = (mmu_state_q == ACC) ? 1'b0 : lsu_ctrl_byp.valid; + end + end else begin + // MMU input + assign misaligned_exception = cva6_misaligned_exception; + assign st_translation_req = cva6_st_translation_req; + assign translation_req = cva6_translation_req; + assign mmu_vaddr = cva6_mmu_vaddr; + // MMU output + assign cva6_translation_valid = translation_valid; + assign cva6_mmu_paddr = mmu_paddr; + assign cva6_mmu_exception = mmu_exception; + assign cva6_dtlb_hit = dtlb_hit; + assign cva6_dtlb_ppn = dtlb_ppn; + // No accelerator + assign acc_mmu_resp_o = '0; + // Feed forward the lsu_ctrl bypass + assign lsu_ctrl = lsu_ctrl_byp; + end logic store_buffer_empty; // ------------------ @@ -418,15 +526,15 @@ module load_store_unit .result_o (st_result), .ex_o (st_ex), // MMU port - .translation_req_o (st_translation_req), + .translation_req_o (cva6_st_translation_req), .vaddr_o (st_vaddr), .rvfi_mem_paddr_o (rvfi_mem_paddr_o), .tinst_o (st_tinst), .hs_ld_st_inst_o (st_hs_ld_st_inst), .hlvx_inst_o (st_hlvx_inst), - .paddr_i (mmu_paddr), - .ex_i (mmu_exception), - .dtlb_hit_i (dtlb_hit), + .paddr_i (cva6_mmu_paddr), + .ex_i (cva6_mmu_exception), + .dtlb_hit_i (cva6_dtlb_hit), // Load Unit .page_offset_i (page_offset), .page_offset_matches_o(page_offset_matches), @@ -465,10 +573,10 @@ module load_store_unit .tinst_o (ld_tinst), .hs_ld_st_inst_o (ld_hs_ld_st_inst), .hlvx_inst_o (ld_hlvx_inst), - .paddr_i (mmu_paddr), - .ex_i (mmu_exception), - .dtlb_hit_i (dtlb_hit), - .dtlb_ppn_i (dtlb_ppn), + .paddr_i (cva6_mmu_paddr), + .ex_i (cva6_mmu_exception), + .dtlb_hit_i (cva6_dtlb_hit), + .dtlb_ppn_i (cva6_dtlb_ppn), // to store unit .page_offset_o (page_offset), .page_offset_matches_i(page_offset_matches), @@ -510,22 +618,22 @@ module load_store_unit // determine whether this is a load or store always_comb begin : which_op - ld_valid_i = 1'b0; - st_valid_i = 1'b0; + ld_valid_i = 1'b0; + st_valid_i = 1'b0; - translation_req = 1'b0; - mmu_vaddr = {CVA6Cfg.VLEN{1'b0}}; - mmu_tinst = {32{1'b0}}; - mmu_hs_ld_st_inst = 1'b0; - mmu_hlvx_inst = 1'b0; + cva6_translation_req = 1'b0; + cva6_mmu_vaddr = {CVA6Cfg.VLEN{1'b0}}; + mmu_tinst = {32{1'b0}}; + mmu_hs_ld_st_inst = 1'b0; + mmu_hlvx_inst = 1'b0; // check the operation to activate the right functional unit accordingly unique case (lsu_ctrl.fu) // all loads go here LOAD: begin - ld_valid_i = lsu_ctrl.valid; - translation_req = ld_translation_req; - mmu_vaddr = ld_vaddr; + ld_valid_i = lsu_ctrl.valid; + cva6_translation_req = ld_translation_req; + cva6_mmu_vaddr = ld_vaddr; if (CVA6Cfg.RVH) begin mmu_tinst = ld_tinst; mmu_hs_ld_st_inst = ld_hs_ld_st_inst; @@ -534,9 +642,9 @@ module load_store_unit end // all stores go here STORE: begin - st_valid_i = lsu_ctrl.valid; - translation_req = st_translation_req; - mmu_vaddr = st_vaddr; + st_valid_i = lsu_ctrl.valid; + cva6_translation_req = st_translation_req; + cva6_mmu_vaddr = st_vaddr; if (CVA6Cfg.RVH) begin mmu_tinst = st_tinst; mmu_hs_ld_st_inst = st_hs_ld_st_inst; @@ -594,7 +702,7 @@ module load_store_unit // the misaligned exception is passed to the functional unit via the MMU, which in case // can augment the exception if other memory related exceptions like a page fault or access errors always_comb begin : data_misaligned_detection - misaligned_exception = { + cva6_misaligned_exception = { {CVA6Cfg.XLEN{1'b0}}, {CVA6Cfg.XLEN{1'b0}}, {CVA6Cfg.GPLEN{1'b0}}, {32{1'b0}}, 1'b0, 1'b0 }; data_misaligned = 1'b0; @@ -640,26 +748,26 @@ module load_store_unit if (data_misaligned) begin case (lsu_ctrl.fu) LOAD: begin - misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED; - misaligned_exception.valid = 1'b1; + cva6_misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED; + cva6_misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + cva6_misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + cva6_misaligned_exception.tval2 = '0; + cva6_misaligned_exception.tinst = lsu_ctrl.tinst; + cva6_misaligned_exception.gva = ld_st_v_i; end end STORE: begin - misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED; - misaligned_exception.valid = 1'b1; + cva6_misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED; + cva6_misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + cva6_misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + cva6_misaligned_exception.tval2 = '0; + cva6_misaligned_exception.tinst = lsu_ctrl.tinst; + cva6_misaligned_exception.gva = ld_st_v_i; end end default: ; @@ -670,25 +778,25 @@ module load_store_unit case (lsu_ctrl.fu) LOAD: begin - misaligned_exception.cause = riscv::LOAD_PAGE_FAULT; - misaligned_exception.valid = 1'b1; + cva6_misaligned_exception.cause = riscv::LOAD_PAGE_FAULT; + cva6_misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + cva6_misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + cva6_misaligned_exception.tval2 = '0; + cva6_misaligned_exception.tinst = lsu_ctrl.tinst; + cva6_misaligned_exception.gva = ld_st_v_i; end end STORE: begin - misaligned_exception.cause = riscv::STORE_PAGE_FAULT; - misaligned_exception.valid = 1'b1; + cva6_misaligned_exception.cause = riscv::STORE_PAGE_FAULT; + cva6_misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + cva6_misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + cva6_misaligned_exception.tval2 = '0; + cva6_misaligned_exception.tinst = lsu_ctrl.tinst; + cva6_misaligned_exception.gva = ld_st_v_i; end end default: ; @@ -699,25 +807,25 @@ module load_store_unit case (lsu_ctrl.fu) LOAD: begin - misaligned_exception.cause = riscv::LOAD_GUEST_PAGE_FAULT; - misaligned_exception.valid = 1'b1; + cva6_misaligned_exception.cause = riscv::LOAD_GUEST_PAGE_FAULT; + cva6_misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + cva6_misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + cva6_misaligned_exception.tval2 = '0; + cva6_misaligned_exception.tinst = lsu_ctrl.tinst; + cva6_misaligned_exception.gva = ld_st_v_i; end end STORE: begin - misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT; - misaligned_exception.valid = 1'b1; + cva6_misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT; + cva6_misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + cva6_misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + cva6_misaligned_exception.tval2 = '0; + cva6_misaligned_exception.tinst = lsu_ctrl.tinst; + cva6_misaligned_exception.gva = ld_st_v_i; end end default: ; @@ -759,12 +867,10 @@ module load_store_unit .pop_ld_i (pop_ld), .pop_st_i (pop_st), - .lsu_ctrl_o(lsu_ctrl), + .lsu_ctrl_o(lsu_ctrl_byp), .ready_o (lsu_ready_o) ); assign rvfi_lsu_ctrl_o = lsu_ctrl; endmodule - - diff --git a/core/pmp/src/pmp.sv b/core/pmp/src/pmp.sv index f3498711ed..b6d0dbf2ec 100644 --- a/core/pmp/src/pmp.sv +++ b/core/pmp/src/pmp.sv @@ -12,7 +12,9 @@ // Date: 2.10.2019 // Description: purely combinatorial PMP unit (with extraction for more complex configs such as NAPOT) -module pmp #( +module pmp + import ariane_pkg::*; +#( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( // Input @@ -20,8 +22,8 @@ module pmp #( input riscv::pmp_access_t access_type_i, input riscv::priv_lvl_t priv_lvl_i, // Configuration - input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] conf_addr_i, - input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] conf_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] conf_addr_i, + input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] conf_i, // Output output logic allow_o ); diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index d18149fb29..fc325db260 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -36,8 +36,8 @@ module pmp_data_if input riscv::priv_lvl_t ld_st_priv_lvl_i, input logic ld_st_v_i, // PMP - input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, - input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i + input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i, + input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i ); // virtual address causing the exception logic [CVA6Cfg.XLEN-1:0] fetch_vaddr_xlen, lsu_vaddr_xlen;