[rtl] Modify fetch_en_i behavior

This signal used to be a one shot enable out of reset. We need an option
to pause execution for OpenTitan, so fetch_enable is extended to cover
that.

The signal is already driven low by the testbench at the end of test.
This is moved after the performance counter reads to ensure they can
complete.

Fixes #1105

Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
Tom Roberts 2021-06-16 15:36:51 +01:00 committed by Tom Roberts
parent 8a4c1b9e6d
commit 6daae3509a
5 changed files with 26 additions and 21 deletions

View file

@ -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 |

View file

@ -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

View file

@ -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 //
//////////////

View file

@ -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)

View file

@ -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),