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 62e4d7217..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 @@ -810,6 +812,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 @@ -949,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) );