Remove jump target adder

This commit is contained in:
Markus Wegmann 2017-01-09 13:57:24 +01:00
parent 4fa38974d5
commit 9bdec204dc
8 changed files with 201 additions and 40 deletions

View file

@ -163,6 +163,10 @@ module riscv_controller
`endif // ONLY_ALIGNED
output logic jr_stall_o,
output logic load_stall_o,
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
output logic branch_stall_o,
`endif
input logic id_ready_i, // ID stage is ready
@ -180,18 +184,25 @@ module riscv_controller
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE, WAIT_BRANCH_EX
FLUSH_EX, FLUSH_WB,
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,
FLUSH_EX, FLUSH_WB,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
`endif
`else
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE, WAIT_JUMP_EX,
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;
@ -245,6 +256,12 @@ module riscv_controller
halt_id_o = 1'b0;
dbg_ack_o = 1'b0;
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
branch_stall_o = 1'b0,
`endif
unique case (ctrl_fsm_cs)
// We were just reset, wait for fetch_enable
RESET:
@ -334,9 +351,16 @@ module riscv_controller
// handle conditional branches
if (branch_taken_ex_i & id_ready_i) begin
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
halt_if_o = 1'b1;
if (id_ready_i)
ctrl_fsm = WAIT_BRANCH_EX;
`else
// there is a branch in the EX stage that is taken
pc_mux_o = PC_BRANCH;
pc_set_o = 1'b1;
pc_mux_o = PC_BRANCH;
pc_set_o = 1'b1;
// if we want to debug, flush the pipeline
// the current_pc_if will take the value of the next instruction to
@ -352,10 +376,12 @@ module riscv_controller
// that is served to the ID stage is the one of the jump to the
// exception handler
end
if (dbg_req_i)
begin
ctrl_fsm_ns = DBG_SIGNAL;
end
`endif
end
// handle unconditional jumps
@ -575,12 +601,7 @@ module riscv_controller
`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;
@ -642,6 +663,43 @@ module riscv_controller
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
`ifdef NO_JUMP_ADDER
WAIT_BRANCH_EX:
begin
// there is a branch in the EX stage that is taken
branch_stall_o = 1'b1;
halt_if_o = 1'b1;
if (id_ready_i)
begin
pc_mux_o = PC_BRANCH;
pc_set_o = 1'b1;
ctrl_fsm_cs = DECODE;
halt_if_o = 1'b0;
// if we want to debug, flush the pipeline
// the current_pc_if will take the value of the next instruction to
// be executed (NPC)
if (ext_req_i) begin
pc_mux_o = PC_EXCEPTION;
pc_set_o = 1'b1;
exc_ack_o = 1'b1;
halt_id_o = 1'b1; // we don't want to propagate this instruction to EX
exc_save_takenbranch_o = 1'b1;
// we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump to the
// exception handler
end
if (dbg_req_i)
begin
ctrl_fsm_ns = DBG_SIGNAL;
end
end
end
`endif // NO_JUMP_ADDER
`else
// a branch was in ID when a debug trap is hit
DBG_WAIT_BRANCH:
begin

View file

@ -41,6 +41,10 @@ module riscv_decoder
`ifndef ONLY_ALIGNED
input logic data_misaligned_i, // misaligned data load/store in progress
`endif // ONLY_ALIGNED
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
input logic branch_stall_i,
`endif
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// MUL related control signals
@ -76,7 +80,7 @@ module riscv_decoder
// ALU signals
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
output logic [2:0] alu_op_b_mux_sel_o, // oNOperand b selection: reg value or immediate
output logic [1:0] alu_op_c_mux_sel_o, // operand c selection: reg value or jump target
// CONFIG_REGION: VEC_SUPPORT
@ -280,14 +284,14 @@ module riscv_decoder
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
jump_in_id = BRANCH_JAL;
// Calculate and store PC+4
// Calculate jump target in EX
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
alu_op_c_mux_sel_o = OP_C_RA; // Pipeline return address to EX
`else // NO_JUMP_ADDER
@ -311,7 +315,7 @@ module riscv_decoder
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
jump_in_id = BRANCH_JALR;
// Calculate and store PC+4
// Calculate jump target in EX
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;
@ -325,7 +329,7 @@ module riscv_decoder
illegal_insn_o = 1'b1;
end
alu_op_c_mux_sel_o = OP_C_JT; // Pipeline return address to EX
alu_op_c_mux_sel_o = OP_C_RA; // Pipeline return address to EX
`else // NO_JUMP_ADDER
@ -356,7 +360,46 @@ module riscv_decoder
OPCODE_BRANCH: begin // Branch
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
illegal_insn_o = 1'b1;
jump_in_id = BRANCH_COND;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
if (~branch_stall_i)
begin
unique case (instr_rdata_i[14:12])
3'b000: alu_operator_o = ALU_EQ;
3'b001: alu_operator_o = ALU_NE;
3'b100: alu_operator_o = ALU_LTS;
3'b101: alu_operator_o = ALU_GES;
3'b110: alu_operator_o = ALU_LTU;
3'b111: alu_operator_o = ALU_GEU;
3'b010: begin
alu_operator_o = ALU_EQ;
regb_used_o = 1'b0;
alu_op_b_mux_sel_o = OP_B_IMM;
imm_b_mux_sel_o = IMMB_BI;
end
3'b011: begin
alu_operator_o = ALU_NE;
regb_used_o = 1'b0;
alu_op_b_mux_sel_o = OP_B_IMM;
imm_b_mux_sel_o = IMMB_BI;
end
default: begin
illegal_insn_o = 1'b1;
end
endcase
end
else begin
// Calculate jump target in EX
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'b0;
rega_used_o = 1'b1;
end
`else
jump_target_mux_sel_o = JT_COND;

View file

@ -89,6 +89,10 @@ module riscv_ex_stage
input logic branch_in_ex_i,
input logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_i,
input logic regfile_alu_we_i,
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
input logic jump_in_ex_i;
`endif
// directly passed through to WB stage, not used in EX
input logic regfile_we_i,
@ -126,10 +130,7 @@ module riscv_ex_stage
`ifdef SPLITTED_ADDER
output logic alu_ready_o,
`endif
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
input logic id_wait_i,
`endif
output logic ex_ready_o, // EX stage ready for new data
output logic ex_valid_o, // EX stage gets new data
@ -163,7 +164,12 @@ module riscv_ex_stage
`ifdef MUL_SUPPORT
assign regfile_alu_wdata_fw_o = mult_en_i ? mult_result : alu_csr_result;
`else
// CONFIG_REGION
`ifdef NO_JUMP_ADDER
assign regfile_alu_wdata_fw_o = jump_in_ex_i ? operand_c_i : alu_csr_result; // Select return address
`else
assign regfile_alu_wdata_fw_o = alu_csr_result;
`endif
`endif // MUL_SUPPORT
@ -173,7 +179,13 @@ module riscv_ex_stage
// branch handling
assign branch_decision_o = alu_cmp_result;
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
assign jump_target_o = adder_result_o;
`else
assign jump_target_o = alu_operand_c_i;
`endif
////////////////////////////

View file

@ -87,7 +87,10 @@ module riscv_id_stage
input logic branch_decision_i,
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
output logic [31:0] jump_target_o,
`endif
`endif // JUMP_IN_ID
// IF and ID stage signals
@ -122,6 +125,11 @@ module riscv_id_stage
output logic [31:0] alu_operand_b_ex_o,
output logic [31:0] alu_operand_c_ex_o, // Still needed if 2r1w reg file used
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
output logic jump_in_ex_o, // Select operand C as return address to save in regfile
`endif
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
output logic [ 4:0] bmask_a_ex_o,
@ -216,7 +224,6 @@ module riscv_id_stage
`endif
`endif // ONLY_ALIGNED
// Interrupt signals
input logic [31:0] irq_i,
input logic irq_enable_i,
@ -302,6 +309,10 @@ module riscv_id_stage
`ifndef ONLY_ALIGNED
logic misaligned_stall;
`endif
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
logic branch_stall;
`endif
logic jr_stall;
logic load_stall;
@ -332,11 +343,13 @@ 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
`ifndef NO_JUMP_ADDER
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
logic [31:0] jump_target; // calculated jump target (-> EX -> IF)
`endif
`endif
// Signals running between controller and exception controller
logic exc_req, ext_req, exc_ack; // handshake
@ -377,8 +390,11 @@ module riscv_id_stage
logic [3:0] imm_b_mux_sel;
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
logic [1:0] jump_target_mux_sel;
`endif
`endif
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
@ -714,7 +730,10 @@ module riscv_id_stage
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
assign jump_target_o = jump_target;
`endif
`endif // JUMP_IN_ID
////////////////////////////////////////////////////////
@ -1087,6 +1106,10 @@ module riscv_id_stage
`ifndef ONLY_ALIGNED
.data_misaligned_i ( data_misaligned_i ),
`endif // ONLY_ALIGNED
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
.branch_stall_i ( branch_stall ),
`endif
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
.mult_multicycle_i ( mult_multicycle_i ),
@ -1323,6 +1346,10 @@ module riscv_id_stage
`ifndef ONLY_ALIGNED
.misaligned_stall_o ( misaligned_stall ),
`endif // ONLY_ALIGNED
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
.branch_stall_o ( branch_stall ),
`endif
.jr_stall_o ( jr_stall ),
.load_stall_o ( load_stall ),

View file

@ -72,8 +72,11 @@ module riscv_if_stage #(
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
input logic [31:0] jump_target_id_i, // jump target address
`endif
`endif
input logic [31:0] jump_target_ex_i, // jump target address
// from hwloop controller
// CONFIG_REGION: HWLP_SUPPORT
@ -90,10 +93,6 @@ module riscv_if_stage #(
output logic if_ready_o,
input logic id_ready_i,
output logic if_valid_o,
// CONFIG_REGION: JUMP_IN_ID
`ifndef JUMP_IN_ID
output logic fetch_valid_o, // intended for jump in EX to see whether it is safe so go back to decode state
`endif
// misc signals
output logic if_busy_o, // is the IF stage busy fetching instructions?
output logic perf_imiss_o // Instruction Fetch Miss
@ -158,9 +157,14 @@ module riscv_if_stage #(
PC_BOOT: fetch_addr_n = {boot_addr_i[31:8], EXC_OFF_RST};
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
PC_JUMP: fetch_addr_n = jump_target_id_i;
`else
PC_JUMP: fetch_addr_n = jump_target_ex_i;
`endif
`else
PC_JUMP: fetch_addr_n = jump_target_ex_i;
`endif // JUMP_IN_ID
PC_BRANCH: fetch_addr_n = jump_target_ex_i;
PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler
@ -495,11 +499,6 @@ module riscv_if_stage #(
assign if_ready_o = valid & id_ready_i;
assign if_valid_o = (~halt_if_i) & if_ready_o;
// CONFIG_REGION: JUMP_IN_ID
`ifndef JUMP_IN_ID
assign fetch_valid_o = fetch_valid;
`endif
//----------------------------------------------------------------------------
// Assertions
//----------------------------------------------------------------------------

