broken path via core busy

This commit is contained in:
Pasquale Davide Schiavone 2017-04-05 14:42:26 +02:00
parent 77e9ea0bce
commit d0a0d8d093
4 changed files with 59 additions and 43 deletions

View file

@ -42,6 +42,7 @@ module zeroriscy_controller
input logic fetch_enable_i, // Start the decoding
output logic ctrl_busy_o, // Core is busy processing instructions
output logic first_fetch_o, // Core is at the FIRST FETCH stage
output logic is_decoding_o, // Core is in decoding state
// decoder related signals
@ -111,12 +112,10 @@ module zeroriscy_controller
// FSM state encoding
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
enum logic [3:0] { RESET, BOOT_SET, WAIT_SLEEP, SLEEP, FIRST_FETCH,
DECODE, FLUSH, IRQ_TAKEN,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
logic exc_req;
`ifndef SYNTHESIS
// synopsys translate_off
// make sure we are called later so that we do not generate messages for
@ -142,7 +141,7 @@ module zeroriscy_controller
// //
////////////////////////////////////////////////////////////////////////////////////////////
assign exc_req = int_req_i | ext_req_i;
always_comb
begin
// Default values
@ -166,6 +165,7 @@ module zeroriscy_controller
dbg_ack_o = 1'b0;
irq_ack_o = 1'b0;
first_fetch_o = 1'b0;
unique case (ctrl_fsm_cs)
// We were just reset, wait for fetch_enable
@ -193,6 +193,15 @@ module zeroriscy_controller
ctrl_fsm_ns = FIRST_FETCH;
end
WAIT_SLEEP:
begin
ctrl_busy_o = 1'b0;
instr_req_o = 1'b0;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
ctrl_fsm_ns = SLEEP;
end
// instruction in if_stage is already valid
SLEEP:
begin
@ -200,13 +209,13 @@ module zeroriscy_controller
// interrupt has arrived
ctrl_busy_o = 1'b0;
instr_req_o = 1'b0;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
if (dbg_req_i) begin
// debug request, now we need to check if we should stay sleeping or
// go to normal processing later
if (fetch_enable_i || exc_req)
if (fetch_enable_i || ext_req_i)
ctrl_fsm_ns = DBG_SIGNAL;
else
ctrl_fsm_ns = DBG_SIGNAL_SLEEP;
@ -222,6 +231,7 @@ module zeroriscy_controller
FIRST_FETCH:
begin
first_fetch_o = 1'b1;
// Stall because of IF miss
if ((id_ready_i == 1'b1) && (dbg_stall_i == 1'b0))
begin
@ -400,7 +410,7 @@ module zeroriscy_controller
if(dbg_req_i)
ctrl_fsm_ns = DBG_SIGNAL_SLEEP;
else
ctrl_fsm_ns = SLEEP;
ctrl_fsm_ns = WAIT_SLEEP;
end
end

View file

@ -225,6 +225,8 @@ module zeroriscy_core
logic perf_jr_stall;
logic perf_ld_stall;
//core busy signals
logic core_ctrl_firstfetch, core_busy_int, core_busy_q;
//////////////////////////////////////////////////////////////////////////////////////////////
// ____ _ _ __ __ _ //
@ -244,13 +246,24 @@ module zeroriscy_core
// if we are sleeping on a barrier let's just wait on the instruction
// interface to finish loading instructions
assign core_busy_o = (data_load_event_ex & data_req_o) ? if_busy : (if_busy | ctrl_busy | lsu_busy);
assign core_busy_int = (data_load_event_ex & data_req_o) ? if_busy : (if_busy | ctrl_busy | lsu_busy);
assign dbg_busy = dbg_req | dbg_csr_req | dbg_jump_req | dbg_reg_wreq | debug_req_i;
always_ff @(posedge clk, negedge rst_ni)
begin
if (rst_ni == 1'b0) begin
core_busy_q <= 1'b0;
end else begin
core_busy_q <= core_busy_int;
end
end
assign clock_en = clock_en_i | core_busy_o | dbg_busy;
assign core_busy_o = core_ctrl_firstfetch ? 1'b1 : core_busy_q;
assign sleeping = (~fetch_enable_i) & (~core_busy_o);
assign dbg_busy = dbg_req | dbg_csr_req | dbg_jump_req | dbg_reg_wreq | debug_req_i;
assign clock_en = clock_en_i | core_busy_o | dbg_busy;
assign sleeping = (~fetch_enable_i) & (~core_busy_o);
// main clock gate of the core
@ -345,6 +358,7 @@ module zeroriscy_core
// Processor Enable
.fetch_enable_i ( fetch_enable_i ),
.ctrl_busy_o ( ctrl_busy ),
.core_ctrl_firstfetch_o ( core_ctrl_firstfetch ),
.is_decoding_o ( is_decoding ),
// Interface to instruction memory

View file

@ -65,7 +65,7 @@ module zeroriscy_exc_controller
enum logic [1:0] { IDLE, WAIT_CONTROLLER_INT, WAIT_CONTROLLER_EXT, WAIT_CONTROLLER_DBG } exc_ctrl_cs, exc_ctrl_ns;
logic req_int, int_req_int, ext_req_int;
logic int_req_int, ext_req_int;
logic [1:0] pc_mux_int, pc_mux_int_q;
logic [5:0] cause_int, cause_int_q;
logic trap_int;
@ -89,44 +89,36 @@ module zeroriscy_exc_controller
assign ext_req_int = irq_enable_i & irq_i;
assign req_int = int_req_int | ext_req_int;
// Exception cause and ISR address selection
always_comb
begin
cause_int = 6'b0;
pc_mux_int = '0;
if (irq_enable_i & irq_i) begin
// pc_mux_int is a critical signal, so try to get it as soon as possible
pc_mux_int = EXC_PC_IRQ;
cause_int = {1'b1,irq_id_i};
end
unique case(1'b1)
if (ebrk_insn_i) begin
cause_int = 6'b0_00011;
end
ebrk_insn_i:
cause_int = 6'b0_00011;
if (ecall_insn_i) begin
cause_int = 6'b0_01011;
pc_mux_int = EXC_PC_ECALL;
end
ecall_insn_i: begin
cause_int = 6'b0_01011;
pc_mux_int = EXC_PC_ECALL;
end
if (illegal_insn_i) begin
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;
end
illegal_insn_i: begin
cause_int = 6'b0_00010;
pc_mux_int = EXC_PC_ILLINSN;
end
if (lsu_store_err_i) begin
cause_int = 6'b0_00111;
pc_mux_int = EXC_PC_STORE;
end
*/
default: begin
//exceptions have priority over interrupts
if (irq_enable_i & irq_i) begin
// pc_mux_int is a critical signal, so try to get it as soon as possible
pc_mux_int = EXC_PC_IRQ;
cause_int = {1'b1,irq_id_i};
end
end
endcase
end
always_ff @(posedge clk, negedge rst_n)
@ -143,8 +135,6 @@ module zeroriscy_exc_controller
// Exception cause and mux output (with bypass)
// assign cause_o = ((exc_ctrl_cs == IDLE && req_int) || ebrk_insn_i) ? cause_int : cause_int_q;
// assign pc_mux_o = (exc_ctrl_cs == IDLE && req_int) ? pc_mux_int : pc_mux_int_q;
assign cause_o = cause_int_q;
assign pc_mux_o = pc_mux_int_q;

View file

@ -52,6 +52,7 @@ module zeroriscy_id_stage
input logic fetch_enable_i,
output logic ctrl_busy_o,
output logic core_ctrl_firstfetch_o,
output logic is_decoding_o,
// Interface to IF stage
@ -518,6 +519,7 @@ module zeroriscy_id_stage
.fetch_enable_i ( fetch_enable_i ),
.ctrl_busy_o ( ctrl_busy_o ),
.first_fetch_o ( core_ctrl_firstfetch_o ),
.is_decoding_o ( is_decoding_o ),
// decoder related signals