Skip to content

Commit

Permalink
Add dualread support to core-v-xif (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
LuigiGiuffrida98 committed Jan 10, 2024
1 parent acf3442 commit b079236
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 133 deletions.
10 changes: 5 additions & 5 deletions rtl/cv32e40px_cs_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,7 @@ module cv32e40px_cs_registers
// minstret is located at index 2
// Programable HPM counters start at index 3
if ((cnt_gidx == 1) || (cnt_gidx >= (NUM_MHPMCOUNTERS + 3))) begin : gen_non_implemented
assign mhpmcounter_q[cnt_gidx] = 'b0;
always_ff @(posedge clk) mhpmcounter_q[cnt_gidx] <= 'b0;
end else begin : gen_implemented
always_ff @(posedge clk, negedge rst_n)
if (!rst_n) begin
Expand Down Expand Up @@ -1483,10 +1483,10 @@ module cv32e40px_cs_registers
for (evt_gidx = 0; evt_gidx < 32; evt_gidx++) begin : gen_mhpmevent
// programable HPM events start at index3
if ((evt_gidx < 3) || (evt_gidx >= (NUM_MHPMCOUNTERS + 3))) begin : gen_non_implemented
assign mhpmevent_q[evt_gidx] = 'b0;
always_ff @(posedge clk) mhpmevent_q[evt_gidx] <= 'b0;
end else begin : gen_implemented
if (NUM_HPM_EVENTS < 32) begin : gen_tie_off
assign mhpmevent_q[evt_gidx][31:NUM_HPM_EVENTS] = 'b0;
always_ff @(posedge clk) mhpmevent_q[evt_gidx][31:NUM_HPM_EVENTS] <= 'b0;
end
always_ff @(posedge clk, negedge rst_n)
if (!rst_n) mhpmevent_q[evt_gidx][NUM_HPM_EVENTS-1:0] <= 'b0;
Expand All @@ -1504,7 +1504,7 @@ module cv32e40px_cs_registers
(en_gidx == 1) ||
(en_gidx >= (NUM_MHPMCOUNTERS+3) ) )
begin : gen_non_implemented
assign mcounteren_q[en_gidx] = 'b0;
always_ff @(posedge clk) mcounteren_q[en_gidx] <= 'b0;
end else begin : gen_implemented
always_ff @(posedge clk, negedge rst_n)
if (!rst_n) mcounteren_q[en_gidx] <= 'b0; // default disable
Expand All @@ -1519,7 +1519,7 @@ module cv32e40px_cs_registers
generate
for (inh_gidx = 0; inh_gidx < 32; inh_gidx++) begin : gen_mcountinhibit
if ((inh_gidx == 1) || (inh_gidx >= (NUM_MHPMCOUNTERS + 3))) begin : gen_non_implemented
assign mcountinhibit_q[inh_gidx] = 'b0;
always_ff @(posedge clk) mcountinhibit_q[inh_gidx] <= 'b0;
end else begin : gen_implemented
always_ff @(posedge clk, negedge rst_n)
if (!rst_n) mcountinhibit_q[inh_gidx] <= 'b1; // default disable
Expand Down
165 changes: 104 additions & 61 deletions rtl/cv32e40px_id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ module cv32e40px_id_stage
localparam REG_D_MSB = 11;
localparam REG_D_LSB = 7;


localparam REGFILE_NUM_READ_PORTS = ((COREV_X_IF == 1) & (X_DUALREAD == 1)) ? 2 : 1;

logic [31:0] instr;


Expand Down Expand Up @@ -381,9 +384,9 @@ module cv32e40px_id_stage
logic [ 5:0] regfile_alu_waddr_id;
logic regfile_alu_we_id, regfile_alu_we_dec_id;

logic [31:0] regfile_data_ra_id;
logic [31:0] regfile_data_rb_id;
logic [31:0] regfile_data_rc_id;
logic [REGFILE_NUM_READ_PORTS-1:0][31:0] regfile_data_ra_id;
logic [REGFILE_NUM_READ_PORTS-1:0][31:0] regfile_data_rb_id;
logic [REGFILE_NUM_READ_PORTS-1:0][31:0] regfile_data_rc_id;

// ALU Control
logic alu_en;
Expand Down Expand Up @@ -438,8 +441,8 @@ module cv32e40px_id_stage
logic [2:0][4:0] x_rs_addr;
logic x_mem_data_req;
logic x_mem_valid;
logic [2:0] x_ex_fwd;
logic [2:0] x_wb_fwd;
logic [RF_READ_PORTS-1:0] x_ex_fwd;
logic [RF_READ_PORTS-1:0] x_wb_fwd;

// Register Write Control
logic regfile_we_id;
Expand Down Expand Up @@ -622,17 +625,18 @@ module cv32e40px_id_stage
// \___/ \__,_|_| |_| |_| .__/ |_|\__,_|_| \__, |\___|\__| //
// |_| |___/ //
//////////////////////////////////////////////////////////////////

always_comb begin : jump_target_mux
unique case (ctrl_transfer_target_mux_sel)
JT_JAL: jump_target = pc_id_i + imm_uj_type;
JT_COND: jump_target = pc_id_i + imm_sb_type;

// JALR: Cannot forward RS1, since the path is too long
JT_JALR: jump_target = regfile_data_ra_id + imm_i_type;
default: jump_target = regfile_data_ra_id + imm_i_type;
endcase
end
generate
always_comb begin : jump_target_mux
unique case (ctrl_transfer_target_mux_sel)
JT_JAL: jump_target = pc_id_i + imm_uj_type;
JT_COND: jump_target = pc_id_i + imm_sb_type;

// JALR: Cannot forward RS1, since the path is too long
JT_JALR: jump_target = regfile_data_ra_id[0] + imm_i_type;
default: jump_target = regfile_data_ra_id[0] + imm_i_type;
endcase
end
endgenerate

assign jump_target_o = jump_target;

Expand Down Expand Up @@ -666,16 +670,18 @@ module cv32e40px_id_stage
endcase
end

// Operand a forwarding mux
always_comb begin : operand_a_fw_mux
case (operand_a_fw_mux_sel)
SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id;
default: operand_a_fw_id = regfile_data_ra_id;
endcase
; // case (operand_a_fw_mux_sel)
end
generate
// Operand a forwarding mux
always_comb begin : operand_a_fw_mux
case (operand_a_fw_mux_sel)
SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id[0];
default: operand_a_fw_id = regfile_data_ra_id[0];
endcase
; // case (operand_a_fw_mux_sel)
end
endgenerate

//////////////////////////////////////////////////////
// ___ _ ____ //
Expand Down Expand Up @@ -732,16 +738,31 @@ module cv32e40px_id_stage
assign alu_operand_b = (scalar_replication == 1'b1) ? operand_b_vec : operand_b;


// Operand b forwarding mux
always_comb begin : operand_b_fw_mux
case (operand_b_fw_mux_sel)
SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id;
default: operand_b_fw_id = regfile_data_rb_id;
endcase
; // case (operand_b_fw_mux_sel)
end
generate
if (X_DUALREAD == 0) begin : no_dualread_fw_b
// Operand b forwarding mux
always_comb begin : operand_b_fw_mux
case (operand_b_fw_mux_sel)
SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id;
default: operand_b_fw_id = regfile_data_rb_id;
endcase
; // case (operand_b_fw_mux_sel)
end
end else begin : dualread_fw_b
// Operand b forwarding mux
always_comb begin : operand_b_fw_mux
case (operand_b_fw_mux_sel)
SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id[0];
default: operand_b_fw_id = regfile_data_rb_id[0];
endcase
; // case (operand_b_fw_mux_sel)
end
end
endgenerate


//////////////////////////////////////////////////////
Expand Down Expand Up @@ -777,17 +798,31 @@ module cv32e40px_id_stage
assign alu_operand_c = (scalar_replication_c == 1'b1) ? operand_c_vec : operand_c;


// Operand c forwarding mux
always_comb begin : operand_c_fw_mux
case (operand_c_fw_mux_sel)
SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id;
default: operand_c_fw_id = regfile_data_rc_id;
endcase
; // case (operand_c_fw_mux_sel)
end

generate
if (X_DUALREAD == 0) begin : no_dualread_fw_c
// Operand c forwarding mux
always_comb begin : operand_c_fw_mux
case (operand_c_fw_mux_sel)
SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id;
default: operand_c_fw_id = regfile_data_rc_id;
endcase
; // case (operand_c_fw_mux_sel)
end
end else begin : dualread_fw_c
// Operand c forwarding mux
always_comb begin : operand_c_fw_mux
case (operand_c_fw_mux_sel)
SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i;
SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i;
SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id[0];
default: operand_c_fw_id = regfile_data_rc_id[0];
endcase
; // case (operand_c_fw_mux_sel)
end
end
endgenerate

///////////////////////////////////////////////////////////////////////////
// ___ _ _ _ ___ ____ //
Expand Down Expand Up @@ -982,13 +1017,17 @@ module cv32e40px_id_stage
.ADDR_WIDTH(6),
.DATA_WIDTH(32),
.FPU (FPU),
.ZFINX (ZFINX)
.ZFINX (ZFINX),
.COREV_X_IF(COREV_X_IF),
.X_DUALREAD(X_DUALREAD)
) register_file_i (
.clk (clk),
.rst_n(rst_n),

.scan_cg_en_i(scan_cg_en_i),

.dualread_i(x_issue_resp_i.dualread),

// Read port a
.raddr_a_i(regfile_addr_ra_id),
.rdata_a_o(regfile_data_ra_id),
Expand Down Expand Up @@ -1037,6 +1076,7 @@ module cv32e40px_id_stage
.x_issue_valid_o (x_issue_valid_o),
.x_issue_ready_i (x_issue_ready_i),
.x_issue_resp_writeback_i(x_issue_resp_i.writeback),
.x_issue_resp_dualread_i (x_issue_resp_i.dualread),
.x_issue_resp_accept_i (x_issue_resp_i.accept),
.x_issue_resp_loadstore_i(x_issue_resp_i.loadstore),
.x_issue_req_rs_valid_o (x_issue_req_o.rs_valid),
Expand Down Expand Up @@ -1118,22 +1158,25 @@ module cv32e40px_id_stage
assign x_mem_valid = x_mem_valid_i;

// xif integer souce operand selection
for (genvar i = 0; i < 3; i++) begin : xif_operand_assignment
always_comb begin
if (i == 0) begin
x_issue_req_o.rs[i] = regfile_data_ra_id;
end else if (i == 1) begin
x_issue_req_o.rs[i] = regfile_data_rb_id;
end else begin
x_issue_req_o.rs[i] = regfile_data_rc_id;
end
if (x_ex_fwd[i]) begin
x_issue_req_o.rs[i] = result_fw_to_x_i;
end else if (x_wb_fwd[i]) begin
x_issue_req_o.rs[i] = regfile_wdata_wb_i;
for (genvar j = 0; j < REGFILE_NUM_READ_PORTS; j++) begin : xif_operand_assignment_dualread
for (genvar i = 0; i < 3; i++) begin : xif_operand_assignment
always_comb begin
if (i == 0) begin
x_issue_req_o.rs[i+3*j] = regfile_data_ra_id[j];
end else if (i == 1) begin
x_issue_req_o.rs[i+3*j] = regfile_data_rb_id[j];
end else begin
x_issue_req_o.rs[i+3*j] = regfile_data_rc_id[j];
end
if (x_ex_fwd[i+3*j]) begin
x_issue_req_o.rs[i+3*j] = result_fw_to_x_i;
end else if (x_wb_fwd[i+3*j]) begin
x_issue_req_o.rs[i+3*j] = regfile_wdata_wb_i;
end
end
end
end

// LSU signal assignment/MUX
always_comb begin
x_mem_data_type_id = 2'b00;
Expand Down
51 changes: 38 additions & 13 deletions rtl/cv32e40px_register_file_ff.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,29 @@ module cv32e40px_register_file #(
parameter ADDR_WIDTH = 5,
parameter DATA_WIDTH = 32,
parameter FPU = 0,
parameter ZFINX = 0
parameter ZFINX = 0,
parameter COREV_X_IF = 0,
parameter X_DUALREAD = 0
) (
// Clock and Reset
input logic clk,
input logic rst_n,

input logic scan_cg_en_i,

input logic [2:0] dualread_i,

//Read port R1
input logic [ADDR_WIDTH-1:0] raddr_a_i,
output logic [DATA_WIDTH-1:0] rdata_a_o,
input logic [ADDR_WIDTH-1:0] raddr_a_i,
output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_a_o,

//Read port R2
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_b_o,

//Read port R3
input logic [ADDR_WIDTH-1:0] raddr_c_i,
output logic [DATA_WIDTH-1:0] rdata_c_o,
input logic [ADDR_WIDTH-1:0] raddr_c_i,
output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_c_o,

// Write port W1
input logic [ADDR_WIDTH-1:0] waddr_a_i,
Expand Down Expand Up @@ -86,17 +90,38 @@ module cv32e40px_register_file #(
//-----------------------------------------------------------------------------
//-- READ : Read address decoder RAD
//-----------------------------------------------------------------------------
assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]];
assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]];
assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]];

generate
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;
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]];
assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]];
assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4: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]];
assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]];
assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]];
end
endgenerate
//-----------------------------------------------------------------------------
//-- WRITE : Write Address Decoder (WAD), combinatorial process
//-----------------------------------------------------------------------------

// Mask top bit of write address to disable fp regfile
assign waddr_a = waddr_a_i;
assign waddr_b = waddr_b_i;
assign waddr_a = waddr_a_i;
assign waddr_b = waddr_b_i;

genvar gidx;
generate
Expand Down
Loading

0 comments on commit b079236

Please sign in to comment.