View file

@ -75,7 +75,7 @@
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
// will enable direct jump in ID. Might increase critical path of jump target
`define JUMP_IN_ID
@ -113,22 +113,19 @@
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifdef SMALL_IF
`ifndef JUMP_IN_ID
// CONFIG: 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/fuse the ID and EX stage
`define MERGE_ID_EX
`ifdef SMALL_IF
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
`define NO_JUMP_ADDER
`endif
`endif
`endif

View file

@ -266,6 +266,7 @@ parameter MIMM_S3 = 1'b1;
parameter OP_C_REGC_OR_FWD = 2'b00;
parameter OP_C_REGB_OR_FWD = 2'b01;
parameter OP_C_JT = 2'b10;
parameter OP_C_RA = 2'b10; // same as OP_C_JT
// branch types
parameter BRANCH_NONE = 2'b00;

View file

@ -143,7 +143,12 @@ module riscv_core
// Jump and branch target and decision (EX->IF)
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
logic [31:0] jump_target_id, jump_target_ex;
`else
logic [31:0] jump_target_ex;
`endif
`else
logic [31:0] jump_target_ex;
`endif
@ -164,6 +169,10 @@ module riscv_core
logic [31:0] alu_operand_a_ex;
logic [31:0] alu_operand_b_ex;
logic [31:0] alu_operand_c_ex;
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
logic jump_in_ex;
`endif
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
@ -436,7 +445,10 @@ module riscv_core
// Jump targets
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
.jump_target_id_i ( jump_target_id ),
`endif
`endif // JUMP_IN_ID
.jump_target_ex_i ( jump_target_ex ),
@ -493,8 +505,11 @@ module riscv_core
.branch_decision_i ( branch_decision ),
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
.jump_target_o ( jump_target_id ),
`endif
`endif
// IF and ID control signals
.clear_instr_valid_o ( clear_instr_valid ),
@ -541,6 +556,11 @@ module riscv_core
.alu_req_ex_o ( alu_req_ex ),
`endif
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
.jump_in_ex_o ( jump_in_ex ),
`endif
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
.bmask_a_ex_o ( bmask_a_ex ),
@ -745,6 +765,10 @@ module riscv_core
.branch_in_ex_i ( branch_in_ex ),
.regfile_alu_waddr_i ( regfile_alu_waddr_ex ),
.regfile_alu_we_i ( regfile_alu_we_ex ),
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
.jump_in_ex_i ( jump_in_ex ),
`endif
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE