mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 21:39:13 -04:00
Implement 2r1w register file
This commit is contained in:
parent
83fc605acb
commit
d871d1a590
8 changed files with 264 additions and 25 deletions
|
@ -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
|
||||
|
|
36
decoder.sv
36
decoder.sv
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
127
id_stage.sv
127
id_stage.sv
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue