diff --git a/controller.sv b/controller.sv index 46ea3188..83e96d9e 100644 --- a/controller.sv +++ b/controller.sv @@ -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 diff --git a/debug_unit.sv b/debug_unit.sv index 1c974c04..c3152fd8 100644 --- a/debug_unit.sv +++ b/debug_unit.sv @@ -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) diff --git a/id_stage.sv b/id_stage.sv index 12b91622..b941016a 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -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 diff --git a/if_stage.sv b/if_stage.sv index 3f13ac14..dfbe1a68 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -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 diff --git a/riscv_core.sv b/riscv_core.sv index 60863b2f..d41007dc 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -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