diff --git a/doc/02_user/integration.rst b/doc/02_user/integration.rst index 88902553..af226702 100644 --- a/doc/02_user/integration.rst +++ b/doc/02_user/integration.rst @@ -203,6 +203,8 @@ Interfaces | ``debug_*`` | Debug interface, see :ref:`debug-support` | +-------------------------+------------------------------------------------------------------------+ | ``crash_dump_o`` | A set of signals that can be captured on reset to aid crash debugging. | ++-------------------------+------------------------------------------------------------------------+ +| ``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. | | | | | If this bit is set low, the core will | diff --git a/doc/03_reference/cs_registers.rst b/doc/03_reference/cs_registers.rst index c73894a6..1a85aabc 100644 --- a/doc/03_reference/cs_registers.rst +++ b/doc/03_reference/cs_registers.rst @@ -539,6 +539,14 @@ Other bit fields read as zero. +-------+------+------------------------------------------------------------------+ | Bit# | R/W | Description | +-------+------+------------------------------------------------------------------+ +| 7 | RW | **double_fault_seen:** A synchronous exception was observed when | +| | | the ``sync_exc_seen`` field was set. This field must be manually | +| | | cleared, hardware only sets it (see :ref:`double-fault-detect`). | ++-------+------+------------------------------------------------------------------+ +| 6 | RW | **sync_exc_seen:** A synchronous exception has been observed. | +| | | This flag is cleared when ``mret`` is executed. | +| | | (see :ref:`double-fault-detect`). | ++-------+------+------------------------------------------------------------------+ | 5:3 | WARL | **dummy_instr_mask:** Mask to control frequency of dummy | | | | instruction insertion. If the core has not been configured with | | | | security features (SecureIbex parameter == 0), this field will | diff --git a/doc/03_reference/exception_interrupts.rst b/doc/03_reference/exception_interrupts.rst index a80dd474..3a010e78 100644 --- a/doc/03_reference/exception_interrupts.rst +++ b/doc/03_reference/exception_interrupts.rst @@ -148,3 +148,19 @@ The purpose of the nonstandard ``mstack`` CSRs in Ibex is only to support recove These CSRs are not accessible by software. While handling an NMI, all interrupts are ignored independent of ``mstatus``.MIE. Nested NMIs are not supported. + +.. _double-fault-detect: + +Double Fault Detection +---------------------- + +Ibex has a mechanism to detect when a double fault has occurred. +A double fault is defined as a synchronous exception occurring whilst handling a previous synchronous exception. +The ``cpuctrl`` custom CSR has fields to provide software visibility and access to this mechanism. + +When a synchronous exception occurs, Ibex sets ``cpuctrl``.sync_exception_seen. +Ibex clears ``cpuctrl``.sync_exception_seen when ``mret`` is executed. +If a synchronous exception occurs whilst ``cpuctrl``.sync_exception_seen is set, a double fault has been detected. + +When a double fault is detected, the ``double_fault_seen_o`` output is asserted for one cycle and ``cpuctrl``.double_fault_seen is set. +Note that writing the ``cpuctrl``.double_fault_seen field has no effect on the ``double_fault_seen_o`` output. diff --git a/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv b/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv index 0782aa15..af687e5f 100644 --- a/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv +++ b/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv @@ -175,6 +175,7 @@ module ibex_riscv_compliance ( .debug_req_i ('b0 ), .crash_dump_o ( ), + .double_fault_seen_o ( ), .fetch_enable_i ('b1 ), .alert_minor_o ( ), diff --git a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index c916db39..f8626781 100644 --- a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv +++ b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv @@ -127,6 +127,7 @@ module core_ibex_tb_top; .debug_req_i (dut_if.debug_req ), .crash_dump_o ( ), + .double_fault_seen_o ( ), .fetch_enable_i (dut_if.fetch_enable ), .alert_minor_o (dut_if.alert_minor ), diff --git a/examples/simple_system/rtl/ibex_simple_system.sv b/examples/simple_system/rtl/ibex_simple_system.sv index b61a2930..5acf3ed3 100644 --- a/examples/simple_system/rtl/ibex_simple_system.sv +++ b/examples/simple_system/rtl/ibex_simple_system.sv @@ -225,6 +225,7 @@ module ibex_simple_system ( .debug_req_i ('b0), .crash_dump_o (), + .double_fault_seen_o (), .fetch_enable_i ('b1), .alert_minor_o (), diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 5f18ab2b..2b6f52c5 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -101,6 +101,7 @@ module ibex_core import ibex_pkg::*; #( // Debug Interface input logic debug_req_i, output crash_dump_t crash_dump_o, + output logic double_fault_seen_o, // RISC-V Formal Interface // Does not comply with the coding standards of _i/_o suffixes, but follows @@ -973,6 +974,8 @@ module ibex_core import ibex_pkg::*; #( .csr_mtval_i (csr_mtval), .illegal_csr_insn_o(illegal_csr_insn_id), + .double_fault_seen_o, + // performance counter related signals .instr_ret_i (perf_instr_ret_wb), .instr_ret_compressed_i (perf_instr_ret_compressed_wb), diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index 6779dc39..bac875e4 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -104,6 +104,7 @@ module ibex_cs_registers #( output logic illegal_csr_insn_o, // access to non-existent CSR, // with wrong priviledge level, or // missing write permissions + output logic double_fault_seen_o, // Performance Counters input logic instr_ret_i, // instr retired in ID/EX stage input logic instr_ret_compressed_i, // compressed instr retired @@ -175,6 +176,8 @@ module ibex_cs_registers #( // CPU control register fields typedef struct packed { + logic double_fault_seen; + logic sync_exc_seen; logic [2:0] dummy_instr_mask; logic dummy_instr_en; logic data_ind_timing; @@ -251,7 +254,7 @@ module ibex_cs_registers #( logic [31:0] tmatch_value_rdata; // CPU control bits - cpu_ctrl_t cpuctrl_q, cpuctrl_d, cpuctrl_wdata; + cpu_ctrl_t cpuctrl_q, cpuctrl_d, cpuctrl_wdata_raw, cpuctrl_wdata; logic cpuctrl_we; logic cpuctrl_err; @@ -537,6 +540,9 @@ module ibex_cs_registers #( mhpmcounterh_we = '0; cpuctrl_we = 1'b0; + cpuctrl_d = cpuctrl_q; + + double_fault_seen_o = 1'b0; if (csr_we_int) begin unique case (csr_addr_i) @@ -635,7 +641,10 @@ module ibex_cs_registers #( mhpmcounterh_we[mhpmcounter_idx] = 1'b1; end - CSR_CPUCTRL: cpuctrl_we = 1'b1; + CSR_CPUCTRL: begin + cpuctrl_d = cpuctrl_wdata; + cpuctrl_we = 1'b1; + end default:; endcase @@ -685,6 +694,16 @@ module ibex_cs_registers #( mcause_d = {csr_mcause_i}; // save previous status for recoverable NMI mstack_en = 1'b1; + + if (!csr_mcause_i[5]) begin + cpuctrl_we = 1'b1; + + cpuctrl_d.sync_exc_seen = 1'b1; + if (cpuctrl_q.sync_exc_seen) begin + double_fault_seen_o = 1'b1; + cpuctrl_d.double_fault_seen = 1'b1; + end + end end end // csr_save_cause_i @@ -697,6 +716,9 @@ module ibex_cs_registers #( mstatus_en = 1'b1; mstatus_d.mie = mstatus_q.mpie; // re-enable interrupts + cpuctrl_we = 1'b1; + cpuctrl_d.sync_exc_seen = 1'b0; + if (nmi_mode_i) begin // when returning from an NMI restore state from mstack CSR mstatus_d.mpie = mstack_q.mpie; @@ -1476,27 +1498,27 @@ module ibex_cs_registers #( ////////////////////////// // Cast register write data - assign cpuctrl_wdata = cpu_ctrl_t'(csr_wdata_int[$bits(cpu_ctrl_t)-1:0]); + assign cpuctrl_wdata_raw = cpu_ctrl_t'(csr_wdata_int[$bits(cpu_ctrl_t)-1:0]); // Generate fixed time execution bit if (DataIndTiming) begin : gen_dit - assign cpuctrl_d.data_ind_timing = cpuctrl_wdata.data_ind_timing; + assign cpuctrl_wdata.data_ind_timing = cpuctrl_wdata_raw.data_ind_timing; end else begin : gen_no_dit // tieoff for the unused bit logic unused_dit; - assign unused_dit = cpuctrl_wdata.data_ind_timing; + assign unused_dit = cpuctrl_wdata_raw.data_ind_timing; // field will always read as zero if not configured - assign cpuctrl_d.data_ind_timing = 1'b0; + assign cpuctrl_wdata.data_ind_timing = 1'b0; end assign data_ind_timing_o = cpuctrl_q.data_ind_timing; // Generate dummy instruction signals if (DummyInstructions) begin : gen_dummy - assign cpuctrl_d.dummy_instr_en = cpuctrl_wdata.dummy_instr_en; - assign cpuctrl_d.dummy_instr_mask = cpuctrl_wdata.dummy_instr_mask; + assign cpuctrl_wdata.dummy_instr_en = cpuctrl_wdata_raw.dummy_instr_en; + assign cpuctrl_wdata.dummy_instr_mask = cpuctrl_wdata_raw.dummy_instr_mask; // Signal a write to the seed register assign dummy_instr_seed_en_o = csr_we_int && (csr_addr == CSR_SECURESEED); @@ -1506,12 +1528,12 @@ module ibex_cs_registers #( // tieoff for the unused bit logic unused_dummy_en; logic [2:0] unused_dummy_mask; - assign unused_dummy_en = cpuctrl_wdata.dummy_instr_en; - assign unused_dummy_mask = cpuctrl_wdata.dummy_instr_mask; + assign unused_dummy_en = cpuctrl_wdata_raw.dummy_instr_en; + assign unused_dummy_mask = cpuctrl_wdata_raw.dummy_instr_mask; // field will always read as zero if not configured - assign cpuctrl_d.dummy_instr_en = 1'b0; - assign cpuctrl_d.dummy_instr_mask = 3'b000; + assign cpuctrl_wdata.dummy_instr_en = 1'b0; + assign cpuctrl_wdata.dummy_instr_mask = 3'b000; assign dummy_instr_seed_en_o = 1'b0; assign dummy_instr_seed_o = '0; end @@ -1521,16 +1543,19 @@ module ibex_cs_registers #( // Generate icache enable bit if (ICache) begin : gen_icache_enable - assign cpuctrl_d.icache_enable = cpuctrl_wdata.icache_enable; + assign cpuctrl_wdata.icache_enable = cpuctrl_wdata_raw.icache_enable; end else begin : gen_no_icache // tieoff for the unused icen bit logic unused_icen; - assign unused_icen = cpuctrl_wdata.icache_enable; + assign unused_icen = cpuctrl_wdata_raw.icache_enable; // icen field will always read as zero if ICache not configured - assign cpuctrl_d.icache_enable = 1'b0; + assign cpuctrl_wdata.icache_enable = 1'b0; end + assign cpuctrl_wdata.double_fault_seen = cpuctrl_wdata_raw.double_fault_seen; + assign cpuctrl_wdata.sync_exc_seen = cpuctrl_wdata_raw.sync_exc_seen; + assign icache_enable_o = cpuctrl_q.icache_enable; ibex_csr #( diff --git a/rtl/ibex_lockstep.sv b/rtl/ibex_lockstep.sv index da01d3ea..ebdd1edd 100644 --- a/rtl/ibex_lockstep.sv +++ b/rtl/ibex_lockstep.sv @@ -92,6 +92,7 @@ module ibex_lockstep import ibex_pkg::*; #( input logic debug_req_i, input crash_dump_t crash_dump_i, + input logic double_fault_seen_i, input logic fetch_enable_i, output logic alert_minor_o, @@ -294,6 +295,7 @@ module ibex_lockstep import ibex_pkg::*; #( logic [LineSizeECC-1:0] ic_data_wdata; logic irq_pending; crash_dump_t crash_dump; + logic double_fault_seen; logic icache_inval; logic core_busy; } delayed_outputs_t; @@ -303,31 +305,32 @@ module ibex_lockstep import ibex_pkg::*; #( delayed_outputs_t shadow_outputs_d, shadow_outputs_q; // Assign core outputs to the structure - assign core_outputs_in.instr_req = instr_req_i; - assign core_outputs_in.instr_addr = instr_addr_i; - assign core_outputs_in.data_req = data_req_i; - assign core_outputs_in.data_we = data_we_i; - assign core_outputs_in.data_be = data_be_i; - assign core_outputs_in.data_addr = data_addr_i; - assign core_outputs_in.data_wdata = data_wdata_i; - assign core_outputs_in.dummy_instr_id = dummy_instr_id_i; - assign core_outputs_in.rf_raddr_a = rf_raddr_a_i; - assign core_outputs_in.rf_raddr_b = rf_raddr_b_i; - assign core_outputs_in.rf_waddr_wb = rf_waddr_wb_i; - assign core_outputs_in.rf_we_wb = rf_we_wb_i; - assign core_outputs_in.rf_wdata_wb_ecc = rf_wdata_wb_ecc_i; - assign core_outputs_in.ic_tag_req = ic_tag_req_i; - assign core_outputs_in.ic_tag_write = ic_tag_write_i; - assign core_outputs_in.ic_tag_addr = ic_tag_addr_i; - assign core_outputs_in.ic_tag_wdata = ic_tag_wdata_i; - assign core_outputs_in.ic_data_req = ic_data_req_i; - assign core_outputs_in.ic_data_write = ic_data_write_i; - assign core_outputs_in.ic_data_addr = ic_data_addr_i; - assign core_outputs_in.ic_data_wdata = ic_data_wdata_i; - assign core_outputs_in.irq_pending = irq_pending_i; - assign core_outputs_in.crash_dump = crash_dump_i; - assign core_outputs_in.icache_inval = icache_inval_i; - assign core_outputs_in.core_busy = core_busy_i; + assign core_outputs_in.instr_req = instr_req_i; + assign core_outputs_in.instr_addr = instr_addr_i; + assign core_outputs_in.data_req = data_req_i; + assign core_outputs_in.data_we = data_we_i; + assign core_outputs_in.data_be = data_be_i; + assign core_outputs_in.data_addr = data_addr_i; + assign core_outputs_in.data_wdata = data_wdata_i; + assign core_outputs_in.dummy_instr_id = dummy_instr_id_i; + assign core_outputs_in.rf_raddr_a = rf_raddr_a_i; + assign core_outputs_in.rf_raddr_b = rf_raddr_b_i; + assign core_outputs_in.rf_waddr_wb = rf_waddr_wb_i; + assign core_outputs_in.rf_we_wb = rf_we_wb_i; + assign core_outputs_in.rf_wdata_wb_ecc = rf_wdata_wb_ecc_i; + assign core_outputs_in.ic_tag_req = ic_tag_req_i; + assign core_outputs_in.ic_tag_write = ic_tag_write_i; + assign core_outputs_in.ic_tag_addr = ic_tag_addr_i; + assign core_outputs_in.ic_tag_wdata = ic_tag_wdata_i; + assign core_outputs_in.ic_data_req = ic_data_req_i; + assign core_outputs_in.ic_data_write = ic_data_write_i; + assign core_outputs_in.ic_data_addr = ic_data_addr_i; + assign core_outputs_in.ic_data_wdata = ic_data_wdata_i; + assign core_outputs_in.irq_pending = irq_pending_i; + assign core_outputs_in.crash_dump = crash_dump_i; + assign core_outputs_in.double_fault_seen = double_fault_seen_i; + assign core_outputs_in.icache_inval = icache_inval_i; + assign core_outputs_in.core_busy = core_busy_i; // Delay the outputs always_ff @(posedge clk_i) begin @@ -372,59 +375,60 @@ module ibex_lockstep import ibex_pkg::*; #( .DmHaltAddr ( DmHaltAddr ), .DmExceptionAddr ( DmExceptionAddr ) ) u_shadow_core ( - .clk_i (clk_i), - .rst_ni (rst_shadow_n), + .clk_i (clk_i), + .rst_ni (rst_shadow_n), - .hart_id_i (hart_id_i), - .boot_addr_i (boot_addr_i), + .hart_id_i (hart_id_i), + .boot_addr_i (boot_addr_i), - .instr_req_o (shadow_outputs_d.instr_req), - .instr_gnt_i (shadow_inputs_q[0].instr_gnt), - .instr_rvalid_i (shadow_inputs_q[0].instr_rvalid), - .instr_addr_o (shadow_outputs_d.instr_addr), - .instr_rdata_i (shadow_inputs_q[0].instr_rdata), - .instr_err_i (shadow_inputs_q[0].instr_err), + .instr_req_o (shadow_outputs_d.instr_req), + .instr_gnt_i (shadow_inputs_q[0].instr_gnt), + .instr_rvalid_i (shadow_inputs_q[0].instr_rvalid), + .instr_addr_o (shadow_outputs_d.instr_addr), + .instr_rdata_i (shadow_inputs_q[0].instr_rdata), + .instr_err_i (shadow_inputs_q[0].instr_err), - .data_req_o (shadow_outputs_d.data_req), - .data_gnt_i (shadow_inputs_q[0].data_gnt), - .data_rvalid_i (shadow_inputs_q[0].data_rvalid), - .data_we_o (shadow_outputs_d.data_we), - .data_be_o (shadow_outputs_d.data_be), - .data_addr_o (shadow_outputs_d.data_addr), - .data_wdata_o (shadow_outputs_d.data_wdata), - .data_rdata_i (shadow_inputs_q[0].data_rdata), - .data_err_i (shadow_inputs_q[0].data_err), + .data_req_o (shadow_outputs_d.data_req), + .data_gnt_i (shadow_inputs_q[0].data_gnt), + .data_rvalid_i (shadow_inputs_q[0].data_rvalid), + .data_we_o (shadow_outputs_d.data_we), + .data_be_o (shadow_outputs_d.data_be), + .data_addr_o (shadow_outputs_d.data_addr), + .data_wdata_o (shadow_outputs_d.data_wdata), + .data_rdata_i (shadow_inputs_q[0].data_rdata), + .data_err_i (shadow_inputs_q[0].data_err), - .dummy_instr_id_o (shadow_outputs_d.dummy_instr_id), - .rf_raddr_a_o (shadow_outputs_d.rf_raddr_a), - .rf_raddr_b_o (shadow_outputs_d.rf_raddr_b), - .rf_waddr_wb_o (shadow_outputs_d.rf_waddr_wb), - .rf_we_wb_o (shadow_outputs_d.rf_we_wb), - .rf_wdata_wb_ecc_o (shadow_outputs_d.rf_wdata_wb_ecc), - .rf_rdata_a_ecc_i (shadow_inputs_q[0].rf_rdata_a_ecc), - .rf_rdata_b_ecc_i (shadow_inputs_q[0].rf_rdata_b_ecc), + .dummy_instr_id_o (shadow_outputs_d.dummy_instr_id), + .rf_raddr_a_o (shadow_outputs_d.rf_raddr_a), + .rf_raddr_b_o (shadow_outputs_d.rf_raddr_b), + .rf_waddr_wb_o (shadow_outputs_d.rf_waddr_wb), + .rf_we_wb_o (shadow_outputs_d.rf_we_wb), + .rf_wdata_wb_ecc_o (shadow_outputs_d.rf_wdata_wb_ecc), + .rf_rdata_a_ecc_i (shadow_inputs_q[0].rf_rdata_a_ecc), + .rf_rdata_b_ecc_i (shadow_inputs_q[0].rf_rdata_b_ecc), - .ic_tag_req_o (shadow_outputs_d.ic_tag_req), - .ic_tag_write_o (shadow_outputs_d.ic_tag_write), - .ic_tag_addr_o (shadow_outputs_d.ic_tag_addr), - .ic_tag_wdata_o (shadow_outputs_d.ic_tag_wdata), - .ic_tag_rdata_i (shadow_tag_rdata_q[0]), - .ic_data_req_o (shadow_outputs_d.ic_data_req), - .ic_data_write_o (shadow_outputs_d.ic_data_write), - .ic_data_addr_o (shadow_outputs_d.ic_data_addr), - .ic_data_wdata_o (shadow_outputs_d.ic_data_wdata), - .ic_data_rdata_i (shadow_data_rdata_q[0]), - .ic_scr_key_valid_i (shadow_inputs_q[0].ic_scr_key_valid), + .ic_tag_req_o (shadow_outputs_d.ic_tag_req), + .ic_tag_write_o (shadow_outputs_d.ic_tag_write), + .ic_tag_addr_o (shadow_outputs_d.ic_tag_addr), + .ic_tag_wdata_o (shadow_outputs_d.ic_tag_wdata), + .ic_tag_rdata_i (shadow_tag_rdata_q[0]), + .ic_data_req_o (shadow_outputs_d.ic_data_req), + .ic_data_write_o (shadow_outputs_d.ic_data_write), + .ic_data_addr_o (shadow_outputs_d.ic_data_addr), + .ic_data_wdata_o (shadow_outputs_d.ic_data_wdata), + .ic_data_rdata_i (shadow_data_rdata_q[0]), + .ic_scr_key_valid_i (shadow_inputs_q[0].ic_scr_key_valid), - .irq_software_i (shadow_inputs_q[0].irq_software), - .irq_timer_i (shadow_inputs_q[0].irq_timer), - .irq_external_i (shadow_inputs_q[0].irq_external), - .irq_fast_i (shadow_inputs_q[0].irq_fast), - .irq_nm_i (shadow_inputs_q[0].irq_nm), - .irq_pending_o (shadow_outputs_d.irq_pending), + .irq_software_i (shadow_inputs_q[0].irq_software), + .irq_timer_i (shadow_inputs_q[0].irq_timer), + .irq_external_i (shadow_inputs_q[0].irq_external), + .irq_fast_i (shadow_inputs_q[0].irq_fast), + .irq_nm_i (shadow_inputs_q[0].irq_nm), + .irq_pending_o (shadow_outputs_d.irq_pending), - .debug_req_i (shadow_inputs_q[0].debug_req), - .crash_dump_o (shadow_outputs_d.crash_dump), + .debug_req_i (shadow_inputs_q[0].debug_req), + .crash_dump_o (shadow_outputs_d.crash_dump), + .double_fault_seen_o (shadow_outputs_d.double_fault_seen), `ifdef RVFI .rvfi_valid (), diff --git a/rtl/ibex_top.sv b/rtl/ibex_top.sv index 20419ff0..4269a0d9 100644 --- a/rtl/ibex_top.sv +++ b/rtl/ibex_top.sv @@ -87,6 +87,7 @@ module ibex_top import ibex_pkg::*; #( // Debug Interface input logic debug_req_i, output crash_dump_t crash_dump_o, + output logic double_fault_seen_o, // RISC-V Formal Interface // Does not comply with the coding standards of _i/_o suffixes, but follows @@ -287,6 +288,7 @@ module ibex_top import ibex_pkg::*; #( .debug_req_i, .crash_dump_o, + .double_fault_seen_o, `ifdef RVFI .rvfi_valid, @@ -592,6 +594,7 @@ module ibex_top import ibex_pkg::*; #( irq_pending, debug_req_i, crash_dump_o, + double_fault_seen_o, fetch_enable_i, icache_inval, core_busy_d @@ -650,6 +653,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; logic icache_inval_local; @@ -700,6 +704,7 @@ module ibex_top import ibex_pkg::*; #( irq_pending, debug_req_i, crash_dump_o, + double_fault_seen_o, fetch_enable_i, icache_inval, core_busy_d @@ -750,6 +755,7 @@ module ibex_top import ibex_pkg::*; #( irq_pending_local, debug_req_local, crash_dump_local, + double_fault_seen_local, fetch_enable_local, icache_inval_local, core_busy_local @@ -860,6 +866,7 @@ module ibex_top import ibex_pkg::*; #( .debug_req_i (debug_req_local), .crash_dump_i (crash_dump_local), + .double_fault_seen_i(double_fault_seen_local), .fetch_enable_i (fetch_enable_local), .alert_minor_o (lockstep_alert_minor_local), diff --git a/rtl/ibex_top_tracing.sv b/rtl/ibex_top_tracing.sv index 85d6e200..6aec936a 100644 --- a/rtl/ibex_top_tracing.sv +++ b/rtl/ibex_top_tracing.sv @@ -80,6 +80,7 @@ module ibex_top_tracing import ibex_pkg::*; #( // Debug Interface input logic debug_req_i, output crash_dump_t crash_dump_o, + output logic double_fault_seen_o, // CPU Control Signals input logic fetch_enable_i, @@ -201,6 +202,7 @@ module ibex_top_tracing import ibex_pkg::*; #( .debug_req_i, .crash_dump_o, + .double_fault_seen_o, .rvfi_valid, .rvfi_order,