[rtl] Add minor alert for icache ECC error

This commit is contained in:
Greg Chadwick 2022-03-08 12:07:30 +00:00 committed by Greg Chadwick
parent f89e721040
commit 3438b77921
6 changed files with 31 additions and 12 deletions

View file

@ -164,6 +164,8 @@ The remaining data from hits is buffered in the fill buffer data storage and sup
To deal with misalignment caused by compressed instructions, there is a 16bit skid buffer to store the upper halfword.
.. _icache-ecc:
Cache ECC protection
^^^^^^^^^^^^^^^^^^^^
@ -193,6 +195,7 @@ Any error (single or double bit) in any RAM will effectively cancel a cache hit
The request which observed an error will fetch it's data from the main instruction memory as normal for a cache miss.
The cache index and way (or ways) with errors are stored in IC1, and a cache write is forced the next cycle to invalidate that line.
Lookup requests will be blocked in IC0 while the invalidation write is performed.
If an ECC error is seen a minor alert will be signaled.
Cache invalidation
^^^^^^^^^^^^^^^^^^

View file

@ -81,6 +81,13 @@ When Ibex is configured with the SecureIbex parameter, ECC checking is added to
This can be useful to detect fault injection attacks since the register file covers a reasonably large area.
No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
ICache ECC
----------
The ICache can be configured with ECC protection.
When an ECC error is detected a minor alert is signaled.
See :ref:`icache-ecc` for more information.
Hardened PC
-----------

View file

@ -105,7 +105,9 @@ module ic_top import ibex_pkg::*; #(
.icache_enable_i ( icache_enable_i ),
.icache_inval_i ( icache_inval_i ),
.busy_o ( busy_o )
.busy_o ( busy_o ),
// TODO: Probe this and verify functionality
.ecc_error_o ( )
);
///////////////////////////////

View file

@ -181,6 +181,7 @@ module ibex_core import ibex_pkg::*; #(
logic [31:0] dummy_instr_seed;
logic icache_enable;
logic icache_inval;
logic icache_ecc_error;
logic pc_mismatch_alert;
logic csr_shadow_err;
@ -432,6 +433,7 @@ module ibex_core import ibex_pkg::*; #(
.dummy_instr_seed_i (dummy_instr_seed),
.icache_enable_i (icache_enable),
.icache_inval_i (icache_inval),
.icache_ecc_error_o (icache_ecc_error),
// branch targets
.branch_target_ex_i(branch_target_ex),
@ -852,8 +854,7 @@ module ibex_core import ibex_pkg::*; #(
///////////////////
// Minor alert - core is in a recoverable state
// TODO add I$ ECC errors here
assign alert_minor_o = 1'b0;
assign alert_minor_o = icache_ecc_error;
// Major alert - core is unrecoverable
assign alert_major_o = rf_ecc_err_comb | pc_mismatch_alert | csr_shadow_err;

View file

@ -64,7 +64,8 @@ module ibex_icache import ibex_pkg::*; #(
// Cache status
input logic icache_enable_i,
input logic icache_inval_i,
output logic busy_o
output logic busy_o,
output logic ecc_error_o
);
// Number of fill buffers (must be >= 2)
@ -506,12 +507,15 @@ module ibex_icache import ibex_pkg::*; #(
assign ecc_write_ways = ecc_correction_ways_q;
assign ecc_write_index = ecc_correction_index_q;
assign ecc_error_o = ecc_err_ic1;
end else begin : gen_no_data_ecc
assign ecc_err_ic1 = 1'b0;
assign ecc_write_req = 1'b0;
assign ecc_write_ways = '0;
assign ecc_write_index = '0;
assign hit_data_ic1 = hit_data_ecc_ic1;
assign ecc_error_o = 1'b0;
end
///////////////////////////////

View file

@ -87,12 +87,13 @@ module ibex_if_stage import ibex_pkg::*; #(
input exc_pc_sel_e exc_pc_mux_i, // selects ISR address
input exc_cause_e exc_cause, // selects ISR address for
// vectorized interrupt lines
input logic dummy_instr_en_i,
input logic [2:0] dummy_instr_mask_i,
input logic dummy_instr_seed_en_i,
input logic [31:0] dummy_instr_seed_i,
input logic icache_enable_i,
input logic icache_inval_i,
input logic dummy_instr_en_i,
input logic [2:0] dummy_instr_mask_i,
input logic dummy_instr_seed_en_i,
input logic [31:0] dummy_instr_seed_i,
input logic icache_enable_i,
input logic icache_inval_i,
output logic icache_ecc_error_o,
// jump and branch target
input logic [31:0] branch_target_ex_i, // branch/jump target address
@ -251,7 +252,8 @@ module ibex_if_stage import ibex_pkg::*; #(
.icache_enable_i ( icache_enable_i ),
.icache_inval_i ( icache_inval_i ),
.busy_o ( prefetch_busy )
.busy_o ( prefetch_busy ),
.ecc_error_o ( icache_ecc_error_o )
);
end else begin : gen_prefetch_buffer
// prefetch buffer, caches a fixed number of instructions
@ -301,6 +303,7 @@ module ibex_if_stage import ibex_pkg::*; #(
assign ic_data_write_o = 'b0;
assign ic_data_addr_o = 'b0;
assign ic_data_wdata_o = 'b0;
assign icache_ecc_error_o = 'b0;
`ifndef SYNTHESIS
// If we don't instantiate an icache and this is a simulation then we have a problem because the
@ -317,7 +320,6 @@ module ibex_if_stage import ibex_pkg::*; #(
return 0;
endfunction
`endif
end
assign unused_fetch_addr_n0 = fetch_addr_n[0];