mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
[rtl] Switch to multi-bit fetch enable
The multi-bit enable aids security hardening. For non secure Ibex all but the bottom bit is ignored so it is effectively a single bit enable.
This commit is contained in:
parent
3475b9106c
commit
b18eceba81
11 changed files with 111 additions and 72 deletions
|
@ -208,9 +208,12 @@ Interfaces
|
|||
+----------------------------+------------------------------------------------------------------------+
|
||||
| ``double_fault_seen_o`` | A double fault was observed, see :ref:`double-fault-detect` |
|
||||
+----------------------------+-------------------------+-----+----------------------------------------+
|
||||
| ``fetch_enable_i`` | 1 | in | Allow the core to fetch instructions. |
|
||||
| ``fetch_enable_i`` | 4 | in | Allow the core to fetch instructions. |
|
||||
| | | | If this bit is set low, the core will |
|
||||
| | | | pause fetching new instructions. |
|
||||
| | | | pause fetching new instructions. A |
|
||||
| | | | multi-bit encoding scheme is used. See |
|
||||
| | | | `FetchEnableOn` / `FetchEnableOff` in |
|
||||
| | | | :file:`rtl/ibex_pkg.sv` |
|
||||
+----------------------------+-------------------------+-----+----------------------------------------+
|
||||
| ``core_sleep_o`` | 1 | out | Core in WFI with no outstanding data |
|
||||
| | | | or instruction accesses. Deasserts |
|
||||
|
|
|
@ -131,57 +131,57 @@ module ibex_riscv_compliance (
|
|||
.DmHaltAddr (32'h00000000 ),
|
||||
.DmExceptionAddr (32'h00000000 )
|
||||
) u_top (
|
||||
.clk_i (clk_sys ),
|
||||
.rst_ni (rst_sys_n ),
|
||||
.clk_i (clk_sys ),
|
||||
.rst_ni (rst_sys_n ),
|
||||
|
||||
.test_en_i ('b0 ),
|
||||
.scan_rst_ni (1'b1 ),
|
||||
.ram_cfg_i ('b0 ),
|
||||
.test_en_i ('b0 ),
|
||||
.scan_rst_ni (1'b1 ),
|
||||
.ram_cfg_i ('b0 ),
|
||||
|
||||
.hart_id_i (32'b0 ),
|
||||
.hart_id_i (32'b0 ),
|
||||
// First instruction executed is at 0x0 + 0x80
|
||||
.boot_addr_i (32'h00000000 ),
|
||||
.boot_addr_i (32'h00000000 ),
|
||||
|
||||
.instr_req_o (host_req[CoreI] ),
|
||||
.instr_gnt_i (host_gnt[CoreI] ),
|
||||
.instr_rvalid_i (host_rvalid[CoreI]),
|
||||
.instr_addr_o (host_addr[CoreI] ),
|
||||
.instr_rdata_i (host_rdata[CoreI] ),
|
||||
.instr_rdata_intg_i ('0 ),
|
||||
.instr_err_i (host_err[CoreI] ),
|
||||
.instr_req_o (host_req[CoreI] ),
|
||||
.instr_gnt_i (host_gnt[CoreI] ),
|
||||
.instr_rvalid_i (host_rvalid[CoreI] ),
|
||||
.instr_addr_o (host_addr[CoreI] ),
|
||||
.instr_rdata_i (host_rdata[CoreI] ),
|
||||
.instr_rdata_intg_i ('0 ),
|
||||
.instr_err_i (host_err[CoreI] ),
|
||||
|
||||
.data_req_o (host_req[CoreD] ),
|
||||
.data_gnt_i (host_gnt[CoreD] ),
|
||||
.data_rvalid_i (host_rvalid[CoreD]),
|
||||
.data_we_o (host_we[CoreD] ),
|
||||
.data_be_o (host_be[CoreD] ),
|
||||
.data_addr_o (host_addr[CoreD] ),
|
||||
.data_wdata_o (host_wdata[CoreD] ),
|
||||
.data_wdata_intg_o ( ),
|
||||
.data_rdata_i (host_rdata[CoreD] ),
|
||||
.data_rdata_intg_i ('0 ),
|
||||
.data_err_i (host_err[CoreD] ),
|
||||
.data_req_o (host_req[CoreD] ),
|
||||
.data_gnt_i (host_gnt[CoreD] ),
|
||||
.data_rvalid_i (host_rvalid[CoreD] ),
|
||||
.data_we_o (host_we[CoreD] ),
|
||||
.data_be_o (host_be[CoreD] ),
|
||||
.data_addr_o (host_addr[CoreD] ),
|
||||
.data_wdata_o (host_wdata[CoreD] ),
|
||||
.data_wdata_intg_o ( ),
|
||||
.data_rdata_i (host_rdata[CoreD] ),
|
||||
.data_rdata_intg_i ('0 ),
|
||||
.data_err_i (host_err[CoreD] ),
|
||||
|
||||
.irq_software_i (1'b0 ),
|
||||
.irq_timer_i (1'b0 ),
|
||||
.irq_external_i (1'b0 ),
|
||||
.irq_fast_i (15'b0 ),
|
||||
.irq_nm_i (1'b0 ),
|
||||
.irq_software_i (1'b0 ),
|
||||
.irq_timer_i (1'b0 ),
|
||||
.irq_external_i (1'b0 ),
|
||||
.irq_fast_i (15'b0 ),
|
||||
.irq_nm_i (1'b0 ),
|
||||
|
||||
.scramble_key_valid_i ('0 ),
|
||||
.scramble_key_i ('0 ),
|
||||
.scramble_nonce_i ('0 ),
|
||||
.scramble_req_o ( ),
|
||||
.scramble_key_valid_i ('0 ),
|
||||
.scramble_key_i ('0 ),
|
||||
.scramble_nonce_i ('0 ),
|
||||
.scramble_req_o ( ),
|
||||
|
||||
.debug_req_i ('b0 ),
|
||||
.crash_dump_o ( ),
|
||||
.double_fault_seen_o ( ),
|
||||
.debug_req_i ('b0 ),
|
||||
.crash_dump_o ( ),
|
||||
.double_fault_seen_o ( ),
|
||||
|
||||
.fetch_enable_i ('b1 ),
|
||||
.alert_minor_o ( ),
|
||||
.alert_major_internal_o ( ),
|
||||
.alert_major_bus_o ( ),
|
||||
.core_sleep_o ( )
|
||||
.fetch_enable_i (ibex_pkg::FetchEnableOn),
|
||||
.alert_minor_o ( ),
|
||||
.alert_major_internal_o ( ),
|
||||
.alert_major_bus_o ( ),
|
||||
.core_sleep_o ( )
|
||||
);
|
||||
|
||||
// SRAM block for instruction and data storage
|
||||
|
|
28
dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
vendored
28
dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
vendored
|
@ -4,20 +4,20 @@
|
|||
|
||||
// Interface to probe DUT internal signal
|
||||
interface core_ibex_dut_probe_if(input logic clk);
|
||||
logic reset;
|
||||
logic illegal_instr;
|
||||
logic ecall;
|
||||
logic wfi;
|
||||
logic ebreak;
|
||||
logic dret;
|
||||
logic mret;
|
||||
logic fetch_enable;
|
||||
logic core_sleep;
|
||||
logic alert_minor;
|
||||
logic alert_major_internal;
|
||||
logic alert_major_bus;
|
||||
logic debug_req;
|
||||
ibex_pkg::priv_lvl_e priv_mode;
|
||||
logic reset;
|
||||
logic illegal_instr;
|
||||
logic ecall;
|
||||
logic wfi;
|
||||
logic ebreak;
|
||||
logic dret;
|
||||
logic mret;
|
||||
ibex_pkg::fetch_enable_t fetch_enable;
|
||||
logic core_sleep;
|
||||
logic alert_minor;
|
||||
logic alert_major_internal;
|
||||
logic alert_major_bus;
|
||||
logic debug_req;
|
||||
ibex_pkg::priv_lvl_e priv_mode;
|
||||
|
||||
clocking dut_cb @(posedge clk);
|
||||
output fetch_enable;
|
||||
|
|
|
@ -132,10 +132,10 @@ class core_ibex_base_test extends uvm_test;
|
|||
enable_irq_seq = cfg.enable_irq_single_seq || cfg.enable_irq_multiple_seq;
|
||||
phase.raise_objection(this);
|
||||
cur_run_phase = phase;
|
||||
dut_vif.dut_cb.fetch_enable <= 1'b0;
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOff;
|
||||
clk_vif.wait_clks(100);
|
||||
load_binary_to_mem();
|
||||
dut_vif.dut_cb.fetch_enable <= 1'b1;
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOn;
|
||||
send_stimulus();
|
||||
wait_for_test_done();
|
||||
cur_run_phase = null;
|
||||
|
@ -194,7 +194,7 @@ class core_ibex_base_test extends uvm_test;
|
|||
check_perf_stats();
|
||||
// De-assert fetch enable to finish the test
|
||||
clk_vif.wait_clks(10);
|
||||
dut_vif.dut_cb.fetch_enable <= 1'b0;
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOff;
|
||||
end
|
||||
// Wait some time for the remaining instruction to finish
|
||||
clk_vif.wait_clks(3000);
|
||||
|
|
|
@ -47,7 +47,7 @@ class core_ibex_reset_test extends core_ibex_base_test;
|
|||
clk_vif.wait_clks($urandom_range(0, 50000));
|
||||
fork
|
||||
begin
|
||||
dut_vif.dut_cb.fetch_enable <= 1'b0;
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOff;
|
||||
clk_vif.apply_reset(.reset_width_clks (100));
|
||||
end
|
||||
begin
|
||||
|
@ -61,7 +61,7 @@ class core_ibex_reset_test extends core_ibex_base_test;
|
|||
end
|
||||
join
|
||||
// Assert fetch_enable to have the core start executing from boot address
|
||||
dut_vif.dut_cb.fetch_enable <= 1'b1;
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOn;
|
||||
end
|
||||
endtask
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ module ibex_simple_system (
|
|||
.crash_dump_o (),
|
||||
.double_fault_seen_o (),
|
||||
|
||||
.fetch_enable_i ('b1),
|
||||
.fetch_enable_i (ibex_pkg::FetchEnableOn),
|
||||
.alert_minor_o (),
|
||||
.alert_major_internal_o (),
|
||||
.alert_major_bus_o (),
|
||||
|
|
|
@ -137,7 +137,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
`endif
|
||||
|
||||
// CPU Control Signals
|
||||
input logic fetch_enable_i,
|
||||
input fetch_enable_t fetch_enable_i,
|
||||
output logic alert_minor_o,
|
||||
output logic alert_major_o,
|
||||
output logic icache_inval_o,
|
||||
|
@ -450,8 +450,25 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// available
|
||||
assign perf_iside_wait = id_in_ready & ~instr_valid_id;
|
||||
|
||||
// Multi-bit fetch enable used when SecureIbex == 1. When SecureIbex == 0 only use the bottom-bit
|
||||
// of fetch_enable_i. Ensure the multi-bit encoding has the bottom bit set for on and unset for
|
||||
// off so FetchEnableOn/FetchEnableOff can be used without needing to know the value of
|
||||
// SecureIbex.
|
||||
`ASSERT_INIT(FetchEnableSecureOnBottomBitSet, FetchEnableOn[0] == 1'b1)
|
||||
`ASSERT_INIT(FetchEnableSecureOffBottomBitClear, FetchEnableOff[0] == 1'b0)
|
||||
|
||||
// fetch_enable_i can be used to stop the core fetching new instructions
|
||||
assign instr_req_gated = instr_req_int & fetch_enable_i;
|
||||
if (SecureIbex) begin : g_instr_req_gated_secure
|
||||
// For secure Ibex fetch_enable_i must be a specific multi-bit pattern to enable instruction
|
||||
// fetch
|
||||
assign instr_req_gated = instr_req_int & (fetch_enable_i == FetchEnableOn);
|
||||
end else begin : g_instr_req_gated_non_secure
|
||||
// For non secure Ibex only the bottom bit of fetch enable is considered
|
||||
logic unused_fetch_enable;
|
||||
assign unused_fetch_enable = ^fetch_enable_i[$bits(fetch_enable_t)-1:1];
|
||||
|
||||
assign instr_req_gated = instr_req_int & fetch_enable_i[0];
|
||||
end
|
||||
|
||||
//////////////
|
||||
// ID stage //
|
||||
|
|
|
@ -94,7 +94,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
input crash_dump_t crash_dump_i,
|
||||
input logic double_fault_seen_i,
|
||||
|
||||
input logic fetch_enable_i,
|
||||
input fetch_enable_t fetch_enable_i,
|
||||
output logic alert_minor_o,
|
||||
output logic alert_major_internal_o,
|
||||
output logic alert_major_bus_o,
|
||||
|
@ -182,7 +182,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
logic [14:0] irq_fast;
|
||||
logic irq_nm;
|
||||
logic debug_req;
|
||||
logic fetch_enable;
|
||||
fetch_enable_t fetch_enable;
|
||||
logic ic_scr_key_valid;
|
||||
} delayed_inputs_t;
|
||||
|
||||
|
|
|
@ -606,4 +606,15 @@ package ibex_pkg;
|
|||
128'h14e8cecae3040d5e12286bb3cc113298;
|
||||
parameter logic [SCRAMBLE_NONCE_W-1:0] RndCnstIbexNonceDefault =
|
||||
64'hf79780bc735f3843;
|
||||
|
||||
// Fetch enable. Mult-bit signal used for security hardening. For non-secure implementation all
|
||||
// bits other than the bottom bit are ignored.
|
||||
typedef logic [3:0] fetch_enable_t;
|
||||
|
||||
// Note that if adjusting these parameters it is assumed the bottom bit is set for On and unset
|
||||
// for Off. This allows the use of FetchEnableOn/FetchEnableOff to work for both secure and
|
||||
// non-secure Ibex. If this assumption is broken the RTL that uses the fetch_enable signal within
|
||||
// `ibex_core` may need adjusting.
|
||||
parameter fetch_enable_t FetchEnableOn = 4'b1001;
|
||||
parameter fetch_enable_t FetchEnableOff = 4'b0110;
|
||||
endpackage
|
||||
|
|
|
@ -123,7 +123,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
`endif
|
||||
|
||||
// CPU Control Signals
|
||||
input logic fetch_enable_i,
|
||||
input fetch_enable_t fetch_enable_i,
|
||||
output logic alert_minor_o,
|
||||
output logic alert_major_internal_o,
|
||||
output logic alert_major_bus_o,
|
||||
|
@ -182,6 +182,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
logic scramble_key_valid_d, scramble_key_valid_q;
|
||||
logic scramble_req_d, scramble_req_q;
|
||||
|
||||
fetch_enable_t fetch_enable_buf;
|
||||
|
||||
/////////////////////
|
||||
// Main clock gate //
|
||||
/////////////////////
|
||||
|
@ -208,6 +210,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
// Core instantiation //
|
||||
////////////////////////
|
||||
|
||||
// Buffer fetch_enable_i to prevent synthesis optimising away multi-bit signal
|
||||
prim_buf #(.Width($bits(fetch_enable_t))) u_fetch_enable_buf (
|
||||
.in_i (fetch_enable_i),
|
||||
.out_o(fetch_enable_buf)
|
||||
);
|
||||
|
||||
ibex_core #(
|
||||
.PMPEnable (PMPEnable),
|
||||
.PMPGranularity (PMPGranularity),
|
||||
|
@ -322,7 +330,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.rvfi_ext_mcycle,
|
||||
`endif
|
||||
|
||||
.fetch_enable_i,
|
||||
.fetch_enable_i(fetch_enable_buf),
|
||||
.alert_minor_o (core_alert_minor),
|
||||
.alert_major_o (core_alert_major),
|
||||
.icache_inval_o(icache_inval),
|
||||
|
@ -656,7 +664,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
logic debug_req_local;
|
||||
crash_dump_t crash_dump_local;
|
||||
logic double_fault_seen_local;
|
||||
logic fetch_enable_local;
|
||||
fetch_enable_t fetch_enable_local;
|
||||
|
||||
logic icache_inval_local;
|
||||
logic core_busy_local;
|
||||
|
|
|
@ -83,7 +83,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
output logic double_fault_seen_o,
|
||||
|
||||
// CPU Control Signals
|
||||
input logic fetch_enable_i,
|
||||
input fetch_enable_t fetch_enable_i,
|
||||
output logic alert_minor_o,
|
||||
output logic alert_major_internal_o,
|
||||
output logic alert_major_bus_o,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue