diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index dee9faf94fc..1dfa02d03d8 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -21,122 +21,125 @@ module csr_regfile parameter int unsigned MHPMCounterNum = 6 ) ( // Subsystem Clock - SUBSYSTEM - input logic clk_i, + input logic clk_i, // Asynchronous reset active low - SUBSYSTEM - input logic rst_ni, + input logic rst_ni, // Timer threw a interrupt - SUBSYSTEM - input logic time_irq_i, + input logic time_irq_i, // send a flush request out when a CSR with a side effect changes - CONTROLLER - output logic flush_o, + output logic flush_o, // halt requested - CONTROLLER - output logic halt_csr_o, + output logic halt_csr_o, // Instruction to be committed - ID_STAGE - input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i, + input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i, // Commit acknowledged a instruction -> increase instret CSR - COMMIT_STAGE - input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, + input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, // Address from which to start booting, mtvec is set to the same address - SUBSYSTEM - input logic [ riscv::VLEN-1:0] boot_addr_i, + input logic [riscv::VLEN-1:0] boot_addr_i, // Hart id in a multicore environment (reflected in a CSR) - SUBSYSTEM - input logic [ riscv::XLEN-1:0] hart_id_i, + input logic [riscv::XLEN-1:0] hart_id_i, // we are taking an exception // We've got an exception from the commit stage, take it - COMMIT_STAGE - input exception_t ex_i, + input exception_t ex_i, // Operation to perform on the CSR file - COMMIT_STAGE - input fu_op csr_op_i, + input fu_op csr_op_i, // Address of the register to read/write - EX_STAGE - input logic [ 11:0] csr_addr_i, + input logic [11:0] csr_addr_i, // Write data in - COMMIT_STAGE - input logic [ riscv::XLEN-1:0] csr_wdata_i, + input logic [riscv::XLEN-1:0] csr_wdata_i, // Read data out - COMMIT_STAGE - output logic [ riscv::XLEN-1:0] csr_rdata_o, + output logic [riscv::XLEN-1:0] csr_rdata_o, // Mark the FP sate as dirty - COMMIT_STAGE - input logic dirty_fp_state_i, + input logic dirty_fp_state_i, // Write fflags register e.g.: we are retiring a floating point instruction - COMMIT_STAGE - input logic csr_write_fflags_i, + input logic csr_write_fflags_i, // Mark the V state as dirty - ACC_DISPATCHER - input logic dirty_v_state_i, + input logic dirty_v_state_i, // PC of instruction accessing the CSR - COMMIT_STAGE - input logic [ riscv::VLEN-1:0] pc_i, + input logic [riscv::VLEN-1:0] pc_i, // attempts to access a CSR without appropriate privilege - COMMIT_STAGE - output exception_t csr_exception_o, + output exception_t csr_exception_o, // Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - FRONTEND - output logic [ riscv::VLEN-1:0] epc_o, + output logic [riscv::VLEN-1:0] epc_o, // Return from exception, set the PC of epc_o - FRONTEND - output logic eret_o, + output logic eret_o, // Output base of exception vector, correct CSR is output (mtvec, stvec) - FRONTEND - output logic [ riscv::VLEN-1:0] trap_vector_base_o, + output logic [riscv::VLEN-1:0] trap_vector_base_o, // Current privilege level the CPU is in - EX_STAGE - output riscv::priv_lvl_t priv_lvl_o, + output riscv::priv_lvl_t priv_lvl_o, // Imprecise FP exception from the accelerator (fcsr.fflags format) - ACC_DISPATCHER - input logic [ 4:0] acc_fflags_ex_i, + input logic [4:0] acc_fflags_ex_i, // An FP exception from the accelerator occurred - ACC_DISPATCHER - input logic acc_fflags_ex_valid_i, + input logic acc_fflags_ex_valid_i, // Floating point extension status - ID_STAGE - output riscv::xs_t fs_o, + output riscv::xs_t fs_o, // Floating-Point Accured Exceptions - COMMIT_STAGE - output logic [ 4:0] fflags_o, + output logic [4:0] fflags_o, // Floating-Point Dynamic Rounding Mode - EX_STAGE - output logic [ 2:0] frm_o, + output logic [2:0] frm_o, // Floating-Point Precision Control - EX_STAGE - output logic [ 6:0] fprec_o, + output logic [6:0] fprec_o, // Vector extension status - ID_STAGE - output riscv::xs_t vs_o, + output riscv::xs_t vs_o, // interrupt management to id stage - ID_STAGE - output irq_ctrl_t irq_ctrl_o, + output irq_ctrl_t irq_ctrl_o, // enable VA translation - EX_STAGE - output logic en_translation_o, + output logic en_translation_o, // enable VA translation for load and stores - EX_STAGE - output logic en_ld_st_translation_o, + output logic en_ld_st_translation_o, // Privilege level at which load and stores should happen - EX_STAGE - output riscv::priv_lvl_t ld_st_priv_lvl_o, + output riscv::priv_lvl_t ld_st_priv_lvl_o, // TO_BE_COMPLETED - EX_STAGE - output logic sum_o, + output logic sum_o, // TO_BE_COMPLETED - EX_STAGE - output logic mxr_o, + output logic mxr_o, // TO_BE_COMPLETED - EX_STAGE - output logic [ riscv::PPNW-1:0] satp_ppn_o, + output logic [riscv::PPNW-1:0] satp_ppn_o, // TO_BE_COMPLETED - EX_STAGE - output logic [ AsidWidth-1:0] asid_o, + output logic [AsidWidth-1:0] asid_o, // external interrupt in - SUBSYSTEM - input logic [ 1:0] irq_i, + input logic [1:0] irq_i, // inter processor interrupt -> connected to machine mode sw - SUBSYSTEM - input logic ipi_i, + input logic ipi_i, // debug request in - ID_STAGE - input logic debug_req_i, + input logic debug_req_i, // TO_BE_COMPLETED - FRONTEND - output logic set_debug_pc_o, + output logic set_debug_pc_o, // trap virtual memory - ID_STAGE - output logic tvm_o, + output logic tvm_o, // timeout wait - ID_STAGE - output logic tw_o, + output logic tw_o, // trap sret - ID_STAGE - output logic tsr_o, + output logic tsr_o, // we are in debug mode -> that will change some decoding - EX_STAGE - output logic debug_mode_o, + output logic debug_mode_o, // we are in single-step mode - COMMIT_STAGE - output logic single_step_o, + output logic single_step_o, // L1 ICache Enable - CACHE - output logic icache_en_o, + output logic icache_en_o, // L1 DCache Enable - CACHE - output logic dcache_en_o, + output logic dcache_en_o, // Accelerator memory consistent mode - ACC_DISPATCHER - output logic acc_cons_en_o, + output logic acc_cons_en_o, // Performance Counter // read/write address to performance counter module - PERF_COUNTERS - output logic [ 11:0] perf_addr_o, + output logic [11:0] perf_addr_o, // write data to performance counter module - PERF_COUNTERS - output logic [ riscv::XLEN-1:0] perf_data_o, + output logic [riscv::XLEN-1:0] perf_data_o, // read data from performance counter module - PERF_COUNTERS - input logic [ riscv::XLEN-1:0] perf_data_i, + input logic [riscv::XLEN-1:0] perf_data_i, // TO_BE_COMPLETED - PERF_COUNTERS - output logic perf_we_o, + output logic perf_we_o, // PMP configuration containing pmpcfg for max 16 PMPs - ACC_DISPATCHER - output riscv::pmpcfg_t [ 15:0] pmpcfg_o, + output riscv::pmpcfg_t [15:0] pmpcfg_o, // PMP addresses - ACC_DISPATCHER - output logic [ 15:0][riscv::PLEN-3:0] pmpaddr_o, + output logic [15:0][riscv::PLEN-3:0] pmpaddr_o, // TO_BE_COMPLETED - PERF_COUNTERS - output logic [ 31:0] mcountinhibit_o + output logic [31:0] mcountinhibit_o, + // RVFI + output rvfi_probes_csr_t rvfi_csr_o ); + // internal signal to keep track of access exceptions logic read_access_exception, update_access_exception, privilege_violation; logic csr_we, csr_read; @@ -191,8 +194,8 @@ module csr_regfile logic [63:0] cycle_q, cycle_d; logic [63:0] instret_q, instret_d; - riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d; - logic [15:0][riscv::PLEN-3:0] pmpaddr_q, pmpaddr_d; + riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d, pmpcfg_next; + logic [15:0][riscv::PLEN-3:0] pmpaddr_q, pmpaddr_d, pmpaddr_next; logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q; logic [3:0] index; @@ -1667,23 +1670,29 @@ module csr_regfile // wait for interrupt wfi_q <= wfi_d; // pmp - for (int i = 0; i < 16; i++) begin - if (i < CVA6Cfg.NrPMPEntries) begin - // We only support >=8-byte granularity, NA4 is disabled - if(!CVA6Cfg.PMPEntryReadOnly[i] && pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin - pmpcfg_q[i] <= pmpcfg_d[i]; - end else begin - pmpcfg_q[i] <= pmpcfg_q[i]; - end - if (!CVA6Cfg.PMPEntryReadOnly[i]) begin - pmpaddr_q[i] <= pmpaddr_d[i]; - end else begin - pmpaddr_q[i] <= pmpaddr_q[i]; - end + pmpcfg_q <= pmpcfg_next; + pmpaddr_q <= pmpaddr_next; + end + end + + // write logic pmp + always_comb begin : write + for (int i = 0; i < 16; i++) begin + if (i < CVA6Cfg.NrPMPEntries) begin + // We only support >=8-byte granularity, NA4 is disabled + if(!CVA6Cfg.PMPEntryReadOnly[i] && pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin + pmpcfg_next[i] = pmpcfg_d[i]; end else begin - pmpcfg_q[i] <= '0; - pmpaddr_q[i] <= '0; + pmpcfg_next[i] = pmpcfg_q[i]; + end + if (!CVA6Cfg.PMPEntryReadOnly[i]) begin + pmpaddr_next[i] = pmpaddr_d[i]; + end else begin + pmpaddr_next[i] = pmpaddr_q[i]; end + end else begin + pmpcfg_next[i] = '0; + pmpaddr_next[i] = '0; end end end @@ -1699,4 +1708,45 @@ module csr_regfile $stop(); end //pragma translate_on + + + //RVFI CSR + + //------------- + // RVFI + //------------- + assign rvfi_csr_o.fcsr_q = CVA6Cfg.FpPresent ? fcsr_q : '0; + assign rvfi_csr_o.dcsr_q = CVA6Cfg.DebugEn ? dcsr_q : '0; + assign rvfi_csr_o.dpc_q = CVA6Cfg.DebugEn ? dpc_q : '0; + assign rvfi_csr_o.dscratch0_q = CVA6Cfg.DebugEn ? dscratch0_q : '0; + assign rvfi_csr_o.dscratch1_q = CVA6Cfg.DebugEn ? dscratch1_q : '0; + assign rvfi_csr_o.mie_q = mie_q; + assign rvfi_csr_o.mip_q = mip_q; + assign rvfi_csr_o.stvec_q = CVA6Cfg.RVS ? stvec_q : '0; + assign rvfi_csr_o.scounteren_q = CVA6Cfg.RVS ? scounteren_q : '0; + assign rvfi_csr_o.sscratch_q = CVA6Cfg.RVS ? sscratch_q : '0; + assign rvfi_csr_o.sepc_q = CVA6Cfg.RVS ? sepc_q : '0; + assign rvfi_csr_o.scause_q = CVA6Cfg.RVS ? scause_q : '0; + assign rvfi_csr_o.stval_q = CVA6Cfg.RVS ? stval_q : '0; + assign rvfi_csr_o.satp_q = CVA6Cfg.RVS ? satp_q : '0; + assign rvfi_csr_o.mstatus_extended = mstatus_extended; + assign rvfi_csr_o.medeleg_q = CVA6Cfg.RVS ? medeleg_q : '0; + assign rvfi_csr_o.mideleg_q = CVA6Cfg.RVS ? mideleg_q : '0; + assign rvfi_csr_o.mtvec_q = mtvec_q; + assign rvfi_csr_o.mcounteren_q = mcounteren_q; + assign rvfi_csr_o.mscratch_q = mscratch_q; + assign rvfi_csr_o.mepc_q = mepc_q; + assign rvfi_csr_o.mcause_q = mcause_q; + assign rvfi_csr_o.mtval_q = mtval_q; + assign rvfi_csr_o.fiom_q = fiom_q; + assign rvfi_csr_o.mcountinhibit_q = mcountinhibit_q; + assign rvfi_csr_o.cycle_q = cycle_q; + assign rvfi_csr_o.instret_q = instret_q; + assign rvfi_csr_o.dcache_q = dcache_q; + assign rvfi_csr_o.icache_q = icache_q; + assign rvfi_csr_o.acc_cons_q = CVA6Cfg.EnableAccelerator ? acc_cons_q : '0; + assign rvfi_csr_o.pmpcfg_q = pmpcfg_q; + assign rvfi_csr_o.pmpaddr_q = pmpaddr_q; + + endmodule diff --git a/core/cva6.sv b/core/cva6.sv index 385a487908c..99837ad8f2e 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -18,30 +18,10 @@ module cva6 #( // CVA6 config parameter config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg, - parameter bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace), - // RVFI + parameter type rvfi_probes_t = struct packed { - logic [TRANS_ID_BITS-1:0] issue_pointer; - logic [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer; - logic flush_unissued_instr; - logic decoded_instr_valid; - logic flush; - logic decoded_instr_ack; - logic issue_instr_ack; - logic fetch_entry_valid; - logic [31:0] instruction; - logic is_compressed; - riscv::xlen_t rs1_forwarding; - riscv::xlen_t rs2_forwarding; - scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr; - exception_t ex_commit; - riscv::priv_lvl_t priv_lvl; - lsu_ctrl_t lsu_ctrl; - logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; - logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; - logic [riscv::PLEN-1:0] mem_paddr; - logic debug_mode; - logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata; + logic csr; //disabled + rvfi_probes_instr_t instr; }, // AXI types @@ -408,67 +388,66 @@ module cva6 // ---------------------------- logic [11:0] addr_csr_perf; riscv::xlen_t data_csr_perf, data_perf_csr; - 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 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; // -------------- // 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; - - 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; + 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; + + 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_t rvfi_probes; - + 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 @@ -881,6 +860,8 @@ module cva6 .pmpcfg_o (pmpcfg), .pmpaddr_o (pmpaddr), .mcountinhibit_o (mcountinhibit_csr_perf), + //RVFI + .rvfi_csr_o (rvfi_csr), .debug_req_i, .ipi_i, .irq_i, @@ -1374,44 +1355,45 @@ module cva6 //pragma translate_on - if (IsRVFI) begin + //RVFI INSTR - cva6_rvfi_probes #( - .CVA6Cfg (CVA6ExtendCfg), - .rvfi_probes_t(rvfi_probes_t) - ) i_cva6_rvfi_combi ( + cva6_rvfi_probes #( + .CVA6Cfg (CVA6ExtendCfg), + .rvfi_probes_t(rvfi_probes_t) + ) i_cva6_rvfi_probes ( - .flush_i (flush_ctrl_if), - .issue_instr_ack_i (issue_instr_issue_id), - .fetch_entry_valid_i(fetch_valid_if_id), - .instruction_i (fetch_entry_if_id.instruction), - .is_compressed_i (rvfi_is_compressed), + .flush_i (flush_ctrl_if), + .issue_instr_ack_i (issue_instr_issue_id), + .fetch_entry_valid_i(fetch_valid_if_id), + .instruction_i (fetch_entry_if_id.instruction), + .is_compressed_i (rvfi_is_compressed), - .issue_pointer_i (rvfi_issue_pointer), - .commit_pointer_i(rvfi_commit_pointer), + .issue_pointer_i (rvfi_issue_pointer), + .commit_pointer_i(rvfi_commit_pointer), - .flush_unissued_instr_i(flush_unissued_instr_ctrl_id), - .decoded_instr_valid_i (issue_entry_valid_id_issue), - .decoded_instr_ack_i (issue_instr_issue_id), + .flush_unissued_instr_i(flush_unissued_instr_ctrl_id), + .decoded_instr_valid_i (issue_entry_valid_id_issue), + .decoded_instr_ack_i (issue_instr_issue_id), - .rs1_forwarding_i(rs1_forwarding_id_ex), - .rs2_forwarding_i(rs2_forwarding_id_ex), + .rs1_forwarding_i(rs1_forwarding_id_ex), + .rs2_forwarding_i(rs2_forwarding_id_ex), - .commit_instr_i(commit_instr_id_commit), - .ex_commit_i (ex_commit), - .priv_lvl_i (priv_lvl), + .commit_instr_i(commit_instr_id_commit), + .ex_commit_i (ex_commit), + .priv_lvl_i (priv_lvl), - .lsu_ctrl_i (rvfi_lsu_ctrl), - .wbdata_i (wbdata_ex_id), - .commit_ack_i(commit_ack), - .mem_paddr_i (rvfi_mem_paddr), - .debug_mode_i(debug_mode), - .wdata_i (wdata_commit_id), + .lsu_ctrl_i (rvfi_lsu_ctrl), + .wbdata_i (wbdata_ex_id), + .commit_ack_i(commit_ack), + .mem_paddr_i (rvfi_mem_paddr), + .debug_mode_i(debug_mode), + .wdata_i (wdata_commit_id), - .rvfi_probes_o(rvfi_probes_o) + .csr_i(rvfi_csr), - ); + .rvfi_probes_o(rvfi_probes_o) + + ); - end //IsRVFI endmodule // ariane diff --git a/core/cva6_rvfi.sv b/core/cva6_rvfi.sv index d4d9f103424..acc37710375 100644 --- a/core/cva6_rvfi.sv +++ b/core/cva6_rvfi.sv @@ -14,14 +14,18 @@ module cva6_rvfi #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type rvfi_instr_t = logic, + parameter type rvfi_csr_t = logic, parameter type rvfi_probes_t = logic + ) ( input logic clk_i, input logic rst_ni, input rvfi_probes_t rvfi_probes_i, - output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o + output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr_o, + output rvfi_csr_t rvfi_csr_o + ); @@ -32,146 +36,100 @@ module cva6_rvfi localparam bit RVF = (riscv::IS_XLEN64 | riscv::IS_XLEN32) & CVA6Cfg.FpuEn; localparam bit RVD = (riscv::IS_XLEN64 ? 1 : 0) & CVA6Cfg.FpuEn; localparam bit FpPresent = RVF | RVD | CVA6Cfg.XF16 | CVA6Cfg.XF16ALT | CVA6Cfg.XF8; - localparam bit NSX = CVA6Cfg.XF16 | CVA6Cfg.XF16ALT | CVA6Cfg.XF8 | CVA6Cfg.XFVec; // Are non-standard extensions present? - localparam int unsigned FLen = RVD ? 64 : // D ext. - RVF ? 32 : // F ext. - CVA6Cfg.XF16 ? 16 : // Xf16 ext. - CVA6Cfg.XF16ALT ? 16 : // Xf16alt ext. - CVA6Cfg.XF8 ? 8 : // Xf8 ext. - 1; // Unused in case of no FP - - // Transprecision floating-point extensions configuration - localparam bit RVFVec = RVF & CVA6Cfg.XFVec & FLen>32; // FP32 vectors available if vectors and larger fmt enabled - localparam bit XF16Vec = CVA6Cfg.XF16 & CVA6Cfg.XFVec & FLen>16; // FP16 vectors available if vectors and larger fmt enabled - localparam bit XF16ALTVec = CVA6Cfg.XF16ALT & CVA6Cfg.XFVec & FLen>16; // FP16ALT vectors available if vectors and larger fmt enabled - localparam bit XF8Vec = CVA6Cfg.XF8 & CVA6Cfg.XFVec & FLen>8; // FP8 vectors available if vectors and larger fmt enabled - - localparam bit EnableAccelerator = CVA6Cfg.RVV; // Currently only used by V extension (Ara) - localparam int unsigned NrWbPorts = (CVA6Cfg.CvxifEn || EnableAccelerator) ? 5 : 4; - - localparam NrRgprPorts = 2; - - localparam bit NonIdemPotenceEn = CVA6Cfg.NrNonIdempotentRules && CVA6Cfg.NonIdempotentLength; // Currently only used by V extension (Ara) - - localparam config_pkg::cva6_cfg_t CVA6ExtendCfg = { - CVA6Cfg.NrCommitPorts, - CVA6Cfg.AxiAddrWidth, - CVA6Cfg.AxiDataWidth, - CVA6Cfg.AxiIdWidth, - CVA6Cfg.AxiUserWidth, - CVA6Cfg.NrLoadBufEntries, - CVA6Cfg.FpuEn, - CVA6Cfg.XF16, - CVA6Cfg.XF16ALT, - CVA6Cfg.XF8, - CVA6Cfg.RVA, - CVA6Cfg.RVB, - CVA6Cfg.RVV, - CVA6Cfg.RVC, - CVA6Cfg.RVZCB, - CVA6Cfg.XFVec, - CVA6Cfg.CvxifEn, - CVA6Cfg.ZiCondExtEn, - // Extended - bit'(RVF), - bit'(RVD), - bit'(FpPresent), - bit'(NSX), - unsigned'(FLen), - bit'(RVFVec), - bit'(XF16Vec), - bit'(XF16ALTVec), - bit'(XF8Vec), - unsigned'(NrRgprPorts), - unsigned'(NrWbPorts), - bit'(EnableAccelerator), - CVA6Cfg.RVS, - CVA6Cfg.RVU, - CVA6Cfg.HaltAddress, - CVA6Cfg.ExceptionAddress, - CVA6Cfg.RASDepth, - CVA6Cfg.BTBEntries, - CVA6Cfg.BHTEntries, - CVA6Cfg.DmBaseAddress, - CVA6Cfg.TvalEn, - CVA6Cfg.NrPMPEntries, - CVA6Cfg.PMPCfgRstVal, - CVA6Cfg.PMPAddrRstVal, - CVA6Cfg.PMPEntryReadOnly, - CVA6Cfg.NOCType, - CVA6Cfg.NrNonIdempotentRules, - CVA6Cfg.NonIdempotentAddrBase, - CVA6Cfg.NonIdempotentLength, - CVA6Cfg.NrExecuteRegionRules, - CVA6Cfg.ExecuteRegionAddrBase, - CVA6Cfg.ExecuteRegionLength, - CVA6Cfg.NrCachedRegionRules, - CVA6Cfg.CachedRegionAddrBase, - CVA6Cfg.CachedRegionLength, - CVA6Cfg.MaxOutstandingStores, - CVA6Cfg.DebugEn, - NonIdemPotenceEn, - CVA6Cfg.AxiBurstWriteEn - }; - - 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 [CVA6ExtendCfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer; - - logic flush_unissued_instr; - logic decoded_instr_valid; - logic decoded_instr_ack; - - riscv::xlen_t rs1_forwarding; - riscv::xlen_t rs2_forwarding; - - scoreboard_entry_t [CVA6ExtendCfg.NrCommitPorts-1:0] commit_instr; - exception_t ex_commit; - riscv::priv_lvl_t priv_lvl; - - lsu_ctrl_t lsu_ctrl; - logic [ CVA6ExtendCfg.NrWbPorts-1:0][ riscv::XLEN-1:0] wbdata; - logic [CVA6ExtendCfg.NrCommitPorts-1:0] commit_ack; - logic [ riscv::PLEN-1:0] mem_paddr; - logic debug_mode; - logic [CVA6ExtendCfg.NrCommitPorts-1:0][ riscv::XLEN-1:0] wdata; - - 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; - - assign flush = rvfi_probes_i.flush; - assign issue_instr_ack = rvfi_probes_i.issue_instr_ack; - assign fetch_entry_valid = rvfi_probes_i.fetch_entry_valid; - assign instruction = rvfi_probes_i.instruction; - assign is_compressed = rvfi_probes_i.is_compressed; - - assign issue_pointer = rvfi_probes_i.issue_pointer; - assign commit_pointer = rvfi_probes_i.commit_pointer; - - assign flush_unissued_instr = rvfi_probes_i.flush_unissued_instr; - assign decoded_instr_valid = rvfi_probes_i.decoded_instr_valid; - assign decoded_instr_ack = rvfi_probes_i.decoded_instr_ack; - - assign rs1_forwarding = rvfi_probes_i.rs1_forwarding; - assign rs2_forwarding = rvfi_probes_i.rs2_forwarding; - - assign commit_instr = rvfi_probes_i.commit_instr; - assign ex_commit = rvfi_probes_i.ex_commit; - assign priv_lvl = rvfi_probes_i.priv_lvl; - - assign lsu_ctrl = rvfi_probes_i.lsu_ctrl; - assign wbdata = rvfi_probes_i.wbdata; - assign commit_ack = rvfi_probes_i.commit_ack; - assign mem_paddr = rvfi_probes_i.mem_paddr; - assign debug_mode = rvfi_probes_i.debug_mode; - assign wdata = rvfi_probes_i.wdata; + + localparam riscv::xlen_t IsaCode = (riscv::XLEN'(CVA6Cfg.RVA) << 0) // A - Atomic Instructions extension + | (riscv::XLEN'(CVA6Cfg.RVB) << 1) // C - Bitmanip extension + | (riscv::XLEN'(CVA6Cfg.RVC) << 2) // C - Compressed extension + | (riscv::XLEN'(CVA6Cfg.RVD) << 3) // D - Double precision floating-point extension + | (riscv::XLEN'(CVA6Cfg.RVF) << 5) // F - Single precision floating-point extension + | (riscv::XLEN'(1) << 8) // I - RV32I/64I/128I base ISA + | (riscv::XLEN'(1) << 12) // M - Integer Multiply/Divide extension + | (riscv::XLEN'(0) << 13) // N - User level interrupts supported + | (riscv::XLEN'(CVA6Cfg.RVS) << 18) // S - Supervisor mode implemented + | (riscv::XLEN'(CVA6Cfg.RVU) << 20) // U - User mode implemented + | (riscv::XLEN'(CVA6Cfg.RVV) << 21) // V - Vector extension + | (riscv::XLEN'(CVA6Cfg.NSX) << 23) // X - Non-standard extensions present + | ((riscv::XLEN == 64 ? 2 : 1) << riscv::XLEN - 2); // MXL + + localparam riscv::xlen_t hart_id_i = '0; + 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 flush_unissued_instr; + logic decoded_instr_valid; + logic decoded_instr_ack; + + riscv::xlen_t rs1_forwarding; + riscv::xlen_t rs2_forwarding; + + scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr; + exception_t ex_commit; + riscv::priv_lvl_t priv_lvl; + + lsu_ctrl_t lsu_ctrl; + logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; + logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; + logic [riscv::PLEN-1:0] mem_paddr; + logic debug_mode; + logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata; + + 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; + + riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d; + + rvfi_probes_csr_t csr; + rvfi_probes_instr_t instr; + + always_comb begin + csr = '0; + instr = '0; + + if ($bits(rvfi_probes_i.instr) == $bits(instr)) begin + instr = rvfi_probes_i.instr; + end + + if ($bits(rvfi_probes_i.csr) == $bits(csr)) begin + csr = rvfi_probes_i.csr; + end + + end + + + assign flush = instr.flush; + assign issue_instr_ack = instr.issue_instr_ack; + assign fetch_entry_valid = instr.fetch_entry_valid; + assign instruction = instr.instruction; + assign is_compressed = instr.is_compressed; + + assign issue_pointer = instr.issue_pointer; + assign commit_pointer = instr.commit_pointer; + + assign flush_unissued_instr = instr.flush_unissued_instr; + assign decoded_instr_valid = instr.decoded_instr_valid; + assign decoded_instr_ack = instr.decoded_instr_ack; + + assign rs1_forwarding = instr.rs1_forwarding; + assign rs2_forwarding = instr.rs2_forwarding; + + assign commit_instr = instr.commit_instr; + assign ex_commit = instr.ex_commit; + assign priv_lvl = instr.priv_lvl; + + assign lsu_ctrl = instr.lsu_ctrl; + assign wbdata = instr.wbdata; + assign commit_ack = instr.commit_ack; + assign mem_paddr = instr.mem_paddr; + assign debug_mode = instr.debug_mode; + assign wdata = instr.wdata; assign lsu_addr = lsu_ctrl.vaddr; assign lsu_rmask = lsu_ctrl.fu == LOAD ? lsu_ctrl.be : '0; @@ -260,36 +218,231 @@ module cva6_rvfi //---------------------------------------------------------------------------------------------------------- always_comb begin - for (int i = 0; i < CVA6ExtendCfg.NrCommitPorts; i++) begin + for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin logic exception; exception = commit_instr[i].valid && ex_commit.valid; - rvfi_o[i].valid = (commit_ack[i] && !ex_commit.valid) || + rvfi_instr_o[i].valid = (commit_ack[i] && !ex_commit.valid) || (exception && (ex_commit.cause == riscv::ENV_CALL_MMODE || ex_commit.cause == riscv::ENV_CALL_SMODE || ex_commit.cause == riscv::ENV_CALL_UMODE)); - rvfi_o[i].insn = mem_q[commit_pointer[i]].instr; + rvfi_instr_o[i].insn = mem_q[commit_pointer[i]].instr; // when trap, the instruction is not executed - rvfi_o[i].trap = exception; - rvfi_o[i].cause = ex_commit.cause; - rvfi_o[i].mode = (CVA6ExtendCfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl; - rvfi_o[i].ixl = riscv::XLEN == 64 ? 2 : 1; - rvfi_o[i].rs1_addr = commit_instr[i].rs1[4:0]; - rvfi_o[i].rs2_addr = commit_instr[i].rs2[4:0]; - rvfi_o[i].rd_addr = commit_instr[i].rd[4:0]; - rvfi_o[i].rd_wdata = (CVA6ExtendCfg.FpPresent && is_rd_fpr(commit_instr[i].op)) ? + rvfi_instr_o[i].trap = exception; + rvfi_instr_o[i].cause = ex_commit.cause; + rvfi_instr_o[i].mode = (CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl; + rvfi_instr_o[i].ixl = riscv::XLEN == 64 ? 2 : 1; + rvfi_instr_o[i].rs1_addr = commit_instr[i].rs1[4:0]; + rvfi_instr_o[i].rs2_addr = commit_instr[i].rs2[4:0]; + rvfi_instr_o[i].rd_addr = commit_instr[i].rd[4:0]; + rvfi_instr_o[i].rd_wdata = (FpPresent && is_rd_fpr(commit_instr[i].op)) ? commit_instr[i].result : wdata[i]; - rvfi_o[i].pc_rdata = commit_instr[i].pc; - rvfi_o[i].mem_addr = mem_q[commit_pointer[i]].lsu_addr; + rvfi_instr_o[i].pc_rdata = commit_instr[i].pc; + rvfi_instr_o[i].mem_addr = mem_q[commit_pointer[i]].lsu_addr; // So far, only write paddr is reported. TODO: read paddr - rvfi_o[i].mem_paddr = mem_paddr; - rvfi_o[i].mem_wmask = mem_q[commit_pointer[i]].lsu_wmask; - rvfi_o[i].mem_wdata = mem_q[commit_pointer[i]].lsu_wdata; - rvfi_o[i].mem_rmask = mem_q[commit_pointer[i]].lsu_rmask; - rvfi_o[i].mem_rdata = commit_instr[i].result; - rvfi_o[i].rs1_rdata = mem_q[commit_pointer[i]].rs1_rdata; - rvfi_o[i].rs2_rdata = mem_q[commit_pointer[i]].rs2_rdata; + rvfi_instr_o[i].mem_paddr = mem_paddr; + rvfi_instr_o[i].mem_wmask = mem_q[commit_pointer[i]].lsu_wmask; + rvfi_instr_o[i].mem_wdata = mem_q[commit_pointer[i]].lsu_wdata; + rvfi_instr_o[i].mem_rmask = mem_q[commit_pointer[i]].lsu_rmask; + rvfi_instr_o[i].mem_rdata = commit_instr[i].result; + rvfi_instr_o[i].rs1_rdata = mem_q[commit_pointer[i]].rs1_rdata; + rvfi_instr_o[i].rs2_rdata = mem_q[commit_pointer[i]].rs2_rdata; end end + //---------------------------------------------------------------------------------------------------------- + // CSR + //---------------------------------------------------------------------------------------------------------- + + + always_comb begin + + rvfi_csr_o.fflags = CVA6Cfg.FpPresent ? + '{rdata: {'0, csr.fcsr_q.fflags}, wdata: {'0, csr.fcsr_q.fflags}, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.frm = CVA6Cfg.FpPresent ? + '{rdata: {'0, csr.fcsr_q.frm}, wdata: {'0, csr.fcsr_q.frm}, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.fcsr = CVA6Cfg.FpPresent ? + '{ + rdata: {'0, csr.fcsr_q.frm, csr.fcsr_q.fflags}, + wdata: {'0, csr.fcsr_q.frm, csr.fcsr_q.fflags}, + rmask: '1, + wmask: '1 + } + : '0; + rvfi_csr_o.ftran = CVA6Cfg.FpPresent ? + '{rdata: {'0, csr.fcsr_q.fprec}, wdata: {'0, csr.fcsr_q.fprec}, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.dcsr = CVA6Cfg.DebugEn ? + '{rdata: {'0, csr.dcsr_q}, wdata: {'0, csr.dcsr_q}, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.dpc = CVA6Cfg.DebugEn ? + '{rdata: {csr.dpc_q}, wdata: csr.dpc_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.dscratch0 = CVA6Cfg.DebugEn ? + '{rdata: csr.dscratch0_q, wdata: csr.dscratch0_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.dscratch1 = CVA6Cfg.DebugEn ? + '{rdata: csr.dscratch1_q, wdata: csr.dscratch1_q, rmask: '1, wmask: '1} + : '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], + rmask: '1, + wmask: '1 + } + : '0; + rvfi_csr_o.sie = CVA6Cfg.RVS ? + '{rdata: csr.mie_q & csr.mideleg_q, wdata: csr.mie_q & csr.mideleg_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.sip = CVA6Cfg.RVS ? + '{rdata: csr.mip_q & csr.mideleg_q, wdata: csr.mip_q & csr.mideleg_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.stvec = CVA6Cfg.RVS ? + '{rdata: csr.stvec_q, wdata: csr.stvec_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.scounteren = CVA6Cfg.RVS ? + '{rdata: csr.scounteren_q, wdata: csr.scounteren_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.sscratch = CVA6Cfg.RVS ? + '{rdata: csr.sscratch_q, wdata: csr.sscratch_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.sepc = CVA6Cfg.RVS ? + '{rdata: csr.sepc_q, wdata: csr.sepc_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.scause = CVA6Cfg.RVS ? + '{rdata: csr.scause_q, wdata: csr.scause_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.stval = CVA6Cfg.RVS ? + '{rdata: csr.stval_q, wdata: csr.stval_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.satp = CVA6Cfg.RVS ? + '{rdata: csr.satp_q, wdata: csr.satp_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.mstatus = '{ + rdata: csr.mstatus_extended, + wdata: csr.mstatus_extended, + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.mstatush = riscv::XLEN == 32 ? + '{rdata: '0, wdata: '0, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.misa = '{rdata: IsaCode, wdata: IsaCode, rmask: '1, wmask: '1}; + rvfi_csr_o.medeleg = CVA6Cfg.RVS ? + '{rdata: csr.medeleg_q, wdata: csr.medeleg_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.mideleg = CVA6Cfg.RVS ? + '{rdata: csr.mideleg_q, wdata: csr.mideleg_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.mie = '{rdata: csr.mie_q, wdata: csr.mie_q, rmask: '1, wmask: '1}; + rvfi_csr_o.mtvec = '{rdata: csr.mtvec_q, wdata: csr.mtvec_q, rmask: '1, wmask: '1}; + rvfi_csr_o.mcounteren = '{ + rdata: csr.mcounteren_q, + wdata: csr.mcounteren_q, + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.mscratch = '{rdata: csr.mscratch_q, wdata: csr.mscratch_q, rmask: '1, wmask: '1}; + rvfi_csr_o.mepc = '{rdata: csr.mepc_q, wdata: csr.mepc_q, rmask: '1, wmask: '1}; + rvfi_csr_o.mcause = '{rdata: csr.mcause_q, wdata: csr.mcause_q, rmask: '1, wmask: '1}; + rvfi_csr_o.mtval = '{rdata: csr.mtval_q, wdata: csr.mtval_q, rmask: '1, wmask: '1}; + rvfi_csr_o.mip = '{rdata: csr.mip_q, wdata: csr.mip_q, rmask: '1, wmask: '1}; + rvfi_csr_o.menvcfg = '{rdata: {'0, csr.fiom_q}, wdata: {'0, csr.fiom_q}, rmask: '1, wmask: '1}; + rvfi_csr_o.menvcfgh = riscv::XLEN == 32 ? + '{rdata: '0, wdata: '0, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.mvendorid = '{ + rdata: OPENHWGROUP_MVENDORID, + wdata: OPENHWGROUP_MVENDORID, + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.marchid = '{ + rdata: ARIANE_MARCHID, + wdata: ARIANE_MARCHID, + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.mhartid = '{rdata: hart_id_i, wdata: hart_id_i, rmask: '1, wmask: '1}; + rvfi_csr_o.mcountinhibit = '{ + rdata: {'0, csr.mcountinhibit_q}, + wdata: {'0, csr.mcountinhibit_q}, + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.mcycle = '{ + rdata: csr.cycle_q[riscv::XLEN-1:0], + wdata: csr.cycle_q[riscv::XLEN-1:0], + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.mcycleh = riscv::XLEN == 32 ? + '{rdata: csr.cycle_q[63:32], wdata: csr.cycle_q[63:32], rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.minstret = '{ + rdata: csr.instret_q[riscv::XLEN-1:0], + wdata: csr.instret_q[riscv::XLEN-1:0], + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.minstreth = riscv::XLEN == 32 ? + '{rdata: csr.instret_q[63:32], wdata: csr.instret_q[63:32], rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.cycle = '{ + rdata: csr.cycle_q[riscv::XLEN-1:0], + wdata: csr.cycle_q[riscv::XLEN-1:0], + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.cycleh = riscv::XLEN == 32 ? + '{rdata: csr.cycle_q[63:32], wdata: csr.cycle_q[63:32], rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.instret = '{ + rdata: csr.instret_q[riscv::XLEN-1:0], + wdata: csr.instret_q[riscv::XLEN-1:0], + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.instreth = riscv::XLEN == 32 ? + '{rdata: csr.instret_q[63:32], wdata: csr.instret_q[63:32], rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.dcache = '{rdata: csr.dcache_q, wdata: csr.dcache_q, rmask: '1, wmask: '1}; + rvfi_csr_o.icache = '{rdata: csr.icache_q, wdata: csr.icache_q, rmask: '1, wmask: '1}; + rvfi_csr_o.acc_cons = CVA6Cfg.EnableAccelerator ? + '{rdata: csr.acc_cons_q, wdata: csr.acc_cons_q, rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.pmpcfg0 = '{ + rdata: csr.pmpcfg_q[riscv::XLEN/8-1:0], + wdata: csr.pmpcfg_q[riscv::XLEN/8-1:0], + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.pmpcfg1 = riscv::XLEN == 32 ? + '{rdata: csr.pmpcfg_q[7:4], wdata: csr.pmpcfg_q[7:4], rmask: '1, wmask: '1} + : '0; + rvfi_csr_o.pmpcfg2 = '{ + rdata: csr.pmpcfg_q[8+:riscv::XLEN/8], + wdata: csr.pmpcfg_q[8+:riscv::XLEN/8], + rmask: '1, + wmask: '1 + }; + rvfi_csr_o.pmpcfg3 = riscv::XLEN == 32 ? + '{rdata: csr.pmpcfg_q[15:12], wdata: csr.pmpcfg_q[15:12], rmask: '1, wmask: '1} + : '0; + + for (int i = 0; i < 16; i++) begin + rvfi_csr_o.pmpaddr[i] = '{ + rdata: csr.pmpcfg_q[i].addr_mode[1] == 1'b1 ? {'0, csr.pmpaddr_q[i][riscv::PLEN-3:0]} : {'0, csr.pmpaddr_q[i][riscv::PLEN-3:1], 1'b0}, + wdata: csr.pmpcfg_q[i].addr_mode[1] == 1'b1 ? {'0, csr.pmpaddr_q[i][riscv::PLEN-3:0]} : {'0, csr.pmpaddr_q[i][riscv::PLEN-3:1], 1'b0}, + rmask: '1, + wmask: '1 + }; + end; + + end + + endmodule diff --git a/core/cva6_rvfi_probes.sv b/core/cva6_rvfi_probes.sv index 81d2c5df3df..ef717d1f421 100644 --- a/core/cva6_rvfi_probes.sv +++ b/core/cva6_rvfi_probes.sv @@ -14,6 +14,7 @@ module cva6_rvfi_probes #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type rvfi_probes_t = logic + ) ( input logic flush_i, @@ -36,46 +37,76 @@ module cva6_rvfi_probes input exception_t ex_commit_i, input riscv::priv_lvl_t priv_lvl_i, - input lsu_ctrl_t lsu_ctrl_i, - input logic [ CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, - input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, - input logic [ riscv::PLEN-1:0] mem_paddr_i, - input logic debug_mode_i, - input logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata_i, - output rvfi_probes_t rvfi_probes_o + input lsu_ctrl_t lsu_ctrl_i, + input logic [ CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, + input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, + input logic [ riscv::PLEN-1:0] mem_paddr_i, + input logic debug_mode_i, + input logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata_i, + + input rvfi_probes_csr_t csr_i, + + output rvfi_probes_t rvfi_probes_o ); + + rvfi_probes_csr_t csr; + rvfi_probes_instr_t instr; + always_comb begin - rvfi_probes_o = '0; + csr = '0; + instr = '0; - rvfi_probes_o.flush = flush_i; - rvfi_probes_o.issue_instr_ack = issue_instr_ack_i; - rvfi_probes_o.fetch_entry_valid = fetch_entry_valid_i; - rvfi_probes_o.instruction = instruction_i; - rvfi_probes_o.is_compressed = is_compressed_i; + instr.flush = flush_i; + instr.issue_instr_ack = issue_instr_ack_i; + instr.fetch_entry_valid = fetch_entry_valid_i; + instr.instruction = instruction_i; + instr.is_compressed = is_compressed_i; - rvfi_probes_o.issue_pointer = issue_pointer_i; - rvfi_probes_o.commit_pointer = commit_pointer_i; + instr.issue_pointer = issue_pointer_i; - rvfi_probes_o.flush_unissued_instr = flush_unissued_instr_i; - rvfi_probes_o.decoded_instr_valid = decoded_instr_valid_i; - rvfi_probes_o.decoded_instr_ack = decoded_instr_ack_i; + instr.flush_unissued_instr = flush_unissued_instr_i; + instr.decoded_instr_valid = decoded_instr_valid_i; + instr.decoded_instr_ack = decoded_instr_ack_i; - rvfi_probes_o.rs1_forwarding = rs1_forwarding_i; - rvfi_probes_o.rs2_forwarding = rs2_forwarding_i; + instr.rs1_forwarding = rs1_forwarding_i; + instr.rs2_forwarding = rs2_forwarding_i; - rvfi_probes_o.commit_instr = commit_instr_i; - rvfi_probes_o.ex_commit = ex_commit_i; - rvfi_probes_o.priv_lvl = priv_lvl_i; + instr.ex_commit = ex_commit_i; + instr.priv_lvl = priv_lvl_i; - rvfi_probes_o.lsu_ctrl = lsu_ctrl_i; - rvfi_probes_o.wbdata = wbdata_i; - rvfi_probes_o.commit_ack = commit_ack_i; - rvfi_probes_o.mem_paddr = mem_paddr_i; - rvfi_probes_o.debug_mode = debug_mode_i; - rvfi_probes_o.wdata = wdata_i; + instr.lsu_ctrl = lsu_ctrl_i; + instr.wbdata = wbdata_i; + instr.mem_paddr = mem_paddr_i; + instr.debug_mode = debug_mode_i; + + instr.commit_pointer = commit_pointer_i; + instr.commit_instr = commit_instr_i; + instr.commit_ack = commit_ack_i; + instr.wdata = wdata_i; + + csr = csr_i; + + end + + + always_comb begin + rvfi_probes_o = '0; + + if ($bits(rvfi_probes_o.instr) == $bits(instr)) begin + rvfi_probes_o.instr = instr; + end + + if ($bits(rvfi_probes_o.csr) == $bits(csr)) begin + rvfi_probes_o.csr = csr; + end end endmodule + + + + + diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 1616fafa20a..77627e0dc0f 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -673,8 +673,6 @@ package ariane_pkg; // ID/EX/WB Stage // --------------- - localparam RVFI = cva6_config_pkg::CVA6ConfigRvfiTrace; - typedef 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 @@ -834,6 +832,138 @@ package ariane_pkg; logic [DCACHE_USER_WIDTH-1:0] data_ruser; } dcache_req_o_t; + // RVFI instr + typedef struct packed { + logic [TRANS_ID_BITS-1:0] issue_pointer; + logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer; + logic flush_unissued_instr; + logic decoded_instr_valid; + logic decoded_instr_ack; + logic flush; + logic issue_instr_ack; + logic fetch_entry_valid; + logic [31:0] instruction; + logic is_compressed; + riscv::xlen_t rs1_forwarding; + riscv::xlen_t rs2_forwarding; + scoreboard_entry_t [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0] commit_instr; + exception_t ex_commit; + riscv::priv_lvl_t priv_lvl; + lsu_ctrl_t lsu_ctrl; + 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; + logic debug_mode; + logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][riscv::XLEN-1:0] wdata; + } rvfi_probes_instr_t; + + // RVFI CSR element + typedef struct packed { + riscv::xlen_t rdata; + riscv::xlen_t rmask; + riscv::xlen_t wdata; + riscv::xlen_t wmask; + } rvfi_csr_elmt_t; + + // RVFI CSR structure + typedef struct packed { + riscv::fcsr_t fcsr_q; + riscv::dcsr_t dcsr_q; + riscv::xlen_t dpc_q; + riscv::xlen_t dscratch0_q; + riscv::xlen_t dscratch1_q; + riscv::xlen_t mie_q; + riscv::xlen_t mip_q; + riscv::xlen_t stvec_q; + riscv::xlen_t scounteren_q; + riscv::xlen_t sscratch_q; + riscv::xlen_t sepc_q; + riscv::xlen_t scause_q; + riscv::xlen_t stval_q; + riscv::satp_t satp_q; + riscv::xlen_t mstatus_extended; + riscv::xlen_t medeleg_q; + riscv::xlen_t mideleg_q; + riscv::xlen_t mtvec_q; + riscv::xlen_t mcounteren_q; + riscv::xlen_t mscratch_q; + riscv::xlen_t mepc_q; + riscv::xlen_t mcause_q; + riscv::xlen_t mtval_q; + logic fiom_q; + logic [MHPMCounterNum+3-1:0] mcountinhibit_q; + logic [63:0] cycle_q; + logic [63:0] instret_q; + riscv::xlen_t dcache_q; + riscv::xlen_t icache_q; + riscv::xlen_t acc_cons_q; + riscv::pmpcfg_t [15:0] pmpcfg_q; + logic [15:0][riscv::PLEN-3:0] pmpaddr_q; + } rvfi_probes_csr_t; + + // RVFI CSR structure + typedef struct packed { + rvfi_csr_elmt_t fflags; + rvfi_csr_elmt_t frm; + rvfi_csr_elmt_t fcsr; + rvfi_csr_elmt_t ftran; + rvfi_csr_elmt_t dcsr; + rvfi_csr_elmt_t dpc; + rvfi_csr_elmt_t dscratch0; + rvfi_csr_elmt_t dscratch1; + rvfi_csr_elmt_t sstatus; + rvfi_csr_elmt_t sie; + rvfi_csr_elmt_t sip; + rvfi_csr_elmt_t stvec; + rvfi_csr_elmt_t scounteren; + rvfi_csr_elmt_t sscratch; + rvfi_csr_elmt_t sepc; + rvfi_csr_elmt_t scause; + rvfi_csr_elmt_t stval; + rvfi_csr_elmt_t satp; + rvfi_csr_elmt_t mstatus; + rvfi_csr_elmt_t mstatush; + rvfi_csr_elmt_t misa; + rvfi_csr_elmt_t medeleg; + rvfi_csr_elmt_t mideleg; + rvfi_csr_elmt_t mie; + rvfi_csr_elmt_t mtvec; + rvfi_csr_elmt_t mcounteren; + rvfi_csr_elmt_t mscratch; + rvfi_csr_elmt_t mepc; + rvfi_csr_elmt_t mcause; + rvfi_csr_elmt_t mtval; + rvfi_csr_elmt_t mip; + rvfi_csr_elmt_t menvcfg; + rvfi_csr_elmt_t menvcfgh; + rvfi_csr_elmt_t mvendorid; + rvfi_csr_elmt_t marchid; + rvfi_csr_elmt_t mhartid; + rvfi_csr_elmt_t mcountinhibit; + rvfi_csr_elmt_t mcycle; + rvfi_csr_elmt_t mcycleh; + rvfi_csr_elmt_t minstret; + rvfi_csr_elmt_t minstreth; + rvfi_csr_elmt_t cycle; + rvfi_csr_elmt_t cycleh; + rvfi_csr_elmt_t instret; + rvfi_csr_elmt_t instreth; + rvfi_csr_elmt_t dcache; + rvfi_csr_elmt_t icache; + rvfi_csr_elmt_t acc_cons; + rvfi_csr_elmt_t pmpcfg0; + rvfi_csr_elmt_t pmpcfg1; + rvfi_csr_elmt_t pmpcfg2; + rvfi_csr_elmt_t pmpcfg3; + rvfi_csr_elmt_t[15:0] pmpaddr; + + } rvfi_csr_t; + + + localparam RVFI = cva6_config_pkg::CVA6ConfigRvfiTrace; + + + // ---------------------- // Arithmetic Functions // ---------------------- diff --git a/corev_apu/fpga/src/ariane_xilinx.sv b/corev_apu/fpga/src/ariane_xilinx.sv index 7857e5d436a..3bd1845bc62 100644 --- a/corev_apu/fpga/src/ariane_xilinx.sv +++ b/corev_apu/fpga/src/ariane_xilinx.sv @@ -219,8 +219,10 @@ localparam config_pkg::cva6_cfg_t CVA6Cfg = '{ AxiBurstWriteEn: bit'(0) }; -localparam type rvfi_probes_t = logic; - +localparam type rvfi_probes_t = struct packed { + logic csr; + logic instr; + }; // 24 MByte in 8 byte words localparam NumWords = (24 * 1024 * 1024) / 8; @@ -766,7 +768,6 @@ ariane_axi::resp_t axi_ariane_resp; ariane #( .CVA6Cfg ( CVA6Cfg ), - .IsRVFI ( IsRVFI ), .rvfi_probes_t ( rvfi_probes_t ) ) i_ariane ( .clk_i ( clk ), diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index 1ec15ef3d9d..75177e6f6c9 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -15,8 +15,10 @@ module ariane import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter bit IsRVFI = bit'(0), - parameter type rvfi_probes_t = logic, + parameter type rvfi_probes_t = struct packed { + logic csr; + logic instr; + }, parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth, parameter int unsigned AxiDataWidth = ariane_axi::DataWidth, parameter int unsigned AxiIdWidth = ariane_axi::IdWidth, @@ -51,7 +53,6 @@ module ariane import ariane_pkg::*; #( cva6 #( .CVA6Cfg ( CVA6Cfg ), - .IsRVFI ( IsRVFI ), .rvfi_probes_t ( rvfi_probes_t ), .axi_ar_chan_t (axi_ar_chan_t), .axi_aw_chan_t (axi_aw_chan_t), diff --git a/corev_apu/tb/ariane_testharness.sv b/corev_apu/tb/ariane_testharness.sv index 3530da0a9a7..054e513fe67 100644 --- a/corev_apu/tb/ariane_testharness.sv +++ b/corev_apu/tb/ariane_testharness.sv @@ -36,6 +36,8 @@ module ariane_testharness #( localparam [7:0] hart_id = '0; + + // RVFI localparam type rvfi_instr_t = struct packed { logic [config_pkg::NRET-1:0] valid; logic [config_pkg::NRET*64-1:0] order; @@ -61,29 +63,11 @@ module ariane_testharness #( logic [config_pkg::NRET*riscv::XLEN-1:0] mem_rdata; logic [config_pkg::NRET*riscv::XLEN-1:0] mem_wdata; }; - + + localparam type rvfi_probes_t = struct packed { - logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer; - logic [CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] commit_pointer; - logic flush_unissued_instr; - logic decoded_instr_valid; - logic decoded_instr_ack; - logic flush; - logic issue_instr_ack; - logic fetch_entry_valid; - logic [31:0] instruction; - logic is_compressed; - riscv::xlen_t rs1_forwarding; - riscv::xlen_t rs2_forwarding; - ariane_pkg::scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr; - ariane_pkg::exception_t ex_commit; - riscv::priv_lvl_t priv_lvl; - ariane_pkg::lsu_ctrl_t lsu_ctrl; - logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; - logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; - logic [riscv::PLEN-1:0] mem_paddr; - logic debug_mode; - logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata; + ariane_pkg::rvfi_probes_csr_t csr; + ariane_pkg::rvfi_probes_instr_t instr; }; // disable test-enable @@ -651,11 +635,11 @@ module ariane_testharness #( ariane_axi::req_t axi_ariane_req; ariane_axi::resp_t axi_ariane_resp; rvfi_probes_t rvfi_probes; + ariane_pkg::rvfi_csr_t rvfi_csr; rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr; ariane #( .CVA6Cfg ( CVA6Cfg ), - .IsRVFI ( IsRVFI ), .rvfi_probes_t ( rvfi_probes_t ), .noc_req_t ( ariane_axi::req_t ), .noc_resp_t ( ariane_axi::resp_t ) @@ -698,20 +682,25 @@ module ariane_testharness #( end end + + cva6_rvfi #( .CVA6Cfg (CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), + .rvfi_csr_t(ariane_pkg::rvfi_csr_t), .rvfi_probes_t(rvfi_probes_t) ) i_cva6_rvfi ( .clk_i (clk_i), .rst_ni (rst_ni), .rvfi_probes_i(rvfi_probes), - .rvfi_o(rvfi_instr) + .rvfi_instr_o(rvfi_instr), + .rvfi_csr_o(rvfi_csr) ); rvfi_tracer #( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), + .rvfi_csr_t(ariane_pkg::rvfi_csr_t), // .HART_ID(hart_id), .DEBUG_START(0), @@ -720,6 +709,7 @@ module ariane_testharness #( .clk_i(clk_i), .rst_ni(rst_ni), .rvfi_i(rvfi_instr), + .rvfi_csr_i(rvfi_csr), .end_of_test_o(rvfi_exit) ); diff --git a/corev_apu/tb/rvfi_tracer.sv b/corev_apu/tb/rvfi_tracer.sv index 75f68beb576..9faf6a6f76b 100644 --- a/corev_apu/tb/rvfi_tracer.sv +++ b/corev_apu/tb/rvfi_tracer.sv @@ -10,6 +10,7 @@ module rvfi_tracer #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type rvfi_instr_t = logic, + parameter type rvfi_csr_t = logic, // parameter logic [7:0] HART_ID = '0, parameter int unsigned DEBUG_START = 0, @@ -18,6 +19,7 @@ module rvfi_tracer #( input logic clk_i, input logic rst_ni, input rvfi_instr_t[CVA6Cfg.NrCommitPorts-1:0] rvfi_i, + input rvfi_csr_t rvfi_csr_i, output logic[31:0] end_of_test_o ); diff --git a/pd/synth/cva6_synth.tcl b/pd/synth/cva6_synth.tcl index 5ba39d4234d..d05c2e2859c 100644 --- a/pd/synth/cva6_synth.tcl +++ b/pd/synth/cva6_synth.tcl @@ -58,6 +58,9 @@ set_output_delay $output_delay -max -clock main_clk i_cache_subsystem/i_wt_dcach set_output_delay $output_delay -max -clock main_clk i_cache_subsystem/i_cva6_icache/gen_sram_*__data_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/addr_i[*] set_output_delay $output_delay -max -clock main_clk i_cache_subsystem/i_cva6_icache/gen_sram_*__tag_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/addr_i[*] + +set_false_path -to [get_ports {rvfi_probes_o}] + # Check the current design for consistency check_design -summary > ${DCRM_CHECK_DESIGN_REPORT} diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index 011b84b753d..8d463e0c861 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -36,8 +36,8 @@ import "DPI-C" context function void read_section_sv(input longint address, inou module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter bit IsRVFI = 1'b0, parameter type rvfi_instr_t = logic, + parameter type rvfi_csr_t = logic, // parameter int unsigned AXI_USER_EN = 0, parameter int unsigned NUM_WORDS = 2**25 @@ -47,6 +47,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( input logic [XLEN-1:0] boot_addr_i, output logic [31:0] tb_exit_o, output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o, + output rvfi_csr_t rvfi_csr_o, input cvxif_pkg::cvxif_resp_t cvxif_resp, output cvxif_pkg::cvxif_req_t cvxif_req, uvma_axi_intf axi_slave, @@ -54,31 +55,11 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( uvmt_default_inputs_intf default_inputs_vif ); - localparam type rvfi_probes_t = struct packed { - logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer; - logic [CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] commit_pointer; - logic flush_unissued_instr; - logic decoded_instr_valid; - logic decoded_instr_ack; - logic flush; - logic issue_instr_ack; - logic fetch_entry_valid; - logic [31:0] instruction; - logic is_compressed; - riscv::xlen_t rs1_forwarding; - riscv::xlen_t rs2_forwarding; - ariane_pkg::scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr; - ariane_pkg::exception_t ex_commit; - riscv::priv_lvl_t priv_lvl; - ariane_pkg::lsu_ctrl_t lsu_ctrl; - logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; - logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; - logic [riscv::PLEN-1:0] mem_paddr; - logic debug_mode; - logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata; + ariane_pkg::rvfi_probes_csr_t csr; + ariane_pkg::rvfi_probes_instr_t instr; }; - + ariane_axi::req_t axi_ariane_req; ariane_axi::resp_t axi_ariane_resp; @@ -87,13 +68,14 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr; rvfi_probes_t rvfi_probes; + rvfi_csr_t rvfi_csr; assign rvfi_o = rvfi_instr; - + assign rvfi_csr_o = rvfi_csr; + cva6 #( .CVA6Cfg ( CVA6Cfg ), - .rvfi_probes_t ( rvfi_probes_t ), - .IsRVFI ( IsRVFI ) - ) i_cva6 ( + .rvfi_probes_t ( rvfi_probes_t ) + ) i_cva6 ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .boot_addr_i ( boot_addr_i ),//Driving the boot_addr value from the core control agent @@ -116,17 +98,20 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( cva6_rvfi #( .CVA6Cfg (CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), + .rvfi_csr_t(rvfi_csr_t), .rvfi_probes_t(rvfi_probes_t) ) i_cva6_rvfi ( .clk_i (clk_i), .rst_ni (rst_ni), .rvfi_probes_i(rvfi_probes), - .rvfi_o(rvfi_instr) + .rvfi_instr_o(rvfi_instr), + .rvfi_csr_o(rvfi_csr) ); rvfi_tracer #( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), + .rvfi_csr_t(rvfi_csr_t), // .HART_ID(8'h0), .DEBUG_START(0), @@ -135,6 +120,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( .clk_i(clk_i), .rst_ni(rst_ni), .rvfi_i(rvfi_instr), + .rvfi_csr_i(rvfi_csr), .end_of_test_o(tb_exit_o) ) ; diff --git a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv index bd9d2b62029..d580b251d1d 100644 --- a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv +++ b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv @@ -16,8 +16,8 @@ module uvmt_cva6_dut_wrap # ( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter bit IsRVFI = 1'b0, parameter type rvfi_instr_t = logic, + parameter type rvfi_csr_t = logic, // parameter int unsigned AXI_USER_EN = 0, parameter int unsigned NUM_WORDS = 2**25 @@ -31,15 +31,16 @@ module uvmt_cva6_dut_wrap # ( uvmt_default_inputs_intf default_inputs_vif, uvme_cva6_core_cntrl_if core_cntrl_if, output logic[31:0] tb_exit_o, - output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o + output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o, + output rvfi_csr_t rvfi_csr_o ); cva6_tb_wrapper #( .CVA6Cfg ( CVA6Cfg ), - .IsRVFI ( IsRVFI ), - .rvfi_instr_t ( rvfi_instr_t ), + .rvfi_instr_t ( rvfi_instr_t ), + .rvfi_csr_t ( rvfi_csr_t ), // .AXI_USER_EN (AXI_USER_EN), .NUM_WORDS (NUM_WORDS) @@ -54,6 +55,7 @@ module uvmt_cva6_dut_wrap # ( .axi_switch_vif ( axi_switch_vif ), .default_inputs_vif ( default_inputs_vif ), .tb_exit_o ( tb_exit_o ), + .rvfi_csr_o ( rvfi_csr_o ), .rvfi_o ( rvfi_o ) ); diff --git a/verif/tb/uvmt/uvmt_cva6_tb.sv b/verif/tb/uvmt/uvmt_cva6_tb.sv index 31f8fe6741c..4d8aedfff14 100644 --- a/verif/tb/uvmt/uvmt_cva6_tb.sv +++ b/verif/tb/uvmt/uvmt_cva6_tb.sv @@ -34,7 +34,9 @@ module uvmt_cva6_tb; // CVA6 config localparam config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg; - localparam bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace); + + // RVFI + localparam type rvfi_instr_t = struct packed { logic [config_pkg::NRET-1:0] valid; logic [config_pkg::NRET*64-1:0] order; @@ -60,7 +62,7 @@ module uvmt_cva6_tb; logic [config_pkg::NRET*riscv::XLEN-1:0] mem_rdata; logic [config_pkg::NRET*riscv::XLEN-1:0] mem_wdata; }; - + localparam AXI_USER_EN = ariane_pkg::AXI_USER_EN; localparam NUM_WORDS = 2**24; @@ -115,9 +117,9 @@ module uvmt_cva6_tb; */ uvmt_cva6_dut_wrap #( - .CVA6Cfg ( CVA6Cfg ), - .IsRVFI ( IsRVFI ), - .rvfi_instr_t ( rvfi_instr_t ), + .CVA6Cfg ( CVA6Cfg ), + .rvfi_instr_t ( rvfi_instr_t ), + .rvfi_csr_t ( ariane_pkg::rvfi_csr_t ), // .AXI_USER_EN (AXI_USER_EN), .NUM_WORDS (NUM_WORDS) @@ -129,7 +131,8 @@ module uvmt_cva6_tb; .default_inputs_vif (default_inputs_vif), .core_cntrl_if(core_cntrl_if), .tb_exit_o(rvfi_if.tb_exit_o), - .rvfi_o(rvfi_if.rvfi_o) + .rvfi_o(rvfi_if.rvfi_o), + .rvfi_csr_o() ); for (genvar i = 0; i < RVFI_NRET; i++) begin