Implement 2r1w register file

This commit is contained in:
Markus Wegmann 2016-12-15 15:55:56 +01:00
parent 83fc605acb
commit d871d1a590
8 changed files with 264 additions and 25 deletions

View file

@ -45,7 +45,10 @@ module riscv_controller
input logic rega_used_i, // register A is used
input logic regb_used_i, // register B is used
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
input logic regc_used_i, // register C is used
`endif // THREE_PORT_REG_FILE
// from IF/ID pipeline
input logic instr_valid_i, // instruction coming from IF/ID pipeline is valid
@ -96,15 +99,21 @@ module riscv_controller
input logic regfile_we_ex_i, // FW: write enable from EX stage
input logic [4:0] regfile_waddr_wb_i, // FW: write address from WB stage
input logic regfile_we_wb_i, // FW: write enable from WB stage
input logic [4:0] regfile_alu_waddr_fw_i, // FW: ALU/MUL write address from EX stage
input logic regfile_alu_we_fw_i, // FW: ALU/MUL write enable from EX stage
// forwarding signals
output logic [1:0] operand_a_fw_mux_sel_o, // regfile ra data selector form ID stage
output logic [1:0] operand_b_fw_mux_sel_o, // regfile rb data selector form ID stage
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
output logic [1:0] operand_c_fw_mux_sel_o, // regfile rc data selector form ID stage
`endif // THREE_PORT_REG_FILE
// forwarding detection signals
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
input logic reg_d_ex_is_reg_a_i,
input logic reg_d_ex_is_reg_b_i,
input logic reg_d_ex_is_reg_c_i,
@ -114,6 +123,14 @@ module riscv_controller
input logic reg_d_alu_is_reg_a_i,
input logic reg_d_alu_is_reg_b_i,
input logic reg_d_alu_is_reg_c_i,
`else
input logic reg_d_ex_is_reg_a_i,
input logic reg_d_ex_is_reg_b_i,
input logic reg_d_wb_is_reg_a_i,
input logic reg_d_wb_is_reg_b_i,
input logic reg_d_alu_is_reg_a_i,
input logic reg_d_alu_is_reg_b_i,
`endif // THREE_PORT_REG_FILE
// stall signals
@ -559,7 +576,10 @@ module riscv_controller
// default assignements
operand_a_fw_mux_sel_o = SEL_REGFILE;
operand_b_fw_mux_sel_o = SEL_REGFILE;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
operand_c_fw_mux_sel_o = SEL_REGFILE;
`endif // THREE_PORT_REG_FILE
// Forwarding WB -> ID
if (regfile_we_wb_i == 1'b1)
@ -568,19 +588,25 @@ module riscv_controller
operand_a_fw_mux_sel_o = SEL_FW_WB;
if (reg_d_wb_is_reg_b_i == 1'b1)
operand_b_fw_mux_sel_o = SEL_FW_WB;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if (reg_d_wb_is_reg_c_i == 1'b1)
operand_c_fw_mux_sel_o = SEL_FW_WB;
`endif // THREE_PORT_REG_FILE
end
// Forwarding EX -> ID
if (regfile_alu_we_fw_i == 1'b1)
begin
if (reg_d_alu_is_reg_a_i == 1'b1)
operand_a_fw_mux_sel_o = SEL_FW_EX;
if (reg_d_alu_is_reg_b_i == 1'b1)
operand_b_fw_mux_sel_o = SEL_FW_EX;
if (reg_d_alu_is_reg_c_i == 1'b1)
operand_c_fw_mux_sel_o = SEL_FW_EX;
if (reg_d_alu_is_reg_a_i == 1'b1)
operand_a_fw_mux_sel_o = SEL_FW_EX;
if (reg_d_alu_is_reg_b_i == 1'b1)
operand_b_fw_mux_sel_o = SEL_FW_EX;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if (reg_d_alu_is_reg_c_i == 1'b1)
operand_c_fw_mux_sel_o = SEL_FW_EX;
`endif // THREE_PORT_REG_FILE
end
// for misaligned memory accesses

View file

@ -47,7 +47,10 @@ module riscv_decoder
output logic rega_used_o, // rs1 is used by current instruction
output logic regb_used_o, // rs2 is used by current instruction
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
output logic regc_used_o, // rs3 is used by current instruction
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
@ -66,7 +69,11 @@ module riscv_decoder
output logic [ALU_OP_WIDTH-1:0] alu_operator_o, // ALU operation selection
output logic [2:0] alu_op_a_mux_sel_o, // operand a selection: reg value, PC, immediate or zero
output logic [2:0] alu_op_b_mux_sel_o, // operand b selection: reg value or immediate
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
output logic [1:0] alu_op_c_mux_sel_o, // operand c selection: reg value or jump target
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
output logic [1:0] alu_vec_mode_o, // selects between 32 bit, 16 bit and 8 bit vectorial modes
@ -74,7 +81,10 @@ module riscv_decoder
`endif // VEC_SUPPORT
output logic [0:0] imm_a_mux_sel_o, // immediate selection for operand a
output logic [3:0] imm_b_mux_sel_o, // immediate selection for operand b
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
output logic [1:0] regc_mux_o, // register c selection: S3, RD or 0
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
@ -158,7 +168,10 @@ module riscv_decoder
alu_operator_o = ALU_SLTU;
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
alu_op_b_mux_sel_o = OP_B_REGB_OR_FWD;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
alu_op_c_mux_sel_o = OP_C_REGC_OR_FWD;
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
alu_vec_mode_o = VEC_MODE32;
@ -214,7 +227,10 @@ module riscv_decoder
rega_used_o = 1'b0;
regb_used_o = 1'b0;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
regc_used_o = 1'b0;
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: BIT_SUPPORT
@ -271,7 +287,10 @@ module riscv_decoder
OPCODE_BRANCH: begin // Branch
jump_target_mux_sel_o = JT_COND;
jump_in_id = BRANCH_COND;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
alu_op_c_mux_sel_o = OP_C_JT;
`endif // THREE_PORT_REG_FILE
rega_used_o = 1'b1;
regb_used_o = 1'b1;
@ -335,12 +354,23 @@ module riscv_decoder
// offset from immediate
imm_b_mux_sel_o = IMMB_S;
alu_op_b_mux_sel_o = OP_B_IMM;
end else begin
end
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
else begin
// offset from register
regc_used_o = 1'b1;
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
regc_mux_o = REGC_RD;
end
`else
// Register offset is illegal since no register c available
else begin
data_req = 1'b0;
data_we_o = 1'b0;
illegal_insn_o = 1'b1;
end
`endif // THREE_PORT_REG_FILE
// store size
unique case (instr_rdata_i[13:12])
@ -718,6 +748,9 @@ module riscv_decoder
end
end
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
OPCODE_PULP_OP: begin // PULP specific ALU instructions with three source operands
regfile_alu_we = 1'b1;
rega_used_o = 1'b1;
@ -815,6 +848,7 @@ module riscv_decoder
end
endcase
end
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT

View file

@ -156,6 +156,7 @@ module riscv_ex_stage
// //
////////////////////////////
// CONFIG_REGION: SIMPLE_ALU
`ifdef SIMPLE_ALU
riscv_alu_simplified alu_i
@ -178,7 +179,7 @@ module riscv_ex_stage
assign alu_ready = 1'b1; // As there is no divider, ALU always takes only one cycle
`else
`else // SIMPLE_ALU
riscv_alu alu_i
(
@ -216,7 +217,7 @@ module riscv_ex_stage
.ex_ready_i ( ex_ready_o )
);
`endif
`endif // SIMPLE_ALU
////////////////////////////////////////////////////////////////

View file

@ -98,7 +98,8 @@ module riscv_id_stage #(
output logic [31:0] alu_operand_a_ex_o,
output logic [31:0] alu_operand_b_ex_o,
output logic [31:0] alu_operand_c_ex_o,
output logic [31:0] alu_operand_c_ex_o, // Still needed if 2r1w reg file used
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
output logic [ 4:0] bmask_a_ex_o,
@ -240,7 +241,10 @@ module riscv_id_stage #(
logic rega_used_dec;
logic regb_used_dec;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic regc_used_dec;
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
logic bmask_needed_dec;
@ -290,7 +294,10 @@ module riscv_id_stage #(
// Register file interface
logic [4:0] regfile_addr_ra_id;
logic [4:0] regfile_addr_rb_id;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [4:0] regfile_addr_rc_id;
`endif // THREE_PORT_REG_FILE
logic [4:0] regfile_waddr_id;
logic [4:0] regfile_alu_waddr_id;
@ -298,14 +305,20 @@ module riscv_id_stage #(
logic [31:0] regfile_data_ra_id;
logic [31:0] regfile_data_rb_id;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [31:0] regfile_data_rc_id;
`endif // THREE_PORT_REG_FILE
// ALU Control
logic [ALU_OP_WIDTH-1:0] alu_operator;
logic [2:0] alu_op_a_mux_sel;
logic [2:0] alu_op_b_mux_sel;
logic [1:0] alu_op_c_mux_sel;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [1:0] regc_mux;
`endif // THREE_PORT_REG_FILE
logic [0:0] imm_a_mux_sel;
logic [3:0] imm_b_mux_sel;
@ -364,11 +377,17 @@ module riscv_id_stage #(
// Forwarding
logic [1:0] operand_a_fw_mux_sel;
logic [1:0] operand_b_fw_mux_sel;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [1:0] operand_c_fw_mux_sel;
`endif // THREE_PORT_REG_FILE
logic [31:0] operand_a_fw_id;
logic [31:0] operand_b_fw_id;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [31:0] operand_c_fw_id;
`endif // THREE_PORT_REG_FILE
logic [31:0] operand_b;
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
@ -377,7 +396,7 @@ module riscv_id_stage #(
logic [31:0] alu_operand_a;
logic [31:0] alu_operand_b;
logic [31:0] alu_operand_c;
logic [31:0] alu_operand_c; // Still needed if 2r1w reg file used
// Immediates for ID
// CONFIG_REGION: BIT_SUPPORT
@ -417,6 +436,8 @@ module riscv_id_stage #(
`endif // VEC_SUPPORT
// Forwarding detection signals
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic reg_d_ex_is_reg_a_id;
logic reg_d_ex_is_reg_b_id;
logic reg_d_ex_is_reg_c_id;
@ -426,6 +447,14 @@ module riscv_id_stage #(
logic reg_d_alu_is_reg_a_id;
logic reg_d_alu_is_reg_b_id;
logic reg_d_alu_is_reg_c_id;
`else
logic reg_d_ex_is_reg_a_id;
logic reg_d_ex_is_reg_b_id;
logic reg_d_wb_is_reg_a_id;
logic reg_d_wb_is_reg_b_id;
logic reg_d_alu_is_reg_a_id;
logic reg_d_alu_is_reg_b_id;
`endif // THREE_PORT_REG_FILE
assign instr = instr_rdata_i;
@ -469,6 +498,8 @@ module riscv_id_stage #(
assign regfile_addr_ra_id = instr[`REG_S1];
assign regfile_addr_rb_id = instr[`REG_S2];
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
// register C mux
always_comb
begin
@ -479,18 +510,26 @@ module riscv_id_stage #(
default: regfile_addr_rc_id = '0;
endcase
end
`endif // THREE_PORT_REG_FILE
//---------------------------------------------------------------------------
// destination registers
//---------------------------------------------------------------------------
assign regfile_waddr_id = instr[`REG_D];
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
// Second Register Write Address Selection
// Used for prepost load/store and multiplier
assign regfile_alu_waddr_id = regfile_alu_waddr_mux_sel ?
regfile_waddr_id : regfile_addr_ra_id;
`endif // THREE_PORT_REG_FILE
// Forwarding control signals
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign reg_d_ex_is_reg_a_id = (regfile_waddr_ex_o == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
assign reg_d_ex_is_reg_b_id = (regfile_waddr_ex_o == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
assign reg_d_ex_is_reg_c_id = (regfile_waddr_ex_o == regfile_addr_rc_id) && (regc_used_dec == 1'b1) && (regfile_addr_rc_id != '0);
@ -500,6 +539,14 @@ module riscv_id_stage #(
assign reg_d_alu_is_reg_a_id = (regfile_alu_waddr_fw_i == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
assign reg_d_alu_is_reg_b_id = (regfile_alu_waddr_fw_i == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
assign reg_d_alu_is_reg_c_id = (regfile_alu_waddr_fw_i == regfile_addr_rc_id) && (regc_used_dec == 1'b1) && (regfile_addr_rc_id != '0);
`else // THREE_PORT_REG_FILE
assign reg_d_ex_is_reg_a_id = (regfile_waddr_ex_o == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
assign reg_d_ex_is_reg_b_id = (regfile_waddr_ex_o == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
assign reg_d_wb_is_reg_a_id = (regfile_waddr_wb_i == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
assign reg_d_wb_is_reg_b_id = (regfile_waddr_wb_i == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
assign reg_d_alu_is_reg_a_id = (regfile_alu_waddr_fw_i == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
assign reg_d_alu_is_reg_b_id = (regfile_alu_waddr_fw_i == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
`endif // THREE_PORT_REG_FILE
@ -595,15 +642,18 @@ module riscv_id_stage #(
// | |_| | |_) | __/ | | (_| | | | | (_| | / ___ \ //
// \___/| .__/ \___|_| \__,_|_| |_|\__,_| /_/ \_\ //
// |_| //
////////////////////////////////////////////////////////
///////////////////////////////////////////////////////
/
// ALU_Op_a Mux
always_comb
begin : alu_operand_a_mux
case (alu_op_a_mux_sel)
OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
OP_A_REGB_OR_FWD: alu_operand_a = operand_b_fw_id;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
OP_A_REGC_OR_FWD: alu_operand_a = operand_c_fw_id;
`endif // THREE_PORT_REG_FILE
OP_A_CURRPC: alu_operand_a = pc_id_i;
OP_A_IMM: alu_operand_a = imm_a;
default: alu_operand_a = operand_a_fw_id;
@ -669,7 +719,10 @@ module riscv_id_stage #(
case (alu_op_b_mux_sel)
OP_B_REGA_OR_FWD: operand_b = operand_a_fw_id;
OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
OP_B_REGC_OR_FWD: operand_b = operand_c_fw_id;
`endif // THREE_PORT_REG_FILE
OP_B_IMM: operand_b = imm_b;
OP_B_BMASK: operand_b = $unsigned(operand_b_fw_id[4:0]);
default: operand_b = operand_b_fw_id;
@ -734,6 +787,8 @@ module riscv_id_stage #(
// |_| //
//////////////////////////////////////////////////////
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
// ALU OP C Mux
always_comb
begin : alu_operand_c_mux
@ -756,6 +811,19 @@ module riscv_id_stage #(
endcase; // case (operand_c_fw_mux_sel)
end
`else
// ALU OP C Mux
always_comb
begin : alu_operand_c_mux
case (alu_op_c_mux_sel)
OP_C_REGB_OR_FWD: alu_operand_c = operand_b_fw_id;
OP_C_JT: alu_operand_c = jump_target;
default: alu_operand_c = operand_b_fw_id;
endcase // case (alu_op_c_mux_sel)
end
`endif // THREE_PORT_REG_FILE
///////////////////////////////////////////////////////////////////////////
// ___ _ _ _ ___ ____ //
@ -845,6 +913,8 @@ module riscv_id_stage #(
.raddr_a_i ( regfile_addr_ra_id ),
.rdata_a_o ( regfile_data_ra_id ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
// Read port b
.raddr_b_i ( regfile_addr_rb_id ),
.rdata_b_o ( regfile_data_rb_id ),
@ -852,19 +922,38 @@ module riscv_id_stage #(
// Read port c
.raddr_c_i ( (dbg_reg_rreq_i == 1'b0) ? regfile_addr_rc_id : dbg_reg_raddr_i ),
.rdata_c_o ( regfile_data_rc_id ),
`else
.raddr_b_i ( (dbg_reg_rreq_i == 1'b0) ? regfile_addr_rb_id : dbg_reg_raddr_i ),
.rdata_b_o ( regfile_data_rb_id ),
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
// Write port a
.waddr_a_i ( regfile_waddr_wb_i ),
.wdata_a_i ( regfile_wdata_wb_i ),
.we_a_i ( regfile_we_wb_i ),
// Write port b
.waddr_b_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_alu_waddr_fw_i : dbg_reg_waddr_i ),
.waddr_b_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_alu_waddr_fw_i : dbg_reg_waddr_i ),
.wdata_b_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_alu_wdata_fw_i : dbg_reg_wdata_i ),
.we_b_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_alu_we_fw_i : 1'b1 )
`else
// Write port a (multiplex between ALU and LSU)
.waddr_a_i ( (dbg_reg_wreq_i == 1'b0) ? ( (regfile_alu_we_fw_i == 1'b1) ? regfile_alu_waddr_fw_i : regfile_waddr_wb_i) : dbg_reg_waddr_i ),
.wdata_a_i ( (dbg_reg_wreq_i == 1'b0) ? ( (regfile_alu_we_fw_i == 1'b1) ? regfile_alu_wdata_fw_i : regfile_wdata_wb_i) : dbg_reg_wdata_i ),
.we_a_i ( (dbg_reg_wreq_i == 1'b0) ? (regfile_alu_we_fw_i | regfile_we_wb_i) : 1'b1 )
`endif // THREE_PORT_REG_FILE
);
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign dbg_reg_rdata_o = regfile_data_rc_id;
`else
assign dbg_reg_rdata_o = regfile_data_rb_id;
`endif // THREE_PORT_REG_FILE
///////////////////////////////////////////////
@ -894,7 +983,10 @@ module riscv_id_stage #(
.rega_used_o ( rega_used_dec ),
.regb_used_o ( regb_used_dec ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.regc_used_o ( regc_used_dec ),
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
@ -914,6 +1006,7 @@ module riscv_id_stage #(
.alu_op_a_mux_sel_o ( alu_op_a_mux_sel ),
.alu_op_b_mux_sel_o ( alu_op_b_mux_sel ),
.alu_op_c_mux_sel_o ( alu_op_c_mux_sel ),
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
.alu_vec_mode_o ( alu_vec_mode ),
@ -921,7 +1014,10 @@ module riscv_id_stage #(
`endif // VEC_SUPPORT
.imm_a_mux_sel_o ( imm_a_mux_sel ),
.imm_b_mux_sel_o ( imm_b_mux_sel ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.regc_mux_o ( regc_mux ),
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
@ -999,7 +1095,10 @@ module riscv_id_stage #(
.rega_used_i ( rega_used_dec ),
.regb_used_i ( regb_used_dec ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.regc_used_i ( regc_used_dec ),
`endif // THREE_PORT_REG_FILE
// from IF/ID pipeline
.instr_valid_i ( instr_valid_i ),
@ -1050,11 +1149,13 @@ module riscv_id_stage #(
.regfile_waddr_wb_i ( regfile_waddr_wb_i ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_wb_i ( regfile_we_wb_i ),
// regfile port 2
// regfile port 2 (or multiplexer signal in case of a 2r1w)
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw_i ),
// Forwarding detection signals
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.reg_d_ex_is_reg_a_i ( reg_d_ex_is_reg_a_id ),
.reg_d_ex_is_reg_b_i ( reg_d_ex_is_reg_b_id ),
.reg_d_ex_is_reg_c_i ( reg_d_ex_is_reg_c_id ),
@ -1064,11 +1165,21 @@ module riscv_id_stage #(
.reg_d_alu_is_reg_a_i ( reg_d_alu_is_reg_a_id ),
.reg_d_alu_is_reg_b_i ( reg_d_alu_is_reg_b_id ),
.reg_d_alu_is_reg_c_i ( reg_d_alu_is_reg_c_id ),
`else
.reg_d_ex_is_reg_a_i ( reg_d_ex_is_reg_a_id ),
.reg_d_ex_is_reg_b_i ( reg_d_ex_is_reg_b_id ),
.reg_d_wb_is_reg_a_i ( reg_d_wb_is_reg_a_id ),
.reg_d_wb_is_reg_b_i ( reg_d_wb_is_reg_b_id ),
`endif // THREE_PORT_REG_FILE
// Forwarding signals
.operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ),
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
`endif // THREE_PORT_REG_FILE
// Stall signals
.halt_if_o ( halt_if_o ),
@ -1192,7 +1303,7 @@ always_ff @(posedge clk, negedge rst_n)
alu_operator_ex_o <= ALU_SLTU;
alu_operand_a_ex_o <= '0;
alu_operand_b_ex_o <= '0;
alu_operand_c_ex_o <= '0;
alu_operand_c_ex_o <= '0; // Still needed for jump target if 2r1w reg file used
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT

View file

@ -69,6 +69,10 @@
// Dependent definitions
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
@ -78,8 +82,6 @@
// use simplified ALU
`define SIMPLE_ALU
// reduce register file to 1w2r
`define TWO_PORT_REG_FILE
`endif
`endif

View file

@ -24,6 +24,8 @@
// //
////////////////////////////////////////////////////////////////////////////////
`include "riscv_config.sv"
module riscv_register_file
#(
parameter ADDR_WIDTH = 5,
@ -44,19 +46,27 @@ module riscv_register_file
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
//Read port R3
input logic [ADDR_WIDTH-1:0] raddr_c_i,
output logic [DATA_WIDTH-1:0] rdata_c_o,
`endif // THREE_PORT_REG_FILE
// Write port W1
input logic [ADDR_WIDTH-1:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i,
input logic we_a_i
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
,
// Write port W2
input logic [ADDR_WIDTH-1:0] waddr_b_i,
input logic [DATA_WIDTH-1:0] wdata_b_i,
input logic we_b_i
`endif // THREE_PORT_REG_FILE
);
localparam NUM_WORDS = 2**ADDR_WIDTH;
@ -64,11 +74,17 @@ module riscv_register_file
logic [DATA_WIDTH-1:0] mem[NUM_WORDS];
logic [NUM_WORDS-1:1] waddr_onehot_a;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [NUM_WORDS-1:1] waddr_onehot_b, waddr_onehot_b_q;
`endif // THREE_PORT_REG_FILE
logic [NUM_WORDS-1:1] mem_clocks;
logic [DATA_WIDTH-1:0] wdata_a_q;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [DATA_WIDTH-1:0] wdata_b_q;
`endif // THREE_PORT_REG_FILE
logic clk_int;
@ -77,15 +93,16 @@ module riscv_register_file
int unsigned k;
genvar x;
genvar y;
//-----------------------------------------------------------------------------
//-- READ : Read address decoder RAD
//-----------------------------------------------------------------------------
assign rdata_a_o = mem[raddr_a_i];
assign rdata_b_o = mem[raddr_b_i];
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign rdata_c_o = mem[raddr_c_i];
`endif // THREE_PORT_REG_FILE
//-----------------------------------------------------------------------------
// WRITE : SAMPLE INPUT DATA
@ -94,7 +111,12 @@ module riscv_register_file
cluster_clock_gating CG_WE_GLOBAL
(
.clk_i ( clk ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.en_i ( we_a_i | we_b_i ),
`else
.en_i ( we_a_i ),
`endif // THREE_PORT_REG_FILE
.test_en_i ( test_en_i ),
.clk_o ( clk_int )
);
@ -104,16 +126,21 @@ module riscv_register_file
begin : sample_waddr
if (~rst_n) begin
wdata_a_q <= '0;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
wdata_b_q <= '0;
waddr_onehot_b_q <= '0;
`endif // THREE_PORT_REG_FILE
end else begin
if(we_a_i)
wdata_a_q <= wdata_a_i;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if(we_b_i)
wdata_b_q <= wdata_b_i;
waddr_onehot_b_q <= waddr_onehot_b;
`endif // THREE_PORT_REG_FILE
end
end
@ -131,6 +158,8 @@ module riscv_register_file
end
end
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
always_comb
begin : p_WADb
for(j = 1; j < NUM_WORDS; j++)
@ -141,6 +170,7 @@ module riscv_register_file
waddr_onehot_b[j] = 1'b0;
end
end
`endif // THREE_PORT_REG_FILE
//-----------------------------------------------------------------------------
//-- WRITE : Clock gating (if integrated clock-gating cells are available)
@ -151,7 +181,12 @@ module riscv_register_file
cluster_clock_gating CG_Inst
(
.clk_i ( clk_int ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.en_i ( waddr_onehot_a[x] | waddr_onehot_b[x] ),
`else
.en_i ( waddr_onehot_a[x] ),
`endif // THREE_PORT_REG_FILE
.test_en_i ( test_en_i ),
.clk_o ( mem_clocks[x] )
);
@ -175,7 +210,12 @@ module riscv_register_file
for(k = 1; k < NUM_WORDS; k++)
begin : w_WordIter
if(mem_clocks[k] == 1'b1)
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
mem[k] = waddr_onehot_b_q[k] ? wdata_b_q : wdata_a_q;
`else
mem[k] = wdata_a_q;
`endif // THREE_PORT_REG_FILE
end
end

View file

@ -20,6 +20,8 @@
// //
////////////////////////////////////////////////////////////////////////////////
`include "riscv_config.sv"
module riscv_register_file
#(
parameter ADDR_WIDTH = 5,
@ -40,26 +42,37 @@ module riscv_register_file
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
//Read port R3
input logic [ADDR_WIDTH-1:0] raddr_c_i,
output logic [DATA_WIDTH-1:0] rdata_c_o,
`endif // THREE_PORT_REG_FILE
// Write port W1
input logic [ADDR_WIDTH-1:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i,
input logic we_a_i
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
,
// Write port W2
input logic [ADDR_WIDTH-1:0] waddr_b_i,
input logic [DATA_WIDTH-1:0] wdata_b_i,
input logic we_b_i
`endif // THREE_PORT_REG_FILE
);
localparam NUM_WORDS = 2**ADDR_WIDTH;
logic [NUM_WORDS-1:0][DATA_WIDTH-1:0] rf_reg;
logic [NUM_WORDS-1:0] we_a_dec;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [NUM_WORDS-1:0] we_b_dec;
`endif // THREE_PORT_REG_FILE
always_comb
begin : we_a_decoder
@ -71,6 +84,8 @@ module riscv_register_file
end
end
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
always_comb
begin : we_b_decoder
for (int i=0; i<NUM_WORDS; i++) begin
@ -80,6 +95,7 @@ module riscv_register_file
we_b_dec[i] = 1'b0;
end
end
`endif // THREE_PORT_REG_FILE
genvar i;
generate
@ -93,10 +109,15 @@ module riscv_register_file
if (rst_n==1'b0) begin
rf_reg[i] <= 'b0;
end else begin
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if(we_b_dec[i] == 1'b1)
rf_reg[i] <= wdata_b_i;
else if(we_a_dec[i] == 1'b1)
rf_reg[i] <= wdata_a_i;
`else
rf_reg[i] <= wdata_a_i;
`endif // THREE_PORT_REG_FILE
end
end
@ -109,6 +130,9 @@ module riscv_register_file
assign rdata_a_o = rf_reg[raddr_a_i];
assign rdata_b_o = rf_reg[raddr_b_i];
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign rdata_c_o = rf_reg[raddr_c_i];
`endif // THREE_PORT_REG_FILE
endmodule

View file

@ -481,7 +481,8 @@ module riscv_core
.alu_operator_ex_o ( alu_operator_ex ),
.alu_operand_a_ex_o ( alu_operand_a_ex ),
.alu_operand_b_ex_o ( alu_operand_b_ex ),
.alu_operand_c_ex_o ( alu_operand_c_ex ),
.alu_operand_c_ex_o ( alu_operand_c_ex ), // Still needed if 2r1w reg file used
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
.bmask_a_ex_o ( bmask_a_ex ),