diff --git a/doc/02_user/integration.rst b/doc/02_user/integration.rst index 722ce78d..e1eca280 100644 --- a/doc/02_user/integration.rst +++ b/doc/02_user/integration.rst @@ -187,12 +187,9 @@ Interfaces +-------------------------+------------------------------------------------------------------------+ | ``crash_dump_o`` | A set of signals that can be captured on reset to aid crash debugging. | +-------------------------+-------------------------+-----+----------------------------------------+ -| ``fetch_enable_i`` | 1 | in | When it comes out of reset, the core | -| | | | will not start fetching and executing | -| | | | instructions until it sees this pin | -| | | | set to 1'b1. Once started, it will | -| | | | continue until the next reset, | -| | | | regardless of the value of this pin. | +| ``fetch_enable_i`` | 1 | in | Allow the core to fetch instructions. | +| | | | If this bit is set low, the core will | +| | | | pause fetching new instructions. | +-------------------------+-------------------------+-----+----------------------------------------+ | ``core_sleep_o`` | 1 | out | Core in WFI with no outstanding data | | | | | or instruction accesses. Deasserts | diff --git a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv index f1edab69..52e4e20a 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv @@ -126,10 +126,13 @@ class core_ibex_base_test extends uvm_test; wait (dut_vif.ecall === 1'b1); vseq.stop(); `uvm_info(`gfn, "ECALL instruction is detected, test done", UVM_LOW) - // De-assert fetch enable to finish the test - dut_vif.dut_cb.fetch_enable <= 1'b0; fork - check_perf_stats(); + begin + check_perf_stats(); + // De-assert fetch enable to finish the test + clk_vif.wait_clks(10); + dut_vif.dut_cb.fetch_enable <= 1'b0; + end // Wait some time for the remaining instruction to finish clk_vif.wait_clks(3000); join diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 4f0e1411..3a694f04 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -128,6 +128,7 @@ module ibex_core import ibex_pkg::*; #( `endif // CPU Control Signals + input logic fetch_enable_i, output logic alert_minor_o, output logic alert_major_o, output logic core_busy_o @@ -272,6 +273,7 @@ module ibex_core import ibex_pkg::*; #( // Signals between instruction core interface and pipe (if and id stages) logic instr_req_int; // Id stage asserts a req to instruction core interface + logic instr_req_gated; // Writeback stage logic en_wb; @@ -400,7 +402,7 @@ module ibex_core import ibex_pkg::*; #( .rst_ni ( rst_ni ), .boot_addr_i ( boot_addr_i ), - .req_i ( instr_req_int ), // instruction request control + .req_i ( instr_req_gated ), // instruction request control // instruction cache interface .instr_req_o ( instr_req_out ), @@ -475,6 +477,9 @@ module ibex_core import ibex_pkg::*; #( // Qualify the instruction request with PMP error assign instr_req_o = instr_req_out & ~pmp_req_err[PMP_I]; + // fetch_enable_i can be used to stop the core fetching new instructions + assign instr_req_gated = instr_req_int & fetch_enable_i; + ////////////// // ID stage // ////////////// diff --git a/rtl/ibex_lockstep.sv b/rtl/ibex_lockstep.sv index 98fc30eb..051e66f4 100644 --- a/rtl/ibex_lockstep.sv +++ b/rtl/ibex_lockstep.sv @@ -86,6 +86,7 @@ module ibex_lockstep import ibex_pkg::*; #( input logic debug_req_i, input crash_dump_t crash_dump_i, + input logic fetch_enable_i, output logic alert_minor_o, output logic alert_major_o, input logic core_busy_i, @@ -143,6 +144,7 @@ module ibex_lockstep import ibex_pkg::*; #( logic [14:0] irq_fast; logic irq_nm; logic debug_req; + logic fetch_enable; } delayed_inputs_t; delayed_inputs_t [LockstepOffset-1:0] shadow_inputs_q; @@ -168,6 +170,7 @@ module ibex_lockstep import ibex_pkg::*; #( assign shadow_inputs_in.irq_fast = irq_fast_i; assign shadow_inputs_in.irq_nm = irq_nm_i; assign shadow_inputs_in.debug_req = debug_req_i; + assign shadow_inputs_in.fetch_enable = fetch_enable_i; // Delay the inputs always_ff @(posedge clk_i or negedge rst_ni) begin @@ -368,6 +371,7 @@ module ibex_lockstep import ibex_pkg::*; #( .rvfi_mem_wdata (), `endif + .fetch_enable_i (shadow_inputs_q[0].fetch_enable), .alert_minor_o (shadow_alert_minor), .alert_major_o (shadow_alert_major), .core_busy_o (shadow_outputs.core_busy) diff --git a/rtl/ibex_top.sv b/rtl/ibex_top.sv index a814e2b7..c6e56638 100644 --- a/rtl/ibex_top.sv +++ b/rtl/ibex_top.sv @@ -126,7 +126,6 @@ module ibex_top #( // Clock signals logic clk; logic core_busy_d, core_busy_q; - logic fetch_enable_q; logic clock_en; logic irq_pending; // Core <-> Register file signals @@ -165,16 +164,7 @@ module ibex_top #( end end - // capture fetch_enable_i in fetch_enable_q, once for ever - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - fetch_enable_q <= 1'b0; - end else if (fetch_enable_i) begin - fetch_enable_q <= 1'b1; - end - end - - assign clock_en = fetch_enable_q & (core_busy_q | debug_req_i | irq_pending | irq_nm_i); + assign clock_en = core_busy_q | debug_req_i | irq_pending | irq_nm_i; assign core_sleep_o = ~clock_en; prim_clock_gating core_clock_gate_i ( @@ -293,6 +283,7 @@ module ibex_top #( .rvfi_mem_wdata, `endif + .fetch_enable_i, .alert_minor_o (core_alert_minor), .alert_major_o (core_alert_major), .core_busy_o (core_busy_d) @@ -466,6 +457,7 @@ module ibex_top #( irq_pending, debug_req_i, crash_dump_o, + fetch_enable_i, core_busy_d }); @@ -518,6 +510,7 @@ module ibex_top #( logic debug_req_local; crash_dump_t crash_dump_local; + logic fetch_enable_local; logic core_busy_local; @@ -563,6 +556,7 @@ module ibex_top #( irq_pending, debug_req_i, crash_dump_o, + fetch_enable_i, core_busy_d }; @@ -608,6 +602,7 @@ module ibex_top #( irq_pending_local, debug_req_local, crash_dump_local, + fetch_enable_local, core_busy_local } = buf_out; @@ -716,6 +711,7 @@ module ibex_top #( .debug_req_i (debug_req_local), .crash_dump_i (crash_dump_local), + .fetch_enable_i (fetch_enable_local), .alert_minor_o (lockstep_alert_minor_local), .alert_major_o (lockstep_alert_major_local), .core_busy_i (core_busy_local),