From ebdbbb7aabdf20fa127a6c7e9c641f89d2b62f8a Mon Sep 17 00:00:00 2001 From: Davide Schiavone Date: Wed, 4 Oct 2023 14:04:18 +0200 Subject: [PATCH 01/50] fix undriven signal (#885) --- rtl/cv32e40p_ex_stage.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index 5d49b5ae8..c51ef7f81 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -413,6 +413,7 @@ module cv32e40p_ex_stage assign apu_read_dep_for_jalr_o = 1'b0; assign apu_write_dep_o = 1'b0; assign fpu_fflags_o = '0; + assign fpu_fflags_we_o = '0; end endgenerate From c8d65849ec060c6f7bc62325b46ba0ab7eae8805 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 14:08:54 +0200 Subject: [PATCH 02/50] fix undriven signal (#885) (#886) --- rtl/cv32e40p_ex_stage.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index 5d49b5ae8..c51ef7f81 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -413,6 +413,7 @@ module cv32e40p_ex_stage assign apu_read_dep_for_jalr_o = 1'b0; assign apu_write_dep_o = 1'b0; assign fpu_fflags_o = '0; + assign fpu_fflags_we_o = '0; end endgenerate From 3db3dcb69f18617583c9a3a421919628e554852e Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 6 Oct 2023 12:06:09 +0800 Subject: [PATCH 03/50] RVFI - Updating from mstatus_we to mstatus_fs_we as mstatus_fs trigger to propagte to trace_ex --- bhv/cv32e40p_rvfi.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index ca158f969..90fc3c828 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -633,6 +633,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; logic [2:0] saved_debug_cause; integer next_send; + event e_empty_queue; function void empty_fifo(); integer i, trace_q_size; trace_q_size = wb_bypass_trace_q.size(); @@ -648,6 +649,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; new_rvfi_trace.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; rvfi_trace_q.push_back(new_rvfi_trace); next_send = next_send + 1; + ->e_empty_queue; end else begin wb_bypass_trace_q.push_back(new_rvfi_trace); end @@ -658,6 +660,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; /* * Function used to alocate a new insn and send it to the rvfi driver */ + event e_add_to_bypass; function void send_rvfi(insn_trace_t m_wb_insn); insn_trace_t new_rvfi_trace; new_rvfi_trace = new(); @@ -667,6 +670,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; next_send = next_send + 1; end else begin wb_bypass_trace_q.push_back(new_rvfi_trace); + ->e_add_to_bypass; end empty_fifo(); endfunction @@ -1163,7 +1167,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; // `CSR_FROM_PIPE(apu_resp, mstatus) `CSR_FROM_PIPE(apu_resp, mstatus_fs) - if (r_pipe_freeze_trace.csr.mstatus_we) begin + if (r_pipe_freeze_trace.csr.mstatus_fs_we) begin trace_ex.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; end endfunction From e45a57dd34d2c7c5aaafc55288c73072fffc5ffd Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 10 Oct 2023 11:20:34 +0800 Subject: [PATCH 04/50] RVFI - Handle fcsr_we when frm_we or fflags_we late rather than early to avoid false fcsr_we issue in rvfi logic --- bhv/cv32e40p_rvfi.sv | 4 +++- bhv/pipe_freeze_trace.sv | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 90fc3c828..21e324445 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1115,6 +1115,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; * The third updates the rvfi interface */ `define CSR_FROM_PIPE(TRACE_NAME, CSR_NAME) \ + if(!trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we) begin \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ + end\ if (r_pipe_freeze_trace.csr.``CSR_NAME``_we) begin \ trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we = r_pipe_freeze_trace.csr.``CSR_NAME``_we; \ trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ @@ -1164,7 +1167,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(apu_resp, fcsr) `CSR_FROM_PIPE(apu_resp, fflags) - // `CSR_FROM_PIPE(apu_resp, mstatus) `CSR_FROM_PIPE(apu_resp, mstatus_fs) if (r_pipe_freeze_trace.csr.mstatus_fs_we) begin diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 58051ab8e..ca9a21042 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -650,10 +650,6 @@ task monitor_pipeline(); if (r_pipe_freeze_trace.csr.fcsr_we) begin r_pipe_freeze_trace.csr.fflags_we = 1'b1; r_pipe_freeze_trace.csr.frm_we = 1'b1; - end else begin - if (r_pipe_freeze_trace.csr.fflags_we || r_pipe_freeze_trace.csr.frm_we) begin - r_pipe_freeze_trace.csr.fcsr_we = 1'b1; - end end if (csr_fcsr_fflags_we_i) begin From 99341599bcd09d59ed8fa5e6db583dd499f8650e Mon Sep 17 00:00:00 2001 From: pascalgouedo Date: Tue, 10 Oct 2023 13:47:00 +0200 Subject: [PATCH 05/50] Updated Pipeline details after bug corrections (#890) * Corrected table name Signed-off-by: Pascal Gouedo * Updated SIMD cv.add/cv.sub Signed-off-by: Pascal Gouedo * Updated Pipeline details after #723, #652, #731 and #742 bugs correction. Signed-off-by: Pascal Gouedo * Formality script improvment Signed-off-by: Pascal Gouedo --------- Signed-off-by: Pascal Gouedo --- docs/source/instruction_set_extensions.rst | 12 ++++++------ docs/source/pipeline.rst | 19 +++++++++++++++---- scripts/lec/synopsys_formality/check_lec.tcl | 2 ++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index 5e4357ef7..c7becb7f3 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -1349,9 +1349,9 @@ SIMD ALU operations +------------------------------------------------------------+------------------------------------------------------------------+ | **Mnemonic** | **Description** | +============================================================+==================================================================+ - | **cv.add[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] + op2[i]) & 0xFFFF | + | **cv.add[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] + op2[i]) & {0xFFFF, 0xFF} | +------------------------------------------------------------+------------------------------------------------------------------+ - | **cv.sub[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] - op2[i]) & 0xFFFF | + | **cv.sub[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] - op2[i]) & {0xFFFF, 0xFF} | +------------------------------------------------------------+------------------------------------------------------------------+ | **cv.avg[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | | | | @@ -2146,11 +2146,11 @@ No carry, overflow is generated. Instructions are rounded up as the mask & 0xFFF | | Note: Arithmetic shift right. | +---------------------------------------+---------------------------------------------------------------------------------------+ -SIMD Complex-numbers Encoding -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +SIMD Complex-number Encoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. table:: SIMD ALU encoding - :name: SIMD ALU encoding +.. table:: SIMD Complex-number encoding + :name: SIMD Complex-number encoding :widths: 11 4 4 9 7 8 8 13 36 :class: no-scrollbar-table diff --git a/docs/source/pipeline.rst b/docs/source/pipeline.rst index 8ee1231cc..516daa2e4 100644 --- a/docs/source/pipeline.rst +++ b/docs/source/pipeline.rst @@ -29,15 +29,25 @@ Pipeline Details CV32E40P has a 4-stage in-order completion pipeline, the 4 stages are: Instruction Fetch (IF) - Fetches instructions from memory via an aligning prefetch buffer, capable of fetching 1 instruction per cycle if the instruction side memory system allows. This prefetech buffer is able to store 2 32-b data. The IF stage also pre-decodes RVC instructions into RV32I base instructions. See :ref:`instruction-fetch` for details. + Fetches instructions from memory via an aligning prefetch buffer, capable of fetching 1 instruction per cycle if the instruction side memory system allows. This prefetch buffer is able to store 2 32-b data. + The IF stage also pre-decodes RVC instructions into RV32I base instructions. See :ref:`instruction-fetch` for details. Instruction Decode (ID) Decodes fetched instruction and performs required register file reads. Jumps are taken from the ID stage. Execute (EX) - Executes the instructions. The EX stage contains the ALU, Multiplier and Divider. Branches (with their condition met) are taken from the EX stage. Multi-cycle instructions will stall this stage until they are complete. The ALU, Multiplier and Divider instructions write back their result to the register file from the EX stage. The address generation part of the load-store-unit (LSU) is contained in EX as well. + Executes the instructions. The EX stage contains the ALU, Multiplier and Divider. Branches (with their condition met) are taken from the EX stage. Multi-cycle instructions will stall this stage until they are complete. + The ALU, Multiplier and Divider instructions write back their result to the register file from the EX stage. The address generation part of the load-store-unit (LSU) is contained in EX as well. - The FPU writes back its result from EX stage as well when FPU_*_LAT is either 0 cycle or more than 1 cycle. It is reusing register file ALU/Mult/Div write port and it has the highest priority so it will stall EX stage if there is a conflict (when FPU_*_LAT > 1). + The FPU writes back its result at EX stage as well through this ALU/Mult/Div register file write port when FPU_*_LAT is either 0 cycle or greater than 1 cycle. + When FPU_*_LAT > 1, FPU write-back has the highest priority so it will stall EX stage if there is a conflict. There are few exceptions to this FPU priority over ALU/Mult/Div. + + They are: + + * There is a multi-cycle MULH in EX. + * There is a Misaligned LOAD/STORE in EX. + * There is a Post-Increment LOAD/STORE in EX. + In those 3 exceptions, EX will not be stalled, FPU result (and flags) are memorized and will be written back in the register file (and FPU CSR) as soon as there is no conflict anymore. Writeback (WB) Writes the result of Load instructions back to the register file. @@ -68,7 +78,8 @@ Those cycles penalty can be hidden if the compiler is able to add instructions b Single- and Multi-Cycle Instructions ------------------------------------ -:numref:`Cycle counts per instruction type` shows the cycle count per instruction type. Some instructions have a variable time, this is indicated as a range e.g. 1..32 means that the instruction takes a minimum of 1 cycle and a maximum of 32 cycles. The cycle counts assume zero stall on the instruction-side interface and zero stall on the data-side memory interface. +:numref:`Cycle counts per instruction type` shows the cycle count per instruction type. Some instructions have a variable time, this is indicated as a range e.g. 1..32 means that the instruction takes a minimum of 1 cycle and a maximum of 32 cycles. +The cycle counts assume zero stall on the instruction-side interface and zero stall on the data-side memory interface. .. _instructions_latency_table: .. table:: Cycle counts per instruction type diff --git a/scripts/lec/synopsys_formality/check_lec.tcl b/scripts/lec/synopsys_formality/check_lec.tcl index 47049591c..612aba257 100644 --- a/scripts/lec/synopsys_formality/check_lec.tcl +++ b/scripts/lec/synopsys_formality/check_lec.tcl @@ -15,6 +15,8 @@ set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_flags_o* verify > ./reports/verify.rpt +report_aborted_points > ./reports/aborted_points.rpt +report_failing_points > ./reports/failing_points.rpt analyze_points -failing > ./reports/analyze.rpt exit From 3222994ee0abfd7fb86043c09602f0d47e2572e9 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 13 Oct 2023 11:51:25 +0800 Subject: [PATCH 06/50] Tracer - Correcting typo on cv.pack decoding --- bhv/include/cv32e40p_tracer_pkg.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bhv/include/cv32e40p_tracer_pkg.sv b/bhv/include/cv32e40p_tracer_pkg.sv index c099ff4f4..81c2062bc 100644 --- a/bhv/include/cv32e40p_tracer_pkg.sv +++ b/bhv/include/cv32e40p_tracer_pkg.sv @@ -449,8 +449,8 @@ package cv32e40p_tracer_pkg; parameter INSTR_CVSHUFFLE2H = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; parameter INSTR_CVSHUFFLE2B = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; - parameter INSTR_CVPACK = {5'b11101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; - parameter INSTR_CVPACKH = {5'b11101, 1'b0, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACK = {5'b11110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACKH = {5'b11110, 1'b0, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; parameter INSTR_CVPACKHIB = {5'b11111, 1'b0, 1'b1, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; parameter INSTR_CVPACKLOB = {5'b11111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; From 265c80eb5cecd3df38dc266448ce12c8ca5ee4c8 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 13 Oct 2023 12:42:37 +0800 Subject: [PATCH 07/50] Tracer - Updating hwloop printing from rd[0] to instr[7] to sort between hwloop 0 and hwloop 1 --- bhv/cv32e40p_instr_trace.svh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index 8c4ae99f3..a89ed4e45 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -679,22 +679,22 @@ class instr_trace_t; // decode and print instruction case (instr[11:8]) // cv.starti, cv.endi - 4'b0000, 4'b0010: str = $sformatf("%-16s %d, 0x%0x", mnemonic, rd[0], imm_iz_type); + 4'b0000, 4'b0010: str = $sformatf("%-16s %d, 0x%0x", mnemonic, instr[7], imm_iz_type); // cv.counti - 4'b0100: str = $sformatf("%-16s %d, %d", mnemonic, rd[0], imm_iz_type); + 4'b0100: str = $sformatf("%-16s %d, %d", mnemonic, instr[7], imm_iz_type); // cv.start, cv.end, cv.count 4'b0001, 4'b0011, 4'b0101: begin regs_read.push_back('{rs1, rs1_value, 0}); - str = $sformatf("%-16s %d, %s", mnemonic, rd[0], regAddrToStr(rs1)); + str = $sformatf("%-16s %d, %s", mnemonic, instr[7], regAddrToStr(rs1)); end // cv.setupi 4'b0110: begin - str = $sformatf("%-16s %d, %d, 0x%0x", mnemonic, rd[0], imm_iz_type, rs1); + str = $sformatf("%-16s %d, %d, 0x%0x", mnemonic, instr[7], imm_iz_type, rs1); end // cv.setup 4'b0111: begin regs_read.push_back('{rs1, rs1_value, 0}); - str = $sformatf("%-16s %d, %s, 0x%0x", mnemonic, rd[0], regAddrToStr(rs1), imm_iz_type); + str = $sformatf("%-16s %d, %s, 0x%0x", mnemonic, instr[7], regAddrToStr(rs1), imm_iz_type); end endcase end @@ -861,7 +861,7 @@ class instr_trace_t; endcase str_sci = ""; end - + // shuffle/pack 6'b110000: begin if (instr[14:12] == 3'b111) begin From 1042a85248b3988260473bb40ff33abef14fbe01 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 10 Oct 2023 10:52:01 +0200 Subject: [PATCH 08/50] Issue #888 correction Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_controller.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtl/cv32e40p_controller.sv b/rtl/cv32e40p_controller.sv index 549802690..986248619 100644 --- a/rtl/cv32e40p_controller.sv +++ b/rtl/cv32e40p_controller.sv @@ -491,6 +491,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; if ( (debug_req_pending || trigger_match_i) & ~debug_mode_q ) begin //Serving the debug + is_decoding_o = COREV_PULP ? 1'b0 : 1'b1; halt_if_o = 1'b1; halt_id_o = 1'b1; ctrl_fsm_ns = DBG_FLUSH; @@ -712,6 +713,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; if ( (debug_req_pending || trigger_match_i) & ~debug_mode_q ) begin //Serving the debug + is_decoding_o = COREV_PULP ? 1'b0 : 1'b1; halt_if_o = 1'b1; halt_id_o = 1'b1; ctrl_fsm_ns = DBG_FLUSH; From 80160c56d59a2ac8b8c0f9dd08fb3ed320d013eb Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 10 Oct 2023 10:59:44 +0200 Subject: [PATCH 09/50] Issue #887 correction Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_ex_stage.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index c51ef7f81..2d025add1 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -371,7 +371,7 @@ module cv32e40p_ex_stage apu_result_q <= 'b0; apu_flags_q <= 'b0; end else begin - if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || (data_req_i && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin apu_rvalid_q <= 1'b1; apu_result_q <= apu_result_i; apu_flags_q <= apu_flags_i; From 206a4badf0841f32c811e947444b10678e82b3ba Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 10 Oct 2023 18:55:00 +0200 Subject: [PATCH 10/50] Reduced line length. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_ex_stage.sv | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index 2d025add1..827531340 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -371,11 +371,16 @@ module cv32e40p_ex_stage apu_result_q <= 'b0; apu_flags_q <= 'b0; end else begin - if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + if (apu_rvalid_i && apu_multicycle && + (data_misaligned_i || data_misaligned_ex_i || + ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || + (mulh_active && (mult_operator_i == MUL_H)))) begin apu_rvalid_q <= 1'b1; apu_result_q <= apu_result_i; apu_flags_q <= apu_flags_i; - end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || + ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || + (mulh_active && (mult_operator_i == MUL_H)))) begin apu_rvalid_q <= 1'b0; end end @@ -383,7 +388,10 @@ module cv32e40p_ex_stage assign apu_req_o = apu_req; assign apu_gnt = apu_gnt_i; - assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); + assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || + ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || + (mulh_active && (mult_operator_i == MUL_H)))) + ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); assign apu_operands_o = apu_operands_i; assign apu_op_o = apu_op_i; assign apu_result = apu_rvalid_q ? apu_result_q : apu_result_i; From ba2f67c470b78df90bb7617dac2e58f286d57b3f Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 18 Oct 2023 17:44:19 +0200 Subject: [PATCH 11/50] Issue #889 correction. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_core.sv | 10 +++++++--- rtl/cv32e40p_ex_stage.sv | 11 ++++++++--- rtl/cv32e40p_id_stage.sv | 5 +++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index e6f9f7098..878dd2985 100644 --- a/rtl/cv32e40p_core.sv +++ b/rtl/cv32e40p_core.sv @@ -158,6 +158,7 @@ module cv32e40p_core logic [31:0] jump_target_id, jump_target_ex; logic branch_in_ex; logic branch_decision; + logic [ 1:0] ctrl_transfer_insn_in_dec; logic ctrl_busy; logic if_busy; @@ -540,9 +541,10 @@ module cv32e40p_core .instr_req_o (instr_req_int), // Jumps and branches - .branch_in_ex_o (branch_in_ex), - .branch_decision_i(branch_decision), - .jump_target_o (jump_target_id), + .branch_in_ex_o (branch_in_ex), + .branch_decision_i (branch_decision), + .jump_target_o (jump_target_id), + .ctrl_transfer_insn_in_dec_o(ctrl_transfer_insn_in_dec), // IF and ID control signals .clear_instr_valid_o(clear_instr_valid), @@ -785,6 +787,8 @@ module cv32e40p_core .data_misaligned_ex_i(data_misaligned_ex), // from ID/EX pipeline .data_misaligned_i (data_misaligned), + .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec), + // FPU .fpu_fflags_we_o(fflags_we), .fpu_fflags_o (fflags_csr), diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index 827531340..a0c52d174 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -81,6 +81,8 @@ module cv32e40p_ex_stage input logic data_misaligned_ex_i, input logic data_misaligned_i, + input logic [1:0] ctrl_transfer_insn_in_dec_i, + // FPU signals output logic fpu_fflags_we_o, output logic [APU_NUSFLAGS_CPU-1:0] fpu_fflags_o, @@ -374,13 +376,15 @@ module cv32e40p_ex_stage if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || - (mulh_active && (mult_operator_i == MUL_H)))) begin + (mulh_active && (mult_operator_i == MUL_H)) || + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin apu_rvalid_q <= 1'b1; apu_result_q <= apu_result_i; apu_flags_q <= apu_flags_i; end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || - (mulh_active && (mult_operator_i == MUL_H)))) begin + (mulh_active && (mult_operator_i == MUL_H)) || + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin apu_rvalid_q <= 1'b0; end end @@ -390,7 +394,8 @@ module cv32e40p_ex_stage assign apu_gnt = apu_gnt_i; assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || - (mulh_active && (mult_operator_i == MUL_H)))) + (mulh_active && (mult_operator_i == MUL_H)) || + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); assign apu_operands_o = apu_operands_i; assign apu_op_o = apu_op_i; diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index 7811eabfd..62e4d7217 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -70,6 +70,7 @@ module cv32e40p_id_stage output logic branch_in_ex_o, input logic branch_decision_i, output logic [31:0] jump_target_o, + output logic [ 1:0] ctrl_transfer_insn_in_dec_o, // IF and ID stage signals output logic clear_instr_valid_o, @@ -1087,7 +1088,7 @@ module cv32e40p_id_stage .debug_wfi_no_sleep_i(debug_wfi_no_sleep), // jump/branches - .ctrl_transfer_insn_in_dec_o (ctrl_transfer_insn_in_dec), + .ctrl_transfer_insn_in_dec_o (ctrl_transfer_insn_in_dec_o), .ctrl_transfer_insn_in_id_o (ctrl_transfer_insn_in_id), .ctrl_transfer_target_mux_sel_o(ctrl_transfer_target_mux_sel), @@ -1187,7 +1188,7 @@ module cv32e40p_id_stage // jump/branch control .branch_taken_ex_i (branch_taken_ex), .ctrl_transfer_insn_in_id_i (ctrl_transfer_insn_in_id), - .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec), + .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec_o), // Interrupt signals .irq_wu_ctrl_i (irq_wu_ctrl), From 34977aa07e41d22098a33f32a38cefc084e2b39b Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 19 Oct 2023 11:18:43 +0200 Subject: [PATCH 12/50] Added a note about MSTATUS.FS update. Signed-off-by: Pascal Gouedo --- docs/source/control_status_registers.rst | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/source/control_status_registers.rst b/docs/source/control_status_registers.rst index 9ccfc070b..be4ae1652 100644 --- a/docs/source/control_status_registers.rst +++ b/docs/source/control_status_registers.rst @@ -445,7 +445,7 @@ Detailed: +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ | 30:15 | RO | 0, Unimplemented. | +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ - | 14:13 | RW | **FS:** Floating point State | + | 14:13 | RW | **FS:** Floating point State (See note below) | | | | | | | | 00 = Off | | | | | @@ -478,6 +478,10 @@ Detailed: | 2:0 | RO | 0, Unimplemented. | +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ +.. note:: + + As allowed by RISC-V ISA and to simplify MSTATUS.FS update in the design, the state is updated to Dirty when executing any F instructions except for all FSW ones. + .. only:: USER User Status (``ustatus``) @@ -652,8 +656,10 @@ Detailed: | 4:0 | RW | **Exception Code** (See note below) | +-------------+-----------+----------------------------------------------------------------------------------+ -**NOTE**: software accesses to `mcause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, -when `mcause[31]` is set, writing 0x1 to `mcause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. +.. note:: + + Software accesses to `mcause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, + when `mcause[31]` is set, writing 0x1 to `mcause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. Machine Trap Value (``mtval``) @@ -1603,8 +1609,10 @@ Detailed: | 4:0 | RW | **Exception Code** (See note below) | +-------------+-----------+------------------------------------------------------------------------------------+ - **NOTE**: software accesses to `ucause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, - when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. + .. note:: + + Software accesses to `ucause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, + when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. .. only:: PMP From ac4bb22a730ef5db43b7ac47224a55ee8f734c4c Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 23 Oct 2023 10:13:42 +0200 Subject: [PATCH 13/50] Reduce line length. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_ex_stage.sv | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index a0c52d174..f327b8db6 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -377,14 +377,16 @@ module cv32e40p_ex_stage (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)) || - ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && + regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin apu_rvalid_q <= 1'b1; apu_result_q <= apu_result_i; apu_flags_q <= apu_flags_i; end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)) || - ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && + regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin apu_rvalid_q <= 1'b0; end end @@ -395,7 +397,8 @@ module cv32e40p_ex_stage assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)) || - ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && + regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); assign apu_operands_o = apu_operands_i; assign apu_op_o = apu_op_i; From 7c2bb288d79d7b61e27a73fb99984ef50d2da1de Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 24 Oct 2023 17:32:55 +0200 Subject: [PATCH 14/50] Corrected MPIE/MPP mode. Signed-off-by: Pascal Gouedo --- docs/source/control_status_registers.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/control_status_registers.rst b/docs/source/control_status_registers.rst index be4ae1652..28f3d2fe6 100644 --- a/docs/source/control_status_registers.rst +++ b/docs/source/control_status_registers.rst @@ -457,13 +457,13 @@ Detailed: | | | | | | | 0 if ``FPU`` = 0 or (``FPU`` = 1 and ``ZFINX`` = 1). | +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ - | 12:11 | RO | **MPP:** Machine Previous Priviledge mode | + | 12:11 | RW | **MPP:** Machine Previous Priviledge mode | | | | | - | | | 11 when the user mode is not enabled. | + | | | Hardwired to 11 when the User mode is not enabled. | +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ | 10:8 | RO | 0, Unimplemented. | +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ - | 7 | RO | **MPIE:** Machine Previous Interrupt Enable | + | 7 | RW | **MPIE:** Machine Previous Interrupt Enable | | | | | | | | When an exception is encountered, MPIE will be set to MIE. | | | | When the mret instruction is executed, the value of MPIE will be stored to MIE. | From f88b1c648cbc9a44ff6c7888bdb921cc64487d29 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 24 Oct 2023 15:40:17 +0200 Subject: [PATCH 15/50] Issue #896 correction Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_core.sv | 13 +++++++++---- rtl/cv32e40p_cs_registers.sv | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index 878dd2985..549869b9b 100644 --- a/rtl/cv32e40p_core.sv +++ b/rtl/cv32e40p_core.sv @@ -202,6 +202,7 @@ module cv32e40p_core logic [ C_RM-1:0] frm_csr; logic [ C_FFLAG-1:0] fflags_csr; logic fflags_we; + logic fregs_we; // APU logic apu_en_ex; @@ -973,6 +974,7 @@ module cv32e40p_core .frm_o (frm_csr), .fflags_i (fflags_csr), .fflags_we_i(fflags_we), + .fregs_we_i (fregs_we), // Interrupt related control signals .mie_bypass_o (mie_bypass), @@ -1041,13 +1043,16 @@ module cv32e40p_core ); // CSR access - assign csr_addr = csr_addr_int; - assign csr_wdata = alu_operand_a_ex; - assign csr_op = csr_op_ex; + assign csr_addr = csr_addr_int; + assign csr_wdata = alu_operand_a_ex; + assign csr_op = csr_op_ex; assign csr_addr_int = csr_num_e'(csr_access_ex ? alu_operand_b_ex[11:0] : '0); - + // Floating-Point registers write + assign fregs_we = (FPU & !ZFINX) ? ((regfile_alu_we_fw && regfile_alu_waddr_fw[5]) || + (regfile_we_wb && regfile_waddr_fw_wb_o[5])) + : 1'b0; /////////////////////////// // ____ __ __ ____ // diff --git a/rtl/cv32e40p_cs_registers.sv b/rtl/cv32e40p_cs_registers.sv index 455e3cfcb..480dd6a2f 100644 --- a/rtl/cv32e40p_cs_registers.sv +++ b/rtl/cv32e40p_cs_registers.sv @@ -68,6 +68,7 @@ module cv32e40p_cs_registers output logic [ 2:0] frm_o, input logic [C_FFLAG-1:0] fflags_i, input logic fflags_we_i, + input logic fregs_we_i, // Interrupts output logic [31:0] mie_bypass_o, @@ -1027,7 +1028,7 @@ module cv32e40p_cs_registers if (ZFINX == 0) begin // FPU Register File/Flags implicit update or modified by CSR instructions - if (fflags_we_i || fcsr_update) begin + if (fregs_we_i || fflags_we_i || fcsr_update) begin mstatus_fs_n = FS_DIRTY; end end From b13c97efd75a4dd8487252b20fd498279f6c8778 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Fri, 27 Oct 2023 15:45:44 +0200 Subject: [PATCH 16/50] Updated CVFPU release version Signed-off-by: Pascal Gouedo --- docs/source/fpu.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/fpu.rst b/docs/source/fpu.rst index 9dc85aa2e..019630a35 100644 --- a/docs/source/fpu.rst +++ b/docs/source/fpu.rst @@ -25,7 +25,7 @@ precision can be enabled by setting the parameter **FPU** of the ``cv32e40p_top` to 1. This will extend the CV32E40P decoder accordingly and will instantiate the FPU. The FPU repository used by the CV32E40P is available at `https://github.com/openhwgroup/cvfpu `_ and its documentation can be found `here `_. -CVFPU v1.0.0 release has been copied in CV32E40P repository inside rtl/vendor (used for verification and implementation) so all core and FPU RTL files should be taken from CV32E40P repository. +CVFPU v0.8.1 release has been copied in CV32E40P repository inside rtl/vendor (used for verification and implementation) so all core and FPU RTL files should be taken from CV32E40P repository. cv32e40p_fpu_manifest file is listing all necessary files for both the Core and CVFPU. From 0f3c925df2d3e0da52464671c705137e29f7a517 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Fri, 27 Oct 2023 15:48:18 +0200 Subject: [PATCH 17/50] Correction to avoid simulation/implementation tools warning. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_fp_wrapper.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/cv32e40p_fp_wrapper.sv b/rtl/cv32e40p_fp_wrapper.sv index 042fa0f22..62ec46c2f 100644 --- a/rtl/cv32e40p_fp_wrapper.sv +++ b/rtl/cv32e40p_fp_wrapper.sv @@ -111,7 +111,7 @@ module cv32e40p_fp_wrapper .int_fmt_i (fpnew_pkg::int_format_e'(fpu_int_fmt)), .vectorial_op_i(fpu_vec_op), .tag_i (1'b0), - .simd_mask_i ('b0), + .simd_mask_i (1'b0), .in_valid_i (apu_req_i), .in_ready_o (apu_gnt_o), .flush_i (1'b0), From e6f280007d37052222c4295d8af2618186d9abfd Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 6 Nov 2023 09:24:07 +0100 Subject: [PATCH 18/50] Additional correction for issue #896 to manage MSTATUS.FS write conflict between CSRW and FLW. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_cs_registers.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rtl/cv32e40p_cs_registers.sv b/rtl/cv32e40p_cs_registers.sv index 480dd6a2f..609662830 100644 --- a/rtl/cv32e40p_cs_registers.sv +++ b/rtl/cv32e40p_cs_registers.sv @@ -213,6 +213,7 @@ module cv32e40p_cs_registers logic [31:0] exception_pc; Status_t mstatus_q, mstatus_n; + logic mstatus_we_int; FS_t mstatus_fs_q, mstatus_fs_n; logic [5:0] mcause_q, mcause_n; logic [5:0] ucause_q, ucause_n; @@ -898,6 +899,7 @@ module cv32e40p_cs_registers dscratch0_n = dscratch0_q; dscratch1_n = dscratch1_q; + mstatus_we_int = 1'b0; mstatus_n = mstatus_q; mcause_n = mcause_q; ucause_n = '0; // Not used if PULP_SECURE == 0 @@ -958,7 +960,8 @@ module cv32e40p_cs_registers mprv: csr_wdata_int[MSTATUS_MPRV_BIT] }; if (FPU == 1 && ZFINX == 0) begin - mstatus_fs_n = FS_t'(csr_wdata_int[MSTATUS_FS_BIT_HIGH:MSTATUS_FS_BIT_LOW]); + mstatus_we_int = 1'b1; + mstatus_fs_n = FS_t'(csr_wdata_int[MSTATUS_FS_BIT_HIGH:MSTATUS_FS_BIT_LOW]); end end // mie: machine interrupt enable @@ -1028,7 +1031,7 @@ module cv32e40p_cs_registers if (ZFINX == 0) begin // FPU Register File/Flags implicit update or modified by CSR instructions - if (fregs_we_i || fflags_we_i || fcsr_update) begin + if ((fregs_we_i && !(mstatus_we_int && mstatus_fs_n != FS_DIRTY)) || fflags_we_i || fcsr_update) begin mstatus_fs_n = FS_DIRTY; end end From adf50bd3339783993cdd4b726f413173e6ba9e35 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Mon, 16 Oct 2023 15:30:17 +0800 Subject: [PATCH 19/50] RVFI - Reporting all illegal instruction --- bhv/cv32e40p_rvfi.sv | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 21e324445..1a8802035 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1140,7 +1140,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; e_dev_commit_rf_to_ex_3, e_dev_commit_rf_to_ex_4, e_dev_commit_rf_to_ex_5; - event e_if_2_id_1, e_if_2_id_2; + event e_if_2_id_1, e_if_2_id_2, e_if_2_id_3; 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; @@ -1628,6 +1628,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; end + if (!r_pipe_freeze_trace.data_we_ex) begin trace_id.m_is_load = 1'b1; trace_id.m_mem.wmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; @@ -1640,6 +1641,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end else begin trace_id.m_mem.rmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; end + if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; trace_id.m_mem_req_id[0] = 0; @@ -1740,12 +1742,19 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; //IF_STAGE if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready) begin - if(trace_if.m_valid && r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin - if_to_id(); - trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; - ->e_if_2_id_2; + if(trace_if.m_valid) begin + if (r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin + if_to_id(); + trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; + ->e_if_2_id_2; + end else if (r_pipe_freeze_trace.is_illegal) begin + if_to_id(); + trace_id.m_is_illegal = 1'b1; + ->e_if_2_id_3; + end end + trace_if.m_insn = r_pipe_freeze_trace.instr_if; //Instr comes from if, buffer for one cycle trace_if.m_pc_rdata = r_pipe_freeze_trace.pc_if; trace_if.m_dbg_taken = is_dbg_taken; From 0cd7a2031077da8fce4d6739aa572ab40b920e08 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Mon, 16 Oct 2023 16:55:22 +0800 Subject: [PATCH 20/50] RVFI - Reporting all ecall instruction --- bhv/cv32e40p_rvfi.sv | 3 +++ bhv/cv32e40p_tb_wrapper.sv | 1 + bhv/pipe_freeze_trace.sv | 2 ++ 3 files changed, 6 insertions(+) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 1a8802035..35bdd27bc 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -73,6 +73,7 @@ module cv32e40p_rvfi input logic is_compressed_id_i, input logic ebrk_insn_dec_i, + input logic ecall_insn_dec_i, input logic [5:0] csr_cause_i, @@ -1751,6 +1752,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if_to_id(); trace_id.m_is_illegal = 1'b1; ->e_if_2_id_3; + end else if (r_pipe_freeze_trace.ecall_insn_dec) begin + if_to_id(); end end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 725ed4f05..915037d2e 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -279,6 +279,7 @@ module cv32e40p_tb_wrapper // .instr (cv32e40p_top_i.core_i.id_stage_i.instr ), .is_compressed_id_i(cv32e40p_top_i.core_i.id_stage_i.is_compressed_i), .ebrk_insn_dec_i (cv32e40p_top_i.core_i.id_stage_i.ebrk_insn_dec), + .ecall_insn_dec_i (cv32e40p_top_i.core_i.id_stage_i.ecall_insn_dec), .csr_cause_i (cv32e40p_top_i.core_i.csr_cause), .debug_csr_save_i (cv32e40p_top_i.core_i.debug_csr_save), diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index ca9a21042..9d658947d 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -64,6 +64,7 @@ typedef struct { logic is_compressed_id; logic ebrk_insn_dec; + logic ecall_insn_dec; logic [5:0] csr_cause; @@ -416,6 +417,7 @@ task monitor_pipeline(); r_pipe_freeze_trace.jump_target_id = jump_target_id_i; r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; + r_pipe_freeze_trace.ecall_insn_dec = ecall_insn_dec_i; r_pipe_freeze_trace.csr_cause = csr_cause_i; r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; r_pipe_freeze_trace.minstret = minstret_i; From 7bd311972f79cc6b3de78c3955a1c00651111c4c Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 17 Oct 2023 11:45:58 +0800 Subject: [PATCH 21/50] Correcting cv.setup and cv.setupi deconding on tracer package --- bhv/include/cv32e40p_tracer_pkg.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bhv/include/cv32e40p_tracer_pkg.sv b/bhv/include/cv32e40p_tracer_pkg.sv index 81c2062bc..d026c4aad 100644 --- a/bhv/include/cv32e40p_tracer_pkg.sv +++ b/bhv/include/cv32e40p_tracer_pkg.sv @@ -196,8 +196,8 @@ package cv32e40p_tracer_pkg; parameter INSTR_CVEND0 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b0, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNTI0 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b0, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNT0 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b0, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUPI0 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b0, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUP0 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI0 = {17'b?, 3'b100, 4'b0110, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP0 = {12'b?, 5'b?, 3'b100, 4'b0111, 1'b0, OPCODE_CUSTOM_1}; parameter INSTR_CVSTARTI1 = {12'b?, 5'b00000, 3'b100, 4'b0000, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_CVSTART1 = {12'b000000000000, 5'b?, 3'b100, 4'b0001, 1'b1, OPCODE_CUSTOM_1}; @@ -205,8 +205,8 @@ package cv32e40p_tracer_pkg; parameter INSTR_CVEND1 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNTI1 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNT1 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b1, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUPI1 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b1, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUP1 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI1 = {17'b?, 3'b100, 4'b0110, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP1 = {12'b?, 5'b?, 3'b100, 4'b0111, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_FF1 = {7'b0100001, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; From 4fa777165f0ab0d812bde3e805733145e096c6b9 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 19 Oct 2023 14:52:06 +0800 Subject: [PATCH 22/50] RVFI - Adding accurate mstatus write mask --- bhv/cv32e40p_rvfi.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 35bdd27bc..ef9623a01 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -618,6 +618,8 @@ module cv32e40p_rvfi logic pc_mux_interrupt; logic pc_mux_nmi; + localparam logic[31:0] MSTATUS_WRITE_MASK = 32'h0000_6088; + `include "pipe_freeze_trace.sv" `include "insn_trace.sv" @@ -842,7 +844,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; //CSR rvfi_csr_mstatus_rmask = new_rvfi_trace.m_csr.mstatus_rmask | new_rvfi_trace.m_csr.mstatus_fs_rmask; - rvfi_csr_mstatus_wmask = new_rvfi_trace.m_csr.mstatus_wmask; + rvfi_csr_mstatus_wmask = new_rvfi_trace.m_csr.mstatus_wmask & MSTATUS_WRITE_MASK; rvfi_csr_mstatus_wmask[31] = new_rvfi_trace.m_csr.mstatus_fs_wmask[31]; rvfi_csr_mstatus_wmask[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wmask[14:13]; From 2ea4fb5163917b0da1f0fc08ed57e038a7f43ae1 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 31 Oct 2023 15:00:32 +0800 Subject: [PATCH 23/50] RVFI - Catching mstatus_fs update caused by flw --- bhv/cv32e40p_rvfi.sv | 24 +++++++++++++++++------- bhv/cv32e40p_tb_wrapper.sv | 2 ++ bhv/pipe_freeze_trace.sv | 4 ++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index ef9623a01..a27ee6d09 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -203,6 +203,7 @@ module cv32e40p_rvfi input logic csr_we_i, input logic [31:0] csr_wdata_int_i, + input logic csr_fregs_we_i, input logic csr_jvt_we_i, input Status_t csr_mstatus_n_i, input Status_t csr_mstatus_q_i, @@ -618,7 +619,7 @@ module cv32e40p_rvfi logic pc_mux_interrupt; logic pc_mux_nmi; - localparam logic[31:0] MSTATUS_WRITE_MASK = 32'h0000_6088; + localparam logic [31:0] MSTATUS_WRITE_MASK = 32'h0000_6088; `include "pipe_freeze_trace.sv" @@ -636,7 +637,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; logic [2:0] saved_debug_cause; integer next_send; - event e_empty_queue; + event e_empty_queue; function void empty_fifo(); integer i, trace_q_size; trace_q_size = wb_bypass_trace_q.size(); @@ -663,7 +664,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; /* * Function used to alocate a new insn and send it to the rvfi driver */ - event e_add_to_bypass; + event e_add_to_bypass; function void send_rvfi(insn_trace_t m_wb_insn); insn_trace_t new_rvfi_trace; new_rvfi_trace = new(); @@ -877,7 +878,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end rvfi_csr_mstatus_wdata[30:18] = '0; // MPRV is not implemented in the target configuration, writes to it are ignored - rvfi_csr_mstatus_wdata[17] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.mprv; + rvfi_csr_mstatus_wdata[17] = 1'b0; //new_rvfi_trace.m_csr.mstatus_wdata.mprv; rvfi_csr_mstatus_wdata[16:15] = '0; if (FPU == 1 && ZFINX == 0) begin rvfi_csr_mstatus_wdata[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wdata; @@ -889,11 +890,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; rvfi_csr_mstatus_wdata[7] = new_rvfi_trace.m_csr.mstatus_wdata.mpie; rvfi_csr_mstatus_wdata[6:5] = '0; // UPIE is not implemented in the target configuration, writes to it are ignored - rvfi_csr_mstatus_wdata[4] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.upie; + rvfi_csr_mstatus_wdata[4] = 1'b0; //new_rvfi_trace.m_csr.mstatus_wdata.upie; rvfi_csr_mstatus_wdata[3] = new_rvfi_trace.m_csr.mstatus_wdata.mie; rvfi_csr_mstatus_wdata[2:1] = '0; // UIE is not implemented in the target configuration, writes to it are ignored - rvfi_csr_mstatus_wdata[0] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.uie; + rvfi_csr_mstatus_wdata[0] = 1'b0; //new_rvfi_trace.m_csr.mstatus_wdata.uie; `SET_RVFI_CSR_FROM_INSN(misa) `SET_RVFI_CSR_FROM_INSN(mie) @@ -1133,6 +1134,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; function void mstatus_to_id(); `CSR_FROM_PIPE(id, mstatus) `CSR_FROM_PIPE(id, mstatus_fs) + if(r_pipe_freeze_trace.csr.fregs_we & !r_pipe_freeze_trace.csr.mstatus_fs_we) begin //writes happening in ex that needs to be reported to id + trace_id.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end ->e_mstatus_to_id; endfunction //those event are for debug purpose @@ -1506,6 +1510,12 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; end + + if (r_pipe_freeze_trace.csr.fregs_we) begin + `CSR_FROM_PIPE(ex, mstatus_fs) + trace_ex.m_csr.mstatus_fs_we = 1'b1; + trace_ex.m_csr.mstatus_fs_wmask = '1; + end end if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin @@ -1745,7 +1755,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; //IF_STAGE if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready) begin - if(trace_if.m_valid) begin + if (trace_if.m_valid) begin if (r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin if_to_id(); trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 915037d2e..89c48a0bd 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -361,6 +361,8 @@ module cv32e40p_tb_wrapper .csr_we_i (cv32e40p_top_i.core_i.cs_registers_i.csr_we_int), .csr_wdata_int_i(cv32e40p_top_i.core_i.cs_registers_i.csr_wdata_int), + .csr_fregs_we_i(cv32e40p_top_i.core_i.cs_registers_i.fregs_we_i), + .csr_mstatus_n_i (cv32e40p_top_i.core_i.cs_registers_i.mstatus_n), .csr_mstatus_q_i (cv32e40p_top_i.core_i.cs_registers_i.mstatus_q), .csr_mstatus_fs_n_i(cv32e40p_top_i.core_i.cs_registers_i.mstatus_fs_n), diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 9d658947d..371f5ebd8 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -199,6 +199,8 @@ typedef struct { logic mcause_we; logic dcsr_we; + logic fregs_we; + logic jvt_we; Status_t mstatus_n; Status_t mstatus_q; @@ -528,6 +530,8 @@ task monitor_pipeline(); r_pipe_freeze_trace.csr.we = csr_we_i; r_pipe_freeze_trace.csr.wdata_int = csr_wdata_int_i; + r_pipe_freeze_trace.csr.fregs_we = csr_fregs_we_i; + r_pipe_freeze_trace.csr.jvt_we = csr_jvt_we_i; r_pipe_freeze_trace.csr.mstatus_n = csr_mstatus_n_i; r_pipe_freeze_trace.csr.mstatus_q = csr_mstatus_q_i; From ea4b9bc0d4b8fee41638eebb689bb8c1891cb892 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Mon, 6 Nov 2023 18:00:24 +0800 Subject: [PATCH 24/50] RVFI - Handling concurrent writes to mstatus_fs when flw followed by csrw --- bhv/cv32e40p_rvfi.sv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index a27ee6d09..b33324636 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1134,7 +1134,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; function void mstatus_to_id(); `CSR_FROM_PIPE(id, mstatus) `CSR_FROM_PIPE(id, mstatus_fs) - if(r_pipe_freeze_trace.csr.fregs_we & !r_pipe_freeze_trace.csr.mstatus_fs_we) begin //writes happening in ex that needs to be reported to id + if(r_pipe_freeze_trace.csr.fregs_we && !r_pipe_freeze_trace.csr.mstatus_fs_we && !(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we)) begin //writes happening in ex that needs to be reported to id trace_id.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; end ->e_mstatus_to_id; @@ -1515,6 +1515,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(ex, mstatus_fs) trace_ex.m_csr.mstatus_fs_we = 1'b1; trace_ex.m_csr.mstatus_fs_wmask = '1; + if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we + trace_ex.m_csr.mstatus_fs_wdata = FS_DIRTY; + end end end From 0bd8bcfa4e5a049543673b19abd0a2ce8f83c331 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Wed, 1 Nov 2023 16:49:55 +0800 Subject: [PATCH 25/50] RVFI - Adjusting rf_we_wb to catch only the relevant register write --- bhv/cv32e40p_rvfi.sv | 20 ++++++++++++++------ bhv/cv32e40p_tb_wrapper.sv | 6 ++++-- bhv/pipe_freeze_trace.sv | 5 +++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index b33324636..addd791a9 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -127,6 +127,9 @@ module cv32e40p_rvfi input logic [31:0] data_wdata_ex_i, input logic lsu_split_q_ex_i, + input logic mult_ready_i, + input logic alu_ready_i, + //// WB probes //// input logic [31:0] pc_wb_i, input logic wb_ready_i, @@ -1293,6 +1296,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_core_is_decoding; // For readability, ctrl_fsm is DECODE or DECODE_HWLOOP + bit s_rf_we_wb_adjusted; // + trace_if = new(); trace_id = new(); trace_ex = new(); @@ -1322,6 +1327,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_core_is_decoding = 1'b0; + s_rf_we_wb_adjusted = 1'b0; + forever begin wait(e_pipe_monitor_ok.triggered); // event triggered #1; @@ -1401,6 +1408,7 @@ 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_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_fflags_we_non_apu = 1'b0; if (r_pipe_freeze_trace.csr.fflags_we) begin @@ -1432,7 +1440,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end if (trace_wb.m_valid && !s_skip_wb) begin - if (r_pipe_freeze_trace.rf_we_wb) begin + if (s_rf_we_wb_adjusted) begin if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0]) && trace_wb.m_mem_req_id_valid[0]) begin trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1450,7 +1458,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_wb.m_valid = 1'b0; end else begin if (s_wb_valid_adjusted) begin - if (r_pipe_freeze_trace.rf_we_wb) begin + if (s_rf_we_wb_adjusted) begin if (!trace_wb.m_ex_fw) begin trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1498,7 +1506,7 @@ 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 (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port) begin + if (s_rf_we_wb_adjusted && !s_apu_to_lsu_port) 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; @@ -1536,7 +1544,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end trace_ex.m_valid = 1'b0; end - end else if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port && !s_was_flush) begin + end else if (s_rf_we_wb_adjusted && !s_apu_to_lsu_port && !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; @@ -1625,7 +1633,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_rd_addr[0] = r_pipe_freeze_trace.ex_reg_addr; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.ex_reg_wdata; trace_id.m_got_ex_reg = 1'b1; - end else if (!trace_ex.m_valid & r_pipe_freeze_trace.rf_we_wb & !trace_id.m_ex_fw) begin + end else if (!trace_ex.m_valid & s_rf_we_wb_adjusted & !trace_id.m_ex_fw) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; end else if (r_pipe_freeze_trace.rf_we_wb) begin @@ -1732,7 +1740,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_mem_req_id_valid[0] = 1'b0; trace_id.m_mem_req_id_valid[1] = 1'b1; end - end else if (r_pipe_freeze_trace.rf_we_wb && !r_pipe_freeze_trace.ex_reg_we) begin + end else if (s_rf_we_wb_adjusted && !r_pipe_freeze_trace.ex_reg_we) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 89c48a0bd..18acc6a99 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -306,9 +306,11 @@ module cv32e40p_tb_wrapper // .rf_addr_alu_i (cv32e40p_top_i.core_i.id_stage_i.regfile_alu_waddr_fw_i), // .rf_wdata_alu_i (cv32e40p_top_i.core_i.id_stage_i.regfile_alu_wdata_fw_i), + .mult_ready_i (cv32e40p_top_i.core_i.ex_stage_i.mult_ready), + .alu_ready_i (cv32e40p_top_i.core_i.ex_stage_i.alu_ready), //// WB probes //// - .wb_valid_i(cv32e40p_top_i.core_i.wb_valid), - + .wb_valid_i (cv32e40p_top_i.core_i.wb_valid), + .wb_ready_i (cv32e40p_top_i.core_i.lsu_ready_wb), //// LSU probes //// .data_we_ex_i (cv32e40p_top_i.core_i.data_we_ex), .data_atop_ex_i (cv32e40p_top_i.core_i.data_atop_ex), diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 371f5ebd8..b5bea9bb3 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -113,6 +113,9 @@ typedef struct { logic [31:0] data_wdata_ex; logic lsu_split_q_ex; + logic mult_ready; + logic alu_ready; + //// WB probes //// logic [31:0] pc_wb; logic wb_ready; @@ -466,6 +469,8 @@ task monitor_pipeline(); r_pipe_freeze_trace.data_wdata_ex = data_wdata_ex_i; r_pipe_freeze_trace.lsu_split_q_ex = lsu_split_q_ex_i; + r_pipe_freeze_trace.mult_ready = mult_ready_i; + r_pipe_freeze_trace.alu_ready = alu_ready_i; //// WB probes //// r_pipe_freeze_trace.pc_wb = pc_wb_i; r_pipe_freeze_trace.wb_ready = wb_ready_i; From 1667c307dfcc8c7d6107725b870c130c327ee075 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 2 Nov 2023 15:17:34 +0800 Subject: [PATCH 26/50] RVFI - Correcting register file writes to catch only relevant ones --- bhv/cv32e40p_rvfi.sv | 98 ++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index addd791a9..4d87737cf 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1296,6 +1296,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_core_is_decoding; // For readability, ctrl_fsm is DECODE or DECODE_HWLOOP + bit s_ex_reg_we_adjusted; //ex_reg_we bit s_rf_we_wb_adjusted; // trace_if = new(); @@ -1327,7 +1328,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_core_is_decoding = 1'b0; - s_rf_we_wb_adjusted = 1'b0; + s_ex_reg_we_adjusted = 1'b0; + s_rf_we_wb_adjusted = 1'b0; forever begin wait(e_pipe_monitor_ok.triggered); // event triggered @@ -1408,6 +1410,7 @@ 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_fflags_we_non_apu = 1'b0; @@ -1439,40 +1442,22 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_skip_wb = 1'b1; end end - if (trace_wb.m_valid && !s_skip_wb) begin - if (s_rf_we_wb_adjusted) begin - if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0]) && trace_wb.m_mem_req_id_valid[0]) begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - trace_wb.m_mem_req_id_valid[0] = 1'b0; - end else if (trace_wb.m_2_rd_insn && (trace_wb.m_rd_addr[1] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[1]) && trace_wb.m_mem_req_id_valid[1]) begin + + if (trace_wb.m_valid && !s_skip_wb && s_rf_we_wb_adjusted) begin + // if (s_rf_we_wb_adjusted) begin + if(trace_wb.m_2_rd_insn) begin trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_wb.m_mem_req_id_valid[1] = 1'b0; + end else begin + trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; end - end + // end + + send_rvfi(trace_wb); + ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; + trace_wb.m_valid = 1'b0; - if (!trace_wb.m_data_missaligned) begin - send_rvfi(trace_wb); - ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; - trace_wb.m_valid = 1'b0; - end else begin - if (s_wb_valid_adjusted) begin - if (s_rf_we_wb_adjusted) begin - if (!trace_wb.m_ex_fw) begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end - if (trace_wb.m_data_missaligned && !trace_wb.m_got_first_data) begin - trace_wb.m_got_first_data = 1'b1; - end else begin - send_rvfi(trace_wb); - ->e_dev_send_wb_2; ->e_send_rvfi_trace_wb_3; - trace_wb.m_valid = 1'b0; - end - end // rf_we_wb - end - end end if (trace_ex.m_valid) begin @@ -1485,14 +1470,14 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(ex, tdata2) tinfo_to_ex(); - if (r_pipe_freeze_trace.regfile_we_lsu) begin + if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_4; - if ((cnt_data_resp == trace_ex.m_mem_req_id[0]) && !(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin + if ( !(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; trace_ex.m_mem_req_id_valid[0] = 1'b0; - end else if ((cnt_data_resp == trace_ex.m_mem_req_id[1]) && trace_ex.m_mem_req_id_valid[1]) begin + end else if (trace_ex.m_mem_req_id_valid[1]) begin trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; @@ -1506,6 +1491,10 @@ 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 && !s_apu_to_lsu_port) begin ->e_dev_commit_rf_to_ex_1; if (trace_ex.m_got_ex_reg) begin @@ -1527,22 +1516,23 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_csr.mstatus_fs_wdata = FS_DIRTY; end end - end - if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end - if (trace_ex.m_is_load) begin // only move relevant instr in wb stage - ->e_ex_to_wb_1; - trace_wb.move_down_pipe(trace_ex); + send_rvfi(trace_ex); + trace_ex.m_valid = 1'b0; + end else begin - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); + if (trace_ex.m_is_load) begin // only move relevant instr in wb stage + ->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 - send_rvfi(trace_ex); - ->e_send_rvfi_trace_ex_6; + trace_ex.m_valid = 1'b0; end - trace_ex.m_valid = 1'b0; end end else if (s_rf_we_wb_adjusted && !s_apu_to_lsu_port && !s_was_flush) begin ->e_dev_commit_rf_to_ex_2; @@ -1636,7 +1626,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end else if (!trace_ex.m_valid & s_rf_we_wb_adjusted & !trace_id.m_ex_fw) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (r_pipe_freeze_trace.rf_we_wb) begin + end else if (s_rf_we_wb_adjusted) begin trace_id.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; trace_id.m_2_rd_insn = 1'b1; @@ -1651,17 +1641,12 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; + trace_id.m_mem_req_id[0] = cnt_data_req; end if (!r_pipe_freeze_trace.data_we_ex) begin trace_id.m_is_load = 1'b1; trace_id.m_mem.wmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; - if (r_pipe_freeze_trace.data_misaligned) begin - trace_id.m_data_missaligned = 1'b1; - trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; - trace_id.m_mem_req_id[0] = cnt_data_req; - trace_id.m_mem_req_id_valid[1] = 1'b1; - end end else begin trace_id.m_mem.rmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; end @@ -1724,15 +1709,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; + trace_id.m_mem_req_id[0] = cnt_data_req; end if (!r_pipe_freeze_trace.data_we_ex) begin trace_id.m_is_load = 1'b1; - if (r_pipe_freeze_trace.data_misaligned) begin - trace_id.m_data_missaligned = 1'b1; - trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; - trace_id.m_mem_req_id[0] = cnt_data_req; - trace_id.m_mem_req_id_valid[1] = 1'b1; - end end if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; From 9971993f4cf3be98cd9101bf6caf9ba575275979 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 2 Nov 2023 15:54:22 +0800 Subject: [PATCH 27/50] RVFI - Correcting rd0 overwrite on cv.lw --- bhv/cv32e40p_rvfi.sv | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 4d87737cf..defe7981d 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1448,6 +1448,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if(trace_wb.m_2_rd_insn) begin trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + end else if (trace_wb.m_ex_fw) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_wb.m_2_rd_insn = 1'b1; end else begin trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; From d5ed95979ddf18c99212e18d2a690f0854e596ca Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 7 Nov 2023 18:44:02 +0800 Subject: [PATCH 28/50] Running verible --- bhv/cv32e40p_rvfi.sv | 78 ++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index defe7981d..d37f40abb 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -127,8 +127,8 @@ module cv32e40p_rvfi input logic [31:0] data_wdata_ex_i, input logic lsu_split_q_ex_i, - input logic mult_ready_i, - input logic alu_ready_i, + input logic mult_ready_i, + input logic alu_ready_i, //// WB probes //// input logic [31:0] pc_wb_i, @@ -1296,37 +1296,37 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_core_is_decoding; // For readability, ctrl_fsm is DECODE or DECODE_HWLOOP - bit s_ex_reg_we_adjusted; //ex_reg_we - bit s_rf_we_wb_adjusted; // + bit s_ex_reg_we_adjusted; //ex_reg_we + bit s_rf_we_wb_adjusted; // - trace_if = new(); - trace_id = new(); - trace_ex = new(); - trace_wb = new(); - s_new_valid_insn = 1'b0; - s_ex_valid_adjusted = 1'b0; + trace_if = new(); + trace_id = new(); + trace_ex = new(); + trace_wb = new(); + s_new_valid_insn = 1'b0; + s_ex_valid_adjusted = 1'b0; - s_id_done = 1'b0; - s_apu_wb_ok = 1'b0; - s_apu_0_cycle_reps = 1'b0; + s_id_done = 1'b0; + s_apu_wb_ok = 1'b0; + s_apu_0_cycle_reps = 1'b0; - next_send = 1; - cnt_data_req = 0; - cnt_data_resp = 0; - cnt_apu_req = 0; - cnt_apu_resp = 0; - csr_is_irq = '0; - is_dbg_taken = '0; - s_was_flush = 1'b0; + next_send = 1; + cnt_data_req = 0; + cnt_data_resp = 0; + cnt_apu_req = 0; + cnt_apu_resp = 0; + csr_is_irq = '0; + is_dbg_taken = '0; + s_was_flush = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - s_skip_wb = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; + s_skip_wb = 1'b0; - s_core_is_decoding = 1'b0; + s_core_is_decoding = 1'b0; s_ex_reg_we_adjusted = 1'b0; s_rf_we_wb_adjusted = 1'b0; @@ -1445,17 +1445,17 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_wb.m_valid && !s_skip_wb && s_rf_we_wb_adjusted) begin // if (s_rf_we_wb_adjusted) begin - if(trace_wb.m_2_rd_insn) begin - trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (trace_wb.m_ex_fw) begin - trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_wb.m_2_rd_insn = 1'b1; - end else begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end + if (trace_wb.m_2_rd_insn) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + end else if (trace_wb.m_ex_fw) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_wb.m_2_rd_insn = 1'b1; + end else begin + trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; + end // end send_rvfi(trace_wb); @@ -1476,7 +1476,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_4; - if ( !(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin + if (!(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; From 7263fccc5c8fafaafe68f257ed052b1ff1786a5a Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Wed, 8 Nov 2023 13:43:38 +0800 Subject: [PATCH 29/50] RVFI - Matching mstatus_fw updtaes when flw with updated register files write trigger --- bhv/cv32e40p_rvfi.sv | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index d37f40abb..190a0e83b 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1444,7 +1444,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end if (trace_wb.m_valid && !s_skip_wb && s_rf_we_wb_adjusted) begin - // if (s_rf_we_wb_adjusted) begin if (trace_wb.m_2_rd_insn) begin trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1456,7 +1455,15 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; end - // end + + if (r_pipe_freeze_trace.csr.fregs_we) begin + `CSR_FROM_PIPE(wb, mstatus_fs) + trace_wb.m_csr.mstatus_fs_we = 1'b1; + trace_wb.m_csr.mstatus_fs_wmask = '1; + if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we + trace_wb.m_csr.mstatus_fs_wdata = FS_DIRTY; + end + end send_rvfi(trace_wb); ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; From 21d05ac0e37b66f83c4b2639061f871e8a42e932 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 9 Nov 2023 14:59:41 +0800 Subject: [PATCH 30/50] RVFI - Checking order of trace_ex when APU response to avoid overwritting wrong csr when fast fpu instruction --- bhv/cv32e40p_rvfi.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 190a0e83b..607868e50 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1134,11 +1134,13 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rmask = '1; event e_mstatus_to_id; + event e_fregs_dirty_1, e_fregs_dirty_2, e_fregs_dirty_3; function void mstatus_to_id(); `CSR_FROM_PIPE(id, mstatus) `CSR_FROM_PIPE(id, mstatus_fs) if(r_pipe_freeze_trace.csr.fregs_we && !r_pipe_freeze_trace.csr.mstatus_fs_we && !(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we)) begin //writes happening in ex that needs to be reported to id trace_id.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + ->e_fregs_dirty_2; end ->e_mstatus_to_id; endfunction @@ -1179,7 +1181,7 @@ 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) begin + 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 endfunction @@ -1463,6 +1465,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we trace_wb.m_csr.mstatus_fs_wdata = FS_DIRTY; end + ->e_fregs_dirty_1; end send_rvfi(trace_wb); @@ -1526,6 +1529,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we trace_ex.m_csr.mstatus_fs_wdata = FS_DIRTY; end + ->e_fregs_dirty_3; end send_rvfi(trace_ex); From 4bea7a41f86b0df5807255cc034e5814ec87e2e9 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 9 Nov 2023 17:10:55 +0800 Subject: [PATCH 31/50] RVFI - Updating mstatus_fs on trace_wb when apu resp --- bhv/cv32e40p_rvfi.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 607868e50..0225e5fb2 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1184,6 +1184,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; 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 + if (r_pipe_freeze_trace.csr.mstatus_fs_we && (trace_wb.m_order > trace_apu_resp.m_order)) begin + trace_wb.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end endfunction function void csr_to_apu_req(); From 49889b045e81704786584907f9f3b4a670726174 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 9 Nov 2023 18:50:31 +0800 Subject: [PATCH 32/50] RVFI - Sending dret when followed by trap --- bhv/cv32e40p_rvfi.sv | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 0225e5fb2..880736e0e 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1264,6 +1264,15 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_is_irq_start; 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) + tinfo_to_id(); + `CSR_FROM_PIPE(id, mip) + send_rvfi(trace_id); + end trace_id.init(trace_if); trace_id.m_trap = ~r_pipe_freeze_trace.minstret; trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; From 672bbf51e9489bf82b3671bf0c2cc5433a938e4b Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 9 Nov 2023 18:46:25 +0100 Subject: [PATCH 33/50] Issue #722 correction Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_id_stage.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index 62e4d7217..60ace6cdf 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -810,6 +810,9 @@ module cv32e40p_id_stage if (ctrl_transfer_target_mux_sel == JT_JALR) begin apu_read_regs[0] = regfile_addr_ra_id; apu_read_regs_valid[0] = 1'b1; + end else begin + apu_read_regs[0] = regfile_addr_ra_id; + apu_read_regs_valid[0] = 1'b0; end end // OP_A_CURRPC: OP_A_REGA_OR_FWD: begin From e6c63556a9e1d9ebaf7c50ec61e21e7bbd899cad Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 9 Nov 2023 18:57:52 +0100 Subject: [PATCH 34/50] Issue #894 correction Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_core.sv | 31 ++++++++++++++++----------- rtl/cv32e40p_ex_stage.sv | 45 +++++++++++++++++++++++++--------------- rtl/cv32e40p_id_stage.sv | 6 ++++-- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index 549869b9b..7d83e548b 100644 --- a/rtl/cv32e40p_core.sv +++ b/rtl/cv32e40p_core.sv @@ -230,6 +230,7 @@ module cv32e40p_core logic regfile_we_ex; logic [ 5:0] regfile_waddr_fw_wb_o; // From WB to ID logic regfile_we_wb; + logic regfile_we_wb_power; logic [ 31:0] regfile_wdata; logic [ 5:0] regfile_alu_waddr_ex; @@ -237,6 +238,7 @@ module cv32e40p_core logic [ 5:0] regfile_alu_waddr_fw; logic regfile_alu_we_fw; + logic regfile_alu_we_fw_power; logic [ 31:0] regfile_alu_wdata_fw; // CSR control @@ -702,13 +704,15 @@ module cv32e40p_core .wake_from_sleep_o(wake_from_sleep), // Forward Signals - .regfile_waddr_wb_i(regfile_waddr_fw_wb_o), // Write address ex-wb pipeline - .regfile_we_wb_i (regfile_we_wb), // write enable for the register file - .regfile_wdata_wb_i(regfile_wdata), // write data to commit in the register file + .regfile_waddr_wb_i (regfile_waddr_fw_wb_o), // Write address ex-wb pipeline + .regfile_we_wb_i (regfile_we_wb), // write enable for the register file + .regfile_we_wb_power_i(regfile_we_wb_power), + .regfile_wdata_wb_i (regfile_wdata), // write data to commit in the register file - .regfile_alu_waddr_fw_i(regfile_alu_waddr_fw), - .regfile_alu_we_fw_i (regfile_alu_we_fw), - .regfile_alu_wdata_fw_i(regfile_alu_wdata_fw), + .regfile_alu_waddr_fw_i (regfile_alu_waddr_fw), + .regfile_alu_we_fw_i (regfile_alu_we_fw), + .regfile_alu_we_fw_power_i(regfile_alu_we_fw_power), + .regfile_alu_wdata_fw_i (regfile_alu_wdata_fw), // from ALU .mult_multicycle_i(mult_multicycle), @@ -740,6 +744,7 @@ module cv32e40p_core // // ///////////////////////////////////////////////////// cv32e40p_ex_stage #( + .COREV_PULP (COREV_PULP), .FPU (FPU), .APU_NARGS_CPU (APU_NARGS_CPU), .APU_WOP_CPU (APU_WOP_CPU), @@ -843,18 +848,20 @@ module cv32e40p_core .regfile_we_i (regfile_we_ex), // Output of ex stage pipeline - .regfile_waddr_wb_o(regfile_waddr_fw_wb_o), - .regfile_we_wb_o (regfile_we_wb), - .regfile_wdata_wb_o(regfile_wdata), + .regfile_waddr_wb_o (regfile_waddr_fw_wb_o), + .regfile_we_wb_o (regfile_we_wb), + .regfile_we_wb_power_o(regfile_we_wb_power), + .regfile_wdata_wb_o (regfile_wdata), // To IF: Jump and branch target and decision .jump_target_o (jump_target_ex), .branch_decision_o(branch_decision), // To ID stage: Forwarding signals - .regfile_alu_waddr_fw_o(regfile_alu_waddr_fw), - .regfile_alu_we_fw_o (regfile_alu_we_fw), - .regfile_alu_wdata_fw_o(regfile_alu_wdata_fw), + .regfile_alu_waddr_fw_o (regfile_alu_waddr_fw), + .regfile_alu_we_fw_o (regfile_alu_we_fw), + .regfile_alu_we_fw_power_o(regfile_alu_we_fw_power), + .regfile_alu_wdata_fw_o (regfile_alu_wdata_fw), // stall control .is_decoding_i (is_decoding), diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index f327b8db6..4d870a969 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -33,6 +33,7 @@ module cv32e40p_ex_stage import cv32e40p_pkg::*; import cv32e40p_apu_core_pkg::*; #( + parameter COREV_PULP = 0, parameter FPU = 0, parameter APU_NARGS_CPU = 3, parameter APU_WOP_CPU = 6, @@ -140,11 +141,13 @@ module cv32e40p_ex_stage // Output of EX stage pipeline output logic [ 5:0] regfile_waddr_wb_o, output logic regfile_we_wb_o, + output logic regfile_we_wb_power_o, output logic [31:0] regfile_wdata_wb_o, // Forwarding ports : to ID stage output logic [ 5:0] regfile_alu_waddr_fw_o, output logic regfile_alu_we_fw_o, + output logic regfile_alu_we_fw_power_o, output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL // To IF: Jump and branch target and decision @@ -192,22 +195,27 @@ module cv32e40p_ex_stage // ALU write port mux always_comb begin - regfile_alu_wdata_fw_o = '0; - regfile_alu_waddr_fw_o = '0; - regfile_alu_we_fw_o = '0; - wb_contention = 1'b0; + regfile_alu_wdata_fw_o = '0; + regfile_alu_waddr_fw_o = '0; + regfile_alu_we_fw_o = 1'b0; + regfile_alu_we_fw_power_o = 1'b0; + wb_contention = 1'b0; - // APU single cycle operations, and multicycle operations (>2cycles) are written back on ALU port + // APU single cycle operations, and multicycle operations (> 2cycles) are written back on ALU port if (apu_valid & (apu_singlecycle | apu_multicycle)) begin - regfile_alu_we_fw_o = 1'b1; - regfile_alu_waddr_fw_o = apu_waddr; - regfile_alu_wdata_fw_o = apu_result; + regfile_alu_we_fw_o = 1'b1; + regfile_alu_we_fw_power_o = 1'b1; + regfile_alu_waddr_fw_o = apu_waddr; + regfile_alu_wdata_fw_o = apu_result; if (regfile_alu_we_i & ~apu_en_i) begin wb_contention = 1'b1; end end else begin - regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; // private fpu incomplete? + regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; + regfile_alu_we_fw_power_o = !COREV_PULP ? regfile_alu_we_i & ~apu_en_i : + regfile_alu_we_i & ~apu_en_i & + mult_ready & alu_ready & lsu_ready_ex_i; regfile_alu_waddr_fw_o = regfile_alu_waddr_i; if (alu_en_i) regfile_alu_wdata_fw_o = alu_result; if (mult_en_i) regfile_alu_wdata_fw_o = mult_result; @@ -217,21 +225,24 @@ module cv32e40p_ex_stage // LSU write port mux always_comb begin - regfile_we_wb_o = 1'b0; - regfile_waddr_wb_o = regfile_waddr_lsu; - regfile_wdata_wb_o = lsu_rdata_i; - wb_contention_lsu = 1'b0; + regfile_we_wb_o = 1'b0; + regfile_we_wb_power_o = 1'b0; + regfile_waddr_wb_o = regfile_waddr_lsu; + regfile_wdata_wb_o = lsu_rdata_i; + wb_contention_lsu = 1'b0; if (regfile_we_lsu) begin - regfile_we_wb_o = 1'b1; + regfile_we_wb_o = 1'b1; + regfile_we_wb_power_o = !COREV_PULP ? 1'b1 : ~data_misaligned_ex_i & wb_ready_i; if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin wb_contention_lsu = 1'b1; end // APU two-cycle operations are written back on LSU port end else if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin - regfile_we_wb_o = 1'b1; - regfile_waddr_wb_o = apu_waddr; - regfile_wdata_wb_o = apu_result; + regfile_we_wb_o = 1'b1; + regfile_we_wb_power_o = 1'b1; + regfile_waddr_wb_o = apu_waddr; + regfile_wdata_wb_o = apu_result; end end diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index 60ace6cdf..93bb13803 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -226,10 +226,12 @@ module cv32e40p_id_stage // Forward Signals input logic [5:0] regfile_waddr_wb_i, input logic regfile_we_wb_i, + input logic regfile_we_wb_power_i, input logic [31:0] regfile_wdata_wb_i, // From wb_stage: selects data from data memory, ex_stage result and sp rdata input logic [ 5:0] regfile_alu_waddr_fw_i, input logic regfile_alu_we_fw_i, + input logic regfile_alu_we_fw_power_i, input logic [31:0] regfile_alu_wdata_fw_i, // from ALU @@ -952,12 +954,12 @@ module cv32e40p_id_stage // Write port a .waddr_a_i(regfile_waddr_wb_i), .wdata_a_i(regfile_wdata_wb_i), - .we_a_i (regfile_we_wb_i), + .we_a_i (regfile_we_wb_power_i), // Write port b .waddr_b_i(regfile_alu_waddr_fw_i), .wdata_b_i(regfile_alu_wdata_fw_i), - .we_b_i (regfile_alu_we_fw_i) + .we_b_i (regfile_alu_we_fw_power_i) ); From 223af2d8f03801c6b5d6fbee5e386c0612ccbcfd Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Wed, 15 Nov 2023 13:01:34 +0800 Subject: [PATCH 35/50] RVFI - Better handling of rf wb when apu contention --- bhv/cv32e40p_rvfi.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 880736e0e..bff2d03fd 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1424,8 +1424,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 +1521,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 +1561,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; From c6466f07fa0b9a85f4111d1f5e3c7bfb425cc14e Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 16 Nov 2023 12:33:51 +0800 Subject: [PATCH 36/50] RVFI - Better mstatus_fs when csr write to fflags --- bhv/cv32e40p_rvfi.sv | 9 ++ bhv/insn_trace.sv | 201 ++++++++++++++++++++------------------- bhv/pipe_freeze_trace.sv | 5 +- 3 files changed, 116 insertions(+), 99 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index bff2d03fd..e895bde38 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; event e_send_rvfi_trace_apu_resp; event @@ -1579,6 +1580,14 @@ 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) begin //First cycle after id_ready, csr write is asserted in this cycle + `CSR_FROM_PIPE(id, mstatus) + `CSR_FROM_PIPE(id, mstatus_fs) + ->e_csr_in_ex; + end + + trace_id.m_sample_csr_write_in_ex = 1'b0; mtvec_to_id(); `CSR_FROM_PIPE(id, mip) 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; From b1ce8d3dbf0e6d45c4b25c3f13864a1af5f2cf71 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 16 Nov 2023 14:03:11 +0800 Subject: [PATCH 37/50] RVFI - Better mepc and mcause reporting --- bhv/cv32e40p_rvfi.sv | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index e895bde38..c1ed962b3 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1156,7 +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; + event e_csr_in_ex, e_csr_irq; event e_send_rvfi_trace_apu_resp; event @@ -1584,23 +1584,19 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if(trace_id.m_sample_csr_write_in_ex) 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 - trace_id.m_sample_csr_write_in_ex = 1'b0; + 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) @@ -1811,6 +1807,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 From fb856d096d2f789d044feeced483c86a40b11614 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 17 Nov 2023 12:47:32 +0800 Subject: [PATCH 38/50] RVFI - Re-adding irq filter on csr update in ex --- bhv/cv32e40p_rvfi.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index c1ed962b3..2996116ee 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1581,7 +1581,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; //EX_STAGE if (trace_id.m_valid) begin - if(trace_id.m_sample_csr_write_in_ex) begin //First cycle after id_ready, csr write is asserted in this cycle + 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) From d6fdb29c00d3e323010c3529a8c8181b98b76c98 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 17 Nov 2023 15:54:40 +0800 Subject: [PATCH 39/50] RVFI - Extending mstatus_fs update to trace_id when fregs_we --- bhv/cv32e40p_rvfi.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 2996116ee..11f7ea7f4 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1182,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 From c83c428bdeaf7649983cda902e7c4a078cfbba0d Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 21 Nov 2023 14:10:31 +0800 Subject: [PATCH 40/50] RVFI - Triggering ex to wb even when DBG --- bhv/cv32e40p_rvfi.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 11f7ea7f4..273afff97 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1427,7 +1427,7 @@ 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_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.ctrl_fsm_cs == DBG_FLUSH) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID));// && !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_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); From be7fef9a869354a2e77aefe94b7f16fc283762d3 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 24 Nov 2023 13:18:07 +0800 Subject: [PATCH 41/50] RVFI - Adding dbg_taken_if to id to ex and ex to wb triggers --- bhv/cv32e40p_rvfi.sv | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 273afff97..27170d76e 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1427,7 +1427,7 @@ 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.ctrl_fsm_cs == DBG_FLUSH) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID));// && !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.ctrl_fsm_cs == DBG_FLUSH) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF));// && !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_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); @@ -1579,8 +1579,13 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end end + //old + // 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); + //issue 51 + 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_FLUSH)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); - 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); + // issue 49 + // 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 == FLUSH_EX)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); //EX_STAGE if (trace_id.m_valid) begin From b94c429098e4d25151f2beee5a417ac631ad2637 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 27 Nov 2023 15:47:43 +0100 Subject: [PATCH 42/50] In controller FSM DECODE_HWLOOP state, aligned ebreak and ecall management to DECODE state. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_controller.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/cv32e40p_controller.sv b/rtl/cv32e40p_controller.sv index 986248619..d2d7b2fe9 100644 --- a/rtl/cv32e40p_controller.sv +++ b/rtl/cv32e40p_controller.sv @@ -766,7 +766,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; ebrk_insn_i: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; + halt_id_o = 1'b0; if (debug_mode_q) // we got back to the park loop in the debug rom @@ -778,15 +778,15 @@ module cv32e40p_controller import cv32e40p_pkg::*; else begin // otherwise just a normal ebreak exception - ctrl_fsm_ns = FLUSH_EX; + ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE_HWLOOP; end end ecall_insn_i: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; - ctrl_fsm_ns = FLUSH_EX; + halt_id_o = 1'b0; + ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE_HWLOOP; end csr_status_i: begin From 45387a8faac9f7e52050d3a549ef5f1e23de5b9e Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 27 Nov 2023 17:32:55 +0100 Subject: [PATCH 43/50] Adjusted FPU DIV/SQRT latency to new T-Head unit. Signed-off-by: Pascal Gouedo --- docs/source/pipeline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/pipeline.rst b/docs/source/pipeline.rst index 516daa2e4..971a0a9e1 100644 --- a/docs/source/pipeline.rst +++ b/docs/source/pipeline.rst @@ -150,7 +150,7 @@ The cycle counts assume zero stall on the instruction-side interface and zero st | Comparison, Conversion | | If there are enough instructions between FPU one and | | or Classify | | the instruction using the result then cycle number is 1. | +------------------------+--------------------------------------+ "Enough instruction" number is either FPU_ADDMUL_LAT, | - | Single Precision | 1..12 | FPU_OTHERS_LAT or 11. | + | Single Precision | 1..19 | FPU_OTHERS_LAT or 11. | | Floating-Point | | If there are no instruction in between then cycle number is | | Division and | | the maximum value for each category. | | Square-Root | | | From b838f1648b7e1e0a8554d6c0ef03b46bbae33dbc Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 27 Nov 2023 17:33:29 +0100 Subject: [PATCH 44/50] Added paragraphs and notes about hardware loops impact on application, exceptions handlers and debugger. Signed-off-by: Pascal Gouedo --- docs/source/corev_hw_loop.rst | 43 +++++++++++++++++++++++++++++++++++ docs/source/debug.rst | 10 ++++++++ 2 files changed, 53 insertions(+) diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 7b83ec09f..7170baf50 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -138,3 +138,46 @@ it is executed 10x10 times. Whereas the outermost loop, from startO to (endO - 4 executes 10 times the innermost loop and adds 2 to the register %[j]. At the end of the loop, the register %[i] contains 300 and the register %[j] contains 20. +.. _hwloop-exceptions_handlers: + +Hardware loops impact on application, exceptions handlers and debugger +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Application and ebreak/ecall exception handlers +----------------------------------------------- + +When an ebreak or an ecall instruction is used in an application, special care should be given for those instruction handlers in case they are placed as the last instruction of an HWLoop. +Those handlers should manage MEPC and lpcountX CSRs updates because an hw loop early-exit could happen if not done. + +At the end of the handlers after restoring the context/CSRs, a piece of smart code should be added (by order of piority): + +1. if MEPC is equal to "lpend0 - 4", then MPEC should be set to lpstart0 and lpcount0 should be decremented by 1 if strictly higher than 0, +2. if MEPC is equal to "lpend1 - 4", then MPEC should be set to lpstart1 and lpcount1 should be decremented by 1 if strictly higher than 0, +3. if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4), then MPEC should be incremented by 4, +4. if instruction at MEPC location is either ecall or ebreak, MPEC should be incremented by 4, +5. if instruction at MEPC location location is c.ebreak, MPEC should be incremented by 2. + +The 2 last cases are the standard ones when ebreak/ecall are not inside an HWLopp. + +Interrupt handlers +------------------ + +When an interrupt is happening on the last HWLoop instruction, its execution is cancelled, its address is saved in MEPC and its execution will be resumed when returning from interrupt handler. +There is nothing special to be done in those interrupt handlers with respect to MEPC and lpcountX updates, they will be correctly managed by design when executing this last HWLoop instruction after interrupt handler execution. + +Illegal instruction exception handler +------------------------------------- + +Depending if an application is going to resume or not after Illegal instruction exception handler, same MEPC/HWLoops CSRs management than ebreak/ecall could be necessary. + +Debugger +-------- + +If ebreak is used to enter in Debug Mode (:ref:`ebreak_scenario_2`) and put at the last instruction location of an HWLoop (not very likely to happen), same management than above should be done but on DPC rather than on MEPC. + +When ebreak instruction is used as Software Breakpoint by a debugger when in debug mode and is placed at the last instruction location of an HWLoop in instruction memory, no special management is foreseen. +When executing the Software Breakpoint/ebreak instruction, control is given back to the debugger which will manage the different cases. +For instance in Single-Step case, original instruction is put back in instruction memory, a Single-Step command is executed on this last instruction (with desgin updating PC and lpcountX to correct values) and Software Breakpoint/ebreak is put back by the debugger in memory. + +When ecall instruction is used by a debugger to execute System Calls and is placed at the last instruction location of an HWLoop in instruction memory, debugger ecall handler in debug rom should do the same than described above for application case. + diff --git a/docs/source/debug.rst b/docs/source/debug.rst index 654183912..b18da9699 100644 --- a/docs/source/debug.rst +++ b/docs/source/debug.rst @@ -162,6 +162,8 @@ The EBREAK instruction description is distributed across several RISC-V specific `RISC-V Priveleged Specification `_, `RISC-V ISA `_. The following is a summary of the behavior for three common scenarios. +.. _ebreak_scenario_1: + Scenario 1 : Enter Exception """""""""""""""""""""""""""" @@ -173,10 +175,14 @@ Executing the EBREAK instruction when the core is **not** in Debug Mode and the To properly return from the exception, the ebreak handler will need to increment the MEPC to the next instruction. This requires querying the size of the ebreak instruction that was used to enter the exception (16 bit c.ebreak or 32 bit ebreak). +As mentioned in :ref:`hwloop-exceptions_handlers`, some additional cases exist for MEPC update when ebreak is the last instruction of an Hardware Loop. + .. note:: The CV32E40P does not support MTVAL CSR register which would have saved the value of the instruction for exceptions. This may be supported on a future core. +.. _ebreak_scenario_2: + Scenario 2 : Enter Debug Mode """"""""""""""""""""""""""""" @@ -187,11 +193,15 @@ Executing the EBREAK instruction when the core is **not** in Debug Mode and the Similar to the exception scenario above, the debugger will need to increment the DPC to the next instruction before returning from Debug Mode. +There is no forseseen situtation where it would be needed to enter in Debug Mode only on the last instruction of an Hardware Loop but just in case this is mentioned in :ref:`hwloop-exceptions_handlers` as well. + .. note:: The default value of DCSR.EBREAKM is 0 and the DCSR is only accessible in Debug Mode. To enter Debug Mode from EBREAK, the user will first need to enter Debug Mode through some other means, such as from the external ``debug_req_i``, and set DCSR.EBREAKM. +.. _ebreak_scenario_3: + Scenario 3 : Exit Program Buffer & Restart Debug Code """"""""""""""""""""""""""""""""""""""""""""""""""""" From ba04544eecf534babd523365d6b5f4b84cf8069d Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 28 Nov 2023 14:58:56 +0800 Subject: [PATCH 45/50] RVFI - Better mret mstatus update sampling --- bhv/cv32e40p_rvfi.sv | 13 +++++++------ bhv/cv32e40p_tb_wrapper.sv | 7 +++++-- bhv/pipe_freeze_trace.sv | 24 +++++++++++++++--------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 27170d76e..771ca6d15 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -75,6 +75,9 @@ module cv32e40p_rvfi input logic ebrk_insn_dec_i, input logic ecall_insn_dec_i, + input logic mret_insn_dec_i, + input logic mret_dec_i, + input logic [5:0] csr_cause_i, input logic debug_csr_save_i, @@ -1579,13 +1582,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end end - //old - // 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); - //issue 51 - 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_FLUSH)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); - // issue 49 - // 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 == FLUSH_EX)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); + // 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_FLUSH) || ((r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) && !r_pipe_freeze_trace.mret_insn_dec)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); //EX_STAGE if (trace_id.m_valid) begin @@ -1594,6 +1593,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, mstatus_fs) `CSR_FROM_PIPE(id, mepc) `CSR_FROM_PIPE(id, mcause) + `CSR_FROM_PIPE(id, dscratch0) + `CSR_FROM_PIPE(id, dscratch1) ->e_csr_in_ex; end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 18acc6a99..ca703682a 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -280,8 +280,11 @@ module cv32e40p_tb_wrapper .is_compressed_id_i(cv32e40p_top_i.core_i.id_stage_i.is_compressed_i), .ebrk_insn_dec_i (cv32e40p_top_i.core_i.id_stage_i.ebrk_insn_dec), .ecall_insn_dec_i (cv32e40p_top_i.core_i.id_stage_i.ecall_insn_dec), - .csr_cause_i (cv32e40p_top_i.core_i.csr_cause), - .debug_csr_save_i (cv32e40p_top_i.core_i.debug_csr_save), + .mret_insn_dec_i (cv32e40p_top_i.core_i.id_stage_i.mret_insn_dec), + .mret_dec_i (cv32e40p_top_i.core_i.id_stage_i.mret_dec), + + .csr_cause_i (cv32e40p_top_i.core_i.csr_cause), + .debug_csr_save_i(cv32e40p_top_i.core_i.debug_csr_save), // HWLOOP regs .hwlp_start_q_i (hwlp_start_q), diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 0fa15f5f5..29e6859df 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -65,6 +65,8 @@ typedef struct { logic ebrk_insn_dec; logic ecall_insn_dec; + logic mret_insn_dec; + logic mret_dec; logic [5:0] csr_cause; @@ -354,19 +356,21 @@ function compute_csr_we(); r_pipe_freeze_trace.csr.mstatus_we = 1'b1; r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; end - CSR_MISA: r_pipe_freeze_trace.csr.misa_we = 1'b1; - CSR_MTVEC: r_pipe_freeze_trace.csr.mtvec_we = 1'b1; - CSR_MSCRATCH: r_pipe_freeze_trace.csr.mscratch_we = 1'b1; - 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_MISA: r_pipe_freeze_trace.csr.misa_we = 1'b1; + CSR_MTVEC: r_pipe_freeze_trace.csr.mtvec_we = 1'b1; + CSR_MSCRATCH: r_pipe_freeze_trace.csr.mscratch_we = 1'b1; + 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: 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; + 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; + CSR_DSCRATCH0: r_pipe_freeze_trace.csr.dscratch0_we = 1'b1; + CSR_DSCRATCH1: r_pipe_freeze_trace.csr.dscratch1_we = 1'b1; endcase end // CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = r_pipe_freeze_trace.csr.mcause_n != r_pipe_freeze_trace.csr.mcause_q; //for debug purpose @@ -426,6 +430,8 @@ task monitor_pipeline(); r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; r_pipe_freeze_trace.ecall_insn_dec = ecall_insn_dec_i; + r_pipe_freeze_trace.mret_insn_dec = mret_insn_dec_i; + r_pipe_freeze_trace.mret_dec = mret_dec_i; r_pipe_freeze_trace.csr_cause = csr_cause_i; r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; r_pipe_freeze_trace.minstret = minstret_i; From ad56cba59a69bc3327dac2d9aa3aca019a85da62 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 28 Nov 2023 12:07:33 +0100 Subject: [PATCH 46/50] Clearer description of handlers management of MEPC/lpcountX. Signed-off-by: Pascal Gouedo --- docs/source/corev_hw_loop.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 7170baf50..81b6ad9c2 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -151,11 +151,11 @@ Those handlers should manage MEPC and lpcountX CSRs updates because an hw loop e At the end of the handlers after restoring the context/CSRs, a piece of smart code should be added (by order of piority): -1. if MEPC is equal to "lpend0 - 4", then MPEC should be set to lpstart0 and lpcount0 should be decremented by 1 if strictly higher than 0, -2. if MEPC is equal to "lpend1 - 4", then MPEC should be set to lpstart1 and lpcount1 should be decremented by 1 if strictly higher than 0, -3. if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4), then MPEC should be incremented by 4, -4. if instruction at MEPC location is either ecall or ebreak, MPEC should be incremented by 4, -5. if instruction at MEPC location location is c.ebreak, MPEC should be incremented by 2. +1. if MEPC = "lpend0 - 4" and lpcount0 >= 2 then MPEC should be set to lpstart0; if MEPC = "lpend0 - 4" and lpcount0 >= 1 then it should be decremented by 1. +2. if MEPC = "lpend1 - 4" and lpcount1 >= 2 then MPEC should be set to lpstart1; if MEPC = "lpend1 - 4" and lpcount1 >= 1 then it should be decremented by 1. +3. if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4) then MPEC should be incremented by 4. +4. if instruction at MEPC location is either ecall or ebreak then MPEC should be incremented by 4. +5. if instruction at MEPC location location is c.ebreak then MPEC should be incremented by 2. The 2 last cases are the standard ones when ebreak/ecall are not inside an HWLopp. From a9d341fedc8b4a6b55b9a2a1e2a831161412ac9f Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 28 Nov 2023 15:05:20 +0100 Subject: [PATCH 47/50] Even clearer description of handlers. Signed-off-by: Pascal Gouedo --- docs/source/corev_hw_loop.rst | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 81b6ad9c2..6d0cbf64d 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -90,12 +90,9 @@ is that it greatly simplifies compiler optimization (relative to basic blocks ma In order to use hardware loops, the compiler needs to setup the loops beforehand with cv.start/i, cv.end/i, cv.count/i or cv.setup/i instructions. The compiler will use HWLoop automatically whenever possible without the need of assembly. -For debugging and context switches, the hardware loop registers are mapped into the CSR custom read-only address space. +For debugging, interrupts and context switches, the hardware loop registers are mapped into the CSR custom read-only address space. To read them csrr instructions should be used and to write them register flavour of hardware loop instructions should be used. Using csrw instructions to write hardware loop registers will generate an illegal instruction exception. - -Since hardware loop feature could be used in interrupt routine/handler, the registers have -to be saved (resp. restored) at the beginning (resp. end) of the interrupt routine together with the general purpose registers. The CSR HWLoop registers are described in the :ref:`cs-registers` section. Below an assembly code example of a nested HWLoop that computes a matrix addition. @@ -149,13 +146,15 @@ Application and ebreak/ecall exception handlers When an ebreak or an ecall instruction is used in an application, special care should be given for those instruction handlers in case they are placed as the last instruction of an HWLoop. Those handlers should manage MEPC and lpcountX CSRs updates because an hw loop early-exit could happen if not done. -At the end of the handlers after restoring the context/CSRs, a piece of smart code should be added (by order of piority): +At the end of the handlers after restoring the context/CSRs, a piece of smart code should be added with following highest to lowest order of priority: -1. if MEPC = "lpend0 - 4" and lpcount0 >= 2 then MPEC should be set to lpstart0; if MEPC = "lpend0 - 4" and lpcount0 >= 1 then it should be decremented by 1. -2. if MEPC = "lpend1 - 4" and lpcount1 >= 2 then MPEC should be set to lpstart1; if MEPC = "lpend1 - 4" and lpcount1 >= 1 then it should be decremented by 1. -3. if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4) then MPEC should be incremented by 4. -4. if instruction at MEPC location is either ecall or ebreak then MPEC should be incremented by 4. -5. if instruction at MEPC location location is c.ebreak then MPEC should be incremented by 2. +1. if MEPC = lpend0 - 4 and lpcount0 > 1 then MPEC should be set to lpstart0 and lpcount0 should be decremented by 1, +2. else if MEPC = lpend0 - 4 and lpcount0 = 1 then MPEC should be incremented by 4 and lpcount0 should be decremented by 1, +3. else if MEPC = lpend1 - 4 and lpcount1 > 1 then MPEC should be set to lpstart1 and lpcount1 should be decremented by 1, +4. else if MEPC = lpend1 - 4 and lpcount1 = 1 then MPEC should be incremented by 4 and lpcount1 should be decremented by 1, +5. else if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4) then MPEC should be incremented by 4, +6. else if instruction at MEPC location is either ecall or ebreak then MPEC should be incremented by 4, +7. else if instruction at MEPC location location is c.ebreak then MPEC should be incremented by 2. The 2 last cases are the standard ones when ebreak/ecall are not inside an HWLopp. @@ -165,6 +164,8 @@ Interrupt handlers When an interrupt is happening on the last HWLoop instruction, its execution is cancelled, its address is saved in MEPC and its execution will be resumed when returning from interrupt handler. There is nothing special to be done in those interrupt handlers with respect to MEPC and lpcountX updates, they will be correctly managed by design when executing this last HWLoop instruction after interrupt handler execution. +Moreover since hardware loop could be used in interrupt routine, the registers have to be saved (resp. restored) at the beginning (resp. end) of the interrupt routine together with the general purpose registers. + Illegal instruction exception handler ------------------------------------- From c02d5c6bb2ecb68592cd602f7aeb3a0f590b01de Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 30 Nov 2023 17:52:59 +0800 Subject: [PATCH 48/50] RVFI - Setting mstatus_fs write mask when fcsr update + Adding DBG_FLUSH to write back trigger --- bhv/cv32e40p_rvfi.sv | 2 +- bhv/pipe_freeze_trace.sv | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 771ca6d15..97a9d0d1e 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1430,7 +1430,7 @@ 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.ctrl_fsm_cs == DBG_FLUSH) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF));// && !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.ctrl_fsm_cs == FLUSH_WB) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF));// && !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_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); diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 29e6859df..88d65d0b0 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -367,7 +367,10 @@ function compute_csr_we(); 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_FCSR: begin + r_pipe_freeze_trace.csr.fcsr_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end CSR_DPC: r_pipe_freeze_trace.csr.dpc_we = 1'b1; CSR_DSCRATCH0: r_pipe_freeze_trace.csr.dscratch0_we = 1'b1; CSR_DSCRATCH1: r_pipe_freeze_trace.csr.dscratch1_we = 1'b1; From 9a6ae9193b3a8f0a525b8d21686add4947d8557e Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Wed, 10 Jan 2024 11:36:30 +0100 Subject: [PATCH 49/50] format verible --- rtl/cv32e40px_ex_stage.sv | 20 +++++++-------- rtl/cv32e40px_register_file_ff.sv | 33 ++++++++++++++++++------- rtl/cv32e40px_x_disp.sv | 10 ++++---- rtl/include/cv32e40px_core_v_xif_pkg.sv | 2 +- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/rtl/cv32e40px_ex_stage.sv b/rtl/cv32e40px_ex_stage.sv index 092a339fe..ce24d433d 100644 --- a/rtl/cv32e40px_ex_stage.sv +++ b/rtl/cv32e40px_ex_stage.sv @@ -209,11 +209,11 @@ module cv32e40px_ex_stage // ALU write port mux always_comb begin - regfile_alu_wdata_fw_o = '0; - regfile_alu_waddr_fw_o = '0; - regfile_alu_we_fw_o = '0; - wb_contention = 1'b0; - result_fw_to_x_o = '0; + regfile_alu_wdata_fw_o = '0; + regfile_alu_waddr_fw_o = '0; + regfile_alu_we_fw_o = '0; + wb_contention = 1'b0; + result_fw_to_x_o = '0; regfile_alu_we_fw_power_o = 1'b0; if (x_result_valid_assigned_i & x_result_we_i & (x_result_rd_i != 5'b00000)) begin regfile_alu_we_fw_o = 1'b1; @@ -225,16 +225,16 @@ module cv32e40px_ex_stage end else begin // APU single cycle operations, and multicycle operations (>2cycles) are written back on ALU port if (apu_valid & (apu_singlecycle | apu_multicycle)) begin - regfile_alu_we_fw_o = 1'b1; + regfile_alu_we_fw_o = 1'b1; regfile_alu_we_fw_power_o = 1'b1; - regfile_alu_waddr_fw_o = apu_waddr; - regfile_alu_wdata_fw_o = apu_result; - result_fw_to_x_o = apu_result; + regfile_alu_waddr_fw_o = apu_waddr; + regfile_alu_wdata_fw_o = apu_result; + result_fw_to_x_o = apu_result; if (regfile_alu_we_i & ~apu_en_i) begin wb_contention = 1'b1; end end else begin - regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; // private fpu incomplete? + regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; // private fpu incomplete? regfile_alu_we_fw_power_o = !COREV_PULP ? regfile_alu_we_i & ~apu_en_i : regfile_alu_we_i & ~apu_en_i & mult_ready & alu_ready & lsu_ready_ex_i; diff --git a/rtl/cv32e40px_register_file_ff.sv b/rtl/cv32e40px_register_file_ff.sv index a33f3d2ce..d0aad5838 100644 --- a/rtl/cv32e40px_register_file_ff.sv +++ b/rtl/cv32e40px_register_file_ff.sv @@ -94,15 +94,30 @@ module cv32e40px_register_file #( if (COREV_X_IF != 0) begin if (X_DUALREAD) begin always_comb begin - rdata_a_o[0] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; - rdata_b_o[0] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; - rdata_c_o[0] = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; - if (dualread_i[0] == 1) rdata_a_o[1] = raddr_a_i[5] ? (mem_fp[{raddr_a_i[4:1], raddr_a_i[0] | 1'b1}]) : (mem[{raddr_a_i[4:1], raddr_a_i[0] | 1'b1}]); - else rdata_a_o[1] = '0; - if (dualread_i[1] == 1) rdata_b_o[1] = raddr_b_i[5] ? (mem_fp[{raddr_b_i[4:1], raddr_b_i[0] | 1'b1}]) : (mem[{raddr_b_i[4:1], raddr_b_i[0] | 1'b1}]); - else rdata_b_o[1] = '0; - if (dualread_i[2] == 1) rdata_c_o[1] = raddr_c_i[5] ? (mem_fp[{raddr_c_i[4:1], raddr_c_i[0] | 1'b1}]) : (mem[{raddr_c_i[4:1], raddr_c_i[0] | 1'b1}]); - else rdata_c_o[1] = '0; + rdata_a_o[0] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + rdata_b_o[0] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + rdata_c_o[0] = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + if (dualread_i[0] == 1) + rdata_a_o[1] = raddr_a_i[5] ? (mem_fp[{ + raddr_a_i[4:1], raddr_a_i[0]|1'b1 + }]) : (mem[{ + raddr_a_i[4:1], raddr_a_i[0]|1'b1 + }]); + else rdata_a_o[1] = '0; + if (dualread_i[1] == 1) + rdata_b_o[1] = raddr_b_i[5] ? (mem_fp[{ + raddr_b_i[4:1], raddr_b_i[0]|1'b1 + }]) : (mem[{ + raddr_b_i[4:1], raddr_b_i[0]|1'b1 + }]); + else rdata_b_o[1] = '0; + if (dualread_i[2] == 1) + rdata_c_o[1] = raddr_c_i[5] ? (mem_fp[{ + raddr_c_i[4:1], raddr_c_i[0]|1'b1 + }]) : (mem[{ + raddr_c_i[4:1], raddr_c_i[0]|1'b1 + }]); + else rdata_c_o[1] = '0; end end else begin assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; diff --git a/rtl/cv32e40px_x_disp.sv b/rtl/cv32e40px_x_disp.sv index 75a97523f..fe1471241 100644 --- a/rtl/cv32e40px_x_disp.sv +++ b/rtl/cv32e40px_x_disp.sv @@ -27,12 +27,12 @@ module cv32e40px_x_disp input logic rst_ni, // compressed interface - output logic [ 3:0] x_compressed_id_o, + output logic [3:0] x_compressed_id_o, // issue interface - output logic x_issue_valid_o, - input logic x_issue_ready_i, - input logic x_issue_resp_accept_i, - input logic x_issue_resp_writeback_i, + output logic x_issue_valid_o, + input logic x_issue_ready_i, + input logic x_issue_resp_accept_i, + input logic x_issue_resp_writeback_i, input logic [ 2:0] x_issue_resp_dualread_i, input logic x_issue_resp_loadstore_i, // unused diff --git a/rtl/include/cv32e40px_core_v_xif_pkg.sv b/rtl/include/cv32e40px_core_v_xif_pkg.sv index 487c2c873..678635d05 100644 --- a/rtl/include/cv32e40px_core_v_xif_pkg.sv +++ b/rtl/include/cv32e40px_core_v_xif_pkg.sv @@ -15,7 +15,7 @@ package cv32e40px_core_v_xif_pkg; // cv-x-if parameters parameter int X_NUM_RS = 3; - parameter int X_DUALREAD = 0; // 0: single read, 1: dual read + parameter int X_DUALREAD = 0; // 0: single read, 1: dual read parameter int X_ID_WIDTH = 4; parameter int X_MEM_WIDTH = 32; parameter int X_RFR_WIDTH = 32; From 12ee46f802c68c0e08d224b9b97da193557d2015 Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Wed, 17 Jan 2024 09:58:14 +0100 Subject: [PATCH 50/50] fix merge master --- rtl/cv32e40px_ex_stage.sv | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rtl/cv32e40px_ex_stage.sv b/rtl/cv32e40px_ex_stage.sv index ce24d433d..3beaf0227 100644 --- a/rtl/cv32e40px_ex_stage.sv +++ b/rtl/cv32e40px_ex_stage.sv @@ -216,9 +216,10 @@ module cv32e40px_ex_stage result_fw_to_x_o = '0; regfile_alu_we_fw_power_o = 1'b0; if (x_result_valid_assigned_i & x_result_we_i & (x_result_rd_i != 5'b00000)) begin - regfile_alu_we_fw_o = 1'b1; - regfile_alu_waddr_fw_o = {1'b0, x_result_rd_i}; - regfile_alu_wdata_fw_o = x_result_data_i; + regfile_alu_we_fw_o = 1'b1; + regfile_alu_we_fw_power_o = 1'b1; + regfile_alu_waddr_fw_o = {1'b0, x_result_rd_i}; + regfile_alu_wdata_fw_o = x_result_data_i; if (regfile_alu_we_i) begin wb_contention = 1'b1; end