From 17b972fe92ae71a1243b9a0b4134942872a2cab7 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 4 Jan 2024 17:25:14 +0100 Subject: [PATCH 1/2] RVFI - Better xret handling --- bhv/cv32e40p_rvfi.sv | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index d3ba8e837..5ddb8695d 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1287,7 +1287,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_is_irq_start = 1'b0; trace_if.m_valid = 1'b0; s_id_done = 1'b0; - `CSR_FROM_PIPE(id, dpc) + // `CSR_FROM_PIPE(id, dpc) endfunction function logic [31:0] be_to_mask(logic [3:0] be); @@ -1578,8 +1578,18 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; // If mret, we need to keep the instruction in Id during flush_ex because mstatus update happens at that time 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.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || ((r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) && !r_pipe_freeze_trace.mret_insn_dec)); //EX_STAGE - if (trace_id.m_valid) begin + // if(trace_id.m_valid && r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin //xret done, we send it to rvfi + // `CSR_FROM_PIPE(id, mip) + // `CSR_FROM_PIPE(id, misa) + // `CSR_FROM_PIPE(id, mstatus) + // `CSR_FROM_PIPE(id, mstatus_fs) + // tinfo_to_id(); + + // send_rvfi(trace_id); + // trace_id.m_valid = 1'b0; + // end + 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) @@ -1587,6 +1597,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, mcause) `CSR_FROM_PIPE(id, dscratch0) `CSR_FROM_PIPE(id, dscratch1) + `CSR_FROM_PIPE(id, dpc) ->e_csr_in_ex; end @@ -1606,9 +1617,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, frm) `CSR_FROM_PIPE(id, fcsr) - if (r_pipe_freeze_trace.csr.we) begin - `CSR_FROM_PIPE(id, dpc) - end + // if (r_pipe_freeze_trace.csr.we) begin + // `CSR_FROM_PIPE(id, dpc) + // end if (r_pipe_freeze_trace.csr.dcsr_we) begin dcsr_to_id(); @@ -1630,6 +1641,15 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_csr.frm_wmask = '0; trace_ex.m_csr.fcsr_wmask = '0; + if(r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin + tinfo_to_id(); + minstret_to_id(); + `CSR_FROM_PIPE(id, tdata1) + `CSR_FROM_PIPE(id, tdata2) + send_rvfi(trace_id); + trace_id.m_valid = 1'b0; + end + if (r_pipe_freeze_trace.apu_req && r_pipe_freeze_trace.apu_gnt) begin trace_id.m_is_apu = 1'b1; trace_id.m_apu_req_id = cnt_apu_req; From a5061c799afa8022c6efc9aa9f4b5c07737fbcf0 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 5 Jan 2024 16:41:13 +0100 Subject: [PATCH 2/2] RVFI - Better minstret csr sampling --- bhv/cv32e40p_rvfi.sv | 40 +++++++++------------------------------- bhv/insn_trace.sv | 4 ++++ 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 5ddb8695d..f47afcb6b 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1272,7 +1272,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_id_done; function void if_to_id(); if (trace_id.m_valid) begin - minstret_to_id(); `CSR_FROM_PIPE(id, misa) `CSR_FROM_PIPE(id, tdata1) `CSR_FROM_PIPE(id, tdata2) @@ -1287,7 +1286,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_is_irq_start = 1'b0; trace_if.m_valid = 1'b0; s_id_done = 1'b0; - // `CSR_FROM_PIPE(id, dpc) endfunction function logic [31:0] be_to_mask(logic [3:0] be); @@ -1369,8 +1367,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID && r_pipe_freeze_trace.ebrk_insn_dec) begin if (trace_id.m_valid) begin - - minstret_to_id(); `CSR_FROM_PIPE(id, misa) `CSR_FROM_PIPE(id, tdata1) `CSR_FROM_PIPE(id, tdata2) @@ -1484,10 +1480,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end if (trace_ex.m_valid) begin - - if (!trace_ex.m_csr.got_minstret) begin + if(trace_ex.m_instret_smaple_trigger == 1) begin //time to sample instret minstret_to_ex(); end + trace_ex.m_instret_smaple_trigger = trace_ex.m_instret_smaple_trigger + 1; + `CSR_FROM_PIPE(ex, misa) `CSR_FROM_PIPE(ex, tdata1) `CSR_FROM_PIPE(ex, tdata2) @@ -1514,9 +1511,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_2; end else begin - if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_1; @@ -1551,9 +1545,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; ->e_ex_to_wb_1; trace_wb.move_down_pipe(trace_ex); end else begin - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end send_rvfi(trace_ex); ->e_send_rvfi_trace_ex_6; end @@ -1578,18 +1569,13 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; // If mret, we need to keep the instruction in Id during flush_ex because mstatus update happens at that time 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.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || ((r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) && !r_pipe_freeze_trace.mret_insn_dec)); //EX_STAGE - // if(trace_id.m_valid && r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin //xret done, we send it to rvfi - // `CSR_FROM_PIPE(id, mip) - // `CSR_FROM_PIPE(id, misa) - // `CSR_FROM_PIPE(id, mstatus) - // `CSR_FROM_PIPE(id, mstatus_fs) - // tinfo_to_id(); - - // send_rvfi(trace_id); - // trace_id.m_valid = 1'b0; - // end if (trace_id.m_valid) begin + if(trace_id.m_instret_smaple_trigger == 1) begin //time to sample instret + minstret_to_id(); + end + trace_id.m_instret_smaple_trigger = trace_id.m_instret_smaple_trigger + 1; + 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) @@ -1617,10 +1603,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, frm) `CSR_FROM_PIPE(id, fcsr) - // if (r_pipe_freeze_trace.csr.we) begin - // `CSR_FROM_PIPE(id, dpc) - // end - if (r_pipe_freeze_trace.csr.dcsr_we) begin dcsr_to_id(); end @@ -1641,9 +1623,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_csr.frm_wmask = '0; trace_ex.m_csr.fcsr_wmask = '0; - if(r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin + if(r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin //xret exit pipeline tinfo_to_id(); - minstret_to_id(); `CSR_FROM_PIPE(id, tdata1) `CSR_FROM_PIPE(id, tdata2) send_rvfi(trace_id); @@ -1737,9 +1718,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (s_new_valid_insn) begin // There is a new valid instruction if (trace_id.m_valid) begin if (trace_ex.m_valid) begin - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end if (trace_wb.m_valid) begin send_rvfi(trace_ex); ->e_send_rvfi_trace_ex_4; diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index 3fe7c1848..71cbaaff4 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -65,6 +65,7 @@ bit m_move_down_pipe; int m_instret_cnt; + int m_instret_smaple_trigger; //We need to sample minstret from csr 2 cycle after id is doen bit m_sample_csr_write_in_ex; @@ -173,6 +174,7 @@ this.m_frm_we_non_apu = 1'b0; this.m_fcsr_we_non_apu = 1'b0; this.m_instret_cnt = 0; + this.m_instret_smaple_trigger = 0; this.m_sample_csr_write_in_ex = 1'b1; endfunction @@ -896,6 +898,7 @@ this.m_got_regs_write = 1'b0; this.m_move_down_pipe = 1'b0; this.m_instret_cnt = 0; + this.m_instret_smaple_trigger = 0; this.m_sample_csr_write_in_ex = 1'b1; this.m_rd_addr[0] = '0; this.m_rd_addr[1] = '0; @@ -970,6 +973,7 @@ 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_instret_smaple_trigger = m_source.m_instret_smaple_trigger; 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;