mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 06:07:19 -04:00
add csr in rvfi (#1833)
This commit is contained in:
parent
68f952b44c
commit
1dec79464e
14 changed files with 776 additions and 421 deletions
|
@ -1,4 +1,4 @@
|
|||
cv32a6_embedded:
|
||||
gates: 110087
|
||||
gates: 110738
|
||||
cv32a65x:
|
||||
gates: 109501
|
||||
gates: 110129
|
||||
|
|
|
@ -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 virtual address translation - EX_STAGE
|
||||
output logic en_translation_o,
|
||||
output logic en_translation_o,
|
||||
// Enable virtual address 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,
|
||||
// Supervisor User Memory - EX_STAGE
|
||||
output logic sum_o,
|
||||
output logic sum_o,
|
||||
// Make Executable Readable - 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;
|
||||
|
||||
|
@ -1673,23 +1676,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
|
||||
|
@ -1705,4 +1714,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
|
||||
|
|
180
core/cva6.sv
180
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 we_csr_perf;
|
||||
|
||||
logic icache_flush_ctrl_cache;
|
||||
logic itlb_miss_ex_perf;
|
||||
logic dtlb_miss_ex_perf;
|
||||
logic dcache_miss_cache_perf;
|
||||
logic icache_miss_cache_perf;
|
||||
logic [ NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
||||
logic stall_issue;
|
||||
logic icache_flush_ctrl_cache;
|
||||
logic itlb_miss_ex_perf;
|
||||
logic dtlb_miss_ex_perf;
|
||||
logic dcache_miss_cache_perf;
|
||||
logic icache_miss_cache_perf;
|
||||
logic [ NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
||||
logic stall_issue;
|
||||
// --------------
|
||||
// CTRL <-> *
|
||||
// --------------
|
||||
logic set_pc_ctrl_pcgen;
|
||||
logic flush_csr_ctrl;
|
||||
logic flush_unissued_instr_ctrl_id;
|
||||
logic flush_ctrl_if;
|
||||
logic flush_ctrl_id;
|
||||
logic flush_ctrl_ex;
|
||||
logic flush_ctrl_bp;
|
||||
logic flush_tlb_ctrl_ex;
|
||||
logic fence_i_commit_controller;
|
||||
logic fence_commit_controller;
|
||||
logic sfence_vma_commit_controller;
|
||||
logic halt_ctrl;
|
||||
logic halt_csr_ctrl;
|
||||
logic dcache_flush_ctrl_cache;
|
||||
logic dcache_flush_ack_cache_ctrl;
|
||||
logic set_debug_pc;
|
||||
logic flush_commit;
|
||||
logic flush_acc;
|
||||
logic set_pc_ctrl_pcgen;
|
||||
logic flush_csr_ctrl;
|
||||
logic flush_unissued_instr_ctrl_id;
|
||||
logic flush_ctrl_if;
|
||||
logic flush_ctrl_id;
|
||||
logic flush_ctrl_ex;
|
||||
logic flush_ctrl_bp;
|
||||
logic flush_tlb_ctrl_ex;
|
||||
logic fence_i_commit_controller;
|
||||
logic fence_commit_controller;
|
||||
logic sfence_vma_commit_controller;
|
||||
logic halt_ctrl;
|
||||
logic halt_csr_ctrl;
|
||||
logic dcache_flush_ctrl_cache;
|
||||
logic dcache_flush_ack_cache_ctrl;
|
||||
logic set_debug_pc;
|
||||
logic flush_commit;
|
||||
logic flush_acc;
|
||||
|
||||
icache_areq_t icache_areq_ex_cache;
|
||||
icache_arsp_t icache_areq_cache_ex;
|
||||
icache_dreq_t icache_dreq_if_cache;
|
||||
icache_drsp_t icache_dreq_cache_if;
|
||||
icache_areq_t icache_areq_ex_cache;
|
||||
icache_arsp_t icache_areq_cache_ex;
|
||||
icache_dreq_t icache_dreq_if_cache;
|
||||
icache_drsp_t icache_dreq_cache_if;
|
||||
|
||||
amo_req_t amo_req;
|
||||
amo_resp_t amo_resp;
|
||||
logic sb_full;
|
||||
amo_req_t amo_req;
|
||||
amo_resp_t amo_resp;
|
||||
logic sb_full;
|
||||
|
||||
// ----------------
|
||||
// DCache <-> *
|
||||
// ----------------
|
||||
dcache_req_i_t [ 2:0] dcache_req_ports_ex_cache;
|
||||
dcache_req_o_t [ 2:0] dcache_req_ports_cache_ex;
|
||||
dcache_req_i_t [ 1:0] dcache_req_ports_acc_cache;
|
||||
dcache_req_o_t [ 1:0] dcache_req_ports_cache_acc;
|
||||
logic dcache_commit_wbuffer_empty;
|
||||
logic dcache_commit_wbuffer_not_ni;
|
||||
dcache_req_i_t [ 2:0] dcache_req_ports_ex_cache;
|
||||
dcache_req_o_t [ 2:0] dcache_req_ports_cache_ex;
|
||||
dcache_req_i_t [ 1:0] dcache_req_ports_acc_cache;
|
||||
dcache_req_o_t [ 1:0] dcache_req_ports_cache_acc;
|
||||
logic dcache_commit_wbuffer_empty;
|
||||
logic dcache_commit_wbuffer_not_ni;
|
||||
|
||||
//RVFI
|
||||
lsu_ctrl_t rvfi_lsu_ctrl;
|
||||
logic [riscv::PLEN-1:0] rvfi_mem_paddr;
|
||||
logic rvfi_is_compressed;
|
||||
rvfi_probes_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
|
||||
|
|
|
@ -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 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 bit EnableAccelerator = CVA6Cfg.RVV; // Currently only used by V extension (Ara)
|
||||
localparam int unsigned NrWbPorts = (CVA6Cfg.CvxifEn || EnableAccelerator) ? 5 : 4;
|
||||
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;
|
||||
|
||||
localparam NrRgprPorts = 2;
|
||||
logic [TRANS_ID_BITS-1:0] issue_pointer;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer;
|
||||
|
||||
localparam bit NonIdemPotenceEn = CVA6Cfg.NrNonIdempotentRules && CVA6Cfg.NonIdempotentLength; // Currently only used by V extension (Ara)
|
||||
logic flush_unissued_instr;
|
||||
logic decoded_instr_valid;
|
||||
logic decoded_instr_ack;
|
||||
|
||||
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
|
||||
};
|
||||
riscv::xlen_t rs1_forwarding;
|
||||
riscv::xlen_t rs2_forwarding;
|
||||
|
||||
logic flush;
|
||||
logic issue_instr_ack;
|
||||
logic fetch_entry_valid;
|
||||
logic [ 31:0] instruction;
|
||||
logic is_compressed;
|
||||
scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr;
|
||||
exception_t ex_commit;
|
||||
riscv::priv_lvl_t priv_lvl;
|
||||
|
||||
logic [ TRANS_ID_BITS-1:0] issue_pointer;
|
||||
logic [CVA6ExtendCfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] commit_pointer;
|
||||
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 flush_unissued_instr;
|
||||
logic decoded_instr_valid;
|
||||
logic decoded_instr_ack;
|
||||
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::xlen_t rs1_forwarding;
|
||||
riscv::xlen_t rs2_forwarding;
|
||||
riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d;
|
||||
|
||||
scoreboard_entry_t [CVA6ExtendCfg.NrCommitPorts-1:0] commit_instr;
|
||||
exception_t ex_commit;
|
||||
riscv::priv_lvl_t priv_lvl;
|
||||
rvfi_probes_csr_t csr;
|
||||
rvfi_probes_instr_t instr;
|
||||
|
||||
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;
|
||||
always_comb begin
|
||||
csr = '0;
|
||||
instr = '0;
|
||||
|
||||
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;
|
||||
if ($bits(rvfi_probes_i.instr) == $bits(instr)) begin
|
||||
instr = rvfi_probes_i.instr;
|
||||
end
|
||||
|
||||
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;
|
||||
if ($bits(rvfi_probes_i.csr) == $bits(csr)) begin
|
||||
csr = rvfi_probes_i.csr;
|
||||
end
|
||||
|
||||
assign issue_pointer = rvfi_probes_i.issue_pointer;
|
||||
assign commit_pointer = rvfi_probes_i.commit_pointer;
|
||||
end
|
||||
|
||||
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 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 commit_instr = rvfi_probes_i.commit_instr;
|
||||
assign ex_commit = rvfi_probes_i.ex_commit;
|
||||
assign priv_lvl = rvfi_probes_i.priv_lvl;
|
||||
assign issue_pointer = instr.issue_pointer;
|
||||
assign commit_pointer = instr.commit_pointer;
|
||||
|
||||
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;
|
||||
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,252 @@ 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
|
||||
|
|
|
@ -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
|
||||
csr = '0;
|
||||
instr = '0;
|
||||
|
||||
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;
|
||||
|
||||
instr.issue_pointer = issue_pointer_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;
|
||||
|
||||
instr.rs1_forwarding = rs1_forwarding_i;
|
||||
instr.rs2_forwarding = rs2_forwarding_i;
|
||||
|
||||
instr.ex_commit = ex_commit_i;
|
||||
instr.priv_lvl = priv_lvl_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;
|
||||
|
||||
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;
|
||||
if ($bits(rvfi_probes_o.instr) == $bits(instr)) begin
|
||||
rvfi_probes_o.instr = instr;
|
||||
end
|
||||
|
||||
rvfi_probes_o.issue_pointer = issue_pointer_i;
|
||||
rvfi_probes_o.commit_pointer = commit_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;
|
||||
|
||||
rvfi_probes_o.rs1_forwarding = rs1_forwarding_i;
|
||||
rvfi_probes_o.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;
|
||||
|
||||
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;
|
||||
if ($bits(rvfi_probes_o.csr) == $bits(csr)) begin
|
||||
rvfi_probes_o.csr = csr;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
// ----------------------
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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)
|
||||
) ;
|
||||
|
||||
|
|
|
@ -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 )
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue