Remove jump in id

This commit is contained in:
Markus Wegmann 2017-01-05 13:22:39 +01:00
parent 17ac38aac1
commit 1ced4c5dca
6 changed files with 89 additions and 1 deletions

View file

@ -171,11 +171,23 @@ module riscv_controller
); );
// FSM state encoding // FSM state encoding
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH, enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE, DECODE,
FLUSH_EX, FLUSH_WB, FLUSH_EX, FLUSH_WB,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns; DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
`else
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE, WAIT_JUMP,
FLUSH_EX, FLUSH_WB,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
`endif
logic jump_done, jump_done_q; logic jump_done, jump_done_q;
@ -316,6 +328,8 @@ module riscv_controller
// we don't need to worry about conditional branches here as they // we don't need to worry about conditional branches here as they
// will be evaluated in the EX stage // will be evaluated in the EX stage
if (jump_in_dec_i == BRANCH_JALR || jump_in_dec_i == BRANCH_JAL) begin if (jump_in_dec_i == BRANCH_JALR || jump_in_dec_i == BRANCH_JAL) begin
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
pc_mux_o = PC_JUMP; pc_mux_o = PC_JUMP;
// if there is a jr stall, wait for it to be gone // if there is a jr stall, wait for it to be gone
@ -327,6 +341,16 @@ module riscv_controller
// we don't have to change our current state here as the prefetch // we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction // buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump target // that is served to the ID stage is the one of the jump target
`else
// if there is a jr stall, wait for it to be gone
if ((~jr_stall_o) && (~jump_done_q)) begin
halt_if_o = 1'b1;
ctrl_fsm_ns = WAIT_JUMP;
end
`endif
end else begin end else begin
// handle exceptions // handle exceptions
if (exc_req_i) begin if (exc_req_i) begin
@ -434,6 +458,21 @@ module riscv_controller
end end
end end
// CONFIG_REGION: JUMP_IN_ID
`ifndef JUMP_IN_ID
// a jump was in ID
WAIT_JUMP:
begin
pc_mux_o = PC_JUMP;
pc_set_o = 1'b1;
jump_done = 1'b1;
ctrl_fsm_ns = DECODE;
end
`endif // JUMP_IN_ID
// a branch was in ID when a debug trap is hit // a branch was in ID when a debug trap is hit
DBG_WAIT_BRANCH: DBG_WAIT_BRANCH:
begin begin

View file

@ -281,6 +281,11 @@ module riscv_decoder
imm_b_mux_sel_o = IMMB_PCINCR; imm_b_mux_sel_o = IMMB_PCINCR;
alu_operator_o = ALU_ADD; alu_operator_o = ALU_ADD;
regfile_alu_we = 1'b1; regfile_alu_we = 1'b1;
// CONFIG_REGION: JUMP_IN_ID
`ifndef JUMP_IN_ID
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline to EX
`endif
// Calculate jump target (= PC + UJ imm) // Calculate jump target (= PC + UJ imm)
end end
@ -301,6 +306,11 @@ module riscv_decoder
regfile_alu_we = 1'b0; regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1; illegal_insn_o = 1'b1;
end end
// CONFIG_REGION: JUMP_IN_ID
`ifndef JUMP_IN_ID
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline to EX
`endif
end end
OPCODE_BRANCH: begin // Branch OPCODE_BRANCH: begin // Branch

View file

@ -85,7 +85,10 @@ module riscv_id_stage
// Jumps and branches // Jumps and branches
output logic branch_in_ex_o, output logic branch_in_ex_o,
input logic branch_decision_i, input logic branch_decision_i,
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
output logic [31:0] jump_target_o, output logic [31:0] jump_target_o,
`endif // JUMP_IN_ID
// IF and ID stage signals // IF and ID stage signals
output logic clear_instr_valid_o, output logic clear_instr_valid_o,
@ -677,8 +680,10 @@ module riscv_id_stage
endcase endcase
end end
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
assign jump_target_o = jump_target; assign jump_target_o = jump_target;
`endif // JUMP_IN_ID
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// ___ _ _ // // ___ _ _ //
@ -1561,10 +1566,20 @@ always_ff @(posedge clk, negedge rst_n)
`ifndef ONLY_ALIGNED `ifndef ONLY_ALIGNED
data_misaligned_ex_o <= 1'b0; data_misaligned_ex_o <= 1'b0;
`endif // ONLY_ALIGNED `endif // ONLY_ALIGNED
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
if ((jump_in_id == BRANCH_COND) || data_load_event_id) begin if ((jump_in_id == BRANCH_COND) || data_load_event_id) begin
pc_ex_o <= pc_id_i; pc_ex_o <= pc_id_i;
end end
branch_in_ex_o <= jump_in_id == BRANCH_COND; branch_in_ex_o <= jump_in_id == BRANCH_COND;
`else
if ((jump_in_id == BRANCH_COND) || (jump_in_id == BRANCH_JAL) || (jump_in_id == BRANCH_JALR) || data_load_event_id) begin
pc_ex_o <= pc_id_i;
end
branch_in_ex_o <= (jump_in_id == BRANCH_COND) || (jump_in_id == BRANCH_JAL) || (jump_in_id == BRANCH_JALR);
`endif
end else if(ex_ready_i) begin end else if(ex_ready_i) begin
// EX stage is ready but we don't have a new instruction for it, // EX stage is ready but we don't have a new instruction for it,
// so we set all write enables to 0, but unstall the pipe // so we set all write enables to 0, but unstall the pipe

