From a5378e8f2bb5dd7fae297f0db52a3454ceb43bc9 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Fri, 11 Aug 2023 12:59:30 +0200 Subject: [PATCH] Issue #722 correction. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_apu_disp.sv | 5 ++++ rtl/cv32e40p_controller.sv | 9 ++++-- rtl/cv32e40p_core.sv | 31 +++++++++++--------- rtl/cv32e40p_ex_stage.sv | 60 ++++++++++++++++++++------------------ rtl/cv32e40p_id_stage.sv | 19 ++++++++---- 5 files changed, 74 insertions(+), 50 deletions(-) diff --git a/rtl/cv32e40p_apu_disp.sv b/rtl/cv32e40p_apu_disp.sv index adc9a3485..94ca9bcbd 100644 --- a/rtl/cv32e40p_apu_disp.sv +++ b/rtl/cv32e40p_apu_disp.sv @@ -47,6 +47,7 @@ module cv32e40p_apu_disp ( input logic [2:0][5:0] read_regs_i, input logic [2:0] read_regs_valid_i, output logic read_dep_o, + output logic read_dep_for_jalr_o, input logic [1:0][5:0] write_regs_i, input logic [1:0] write_regs_valid_i, @@ -189,6 +190,10 @@ module cv32e40p_apu_disp ( assign read_dep_o = (read_dep_req | read_dep_inflight | read_dep_waiting) & is_decoding_i; assign write_dep_o = (write_dep_req | write_dep_inflight | write_dep_waiting) & is_decoding_i; + assign read_dep_for_jalr_o = is_decoding_i & ((|read_deps_req & enable_i) | + (|read_deps_inflight & valid_inflight) | + (|read_deps_waiting & valid_waiting)); + // // Stall signals // diff --git a/rtl/cv32e40p_controller.sv b/rtl/cv32e40p_controller.sv index 7cd3d41d7..2a7550038 100644 --- a/rtl/cv32e40p_controller.sv +++ b/rtl/cv32e40p_controller.sv @@ -31,7 +31,8 @@ module cv32e40p_controller import cv32e40p_pkg::*; #( parameter COREV_CLUSTER = 0, - parameter COREV_PULP = 1 + parameter COREV_PULP = 0, + parameter FPU = 0 ) ( input logic clk, // Gated clock @@ -105,6 +106,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; // APU dependency checks input logic apu_en_i, input logic apu_read_dep_i, + input logic apu_read_dep_for_jalr_i, input logic apu_write_dep_i, output logic apu_stall_o, @@ -1352,7 +1354,10 @@ endgenerate if ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && (((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1)) || ((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_a_i == 1'b1)) || - ((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1))) ) + ((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1)) || + (FPU && (apu_read_dep_for_jalr_i == 1'b1)) + ) + ) begin jr_stall_o = 1'b1; deassert_we_o = 1'b1; diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index d86511402..899492da4 100644 --- a/rtl/cv32e40p_core.sv +++ b/rtl/cv32e40p_core.sv @@ -213,6 +213,7 @@ module cv32e40p_core logic [ 2:0][ 5:0] apu_read_regs; logic [ 2:0] apu_read_regs_valid; logic apu_read_dep; + logic apu_read_dep_for_jalr; logic [ 1:0][ 5:0] apu_write_regs; logic [ 1:0] apu_write_regs_valid; logic apu_write_dep; @@ -620,14 +621,15 @@ module cv32e40p_core .apu_flags_ex_o (apu_flags_ex), .apu_waddr_ex_o (apu_waddr_ex), - .apu_read_regs_o (apu_read_regs), - .apu_read_regs_valid_o (apu_read_regs_valid), - .apu_read_dep_i (apu_read_dep), - .apu_write_regs_o (apu_write_regs), - .apu_write_regs_valid_o(apu_write_regs_valid), - .apu_write_dep_i (apu_write_dep), - .apu_perf_dep_o (perf_apu_dep), - .apu_busy_i (apu_busy), + .apu_read_regs_o (apu_read_regs), + .apu_read_regs_valid_o (apu_read_regs_valid), + .apu_read_dep_i (apu_read_dep), + .apu_read_dep_for_jalr_i(apu_read_dep_for_jalr), + .apu_write_regs_o (apu_write_regs), + .apu_write_regs_valid_o (apu_write_regs_valid), + .apu_write_dep_i (apu_write_dep), + .apu_perf_dep_o (perf_apu_dep), + .apu_busy_i (apu_busy), // CSR ID/EX .csr_access_ex_o (csr_access_ex), @@ -792,12 +794,13 @@ module cv32e40p_core .apu_operands_i(apu_operands_ex), .apu_waddr_i (apu_waddr_ex), - .apu_read_regs_i (apu_read_regs), - .apu_read_regs_valid_i (apu_read_regs_valid), - .apu_read_dep_o (apu_read_dep), - .apu_write_regs_i (apu_write_regs), - .apu_write_regs_valid_i(apu_write_regs_valid), - .apu_write_dep_o (apu_write_dep), + .apu_read_regs_i (apu_read_regs), + .apu_read_regs_valid_i (apu_read_regs_valid), + .apu_read_dep_o (apu_read_dep), + .apu_read_dep_for_jalr_o(apu_read_dep_for_jalr), + .apu_write_regs_i (apu_write_regs), + .apu_write_regs_valid_i (apu_write_regs_valid), + .apu_write_dep_o (apu_write_dep), .apu_perf_type_o(perf_apu_type), .apu_perf_cont_o(perf_apu_cont), diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index a90cfd540..08392f29f 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -94,6 +94,7 @@ module cv32e40p_ex_stage input logic [2:0][5:0] apu_read_regs_i, input logic [2:0] apu_read_regs_valid_i, output logic apu_read_dep_o, + output logic apu_read_dep_for_jalr_o, input logic [1:0][5:0] apu_write_regs_i, input logic [1:0] apu_write_regs_valid_i, output logic apu_write_dep_o, @@ -336,13 +337,14 @@ module cv32e40p_ex_stage .active_o(apu_active), .stall_o (apu_stall), - .is_decoding_i (is_decoding_i), - .read_regs_i (apu_read_regs_i), - .read_regs_valid_i (apu_read_regs_valid_i), - .read_dep_o (apu_read_dep_o), - .write_regs_i (apu_write_regs_i), - .write_regs_valid_i(apu_write_regs_valid_i), - .write_dep_o (apu_write_dep_o), + .is_decoding_i (is_decoding_i), + .read_regs_i (apu_read_regs_i), + .read_regs_valid_i (apu_read_regs_valid_i), + .read_dep_o (apu_read_dep_o), + .read_dep_for_jalr_o(apu_read_dep_for_jalr_o), + .write_regs_i (apu_write_regs_i), + .write_regs_valid_i (apu_write_regs_valid_i), + .write_dep_o (apu_write_dep_o), .perf_type_o(apu_perf_type_o), .perf_cont_o(apu_perf_cont_o), @@ -387,28 +389,28 @@ module cv32e40p_ex_stage assign fpu_fflags_o = apu_rvalid_q ? apu_flags_q : apu_flags_i; end else begin : gen_no_apu // default assignements for the case when no FPU/APU is attached. - assign apu_req_o = '0; - assign apu_operands_o[0] = '0; - assign apu_operands_o[1] = '0; - assign apu_operands_o[2] = '0; - assign apu_op_o = '0; - assign apu_req = 1'b0; - assign apu_gnt = 1'b0; - assign apu_result = 32'b0; - assign apu_valid = 1'b0; - assign apu_waddr = 6'b0; - assign apu_stall = 1'b0; - assign apu_active = 1'b0; - assign apu_ready_wb_o = 1'b1; - assign apu_perf_wb_o = 1'b0; - assign apu_perf_cont_o = 1'b0; - assign apu_perf_type_o = 1'b0; - assign apu_singlecycle = 1'b0; - assign apu_multicycle = 1'b0; - assign apu_read_dep_o = 1'b0; - assign apu_write_dep_o = 1'b0; - assign fpu_fflags_we_o = 1'b0; - assign fpu_fflags_o = '0; + assign apu_req_o = '0; + assign apu_operands_o[0] = '0; + assign apu_operands_o[1] = '0; + assign apu_operands_o[2] = '0; + assign apu_op_o = '0; + assign apu_req = 1'b0; + assign apu_gnt = 1'b0; + assign apu_result = 32'b0; + assign apu_valid = 1'b0; + assign apu_waddr = 6'b0; + assign apu_stall = 1'b0; + assign apu_active = 1'b0; + assign apu_ready_wb_o = 1'b1; + assign apu_perf_wb_o = 1'b0; + assign apu_perf_cont_o = 1'b0; + assign apu_perf_type_o = 1'b0; + assign apu_singlecycle = 1'b0; + assign apu_multicycle = 1'b0; + assign apu_read_dep_o = 1'b0; + assign apu_read_dep_for_jalr_o = 1'b0; + assign apu_write_dep_o = 1'b0; + assign fpu_fflags_o = '0; end endgenerate diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index 80b5b645e..405e5ddaa 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -146,6 +146,7 @@ module cv32e40p_id_stage output logic [2:0][5:0] apu_read_regs_o, output logic [2:0] apu_read_regs_valid_o, input logic apu_read_dep_i, + input logic apu_read_dep_for_jalr_i, output logic [1:0][5:0] apu_write_regs_o, output logic [1:0] apu_write_regs_valid_o, input logic apu_write_dep_i, @@ -804,6 +805,12 @@ module cv32e40p_id_stage // dependency checks always_comb begin unique case (alu_op_a_mux_sel) + OP_A_CURRPC: begin + 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 + end // OP_A_CURRPC: OP_A_REGA_OR_FWD: begin apu_read_regs[0] = regfile_addr_ra_id; apu_read_regs_valid[0] = 1'b1; @@ -847,7 +854,7 @@ module cv32e40p_id_stage apu_read_regs_valid[2] = 1'b1; end OP_C_REGC_OR_FWD: begin - if (alu_op_a_mux_sel != OP_A_REGC_OR_FWD) begin + if ((alu_op_a_mux_sel != OP_A_REGC_OR_FWD) && (ctrl_transfer_target_mux_sel != JT_JALR)) begin apu_read_regs[2] = regfile_addr_rc_id; apu_read_regs_valid[2] = 1'b1; end else begin @@ -1089,7 +1096,8 @@ module cv32e40p_id_stage cv32e40p_controller #( .COREV_CLUSTER(COREV_CLUSTER), - .COREV_PULP (COREV_PULP) + .COREV_PULP (COREV_PULP), + .FPU (FPU) ) controller_i ( .clk (clk), // Gated clock .clk_ungated_i(clk_ungated_i), // Ungated clock @@ -1159,9 +1167,10 @@ module cv32e40p_id_stage .mult_multicycle_i(mult_multicycle_i), // APU - .apu_en_i (apu_en), - .apu_read_dep_i (apu_read_dep_i), - .apu_write_dep_i(apu_write_dep_i), + .apu_en_i (apu_en), + .apu_read_dep_i (apu_read_dep_i), + .apu_read_dep_for_jalr_i(apu_read_dep_for_jalr_i), + .apu_write_dep_i (apu_write_dep_i), .apu_stall_o(apu_stall),