diff --git a/docs/source/control_status_registers.rst b/docs/source/control_status_registers.rst index 9ccfc070b..28f3d2fe6 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 | | | | | @@ -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. | @@ -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 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. 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; diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index e6f9f7098..549869b9b 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; @@ -201,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; @@ -540,9 +542,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 +788,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), @@ -969,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), @@ -1037,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..609662830 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, @@ -212,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; @@ -897,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 @@ -957,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 @@ -1027,7 +1031,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 && !(mstatus_we_int && mstatus_fs_n != FS_DIRTY)) || fflags_we_i || fcsr_update) begin mstatus_fs_n = FS_DIRTY; end end diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index c51ef7f81..f327b8db6 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, @@ -371,11 +373,20 @@ 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)) || + ((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 + 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 apu_rvalid_q <= 1'b0; end end @@ -383,7 +394,12 @@ 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)) || + ((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; assign apu_result = apu_rvalid_q ? apu_result_q : apu_result_i; 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), 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),