View file

@ -69,7 +69,11 @@ module riscv_if_stage #(
input logic [1:0] exc_pc_mux_i, // selects ISR address input logic [1:0] exc_pc_mux_i, // selects ISR address
input logic [4:0] exc_vec_pc_mux_i, // selects ISR address for vectorized interrupt lines input logic [4:0] exc_vec_pc_mux_i, // selects ISR address for vectorized interrupt lines
// jump and branch target and decision // jump and branch target and decision
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
input logic [31:0] jump_target_id_i, // jump target address input logic [31:0] jump_target_id_i, // jump target address
`endif
input logic [31:0] jump_target_ex_i, // jump target address input logic [31:0] jump_target_ex_i, // jump target address
// from hwloop controller // from hwloop controller
// CONFIG_REGION: HWLP_SUPPORT // CONFIG_REGION: HWLP_SUPPORT
@ -144,7 +148,12 @@ module riscv_if_stage #(
unique case (pc_mux_i) unique case (pc_mux_i)
PC_BOOT: fetch_addr_n = {boot_addr_i[31:8], EXC_OFF_RST}; PC_BOOT: fetch_addr_n = {boot_addr_i[31:8], EXC_OFF_RST};
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
PC_JUMP: fetch_addr_n = jump_target_id_i; PC_JUMP: fetch_addr_n = jump_target_id_i;
`else
PC_JUMP: fetch_addr_n = jump_target_ex_i;
`endif // JUMP_IN_ID
PC_BRANCH: fetch_addr_n = jump_target_ex_i; PC_BRANCH: fetch_addr_n = jump_target_ex_i;
PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler
PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception

View file

@ -74,6 +74,10 @@
// will enable clip, min and max operations support. // will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT //`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
//`define JUMP_IN_ID
// Dependent definitions // Dependent definitions

View file

@ -137,7 +137,12 @@ module riscv_core
`endif // MUL_SUPPORT `endif // MUL_SUPPORT
// Jump and branch target and decision (EX->IF) // Jump and branch target and decision (EX->IF)
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
logic [31:0] jump_target_id, jump_target_ex; logic [31:0] jump_target_id, jump_target_ex;
`else
logic [31:0] jump_target_ex;
`endif
logic branch_in_ex; logic branch_in_ex;
logic branch_decision; logic branch_decision;
@ -413,7 +418,10 @@ module riscv_core
.dbg_jump_req_i ( dbg_jump_req ), .dbg_jump_req_i ( dbg_jump_req ),
// Jump targets // Jump targets
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
.jump_target_id_i ( jump_target_id ), .jump_target_id_i ( jump_target_id ),
`endif // JUMP_IN_ID
.jump_target_ex_i ( jump_target_ex ), .jump_target_ex_i ( jump_target_ex ),
// pipeline stalls // pipeline stalls
@ -467,7 +475,10 @@ module riscv_core
// Jumps and branches // Jumps and branches
.branch_in_ex_o ( branch_in_ex ), .branch_in_ex_o ( branch_in_ex ),
.branch_decision_i ( branch_decision ), .branch_decision_i ( branch_decision ),
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
.jump_target_o ( jump_target_id ), .jump_target_o ( jump_target_id ),
`endif
// IF and ID control signals // IF and ID control signals
.clear_instr_valid_o ( clear_instr_valid ), .clear_instr_valid_o ( clear_instr_valid ),