Allow debugging during sleep

This commit is contained in:
Andreas Traber 2016-04-29 16:19:44 +02:00
parent 153c009090
commit a20c6e09c5
5 changed files with 56 additions and 19 deletions

View file

@ -32,7 +32,7 @@ module riscv_controller
input logic rst_n,
input logic fetch_enable_i, // Start the decoding
output logic core_busy_o, // Core is busy processing instructions
output logic ctrl_busy_o, // Core is busy processing instructions
output logic is_decoding_o, // Core is in decoding state
// decoder related signals
@ -175,7 +175,7 @@ module riscv_controller
ctrl_fsm_ns = ctrl_fsm_cs;
core_busy_o = 1'b1;
ctrl_busy_o = 1'b1;
is_decoding_o = 1'b0;
halt_if_o = 1'b0;
@ -186,7 +186,7 @@ module riscv_controller
// We were just reset, wait for fetch_enable
RESET:
begin
core_busy_o = 1'b0;
ctrl_busy_o = 1'b0;
instr_req_o = 1'b0;
if (fetch_enable_i == 1'b1)
@ -208,14 +208,27 @@ module riscv_controller
begin
// we begin execution when either fetch_enable is high or an
// interrupt has arrived
core_busy_o = 1'b0;
ctrl_busy_o = 1'b0;
instr_req_o = 1'b0;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
if (fetch_enable_i || exc_req_i)
begin
ctrl_fsm_ns = FIRST_FETCH;
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_i)
ctrl_fsm_ns = DBG_SIGNAL;
else
ctrl_fsm_ns = DBG_SIGNAL_SLEEP;
end else begin
// no debug request incoming, normal execution flow
if (fetch_enable_i || exc_req_i)
begin
ctrl_fsm_ns = FIRST_FETCH;
end
end
end // case: SLEEP
end
FIRST_FETCH:
begin
@ -409,6 +422,7 @@ module riscv_controller
FLUSH_EX:
begin
halt_if_o = 1'b1;
halt_id_o = 1'b1;
if (ex_valid_i)
ctrl_fsm_ns = FLUSH_WB;
@ -418,6 +432,7 @@ module riscv_controller
FLUSH_WB:
begin
halt_if_o = 1'b1;
halt_id_o = 1'b1;
if(fetch_enable_i) begin
if (dbg_req_i) begin

View file

@ -100,6 +100,8 @@ module riscv_debug_unit
logic [5:0] dbg_cause_q, dbg_cause_n;
logic dbg_ssth_q, dbg_ssth_n;
logic ssth_clear;
// ppc/npc tracking
enum logic [1:0] {IFID, IFEX, IDEX} pc_tracking_fsm_cs, pc_tracking_fsm_ns;
@ -124,6 +126,8 @@ module riscv_debug_unit
dbg_halt = 1'b0;
settings_n = settings_q;
ssth_clear = 1'b0;
if (debug_req_i) begin
if (debug_we_i) begin
//----------------------------------------------------------------------------
@ -169,9 +173,7 @@ module riscv_debug_unit
settings_n[`DBG_SETS_SSTE] = debug_wdata_i[0];
end
5'b0_0001: begin // DBG_HIT
if (debug_wdata_i[0]) begin
// TODO: clear SSTH sticky bit
end
ssth_clear = debug_wdata_i[0];
end
5'b0_0010: begin // DBG_IE
settings_n[`DBG_SETS_ECALL] = debug_wdata_i[11];
@ -381,6 +383,8 @@ module riscv_debug_unit
end
endcase
if (ssth_clear)
dbg_ssth_n = 1'b0;
end
always_ff @(posedge clk, negedge rst_n)

View file

@ -40,7 +40,7 @@ module riscv_id_stage
input logic test_en_i,
input logic fetch_enable_i,
output logic core_busy_o,
output logic ctrl_busy_o,
output logic is_decoding_o,
// Interface to IF stage
@ -812,7 +812,7 @@ module riscv_id_stage
.rst_n ( rst_n ),
.fetch_enable_i ( fetch_enable_i ),
.core_busy_o ( core_busy_o ),
.ctrl_busy_o ( ctrl_busy_o ),
.is_decoding_o ( is_decoding_o ),
// decoder related signals

View file

@ -380,10 +380,12 @@ module riscv_if_stage
// there should never be a grant when there is no request
assert property (
@(posedge clk) (instr_gnt_i) |-> (instr_req_o) );
@(posedge clk) (instr_gnt_i) |-> (instr_req_o) )
else $warning("There was a grant without a request");
// make sure LSB of fetch_addr_n is always 0
assert property (
@(posedge clk) (req_i) |-> (~fetch_addr_n[0]) );
@(posedge clk) (req_i) |-> (~fetch_addr_n[0]) )
else $warning("There was a request while the fetch_addr_n LSB is set");
endmodule

View file

@ -119,7 +119,7 @@ module riscv_core
logic branch_in_ex;
logic branch_decision;
logic core_busy;
logic ctrl_busy;
logic if_busy;
logic lsu_busy;
@ -255,12 +255,28 @@ module riscv_core
logic perf_jr_stall;
logic perf_ld_stall;
//////////////////////////////////////////////////////////////////////////////////////////////
// ____ _ _ __ __ _ //
// / ___| | ___ ___| | __ | \/ | __ _ _ __ __ _ __ _ ___ _ __ ___ ___ _ __ | |_ //
// | | | |/ _ \ / __| |/ / | |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '_ ` _ \ / _ \ '_ \| __| //
// | |___| | (_) | (__| < | | | | (_| | | | | (_| | (_| | __/ | | | | | __/ | | | |_ //
// \____|_|\___/ \___|_|\_\ |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| |_| |_|\___|_| |_|\__| //
// |___/ //
//////////////////////////////////////////////////////////////////////////////////////////////
logic clk;
logic clock_en;
logic dbg_busy;
// 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 || core_busy || lsu_busy);
assign core_busy_o = (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;
assign clock_en = clock_en_i | core_busy_o | dbg_busy;
// main clock gate of the core
@ -269,7 +285,7 @@ module riscv_core
cluster_clock_gating core_clock_gate_i
(
.clk_i ( clk_i ),
.en_i ( clock_en_i ),
.en_i ( clock_en ),
.test_en_i ( test_en_i ),
.clk_o ( clk )
);
@ -368,7 +384,7 @@ module riscv_core
// Processor Enable
.fetch_enable_i ( fetch_enable_i ),
.core_busy_o ( core_busy ),
.ctrl_busy_o ( ctrl_busy ),
.is_decoding_o ( is_decoding ),
// Interface to instruction memory