Try to remove register buffers

This commit is contained in:
Markus Wegmann 2017-01-09 10:59:11 +01:00
parent 4866ad5139
commit c6640e06e4
5 changed files with 17 additions and 108 deletions

View file

@ -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");

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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 ),