mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Try to remove register buffers
This commit is contained in:
parent
4866ad5139
commit
c6640e06e4
5 changed files with 17 additions and 108 deletions
|
@ -857,8 +857,6 @@ module riscv_controller
|
|||
operand_c_fw_mux_sel_o = SEL_FW_WB;
|
||||
end
|
||||
`else
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifndef MERGE_ID_EX
|
||||
if (regfile_we_wb_i == 1'b1)
|
||||
begin
|
||||
if (reg_d_wb_is_reg_a_i == 1'b1)
|
||||
|
@ -866,7 +864,6 @@ module riscv_controller
|
|||
if (reg_d_wb_is_reg_b_i == 1'b1)
|
||||
operand_b_fw_mux_sel_o = SEL_FW_WB;
|
||||
end
|
||||
`endif
|
||||
`endif // THREE_PORT_REG_FILE
|
||||
|
||||
// Forwarding EX -> ID
|
||||
|
@ -888,12 +885,22 @@ module riscv_controller
|
|||
|
||||
// CONFIG_REGION: ONLY_ALIGNED
|
||||
`ifndef ONLY_ALIGNED
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
// for misaligned memory accesses
|
||||
if (data_misaligned_i)
|
||||
begin
|
||||
operand_a_fw_mux_sel_o = SEL_MISALIGNED;
|
||||
operand_b_fw_mux_sel_o = SEL_REGFILE;
|
||||
end
|
||||
`else
|
||||
// for misaligned memory accesses
|
||||
if (data_misaligned_i)
|
||||
begin
|
||||
operand_a_fw_mux_sel_o = SEL_FW_EX;
|
||||
operand_b_fw_mux_sel_o = SEL_REGFILE;
|
||||
end
|
||||
`endif
|
||||
`endif // ONLY_ALIGNED
|
||||
|
||||
// CONFIG_REGION: MUL_SUPPORT
|
||||
|
@ -931,13 +938,13 @@ module riscv_controller
|
|||
// Assertions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifndef NO_JUMP_ADDER
|
||||
// make sure that taken branches do not happen back-to-back, as this is not
|
||||
// possible without branch prediction in the IF stage
|
||||
assert property (
|
||||
@(posedge clk) (branch_taken_ex_i) |=> (~branch_taken_ex_i) ) else $warning("Two branches back-to-back are taken");
|
||||
`endif // MERGE_ID_EX
|
||||
`endif // NO_JUMP_ADDER
|
||||
assert property (
|
||||
@(posedge clk) (~(dbg_req_i & ext_req_i)) ) else $warning("Both dbg_req_i and ext_req_i are active");
|
||||
|
||||
|
|
82
id_stage.sv
82
id_stage.sv
|
@ -115,11 +115,6 @@ module riscv_id_stage
|
|||
input logic ex_valid_i, // EX stage is done
|
||||
input logic wb_valid_i, // WB stage is done
|
||||
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
output logic id_wait_o, // We did not yet buffer the register ports
|
||||
`endif
|
||||
|
||||
// Pipeline ID/EX
|
||||
output logic [31:0] pc_ex_o,
|
||||
|
||||
|
@ -528,15 +523,6 @@ module riscv_id_stage
|
|||
`endif // MERGE_ID_EX
|
||||
`endif // THREE_PORT_REG_FILE
|
||||
|
||||
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
// As we have a latched register file, we need to buffer the register ports to prevent a time loop over the ALU
|
||||
logic [31:0] reg_buffer_a_Q, reg_buffer_b_Q;
|
||||
enum logic { WAIT_WRITE_BACK, COMPUTING } buffer_fsm_Q, buffer_fsm_n;
|
||||
`endif // MERGE_ID_EX
|
||||
|
||||
|
||||
assign instr = instr_rdata_i;
|
||||
|
||||
// immediate extraction and sign extension
|
||||
|
@ -719,17 +705,9 @@ module riscv_id_stage
|
|||
unique case (jump_target_mux_sel)
|
||||
JT_JAL: jump_target = pc_id_i + imm_uj_type;
|
||||
JT_COND: jump_target = pc_id_i + imm_sb_type;
|
||||
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
// JALR: Cannot forward RS1, since the path is too long
|
||||
JT_JALR: jump_target = reg_buffer_a_Q + imm_i_type;
|
||||
default: jump_target = reg_buffer_a_Q + imm_i_type;
|
||||
`else
|
||||
// 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;
|
||||
`endif
|
||||
endcase
|
||||
end
|
||||
`endif
|
||||
|
@ -777,24 +755,14 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : operand_a_fw_mux
|
||||
case (operand_a_fw_mux_sel)
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifndef MERGE_ID_EX
|
||||
SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
|
||||
`else
|
||||
// CONFIG_REGION: ONLY_ALIGNED
|
||||
`ifndef ONLY_ALIGNED
|
||||
SEL_FW_EX: operand_a_fw_id = misaligned_addr_i;
|
||||
SEL_MISALIGNED: operand_a_fw_id = misaligned_addr_i;
|
||||
`endif
|
||||
`endif
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
SEL_REGFILE: operand_a_fw_id = reg_buffer_a_Q;
|
||||
default: operand_a_fw_id = reg_buffer_a_Q;
|
||||
`else
|
||||
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;
|
||||
`endif
|
||||
endcase; // case (operand_a_fw_mux_sel)
|
||||
end
|
||||
|
||||
|
@ -906,15 +874,9 @@ module riscv_id_stage
|
|||
`ifndef MERGE_ID_EX
|
||||
SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
|
||||
`endif // MERGE_ID_EX
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
SEL_REGFILE: operand_b_fw_id = reg_buffer_b_Q;
|
||||
default: operand_b_fw_id = reg_buffer_b_Q;
|
||||
`else
|
||||
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;
|
||||
`endif
|
||||
endcase; // case (operand_b_fw_mux_sel)
|
||||
end
|
||||
|
||||
|
@ -1776,44 +1738,6 @@ module riscv_id_stage
|
|||
end
|
||||
|
||||
|
||||
|
||||
always_ff @(posedge clk or negedge rst_n) begin
|
||||
if(~rst_n) begin
|
||||
reg_buffer_a_Q <= 32'b0;
|
||||
reg_buffer_b_Q <= 32'b0;
|
||||
buffer_fsm_Q <= WAIT_WRITE_BACK;
|
||||
end else begin
|
||||
if ((buffer_fsm_Q == WAIT_WRITE_BACK && (buffer_fsm_n == COMPUTING))) // TODO: Move to combinational process
|
||||
begin
|
||||
reg_buffer_a_Q <= regfile_data_ra_id;
|
||||
reg_buffer_b_Q <= regfile_data_rb_id;
|
||||
end
|
||||
|
||||
buffer_fsm_Q <= buffer_fsm_n;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
buffer_fsm_n = buffer_fsm_Q;
|
||||
|
||||
case (buffer_fsm_Q)
|
||||
WAIT_WRITE_BACK: begin
|
||||
if (~regfile_we_wb_i & instr_valid_i)
|
||||
buffer_fsm_n = COMPUTING;
|
||||
end
|
||||
|
||||
COMPUTING: begin
|
||||
if (id_ready_o)
|
||||
buffer_fsm_n = WAIT_WRITE_BACK;
|
||||
end
|
||||
default : /* default */;
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
assign id_wait_o = (buffer_fsm_Q == WAIT_WRITE_BACK);
|
||||
|
||||
`endif // MERGE_ID_EX
|
||||
|
||||
|
||||
|
@ -1822,14 +1746,14 @@ module riscv_id_stage
|
|||
`ifndef ONLY_ALIGNED
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
assign id_ready_o = ((~misaligned_stall) & (~jr_stall) & (~load_stall) & ex_ready_i & (~id_wait_o | ~instr_valid_i));
|
||||
assign id_ready_o = ((~misaligned_stall) & (~jr_stall) & (~load_stall) & ex_ready_i);
|
||||
`else
|
||||
assign id_ready_o = ((~misaligned_stall) & (~jr_stall) & (~load_stall) & ex_ready_i);
|
||||
`endif
|
||||
`else
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
assign id_ready_o = ((~jr_stall) & (~load_stall) & ex_ready_i & (~id_wait_o | ~instr_valid_i));
|
||||
assign id_ready_o = ((~jr_stall) & (~load_stall) & ex_ready_i);
|
||||
`else
|
||||
assign id_ready_o = ((~jr_stall) & (~load_stall) & ex_ready_i);
|
||||
`endif
|
||||
|
|
|
@ -208,6 +208,7 @@ parameter SP_DSR_MSB = 8'h04;
|
|||
parameter SEL_REGFILE = 2'b00;
|
||||
parameter SEL_FW_EX = 2'b01;
|
||||
parameter SEL_FW_WB = 2'b10;
|
||||
parameter SEL_MISALIGNED = 2'b11;
|
||||
|
||||
// operand a selection
|
||||
parameter OP_A_REGA_OR_FWD = 3'b000;
|
||||
|
|
|
@ -93,10 +93,6 @@ module riscv_load_store_unit
|
|||
`endif
|
||||
|
||||
input logic ex_valid_i,
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
input logic id_wait_i,
|
||||
`endif
|
||||
|
||||
output logic busy_o
|
||||
);
|
||||
|
@ -455,13 +451,8 @@ module riscv_load_store_unit
|
|||
`ifdef SPLITTED_ADDER
|
||||
if (data_req_ex_i & alu_ready_i) begin
|
||||
`else
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
if (data_req_ex_i & ~id_wait_i) begin
|
||||
`else
|
||||
if (data_req_ex_i) begin
|
||||
`endif
|
||||
`endif
|
||||
data_req_o = data_req_ex_i;
|
||||
lsu_ready_ex_o = 1'b0;
|
||||
|
||||
|
@ -490,12 +481,7 @@ module riscv_load_store_unit
|
|||
`ifdef SPLITTED_ADDER
|
||||
if (data_req_ex_i & alu_ready_i) begin
|
||||
`else
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
if (data_req_ex_i & ~id_wait_i) begin
|
||||
`else
|
||||
if (data_req_ex_i) begin
|
||||
`endif
|
||||
`endif
|
||||
data_req_o = data_req_ex_i;
|
||||
lsu_ready_ex_o = 1'b0;
|
||||
|
|
|
@ -261,11 +261,6 @@ module riscv_core
|
|||
logic lsu_ready_ex;
|
||||
logic lsu_ready_wb;
|
||||
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
logic id_wait;
|
||||
`endif
|
||||
|
||||
// CONFIG_REGION: SPLITTED_ADDER
|
||||
`ifdef SPLITTED_ADDER
|
||||
logic alu_ready;
|
||||
|
@ -777,10 +772,6 @@ module riscv_core
|
|||
`ifdef SPLITTED_ADDER
|
||||
.alu_ready_o ( alu_ready ),
|
||||
`endif
|
||||
// CONFIG_REGION: MERGE_ID_EX
|
||||
`ifdef MERGE_ID_EX
|
||||
.id_wait_i ( id_wait ),
|
||||
`endif
|
||||
|
||||
.ex_ready_o ( ex_ready ),
|
||||
.ex_valid_o ( ex_valid ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue