diff --git a/rtl/cve2_core.sv b/rtl/cve2_core.sv index 253eca38a..abec8709c 100644 --- a/rtl/cve2_core.sv +++ b/rtl/cve2_core.sv @@ -177,8 +177,11 @@ module cve2_core import cve2_pkg::*; #( logic [31:0] rf_rdata_a; logic [4:0] rf_raddr_b; logic [31:0] rf_rdata_b; + logic [4:0] rf_raddr_c; + logic [31:0] rf_rdata_c; logic rf_ren_a; logic rf_ren_b; + logic rf_ren_c; logic [4:0] rf_waddr_wb; logic [31:0] rf_wdata_wb; // Writeback register write data that can be used on the forwarding path (doesn't factor in memory @@ -506,8 +509,11 @@ module cve2_core import cve2_pkg::*; #( .rf_rdata_a_i (rf_rdata_a), .rf_raddr_b_o (rf_raddr_b), .rf_rdata_b_i (rf_rdata_b), + .rf_raddr_c_o (rf_raddr_c), + .rf_rdata_c_i (rf_rdata_c), .rf_ren_a_o (rf_ren_a), .rf_ren_b_o (rf_ren_b), + .rf_ren_c_o (rf_ren_c), .rf_waddr_id_o (rf_waddr_id), .rf_wdata_id_o (rf_wdata_id), .rf_we_id_o (rf_we_id), @@ -691,7 +697,8 @@ module cve2_core import cve2_pkg::*; #( cve2_register_file_ff #( .RV32E (RV32E), .DataWidth (32), - .WordZeroVal (32'h0) + .WordZeroVal (32'h0), + .XInterface (XInterface) ) register_file_i ( .clk_i (clk_i), .rst_ni(rst_ni), @@ -702,6 +709,8 @@ module cve2_core import cve2_pkg::*; #( .rdata_a_o(rf_rdata_a), .raddr_b_i(rf_raddr_b), .rdata_b_o(rf_rdata_b), + .raddr_c_i(rf_raddr_c), + .rdata_c_o(rf_rdata_c), .waddr_a_i(rf_waddr_wb), .wdata_a_i(rf_wdata_wb), .we_a_i (rf_we_wb) diff --git a/rtl/cve2_decoder.sv b/rtl/cve2_decoder.sv index 9efad2b46..6a9e929eb 100644 --- a/rtl/cve2_decoder.sv +++ b/rtl/cve2_decoder.sv @@ -56,9 +56,11 @@ module cve2_decoder #( output logic rf_we_o, // write enable for regfile output logic [4:0] rf_raddr_a_o, output logic [4:0] rf_raddr_b_o, + output logic [4:0] rf_raddr_c_o, output logic [4:0] rf_waddr_o, output logic rf_ren_a_o, // Instruction reads from RF addr A output logic rf_ren_b_o, // Instruction reads from RF addr B + output logic rf_ren_c_o, // Instruction reads from RF addr C (if X-IF if used) // ALU output cve2_pkg::alu_op_e alu_operator_o, // ALU operation selection @@ -168,6 +170,7 @@ module cve2_decoder #( assign instr_rs3 = instr[31:27]; assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i) ? instr_rs3 : instr_rs1; // rs3 / rs1 assign rf_raddr_b_o = instr_rs2; // rs2 + assign rf_raddr_c_o = XInterface ? instr_rs3 : '0; // destination register assign instr_rd = instr[11:7]; @@ -214,6 +217,7 @@ module cve2_decoder #( rf_we = 1'b0; rf_ren_a_o = 1'b0; rf_ren_b_o = 1'b0; + rf_ren_c_o = 1'b0; csr_access_o = 1'b0; csr_illegal = 1'b0; @@ -662,6 +666,7 @@ module cve2_decoder #( if(XInterface) begin rf_ren_a_o = x_issue_resp_register_read_i[0]; rf_ren_b_o = x_issue_resp_register_read_i[1]; + rf_ren_c_o = x_issue_resp_register_read_i[2]; rf_wdata_sel_o = $bits(rf_wdata_sel_o)'({RF_WD_COPROC}); end end diff --git a/rtl/cve2_id_stage.sv b/rtl/cve2_id_stage.sv index 9fef525d0..1f39bf19d 100644 --- a/rtl/cve2_id_stage.sv +++ b/rtl/cve2_id_stage.sv @@ -153,8 +153,11 @@ module cve2_id_stage #( input logic [31:0] rf_rdata_a_i, output logic [4:0] rf_raddr_b_o, input logic [31:0] rf_rdata_b_i, + output logic [4:0] rf_raddr_c_o, + input logic [31:0] rf_rdata_c_i, output logic rf_ren_a_o, output logic rf_ren_b_o, + output logic rf_ren_c_o, // Register file write (via writeback) output logic [4:0] rf_waddr_id_o, @@ -220,18 +223,21 @@ module cve2_id_stage #( logic [XInterface:0] rf_wdata_sel; logic rf_we_dec, rf_we_raw; - logic rf_ren_a, rf_ren_b; - logic rf_ren_a_dec, rf_ren_b_dec; + logic rf_ren_a, rf_ren_b, rf_ren_c; + logic rf_ren_a_dec, rf_ren_b_dec, rf_ren_c_dec; // Read enables should only be asserted for valid and legal instructions assign rf_ren_a = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_a_dec; assign rf_ren_b = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_b_dec; + assign rf_ren_c = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_c_dec; assign rf_ren_a_o = rf_ren_a; assign rf_ren_b_o = rf_ren_b; + assign rf_ren_c_o = XInterface ? rf_ren_c : '0; logic [31:0] rf_rdata_a_fwd; logic [31:0] rf_rdata_b_fwd; + logic [31:0] rf_rdata_c_fwd; // ALU Control alu_op_e alu_operator; @@ -352,6 +358,7 @@ module cve2_id_stage #( // Register Interface assign x_register_o.rs[0] = rf_rdata_a_fwd; assign x_register_o.rs[1] = rf_rdata_b_fwd; + assign x_register_o.rs[2] = rf_rdata_c_fwd; assign x_register_o.rs_valid = '1; assign x_register_o.id = x_instr_id_q; assign x_register_o.hartid = hart_id_i; @@ -372,8 +379,10 @@ module cve2_id_stage #( logic unused_x_result_valid; x_result_t unused_x_result; logic unused_coproc_done; + logic [31:0] unused_rf_rdata_c_fwd; assign unused_coproc_done = coproc_done; + assign unused_rf_rdata_c_fwd = rf_rdata_c_fwd; assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i; assign scoreboard_busy = 1'b0; @@ -532,9 +541,11 @@ module cve2_id_stage #( .rf_raddr_a_o(rf_raddr_a_o), .rf_raddr_b_o(rf_raddr_b_o), + .rf_raddr_c_o(rf_raddr_c_o), .rf_waddr_o (rf_waddr_id_o), .rf_ren_a_o (rf_ren_a_dec), .rf_ren_b_o (rf_ren_b_dec), + .rf_ren_c_o (rf_ren_c_dec), // ALU .alu_operator_o (alu_operator), @@ -919,6 +930,7 @@ module cve2_id_stage #( // register file assign rf_rdata_a_fwd = rf_rdata_a_i; assign rf_rdata_b_fwd = rf_rdata_b_i; + assign rf_rdata_c_fwd = rf_rdata_c_i; // Unused Writeback stage only IO & wiring // Assign inputs and internal wiring to unused signals to satisfy lint checks diff --git a/rtl/cve2_pkg.sv b/rtl/cve2_pkg.sv index 50377e74a..8db480348 100644 --- a/rtl/cve2_pkg.sv +++ b/rtl/cve2_pkg.sv @@ -657,7 +657,7 @@ package cve2_pkg; } rvfi_csr_t; // CV-X-IF - parameter int unsigned X_NUM_RS = 2; + parameter int unsigned X_NUM_RS = 3; parameter int unsigned X_ID_WIDTH = 4; parameter int unsigned X_RFR_WIDTH = 32; parameter int unsigned X_RFW_WIDTH = 32; diff --git a/rtl/cve2_register_file_ff.sv b/rtl/cve2_register_file_ff.sv index de45f8f50..1d51eb95e 100644 --- a/rtl/cve2_register_file_ff.sv +++ b/rtl/cve2_register_file_ff.sv @@ -14,7 +14,8 @@ module cve2_register_file_ff #( parameter bit RV32E = 0, parameter int unsigned DataWidth = 32, - parameter logic [DataWidth-1:0] WordZeroVal = '0 + parameter logic [DataWidth-1:0] WordZeroVal = '0, + parameter bit XInterface = 1'b0 ) ( // Clock and Reset input logic clk_i, @@ -30,6 +31,9 @@ module cve2_register_file_ff #( input logic [4:0] raddr_b_i, output logic [DataWidth-1:0] rdata_b_o, + //Read port R3 -- Only when using the X-iF + input logic [4:0] raddr_c_i, + output logic [DataWidth-1:0] rdata_c_o, // Write port W1 input logic [4:0] waddr_a_i, @@ -69,6 +73,7 @@ module cve2_register_file_ff #( assign rdata_a_o = rf_reg[raddr_a_i]; assign rdata_b_o = rf_reg[raddr_b_i]; + assign rdata_c_o = XInterface ? rf_reg[raddr_c_i] : '0; // Signal not used in FF register file logic unused_test_en;