fixed jumps

This commit is contained in:
Pasquale Davide Schiavone 2017-03-03 14:10:34 +01:00
parent ab7b00fbc6
commit 495a05c7f4
5 changed files with 84 additions and 119 deletions

View file

@ -45,7 +45,7 @@ module zeroriscy_controller
// decoder related signals
output logic deassert_we_o, // deassert write enable for next instruction
input logic illegal_insn_i, // decoder encountered an invalid instruction
input logic eret_insn_i, // decoder encountered an eret instruction
input logic mret_insn_i, // decoder encountered an eret instruction
input logic pipe_flush_i, // decoder wants to do a pipe flush
// from IF/ID pipeline
@ -68,8 +68,8 @@ module zeroriscy_controller
input logic branch_in_id_i, // branch in id
input logic branch_taken_ex_i, // branch taken signal
input logic branch_set_i, // branch taken set signal
input logic [1:0] jump_in_id_i, // jump is being calculated in ALU
input logic [1:0] jump_in_dec_i, // jump is being calculated in ALU
input logic jump_set_i, // jump taken set signal
input logic jump_in_id_i, // jump is being calculated in ALU
input logic instr_multicyle_i, // multicycle instructions active
@ -96,15 +96,18 @@ module zeroriscy_controller
output logic halt_if_o,
output logic halt_id_o,
input logic jump_stall_i,
input logic load_stall_i,
input logic branch_stall_i,
input logic id_ready_i, // ID stage is ready
input logic if_valid_i, // IF stage is done
// Performance Counters
output logic perf_jump_o, // we are executing a jump instruction (j, jr, jal, jalr)
output logic perf_jr_stall_o, // stall due to jump-register-hazard
output logic perf_ld_stall_o // stall due to load-use-hazard
output logic perf_jr_stall_o, // stall due to jump instruction
output logic perf_br_stall_o, // stall due to branch instruction
output logic perf_ld_stall_o // stall due to load instruction
);
// FSM state encoding
@ -165,7 +168,6 @@ module zeroriscy_controller
dbg_ack_o = 1'b0;
irq_ack_o = 1'b0;
jump_in_dec = jump_in_dec_i == BRANCH_JALR || jump_in_dec_i == BRANCH_JAL;
unique case (ctrl_fsm_cs)
// We were just reset, wait for fetch_enable
@ -260,7 +262,7 @@ module zeroriscy_controller
if (dbg_req_i)
ctrl_fsm_ns = DBG_SIGNAL;
end
jump_in_dec: begin
jump_set_i: begin
pc_mux_o = PC_JUMP;
pc_set_o = 1'b1;
if (dbg_req_i)
@ -274,7 +276,7 @@ module zeroriscy_controller
if (dbg_req_i)
ctrl_fsm_ns = DBG_SIGNAL;
end
eret_insn_i: begin
mret_insn_i: begin
//handles eret when the core should go back to sleep
pc_mux_o = PC_ERET;
pc_set_o = 1'b1;
@ -453,8 +455,9 @@ module zeroriscy_controller
end
// Performance Counters
assign perf_jump_o = (jump_in_id_i == BRANCH_JAL || jump_in_id_i == BRANCH_JALR);
assign perf_jr_stall_o = 1'b0;
assign perf_jump_o = jump_in_id_i;
assign perf_jr_stall_o = jump_stall_i;
assign perf_br_stall_o = branch_stall_i;
assign perf_ld_stall_o = load_stall_i;

View file

@ -36,17 +36,13 @@ module zeroriscy_decoder
input logic deassert_we_i, // deassert we, we are stalled or not active
input logic data_misaligned_i, // misaligned data load/store in progress
input logic branch_set_i,
input logic jump_set_i,
output logic illegal_insn_o, // illegal instruction encountered
output logic ebrk_insn_o, // trap instruction encountered
output logic eret_insn_o, // return from exception instruction encountered
output logic mret_insn_o, // return from exception instruction encountered
output logic ecall_insn_o, // environment call (syscall) instruction encountered
output logic pipe_flush_o, // pipeline flush is requested
output logic rega_used_o, // rs1 is used by current instruction
output logic regb_used_o, // rs2 is used by current instruction
// from IF/ID pipeline
input logic [31:0] instr_rdata_i, // instruction read from instr memory/cache
input logic illegal_c_insn_i, // compressed instruction decode failed
@ -55,7 +51,6 @@ module zeroriscy_decoder
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, // 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
output logic [0:0] imm_a_mux_sel_o, // immediate selection for operand a
output logic [3:0] imm_b_mux_sel_o, // immediate selection for operand b
@ -81,8 +76,7 @@ module zeroriscy_decoder
// jump/branches
output logic [1:0] jump_in_dec_o, // jump_in_id without deassert
output logic [1:0] jump_in_id_o, // jump is being calculated in ALU
output logic jump_in_id_o, // jump is being calculated in ALU
output logic branch_in_id_o
);
@ -91,12 +85,12 @@ module zeroriscy_decoder
logic data_req;
logic ebrk_insn;
logic eret_insn;
logic mret_insn;
logic pipe_flush;
logic mult_int_en;
logic branch_in_id;
logic [1:0] jump_in_id;
logic jump_in_id;
logic [1:0] csr_op;
@ -112,12 +106,11 @@ module zeroriscy_decoder
always_comb
begin
jump_in_id = BRANCH_NONE;
jump_in_id = 1'b0;
branch_in_id = 1'b0;
alu_operator_o = ALU_SLTU;
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
alu_op_b_mux_sel_o = OP_B_REGB_OR_FWD;
alu_op_c_mux_sel_o = OP_C_REGC_OR_FWD;
imm_a_mux_sel_o = IMMA_ZERO;
imm_b_mux_sel_o = IMMB_I;
@ -140,14 +133,10 @@ module zeroriscy_decoder
illegal_insn_o = 1'b0;
ebrk_insn = 1'b0;
eret_insn = 1'b0;
mret_insn = 1'b0;
ecall_insn_o = 1'b0;
pipe_flush = 1'b0;
rega_used_o = 1'b0;
regb_used_o = 1'b0;
unique case (instr_rdata_i[6:0])
//////////////////////////////////////
@ -160,43 +149,51 @@ module zeroriscy_decoder
//////////////////////////////////////
OPCODE_JAL: begin // Jump and Link
jump_in_id = BRANCH_JAL;
// 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_we = 1'b1;
alu_op_c_mux_sel_o = OP_C_RA; // Pipeline return address to EX
jump_in_id = 1'b1;
if(jump_set_i) begin
// Calculate jump target
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_we = 1'b0;
end else begin
// 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_PCINCR;
alu_operator_o = ALU_ADD;
regfile_we = 1'b1;
end
end
OPCODE_JALR: begin // Jump and Link Register
jump_in_id = BRANCH_JALR;
// Calculate jump target in EX
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
alu_op_b_mux_sel_o = OP_B_ZERO;
imm_b_mux_sel_o = IMMB_SB;
alu_operator_o = ALU_ADD;
regfile_we = 1'b1;
rega_used_o = 1'b1;
jump_in_id = 1'b1;
if(jump_set_i) begin
// Calculate jump target
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
alu_op_b_mux_sel_o = OP_B_IMM;
imm_b_mux_sel_o = IMMB_I;
alu_operator_o = ALU_ADD;
regfile_we = 1'b0;
end else begin
// 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_PCINCR;
alu_operator_o = ALU_ADD;
regfile_we = 1'b1;
end
if (instr_rdata_i[14:12] != 3'b0) begin
jump_in_id = BRANCH_NONE;
jump_in_id = 1'b0;
regfile_we = 1'b0;
illegal_insn_o = 1'b1;
end
alu_op_c_mux_sel_o = OP_C_RA; // Pipeline return address to EX
end
OPCODE_BRANCH: begin // Branch
jump_in_id = BRANCH_COND;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
branch_in_id = 1'b1;
if (~branch_set_i)
@ -220,7 +217,6 @@ module zeroriscy_decoder
imm_b_mux_sel_o = IMMB_SB;
alu_operator_o = ALU_ADD;
regfile_we = 1'b0;
rega_used_o = 1'b1;
end
end
@ -238,14 +234,8 @@ module zeroriscy_decoder
OPCODE_STORE: begin
data_req = 1'b1;
data_we_o = 1'b1;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
alu_operator_o = ALU_ADD;
// pass write data through ALU operand c
alu_op_c_mux_sel_o = OP_C_REGB_OR_FWD;
if (instr_rdata_i[14] == 1'b0) begin
// offset from immediate
imm_b_mux_sel_o = IMMB_S;
@ -274,7 +264,6 @@ module zeroriscy_decoder
OPCODE_LOAD: begin
data_req = 1'b1;
regfile_we = 1'b1;
rega_used_o = 1'b1;
data_type_o = 2'b00;
// offset from immediate
@ -297,7 +286,6 @@ module zeroriscy_decoder
// reg-reg load (different encoding)
if (instr_rdata_i[14:12] == 3'b111) begin
// offset from RS2
regb_used_o = 1'b1;
alu_op_b_mux_sel_o = OP_B_REGB_OR_FWD;
// sign/zero extension
@ -357,7 +345,6 @@ module zeroriscy_decoder
alu_op_b_mux_sel_o = OP_B_IMM;
imm_b_mux_sel_o = IMMB_I;
regfile_we = 1'b1;
rega_used_o = 1'b1;
unique case (instr_rdata_i[14:12])
3'b000: alu_operator_o = ALU_ADD; // Add Immediate
@ -388,7 +375,6 @@ module zeroriscy_decoder
OPCODE_OP: begin // Register-Register ALU operation
regfile_we = 1'b1;
rega_used_o = 1'b1;
if (instr_rdata_i[31]) begin
illegal_insn_o = 1'b1;
@ -397,7 +383,6 @@ module zeroriscy_decoder
begin // non bit-manipulation instructions
if (~instr_rdata_i[28])
regb_used_o = 1'b1;
unique case ({instr_rdata_i[30:25], instr_rdata_i[14:12]})
// RV32I ALU operations
@ -450,7 +435,7 @@ module zeroriscy_decoder
12'h302: // mret
begin
eret_insn = 1'b1;
mret_insn = 1'b1;
end
12'h105: // wfi
@ -478,7 +463,6 @@ module zeroriscy_decoder
// rs1 field is used as immediate
alu_op_a_mux_sel_o = OP_A_IMM;
end else begin
rega_used_o = 1'b1;
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
end
@ -528,12 +512,10 @@ module zeroriscy_decoder
assign regfile_we_o = (deassert_we_i) ? 1'b0 : regfile_we;
assign data_req_o = (deassert_we_i) ? 1'b0 : data_req;
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 jump_in_id_o = (deassert_we_i) ? 1'b0 : jump_in_id;
assign branch_in_id_o = (deassert_we_i) ? 1'b0 : branch_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 mret_insn_o = (deassert_we_i) ? 1'b0 : mret_insn; // TODO: do not deassert?
assign pipe_flush_o = (deassert_we_i) ? 1'b0 : pipe_flush; // TODO: do not deassert?
assign jump_in_dec_o = jump_in_id;
endmodule // controller

View file

@ -49,10 +49,6 @@ module zeroriscy_exc_controller
input logic ebrk_insn_i, // ebrk instruction encountered (EBREAK)
input logic illegal_insn_i, // illegal instruction encountered
input logic ecall_insn_i, // ecall instruction encountered
input logic eret_insn_i, // eret instruction encountered
input logic lsu_load_err_i,
input logic lsu_store_err_i,
// to CSR
output logic [5:0] cause_o,
@ -81,17 +77,14 @@ module zeroriscy_exc_controller
// - Debuger requests halt
assign trap_o = (dbg_settings_i[DBG_SETS_SSTE])
| (ecall_insn_i & dbg_settings_i[DBG_SETS_ECALL])
| (lsu_load_err_i & dbg_settings_i[DBG_SETS_ELSU])
| (lsu_store_err_i & dbg_settings_i[DBG_SETS_ELSU])
| (ebrk_insn_i & dbg_settings_i[DBG_SETS_EBRK])
| (illegal_insn_i & dbg_settings_i[DBG_SETS_EILL])
| (irq_enable_i & irq_i & dbg_settings_i[DBG_SETS_IRQ]);
// request for exception/interrupt
assign int_req_int = ecall_insn_i
| illegal_insn_i
| lsu_load_err_i
| lsu_store_err_i;
| illegal_insn_i;
assign ext_req_int = irq_enable_i & irq_i;
assign req_int = int_req_int | ext_req_int;
@ -121,7 +114,7 @@ assign req_int = int_req_int | ext_req_int;
cause_int = 6'b0_00010;
pc_mux_int = EXC_PC_ILLINSN;
end
/*
if (lsu_load_err_i) begin
cause_int = 6'b0_00101;
pc_mux_int = EXC_PC_LOAD;
@ -131,6 +124,7 @@ assign req_int = int_req_int | ext_req_int;
cause_int = 6'b0_00111;
pc_mux_int = EXC_PC_STORE;
end
*/
end
always_ff @(posedge clk, negedge rst_n)

View file

@ -156,22 +156,21 @@ module zeroriscy_id_stage
logic illegal_insn_dec;
logic ebrk_insn;
logic eret_insn_dec;
logic mret_insn_dec;
logic ecall_insn_dec;
logic pipe_flush_dec;
logic rega_used_dec;
logic regb_used_dec;
logic branch_taken_ex;
logic branch_in_id;
logic branch_in_id_q;
logic branch_set;
logic [1:0] jump_in_id;
logic [1:0] jump_in_dec;
logic jump_set;
logic jump_in_id;
logic instr_multicyle;
logic load_stall;
logic branch_stall;
logic jump_stall;
logic halt_id;
//FSM signals to write back multi cycles instructions
@ -291,7 +290,6 @@ module zeroriscy_id_stage
begin : alu_operand_a_mux
case (alu_op_a_mux_sel)
OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
//OP_A_REGB_OR_FWD: alu_operand_a = regfile_data_rb_id;
OP_A_CURRPC: alu_operand_a = pc_id_i;
OP_A_IMM: alu_operand_a = imm_a;
default: alu_operand_a = operand_a_fw_id;
@ -350,10 +348,8 @@ module zeroriscy_id_stage
always_comb
begin : alu_operand_b_mux
case (alu_op_b_mux_sel)
//OP_B_REGA_OR_FWD: operand_b = regfile_data_ra_id;
OP_B_REGB_OR_FWD: operand_b = regfile_data_rb_id;
OP_B_IMM: operand_b = imm_b;
OP_B_ZERO: operand_b = '0;
default: operand_b = regfile_data_rb_id;
endcase // case (alu_op_b_mux_sel)
end
@ -390,11 +386,7 @@ module zeroriscy_id_stage
if (csr_access)
regfile_wdata_mux = csr_rdata_i;
else
//TODO: modify this
if ((jump_in_id == BRANCH_JALR) || (jump_in_id == BRANCH_JAL))
regfile_wdata_mux = pc_if_i;
else
regfile_wdata_mux = regfile_wdata_ex_i;
regfile_wdata_mux = regfile_wdata_ex_i;
end
end
@ -435,17 +427,14 @@ module zeroriscy_id_stage
.deassert_we_i ( deassert_we ),
.data_misaligned_i ( data_misaligned_i ),
.branch_set_i ( branch_set ),
.jump_set_i ( jump_set ),
.illegal_insn_o ( illegal_insn_dec ),
.ebrk_insn_o ( ebrk_insn ),
.eret_insn_o ( eret_insn_dec ),
.mret_insn_o ( mret_insn_dec ),
.ecall_insn_o ( ecall_insn_dec ),
.pipe_flush_o ( pipe_flush_dec ),
.rega_used_o ( rega_used_dec ),
.regb_used_o ( regb_used_dec ),
// from IF/ID pipeline
.instr_rdata_i ( instr ),
.illegal_c_insn_i ( illegal_c_insn_i ),
@ -454,7 +443,6 @@ module zeroriscy_id_stage
.alu_operator_o ( alu_operator ),
.alu_op_a_mux_sel_o ( alu_op_a_mux_sel ),
.alu_op_b_mux_sel_o ( alu_op_b_mux_sel ),
.alu_op_c_mux_sel_o ( alu_op_c_mux_sel ),
.imm_a_mux_sel_o ( imm_a_mux_sel ),
.imm_b_mux_sel_o ( imm_b_mux_sel ),
@ -475,7 +463,6 @@ module zeroriscy_id_stage
.data_load_event_o ( data_load_event_id ),
// jump/branches
.jump_in_dec_o ( jump_in_dec ),
.jump_in_id_o ( jump_in_id ),
.branch_in_id_o ( branch_in_id )
);
@ -501,7 +488,7 @@ module zeroriscy_id_stage
// decoder related signals
.deassert_we_o ( deassert_we ),
.illegal_insn_i ( illegal_insn_dec ),
.eret_insn_i ( eret_insn_dec ),
.mret_insn_i ( mret_insn_dec ),
.pipe_flush_i ( pipe_flush_dec ),
// from IF/ID pipeline
@ -524,8 +511,8 @@ module zeroriscy_id_stage
.branch_in_id_i ( branch_in_id ),
.branch_taken_ex_i ( branch_taken_ex ),
.branch_set_i ( branch_set ),
.jump_set_i ( jump_set ),
.jump_in_id_i ( jump_in_id ),
.jump_in_dec_i ( jump_in_dec ),
.instr_multicyle_i ( instr_multicyle ),
// Exception Controller Signals
@ -550,6 +537,10 @@ module zeroriscy_id_stage
.halt_if_o ( halt_if_o ),
.halt_id_o ( halt_id ),
.jump_stall_i ( jump_stall ),
.branch_stall_i ( branch_stall ),
.load_stall_i ( load_stall ),
.id_ready_i ( id_ready_o ),
.if_valid_i ( if_valid_i ),
@ -557,6 +548,7 @@ module zeroriscy_id_stage
// Performance Counters
.perf_jump_o ( perf_jump_o ),
.perf_jr_stall_o ( perf_jr_stall_o ),
.perf_br_stall_o ( ),
.perf_ld_stall_o ( perf_ld_stall_o )
);
@ -592,10 +584,6 @@ module zeroriscy_id_stage
.ebrk_insn_i ( is_decoding_o & ebrk_insn ),
.illegal_insn_i ( is_decoding_o & illegal_insn_dec ),
.ecall_insn_i ( is_decoding_o & ecall_insn_dec ),
.eret_insn_i ( is_decoding_o & eret_insn_dec ),
.lsu_load_err_i ( lsu_load_err_i ),
.lsu_store_err_i ( lsu_store_err_i ),
.cause_o ( exc_cause_o ),
.save_cause_o ( save_exc_cause_o ),
@ -658,10 +646,12 @@ module zeroriscy_id_stage
id_wb_fsm_ns = id_wb_fsm_cs;
regfile_we = regfile_we_id & (~halt_id);
load_stall = 1'b0;
jump_stall = 1'b0;
branch_stall = 1'b0;
select_data_rf = RF_EX;
instr_multicyle = 1'b0;
branch_set = 1'b0;
jump_set = 1'b0;
unique case (id_wb_fsm_cs)
@ -681,6 +671,13 @@ module zeroriscy_id_stage
branch_stall = branch_decision_i;
instr_multicyle = branch_decision_i;
end
jump_in_id: begin
//UnCond Branch operation
id_wb_fsm_ns = WAIT_MULTICYCLE;
jump_stall = 1'b1;
instr_multicyle = 1'b1;
jump_set = 1'b1;
end
default:;
endcase
end
@ -705,7 +702,7 @@ module zeroriscy_id_stage
end
// stall control
assign id_ready_o = (~load_stall) & (~branch_stall);
assign id_ready_o = (~load_stall) & (~branch_stall) & (~jump_stall);
assign id_valid_o = (~halt_id) & id_ready_o;

View file

@ -264,17 +264,6 @@ 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;
parameter BRANCH_JAL = 2'b01;
parameter BRANCH_JALR = 2'b10;
parameter BRANCH_COND = 2'b11; // conditional branches
// jump target mux
parameter JT_JAL = 2'b01;
parameter JT_JALR = 2'b10;
parameter JT_COND = 2'b11;
///////////////////////////////////////////////
// ___ _____ ____ _ //