diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 880736e0e..11f7ea7f4 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1156,6 +1156,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; event e_ex_to_wb_1, e_ex_to_wb_2; event e_id_to_ex_1, e_id_to_ex_2; event e_commit_dpc; + event e_csr_in_ex, e_csr_irq; event e_send_rvfi_trace_apu_resp; event @@ -1181,6 +1182,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(apu_resp, mstatus_fs) + if (r_pipe_freeze_trace.csr.mstatus_fs_we && (trace_id.m_order > trace_apu_resp.m_order)) begin + trace_id.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end if (r_pipe_freeze_trace.csr.mstatus_fs_we && (trace_ex.m_order > trace_apu_resp.m_order)) begin trace_ex.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; end @@ -1424,8 +1428,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_new_valid_insn = r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.is_decoding;// && !r_pipe_freeze_trace.apu_rvalid; s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX));// && !r_pipe_freeze_trace.apu_rvalid;; - s_ex_reg_we_adjusted = r_pipe_freeze_trace.ex_reg_we && r_pipe_freeze_trace.mult_ready && r_pipe_freeze_trace.alu_ready && r_pipe_freeze_trace.lsu_ready_ex; - s_rf_we_wb_adjusted = r_pipe_freeze_trace.rf_we_wb && (~r_pipe_freeze_trace.data_misaligned_ex && r_pipe_freeze_trace.wb_ready); + s_ex_reg_we_adjusted = r_pipe_freeze_trace.ex_reg_we && r_pipe_freeze_trace.mult_ready && r_pipe_freeze_trace.alu_ready && r_pipe_freeze_trace.lsu_ready_ex && !s_apu_to_alu_port; + s_rf_we_wb_adjusted = r_pipe_freeze_trace.rf_we_wb && (~r_pipe_freeze_trace.data_misaligned_ex && r_pipe_freeze_trace.wb_ready) && (!s_apu_to_lsu_port || r_pipe_freeze_trace.wb_contention_lsu); s_fflags_we_non_apu = 1'b0; if (r_pipe_freeze_trace.csr.fflags_we) begin @@ -1521,7 +1525,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; minstret_to_ex(); end - if (s_rf_we_wb_adjusted && !s_apu_to_lsu_port) begin + if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_1; if (trace_ex.m_got_ex_reg) begin trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; @@ -1561,7 +1565,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_valid = 1'b0; end end - end else if (s_rf_we_wb_adjusted && !s_apu_to_lsu_port && !s_was_flush) begin + end else if (s_rf_we_wb_adjusted && !s_was_flush) begin ->e_dev_commit_rf_to_ex_2; if (trace_ex.m_got_ex_reg) begin trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; @@ -1579,19 +1583,23 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); //EX_STAGE if (trace_id.m_valid) begin + + if(trace_id.m_sample_csr_write_in_ex && !csr_is_irq && !s_is_irq_start) begin //First cycle after id_ready, csr write is asserted in this cycle + `CSR_FROM_PIPE(id, mstatus) + `CSR_FROM_PIPE(id, mstatus_fs) + `CSR_FROM_PIPE(id, mepc) + `CSR_FROM_PIPE(id, mcause) + ->e_csr_in_ex; + end + + if(r_pipe_freeze_trace.is_decoding) begin + trace_id.m_sample_csr_write_in_ex = 1'b0; + end mtvec_to_id(); `CSR_FROM_PIPE(id, mip) `CSR_FROM_PIPE(id, misa) - if (!csr_is_irq && !s_is_irq_start) begin - mstatus_to_id(); - `CSR_FROM_PIPE(id, mepc) - if (trace_id.m_csr.mcause_we == '0) begin //for debug purpose - `CSR_FROM_PIPE(id, mcause) - end - end - `CSR_FROM_PIPE(id, mcountinhibit) `CSR_FROM_PIPE(id, mscratch) `CSR_FROM_PIPE(id, mie) @@ -1802,6 +1810,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; mstatus_to_id(); `CSR_FROM_PIPE(id, mepc) `CSR_FROM_PIPE(id, mcause) + ->e_csr_irq; end if (!s_id_done && r_pipe_freeze_trace.is_decoding) begin diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index 3db2a7ee0..3fe7c1848 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -66,6 +66,8 @@ int m_instret_cnt; + bit m_sample_csr_write_in_ex; + struct { logic [31:0] addr ; logic [ 3:0] rmask; @@ -145,32 +147,33 @@ function new(); - this.m_order = 0; - this.m_skip_order = 1'b0; - this.m_valid = 1'b0; - this.m_move_down_pipe = 1'b0; - this.m_data_missaligned = 1'b0; - this.m_got_first_data = 1'b0; - this.m_got_ex_reg = 1'b0; - this.m_intr = '0; - this.m_dbg_taken = 1'b0; - this.m_dbg_cause = '0; - this.m_is_ebreak = '0; - this.m_is_illegal = '0; - this.m_is_irq = '0; - this.m_is_memory = 1'b0; - this.m_is_load = 1'b0; - this.m_is_apu = 1'b0; - this.m_is_apu_ok = 1'b0; - this.m_apu_req_id = 0; - this.m_mem_req_id[0] = 0; - this.m_mem_req_id[1] = 0; - this.m_mem_req_id_valid = '0; - this.m_trap = 1'b0; - this.m_fflags_we_non_apu = 1'b0; - this.m_frm_we_non_apu = 1'b0; - this.m_fcsr_we_non_apu = 1'b0; - this.m_instret_cnt = 0; + this.m_order = 0; + this.m_skip_order = 1'b0; + this.m_valid = 1'b0; + this.m_move_down_pipe = 1'b0; + this.m_data_missaligned = 1'b0; + this.m_got_first_data = 1'b0; + this.m_got_ex_reg = 1'b0; + this.m_intr = '0; + this.m_dbg_taken = 1'b0; + this.m_dbg_cause = '0; + this.m_is_ebreak = '0; + this.m_is_illegal = '0; + this.m_is_irq = '0; + this.m_is_memory = 1'b0; + this.m_is_load = 1'b0; + this.m_is_apu = 1'b0; + this.m_is_apu_ok = 1'b0; + this.m_apu_req_id = 0; + this.m_mem_req_id[0] = 0; + this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; + this.m_trap = 1'b0; + this.m_fflags_we_non_apu = 1'b0; + this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; + this.m_instret_cnt = 0; + this.m_sample_csr_write_in_ex = 1'b1; endfunction function void get_mnemonic(); @@ -875,37 +878,38 @@ if(this.m_skip_order) begin this.m_order = this.m_order + 64'h1; end - this.m_skip_order = 1'b0; - this.m_pc_rdata = r_pipe_freeze_trace.pc_id; - this.m_is_illegal = 1'b0; - this.m_is_irq = 1'b0; - this.m_is_memory = 1'b0; - this.m_is_load = 1'b0; - this.m_is_apu = 1'b0; - this.m_is_apu_ok = 1'b0; - this.m_apu_req_id = 0; - this.m_mem_req_id[0] = 0; - this.m_mem_req_id[1] = 0; - this.m_mem_req_id_valid = '0; - this.m_data_missaligned = 1'b0; - this.m_got_first_data = 1'b0; - this.m_got_ex_reg = 1'b0; - this.m_got_regs_write = 1'b0; - this.m_move_down_pipe = 1'b0; - this.m_instret_cnt = 0; - this.m_rd_addr[0] = '0; - this.m_rd_addr[1] = '0; - this.m_2_rd_insn = 1'b0; - this.m_rs1_addr = '0; - this.m_rs2_addr = '0; - this.m_rs3_addr = '0; - this.m_ex_fw = '0; - this.m_csr.got_minstret = '0; - this.m_dbg_taken = '0; - this.m_trap = 1'b0; - this.m_fflags_we_non_apu = 1'b0; - this.m_frm_we_non_apu = 1'b0; - this.m_fcsr_we_non_apu = 1'b0; + this.m_skip_order = 1'b0; + this.m_pc_rdata = r_pipe_freeze_trace.pc_id; + this.m_is_illegal = 1'b0; + this.m_is_irq = 1'b0; + this.m_is_memory = 1'b0; + this.m_is_load = 1'b0; + this.m_is_apu = 1'b0; + this.m_is_apu_ok = 1'b0; + this.m_apu_req_id = 0; + this.m_mem_req_id[0] = 0; + this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; + this.m_data_missaligned = 1'b0; + this.m_got_first_data = 1'b0; + this.m_got_ex_reg = 1'b0; + this.m_got_regs_write = 1'b0; + this.m_move_down_pipe = 1'b0; + this.m_instret_cnt = 0; + this.m_sample_csr_write_in_ex = 1'b1; + this.m_rd_addr[0] = '0; + this.m_rd_addr[1] = '0; + this.m_2_rd_insn = 1'b0; + this.m_rs1_addr = '0; + this.m_rs2_addr = '0; + this.m_rs3_addr = '0; + this.m_ex_fw = '0; + this.m_csr.got_minstret = '0; + this.m_dbg_taken = '0; + this.m_trap = 1'b0; + this.m_fflags_we_non_apu = 1'b0; + this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; this.m_csr.mcause_we = '0; if (is_compressed_id_i) begin this.m_insn[31:16] = '0; @@ -944,47 +948,48 @@ endfunction function void copy_full(insn_trace_t m_source); - this.m_valid = m_source.m_valid; - this.m_stage = m_source.m_stage; - this.m_order = m_source.m_order; - this.m_pc_rdata = m_source.m_pc_rdata; - this.m_insn = m_source.m_insn; - this.m_mnemonic = m_source.m_mnemonic; - this.m_is_memory = m_source.m_is_memory; - this.m_is_load = m_source.m_is_load; - this.m_is_apu = m_source.m_is_apu; - this.m_is_apu_ok = m_source.m_is_apu_ok; - this.m_apu_req_id = m_source.m_apu_req_id; - this.m_mem_req_id = m_source.m_mem_req_id; - this.m_mem_req_id_valid = m_source.m_mem_req_id_valid; - this.m_data_missaligned = m_source.m_data_missaligned; - this.m_got_first_data = m_source.m_got_first_data; - this.m_got_ex_reg = m_source.m_got_ex_reg; - this.m_dbg_taken = m_source.m_dbg_taken; - this.m_dbg_cause = m_source.m_dbg_cause; - this.m_is_ebreak = m_source.m_is_ebreak; - this.m_is_illegal = m_source.m_is_illegal; - this.m_is_irq = m_source.m_is_irq; - this.m_instret_cnt = m_source.m_instret_cnt; - this.m_rs1_addr = m_source.m_rs1_addr; - this.m_rs2_addr = m_source.m_rs2_addr; - this.m_rs3_addr = m_source.m_rs3_addr; - this.m_rs1_rdata = m_source.m_rs1_rdata; - this.m_rs2_rdata = m_source.m_rs2_rdata; - this.m_rs3_rdata = m_source.m_rs3_rdata; - - this.m_ex_fw = m_source.m_ex_fw; - this.m_rd_addr = m_source.m_rd_addr; - this.m_2_rd_insn = m_source.m_2_rd_insn; - this.m_rd_wdata = m_source.m_rd_wdata; - - this.m_intr = m_source.m_intr; - this.m_trap = m_source.m_trap; - this.m_fflags_we_non_apu = m_source.m_fflags_we_non_apu; - this.m_frm_we_non_apu = m_source.m_frm_we_non_apu ; - this.m_fcsr_we_non_apu = m_source.m_fcsr_we_non_apu; - - this.m_mem = m_source.m_mem; + this.m_valid = m_source.m_valid; + this.m_stage = m_source.m_stage; + this.m_order = m_source.m_order; + this.m_pc_rdata = m_source.m_pc_rdata; + this.m_insn = m_source.m_insn; + this.m_mnemonic = m_source.m_mnemonic; + this.m_is_memory = m_source.m_is_memory; + this.m_is_load = m_source.m_is_load; + this.m_is_apu = m_source.m_is_apu; + this.m_is_apu_ok = m_source.m_is_apu_ok; + this.m_apu_req_id = m_source.m_apu_req_id; + this.m_mem_req_id = m_source.m_mem_req_id; + this.m_mem_req_id_valid = m_source.m_mem_req_id_valid; + this.m_data_missaligned = m_source.m_data_missaligned; + this.m_got_first_data = m_source.m_got_first_data; + this.m_got_ex_reg = m_source.m_got_ex_reg; + this.m_dbg_taken = m_source.m_dbg_taken; + this.m_dbg_cause = m_source.m_dbg_cause; + this.m_is_ebreak = m_source.m_is_ebreak; + this.m_is_illegal = m_source.m_is_illegal; + this.m_is_irq = m_source.m_is_irq; + this.m_instret_cnt = m_source.m_instret_cnt; + this.m_sample_csr_write_in_ex = m_source.m_sample_csr_write_in_ex; + this.m_rs1_addr = m_source.m_rs1_addr; + this.m_rs2_addr = m_source.m_rs2_addr; + this.m_rs3_addr = m_source.m_rs3_addr; + this.m_rs1_rdata = m_source.m_rs1_rdata; + this.m_rs2_rdata = m_source.m_rs2_rdata; + this.m_rs3_rdata = m_source.m_rs3_rdata; + + this.m_ex_fw = m_source.m_ex_fw; + this.m_rd_addr = m_source.m_rd_addr; + this.m_2_rd_insn = m_source.m_2_rd_insn; + this.m_rd_wdata = m_source.m_rd_wdata; + + this.m_intr = m_source.m_intr; + this.m_trap = m_source.m_trap; + this.m_fflags_we_non_apu = m_source.m_fflags_we_non_apu; + this.m_frm_we_non_apu = m_source.m_frm_we_non_apu ; + this.m_fcsr_we_non_apu = m_source.m_fcsr_we_non_apu; + + this.m_mem = m_source.m_mem; //CRS `ASSIGN_CSR(mstatus) `ASSIGN_CSR(mstatus_fs) diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index b5bea9bb3..0fa15f5f5 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -360,7 +360,10 @@ function compute_csr_we(); CSR_MEPC: r_pipe_freeze_trace.csr.mepc_we = 1'b1; CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = 1'b1; CSR_DCSR: r_pipe_freeze_trace.csr.dcsr_we = 1'b1; - CSR_FFLAGS: r_pipe_freeze_trace.csr.fflags_we = 1'b1; + CSR_FFLAGS: begin + r_pipe_freeze_trace.csr.fflags_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end CSR_FRM: r_pipe_freeze_trace.csr.frm_we = 1'b1; CSR_FCSR: r_pipe_freeze_trace.csr.fcsr_we = 1'b1; CSR_DPC: r_pipe_freeze_trace.csr.dpc_we = 1'b1;