mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 21:39:13 -04:00
Begin to implement ID-EX merge
This commit is contained in:
parent
42f73781d0
commit
69fc1a2e67
5 changed files with 148 additions and 66 deletions
|
@ -433,14 +433,19 @@ module riscv_controller
|
|||
end
|
||||
end
|
||||
|
||||
// TODO: make sure this is not done multiple times in a row!!!
|
||||
// TODO: make sure this is not done multiple times in a row (RI5CY)!!!
|
||||
// maybe with an assertion?
|
||||
// handle conditional branches
|
||||
// CONFIG_REGION: SPLITTED_ADDER
|
||||
`ifdef SPLITTED_ADDER
|
||||
if (branch_taken_ex_i & ex_valid_i) begin
|
||||
`else
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
if (branch_taken_ex_i & ex_valid_i) begin
|
||||
`else
|
||||
if (branch_taken_ex_i) begin
|
||||
`endif
|
||||
`endif
|
||||
// there is a branch in the EX stage that is taken
|
||||
pc_mux_o = PC_BRANCH;
|
||||
|
|
48
decoder.sv
48
decoder.sv
|
@ -273,6 +273,20 @@ module riscv_decoder
|
|||
//////////////////////////////////////
|
||||
|
||||
OPCODE_JAL: begin // Jump and Link
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
jump_in_id = BRANCH_JAL;
|
||||
// Calculate and store PC+4
|
||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_UJ;
|
||||
alu_operator_o = ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
|
||||
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline return address to EX
|
||||
|
||||
`else // NO_JUMP_ADDER
|
||||
|
||||
jump_target_mux_sel_o = JT_JAL;
|
||||
jump_in_id = BRANCH_JAL;
|
||||
// Calculate and store PC+4
|
||||
|
@ -286,10 +300,31 @@ module riscv_decoder
|
|||
`ifndef JUMP_IN_ID
|
||||
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline to EX
|
||||
`endif
|
||||
// Calculate jump target (= PC + UJ imm)
|
||||
`endif
|
||||
end
|
||||
|
||||
OPCODE_JALR: begin // Jump and Link Register
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
jump_in_id = BRANCH_JALR;
|
||||
// Calculate and store PC+4
|
||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD;
|
||||
imm_b_mux_sel_o = IMMB_SB;
|
||||
alu_operator_o = ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
|
||||
if (instr_rdata_i[14:12] != 3'b0) begin
|
||||
jump_in_id = BRANCH_NONE;
|
||||
regfile_alu_we = 1'b0;
|
||||
illegal_insn_o = 1'b1;
|
||||
end
|
||||
|
||||
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline return address to EX
|
||||
|
||||
`else // NO_JUMP_ADDER
|
||||
|
||||
jump_target_mux_sel_o = JT_JALR;
|
||||
jump_in_id = BRANCH_JALR;
|
||||
// Calculate and store PC+4
|
||||
|
@ -311,9 +346,15 @@ module riscv_decoder
|
|||
`ifndef JUMP_IN_ID
|
||||
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline to EX
|
||||
`endif
|
||||
`endif
|
||||
end
|
||||
|
||||
OPCODE_BRANCH: begin // Branch
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
illegal_insn_o = 1'b1;
|
||||
|
||||
`else
|
||||
jump_target_mux_sel_o = JT_COND;
|
||||
jump_in_id = BRANCH_COND;
|
||||
alu_op_c_mux_sel_o = OP_C_JT;
|
||||
|
@ -344,6 +385,7 @@ module riscv_decoder
|
|||
illegal_insn_o = 1'b1;
|
||||
end
|
||||
endcase
|
||||
`endif // NO_JUMP_ADDER
|
||||
end
|
||||
|
||||
|
||||
|
@ -1274,8 +1316,8 @@ module riscv_decoder
|
|||
`ifdef HWLP_SUPPORT
|
||||
assign hwloop_we_o = (deassert_we_i) ? 3'b0 : hwloop_we;
|
||||
`endif // HWLP_SUPPORT
|
||||
assign csr_op_o = (deassert_we_i) ? CSR_OP_NONE : csr_op;
|
||||
assign jump_in_id_o = (deassert_we_i) ? BRANCH_NONE : jump_in_id;
|
||||
assign csr_op_o = (deassert_we_i) ? CSR_OP_NONE : csr_op;
|
||||
assign jump_in_id_o = (deassert_we_i) ? BRANCH_NONE : jump_in_id;
|
||||
assign ebrk_insn_o = (deassert_we_i) ? 1'b0 : ebrk_insn;
|
||||
assign eret_insn_o = (deassert_we_i) ? 1'b0 : eret_insn; // TODO: do not deassert?
|
||||
assign pipe_flush_o = (deassert_we_i) ? 1'b0 : pipe_flush; // TODO: do not deassert?
|
||||
|
|
141
id_stage.sv
141
id_stage.sv
|
@ -323,7 +323,10 @@ module riscv_id_stage
|
|||
logic [31:0] imm_a; // contains the immediate for operand b
|
||||
logic [31:0] imm_b; // contains the immediate for operand b
|
||||
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
logic [31:0] jump_target; // calculated jump target (-> EX -> IF)
|
||||
`endif
|
||||
|
||||
|
||||
// Signals running between controller and exception controller
|
||||
|
@ -363,7 +366,10 @@ module riscv_id_stage
|
|||
|
||||
logic [0:0] imm_a_mux_sel;
|
||||
logic [3:0] imm_b_mux_sel;
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`if NO_JUMP_ADDER
|
||||
logic [1:0] jump_target_mux_sel;
|
||||
`endif
|
||||
|
||||
// CONFIG_REGION: MUL_SUPPORT
|
||||
`ifdef MUL_SUPPORT
|
||||
|
@ -623,67 +629,70 @@ module riscv_id_stage
|
|||
// //
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// hwloop register id
|
||||
assign hwloop_regid_int = instr[7]; // rd contains hwloop register id
|
||||
|
||||
// hwloop register id
|
||||
assign hwloop_regid_int = instr[7]; // rd contains hwloop register id
|
||||
|
||||
// hwloop target mux
|
||||
always_comb
|
||||
begin
|
||||
case (hwloop_target_mux_sel)
|
||||
1'b0: hwloop_target = pc_id_i + {imm_iz_type[30:0], 1'b0};
|
||||
1'b1: hwloop_target = pc_id_i + {imm_z_type[30:0], 1'b0};
|
||||
endcase
|
||||
end
|
||||
|
||||
// hwloop start mux
|
||||
always_comb
|
||||
begin
|
||||
case (hwloop_start_mux_sel)
|
||||
1'b0: hwloop_start_int = hwloop_target; // for PC + I imm
|
||||
1'b1: hwloop_start_int = pc_if_i; // for next PC
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// hwloop cnt mux
|
||||
always_comb
|
||||
begin : hwloop_cnt_mux
|
||||
case (hwloop_cnt_mux_sel)
|
||||
1'b0: hwloop_cnt_int = imm_iz_type;
|
||||
1'b1: hwloop_cnt_int = operand_a_fw_id;
|
||||
endcase;
|
||||
end
|
||||
|
||||
// multiplex between access from instructions and access via CSR registers
|
||||
assign hwloop_start = hwloop_we_int[0] ? hwloop_start_int : csr_hwlp_data_i;
|
||||
assign hwloop_end = hwloop_we_int[1] ? hwloop_target : csr_hwlp_data_i;
|
||||
assign hwloop_cnt = hwloop_we_int[2] ? hwloop_cnt_int : csr_hwlp_data_i;
|
||||
assign hwloop_regid = (|hwloop_we_int) ? hwloop_regid_int : csr_hwlp_regid_i;
|
||||
assign hwloop_we = (|hwloop_we_int) ? hwloop_we_int : csr_hwlp_we_i;
|
||||
`endif // HWLP_SUPPORT
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// _ _____ _ //
|
||||
// | |_ _ _ __ ___ _ __ |_ _|_ _ _ __ __ _ ___| |_ //
|
||||
// _ | | | | | '_ ` _ \| '_ \ | |/ _` | '__/ _` |/ _ \ __| //
|
||||
// | |_| | |_| | | | | | | |_) | | | (_| | | | (_| | __/ |_ //
|
||||
// \___/ \__,_|_| |_| |_| .__/ |_|\__,_|_| \__, |\___|\__| //
|
||||
// |_| |___/ //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
always_comb
|
||||
begin : jump_target_mux
|
||||
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;
|
||||
|
||||
// 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;
|
||||
// hwloop target mux
|
||||
always_comb
|
||||
begin
|
||||
case (hwloop_target_mux_sel)
|
||||
1'b0: hwloop_target = pc_id_i + {imm_iz_type[30:0], 1'b0};
|
||||
1'b1: hwloop_target = pc_id_i + {imm_z_type[30:0], 1'b0};
|
||||
endcase
|
||||
end
|
||||
|
||||
// hwloop start mux
|
||||
always_comb
|
||||
begin
|
||||
case (hwloop_start_mux_sel)
|
||||
1'b0: hwloop_start_int = hwloop_target; // for PC + I imm
|
||||
1'b1: hwloop_start_int = pc_if_i; // for next PC
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// hwloop cnt mux
|
||||
always_comb
|
||||
begin : hwloop_cnt_mux
|
||||
case (hwloop_cnt_mux_sel)
|
||||
1'b0: hwloop_cnt_int = imm_iz_type;
|
||||
1'b1: hwloop_cnt_int = operand_a_fw_id;
|
||||
endcase;
|
||||
end
|
||||
|
||||
// multiplex between access from instructions and access via CSR registers
|
||||
assign hwloop_start = hwloop_we_int[0] ? hwloop_start_int : csr_hwlp_data_i;
|
||||
assign hwloop_end = hwloop_we_int[1] ? hwloop_target : csr_hwlp_data_i;
|
||||
assign hwloop_cnt = hwloop_we_int[2] ? hwloop_cnt_int : csr_hwlp_data_i;
|
||||
assign hwloop_regid = (|hwloop_we_int) ? hwloop_regid_int : csr_hwlp_regid_i;
|
||||
assign hwloop_we = (|hwloop_we_int) ? hwloop_we_int : csr_hwlp_we_i;
|
||||
`endif // HWLP_SUPPORT
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// _ _____ _ //
|
||||
// | |_ _ _ __ ___ _ __ |_ _|_ _ _ __ __ _ ___| |_ //
|
||||
// _ | | | | | '_ ` _ \| '_ \ | |/ _` | '__/ _` |/ _ \ __| //
|
||||
// | |_| | |_| | | | | | | |_) | | | (_| | | | (_| | __/ |_ //
|
||||
// \___/ \__,_|_| |_| |_| .__/ |_|\__,_|_| \__, |\___|\__| //
|
||||
// |_| |___/ //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifndef NO_JUMP_ADDER
|
||||
always_comb
|
||||
begin : jump_target_mux
|
||||
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;
|
||||
|
||||
// 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
|
||||
`endif
|
||||
|
||||
// CONFIG_REGION: JUMP_IN_ID
|
||||
`ifdef JUMP_IN_ID
|
||||
assign jump_target_o = jump_target;
|
||||
|
@ -752,24 +761,33 @@ module riscv_id_stage
|
|||
IMMB_I: imm_b = imm_i_type;
|
||||
IMMB_S: imm_b = imm_s_type;
|
||||
IMMB_U: imm_b = imm_u_type;
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifndef NO_JUMP_ADDER
|
||||
// CONFIG_REGION: ONLY_ALIGNED
|
||||
`ifndef ONLY_ALIGNED
|
||||
IMMB_PCINCR: imm_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4;
|
||||
`else
|
||||
IMMB_PCINCR: imm_b = (is_compressed_i) ? 32'h2 : 32'h4;
|
||||
`endif // ONLY_ALIGNED
|
||||
`endif // NO_JUMP_ADDER
|
||||
|
||||
IMMB_S2: imm_b = imm_s2_type;
|
||||
IMMB_BI: imm_b = imm_bi_type;
|
||||
IMMB_S3: imm_b = imm_s3_type;
|
||||
IMMB_VS: imm_b = imm_vs_type;
|
||||
IMMB_VU: imm_b = imm_vu_type;
|
||||
IMMB_SB
|
||||
// CONFIG_REGION: MATH_SPECIAL_SUPPORT
|
||||
`ifdef MATH_SPECIAL_SUPPORT
|
||||
IMMB_SHUF: imm_b = imm_shuffle_type;
|
||||
IMMB_CLIP: imm_b = {1'b0, imm_clip_type[31:1]};
|
||||
`endif // MATH_SPECIAL_SUPPORT
|
||||
default: imm_b = imm_i_type;
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
IMMB_UJ: imm_b = imm_uj_type
|
||||
IMMB_SB: imm_b = imm_sb_type;
|
||||
`endif
|
||||
default: imm_b = imm_i_type;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -856,7 +874,7 @@ module riscv_id_stage
|
|||
OP_C_REGC_OR_FWD: alu_operand_c = operand_c_fw_id;
|
||||
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_c_fw_id;
|
||||
default: alu_operand_c = operand_c_fw_id;
|
||||
endcase // case (alu_op_c_mux_sel)
|
||||
end
|
||||
|
||||
|
@ -877,7 +895,12 @@ module riscv_id_stage
|
|||
begin : alu_operand_c_mux
|
||||
case (alu_op_c_mux_sel)
|
||||
OP_C_REGB_OR_FWD: alu_operand_c = operand_b_fw_id;
|
||||
// CONFIG_REGION: NO_JUMP_ADDER
|
||||
`ifdef NO_JUMP_ADDER
|
||||
OP_C_JT: alu_operand_c = pc_if_i; // this is the return address
|
||||
`else
|
||||
OP_C_JT: alu_operand_c = jump_target;
|
||||
`endif
|
||||
default: alu_operand_c = operand_b_fw_id;
|
||||
endcase // case (alu_op_c_mux_sel)
|
||||
end
|
||||
|
|
|
@ -111,15 +111,25 @@
|
|||
|
||||
// CONFIG: SPLITTED_ADDER
|
||||
// will split ALU Adder in half and use two cycles to add operands
|
||||
`define SPLITTED_ADDER
|
||||
//`define SPLITTED_ADDER
|
||||
|
||||
|
||||
`ifdef SMALL_IF
|
||||
`ifndef JUMP_IN_ID
|
||||
// CONFIG: NO_JUMP_ADDER
|
||||
// will use ALU adder to calculate target and return address from prefetcher
|
||||
`define NO_JUMP_ADDER
|
||||
// (NOT IMPLEMENTED!!!) will use ALU adder to calculate target and return address from prefetcher
|
||||
//`define NO_JUMP_ADDER
|
||||
`endif
|
||||
`endif
|
||||
|
||||
`ifndef SPLITTED_ADDER
|
||||
`ifndef NO_JUMP_ADDER
|
||||
`ifdef JUMP_IN_ID
|
||||
// CONFIG: MERGE_ID_EX
|
||||
// will merge the ID and EX stage
|
||||
`define MERGE_ID_EX
|
||||
|
||||
`endif
|
||||
`endif
|
||||
`endif
|
||||
|
||||
|
|
|
@ -239,6 +239,8 @@ parameter IMMB_VU = 4'b0111;
|
|||
parameter IMMB_SHUF = 4'b1000;
|
||||
parameter IMMB_CLIP = 4'b1001;
|
||||
parameter IMMB_BI = 4'b1011;
|
||||
parameter IMMB_UJ = 4'b1100;
|
||||
parameter IMMB_SB = 4'b1101;
|
||||
|
||||
// bit mask selection
|
||||
parameter BMASK_A_ZERO = 1'b0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue