Skip to content

Commit

Permalink
Merge branch 'xret_fix' into dbg_dev
Browse files Browse the repository at this point in the history
rtl/riscv_controller:
We changed the formulation of the state machine in FLUSH_WB to use a default state
transition (ctrl_fsm_ns = DECODE) and reassign something else when we
diverge.

This merge fixes the issue that due to wrong (too early) privilege level
transitions the xret instructions used the wrong return address e.g.
uret used mret's address.
  • Loading branch information
bluewww committed Apr 15, 2019
2 parents a67e5b9 + 4212dc7 commit 667cce6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 32 deletions.
70 changes: 42 additions & 28 deletions rtl/riscv_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ module riscv_controller

input logic dret_insn_i, // decoder encountered an dret instruction

input logic mret_dec_i,
input logic uret_dec_i,
input logic dret_dec_i,

input logic pipe_flush_i, // decoder wants to do a pipe flush
input logic ebrk_insn_i, // decoder encountered an ebreak instruction
input logic fencei_insn_i, // decoder encountered an fence.i instruction
Expand Down Expand Up @@ -184,7 +188,7 @@ module riscv_controller
enum logic [4:0] { RESET, BOOT_SET, SLEEP, WAIT_SLEEP, FIRST_FETCH,
DECODE,
IRQ_TAKEN_ID, IRQ_TAKEN_IF, IRQ_FLUSH, ELW_EXE,
FLUSH_EX, FLUSH_WB,
FLUSH_EX, FLUSH_WB, XRET_JUMP,
DBG_TAKEN_ID, DBG_TAKEN_IF, DBG_FLUSH, DBG_WAIT_BRANCH } ctrl_fsm_cs, ctrl_fsm_ns;

logic jump_done, jump_done_q, jump_in_dec, branch_in_id;
Expand Down Expand Up @@ -404,7 +408,7 @@ module riscv_controller
is_decoding_o = 1'b0;
halt_id_o = 1'b1;
halt_if_o = 1'b1;
csr_save_id_o = 1'b1;
csr_save_if_o = 1'b1;
csr_save_cause_o = 1'b1;

//no jump in this stage as we have to wait one cycle to go to Machine Mode
Expand Down Expand Up @@ -521,11 +525,6 @@ module riscv_controller
mret_insn_i | uret_insn_i | dret_insn_i: begin
halt_if_o = 1'b1;
halt_id_o = 1'b1;

csr_restore_uret_id_o = uret_insn_i;
csr_restore_mret_id_o = mret_insn_i;
csr_restore_dret_id_o = dret_insn_i;

ctrl_fsm_ns = FLUSH_EX;
end
csr_status_i: begin
Expand Down Expand Up @@ -710,6 +709,7 @@ module riscv_controller
halt_if_o = 1'b1;
halt_id_o = 1'b1;

ctrl_fsm_ns = DECODE;

if(data_err_q) begin
//data_error
Expand Down Expand Up @@ -759,31 +759,23 @@ module riscv_controller

end
mret_insn_i: begin
//mret
pc_mux_o = PC_MRET;
pc_set_o = 1'b1;

csr_restore_mret_id_o = 1'b1;
ctrl_fsm_ns = XRET_JUMP;
end
uret_insn_i: begin
//uret
pc_mux_o = PC_URET;
pc_set_o = 1'b1;

csr_restore_uret_id_o = 1'b1;
ctrl_fsm_ns = XRET_JUMP;
end
dret_insn_i: begin
//dret
//TODO: is illegal when not in debug mode
pc_mux_o = PC_DRET;
pc_set_o = 1'b1;
debug_mode_n = 1'b0;

csr_restore_dret_id_o = 1'b1;
ctrl_fsm_ns = XRET_JUMP;
end

csr_status_i: begin

end
pipe_flush_i: begin

ctrl_fsm_ns = WAIT_SLEEP;
end
fencei_insn_i: begin
// we just jump to instruction after the fence.i since that
Expand All @@ -801,14 +793,36 @@ module riscv_controller
// FLUSH_WB e.g. illegal_insn_i. The already fetched instruction will
// be the address we set the dpc to, therefore we got to DBG_TAKEN_IF.
ctrl_fsm_ns = DBG_TAKEN_IF;
end else if(~pipe_flush_i) begin
// regular instruction
ctrl_fsm_ns = DECODE;
end else begin //pipe_flush_i
// we have a wfi, after the flush we got to sleep
ctrl_fsm_ns = WAIT_SLEEP;
end
end

XRET_JUMP:
begin
is_decoding_o = 1'b0;
ctrl_fsm_ns = DECODE;
unique case(1'b1)
mret_dec_i: begin
//mret
pc_mux_o = PC_MRET;
pc_set_o = 1'b1;

end
uret_dec_i: begin
//uret
pc_mux_o = PC_URET;
pc_set_o = 1'b1;

end
dret_dec_i: begin
//dret
//TODO: is illegal when not in debug mode
pc_mux_o = PC_DRET;
pc_set_o = 1'b1;
debug_mode_n = 1'b0;

end
default:;
endcase
end

// a branch was in ID when a trying to go to debug rom wait until we can
Expand Down
13 changes: 12 additions & 1 deletion rtl/riscv_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,15 @@ module riscv_decoder

output logic illegal_insn_o, // illegal instruction encountered
output logic ebrk_insn_o, // trap instruction encountered

output logic mret_insn_o, // return from exception instruction encountered (M)
output logic uret_insn_o, // return from exception instruction encountered (S)

output logic dret_insn_o, // return from debug (M)

output logic mret_dec_o, // return from exception instruction encountered (M) without deassert
output logic uret_dec_o, // return from exception instruction encountered (S) without deassert
output logic dret_dec_o, // return from debug (M) without deassert

output logic ecall_insn_o, // environment call (syscall) instruction encountered
output logic pipe_flush_o, // pipeline flush is requested

Expand Down Expand Up @@ -289,6 +293,10 @@ module riscv_decoder

instr_multicycle_o = 1'b0;

mret_dec_o = 1'b0;
uret_dec_o = 1'b0;
dret_dec_o = 1'b0;

unique case (instr_rdata_i[6:0])

//////////////////////////////////////
Expand Down Expand Up @@ -2168,17 +2176,20 @@ module riscv_decoder
begin
illegal_insn_o = (PULP_SECURE) ? current_priv_lvl_i != PRIV_LVL_M : 1'b0;
mret_insn_o = ~illegal_insn_o;
mret_dec_o = 1'b1;
end

12'h002: // uret
begin
uret_insn_o = (PULP_SECURE) ? 1'b1 : 1'b0;
uret_dec_o = 1'b1;
end

12'h7b2: // dret
begin
illegal_insn_o = (PULP_SECURE) ? current_priv_lvl_i != PRIV_LVL_M : 1'b0;
dret_insn_o = ~illegal_insn_o;
dret_dec_o = 1'b1;
end

12'h105: // wfi
Expand Down
18 changes: 15 additions & 3 deletions rtl/riscv_id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ module riscv_id_stage
logic reg_d_alu_is_reg_b_id;
logic reg_d_alu_is_reg_c_id;

logic mret_dec;
logic uret_dec;
logic dret_dec;

assign instr = instr_rdata_i;

Expand Down Expand Up @@ -985,7 +988,7 @@ module riscv_id_stage
.Q_T ( )
);




///////////////////////////////////////////////
Expand Down Expand Up @@ -1019,11 +1022,15 @@ module riscv_id_stage

.illegal_insn_o ( illegal_insn_dec ),
.ebrk_insn_o ( ebrk_insn ),

.mret_insn_o ( mret_insn_dec ),
.uret_insn_o ( uret_insn_dec ),

.dret_insn_o ( dret_insn_dec ),


.mret_dec_o ( mret_dec ),
.uret_dec_o ( uret_dec ),
.dret_dec_o ( dret_dec ),

.ecall_insn_o ( ecall_insn_dec ),
.pipe_flush_o ( pipe_flush_dec ),

Expand Down Expand Up @@ -1149,6 +1156,11 @@ module riscv_id_stage

.dret_insn_i ( dret_insn_dec ),

.mret_dec_i ( mret_dec ),
.uret_dec_i ( uret_dec ),
.dret_dec_i ( dret_dec ),


.pipe_flush_i ( pipe_flush_dec ),
.ebrk_insn_i ( ebrk_insn ),
.fencei_insn_i ( fencei_insn_dec ),
Expand Down

0 comments on commit 667cce6

Please sign in to comment.