diff --git a/hw/ip_templates/rv_core_ibex/data/rv_core_ibex.hjson.tpl b/hw/ip_templates/rv_core_ibex/data/rv_core_ibex.hjson.tpl index 3eb97ee2f02e5..41fbd34acaaeb 100644 --- a/hw/ip_templates/rv_core_ibex/data/rv_core_ibex.hjson.tpl +++ b/hw/ip_templates/rv_core_ibex/data/rv_core_ibex.hjson.tpl @@ -1124,6 +1124,47 @@ ] }, + { name: "MCOUNTEREN_WRITABLE_REGWEN", + desc: "Register write-enable for !!MCOUNTEREN_WRITABLE.", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1", + desc: "Write enable for !!MCOUNTEREN_WRITABLE. Once set to 0, it can no longer be configured to 1.", + enum: [ + { value: "0", + name: "locked", + desc: "MCOUNTEREN_WRITABLE can no longer be configured until next reset." + }, + { value: "1", + name: "enabled", + desc: "MCOUNTEREN_WRITABLE can still be configured." + }, + ] + }, + ], + }, + + { name: "MCOUNTEREN_WRITABLE", + desc: "Controls whether Ibex mcounteren CSR is writable by software.", + swaccess: "rw", + hwaccess: "hro", + regwen: "MCOUNTEREN_WRITABLE_REGWEN", + fields: [ + { bits: "3:0", + mubi: true, + name: "EN", + resval: true, + desc: ''' + When set to kMultiBitBool4True, the mcounteren CSR is writable by software. + Drives the mcounteren_writable_i input on ibex_top. + ''' + }, + ], + }, + // dv simulation window { window: { name: "DV_SIM_WINDOW", diff --git a/hw/ip_templates/rv_core_ibex/rtl/rv_core_ibex.sv.tpl b/hw/ip_templates/rv_core_ibex/rtl/rv_core_ibex.sv.tpl index b9a8748bc1b8e..7712f2ea07940 100644 --- a/hw/ip_templates/rv_core_ibex/rtl/rv_core_ibex.sv.tpl +++ b/hw/ip_templates/rv_core_ibex/rtl/rv_core_ibex.sv.tpl @@ -237,6 +237,8 @@ module ${module_instance_name} logic [ 3:0] rvfi_mem_wmask; logic [31:0] rvfi_mem_rdata; logic [31:0] rvfi_mem_wdata; + logic rvfi_ext_expanded_insn_valid; + logic [15:0] rvfi_ext_expanded_insn; `endif import tlul_pkg::tl_h2d_t; @@ -433,6 +435,14 @@ module ${module_instance_name} lc_ctrl_pkg::lc_tx_and_hi(lc_cpu_en[0], pwrmgr_cpu_en[0])); + prim_mubi_pkg::mubi4_t mcounteren_writable_mubi4; + ibex_pkg::ibex_mubi_t mcounteren_writable_ibex; + assign mcounteren_writable_mubi4 = prim_mubi_pkg::mubi4_t'(reg2hw.mcounteren_writable.q); + // Convert the mubi4 to ibex_mubi. They are both four bit, but with different encodings. + // This conversion should be a simple wire crossing. + assign mcounteren_writable_ibex = mcounteren_writable_mubi4 == prim_mubi_pkg::MuBi4True ? + ibex_pkg::IbexMuBiOn : ibex_pkg::IbexMuBiOff; + ibex_pkg::crash_dump_t crash_dump; ibex_top #( .PMPEnable ( PMPEnable ), @@ -560,21 +570,26 @@ module ${module_instance_name} .rvfi_mem_rdata, .rvfi_mem_wdata, // Unused ports from the RVFI interface - .rvfi_ext_pre_mip (), - .rvfi_ext_post_mip (), - .rvfi_ext_nmi (), - .rvfi_ext_nmi_int (), - .rvfi_ext_debug_req (), - .rvfi_ext_debug_mode (), - .rvfi_ext_rf_wr_suppress (), - .rvfi_ext_mcycle (), - .rvfi_ext_mhpmcounters (), - .rvfi_ext_mhpmcountersh (), - .rvfi_ext_ic_scr_key_valid(), - .rvfi_ext_irq_valid (), + .rvfi_ext_pre_mip (), + .rvfi_ext_post_mip (), + .rvfi_ext_nmi (), + .rvfi_ext_nmi_int (), + .rvfi_ext_debug_req (), + .rvfi_ext_debug_mode (), + .rvfi_ext_rf_wr_suppress (), + .rvfi_ext_mcycle (), + .rvfi_ext_minstret (), + .rvfi_ext_mhpmcounters (), + .rvfi_ext_mhpmcountersh (), + .rvfi_ext_ic_scr_key_valid (), + .rvfi_ext_irq_valid (), + .rvfi_ext_expanded_insn_valid(), + .rvfi_ext_expanded_insn (), + .rvfi_ext_expanded_insn_last (), `endif // SEC_CM: FETCH.CTRL.LC_GATED .fetch_enable_i (fetch_enable), + .mcounteren_writable_i (mcounteren_writable_ibex), .alert_minor_o (alert_minor), .alert_major_internal_o (alert_major_internal), .alert_major_bus_o (alert_major_bus), @@ -827,7 +842,9 @@ module ${module_instance_name} .rvfi_mem_rmask, .rvfi_mem_wmask, .rvfi_mem_rdata, - .rvfi_mem_wdata + .rvfi_mem_wdata, + .rvfi_ext_expanded_insn_valid, + .rvfi_ext_expanded_insn ); `endif @@ -1111,7 +1128,8 @@ module ${module_instance_name} assign unused_reg2hw_shadow = ^{reg2hw_shadow.alert_test, reg2hw_shadow.nmi_enable, reg2hw_shadow.nmi_state, reg2hw_shadow.rnd_data, - reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err}; + reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err, + reg2hw_shadow.mcounteren_writable}; ///////////////////////////////////////////////////////////////// // Shadow Core Data Address Translation Unit and TL-UL Adapter // diff --git a/hw/top_darjeeling/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson b/hw/top_darjeeling/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson index a7c976a7587a9..7693497078771 100644 --- a/hw/top_darjeeling/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson +++ b/hw/top_darjeeling/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson @@ -1098,6 +1098,47 @@ ] }, + { name: "MCOUNTEREN_WRITABLE_REGWEN", + desc: "Register write-enable for !!MCOUNTEREN_WRITABLE.", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1", + desc: "Write enable for !!MCOUNTEREN_WRITABLE. Once set to 0, it can no longer be configured to 1.", + enum: [ + { value: "0", + name: "locked", + desc: "MCOUNTEREN_WRITABLE can no longer be configured until next reset." + }, + { value: "1", + name: "enabled", + desc: "MCOUNTEREN_WRITABLE can still be configured." + }, + ] + }, + ], + }, + + { name: "MCOUNTEREN_WRITABLE", + desc: "Controls whether Ibex mcounteren CSR is writable by software.", + swaccess: "rw", + hwaccess: "hro", + regwen: "MCOUNTEREN_WRITABLE_REGWEN", + fields: [ + { bits: "3:0", + mubi: true, + name: "EN", + resval: true, + desc: ''' + When set to kMultiBitBool4True, the mcounteren CSR is writable by software. + Drives the mcounteren_writable_i input on ibex_top. + ''' + }, + ], + }, + // dv simulation window { window: { name: "DV_SIM_WINDOW", diff --git a/hw/top_darjeeling/ip_autogen/rv_core_ibex/doc/registers.md b/hw/top_darjeeling/ip_autogen/rv_core_ibex/doc/registers.md index bfe58a8122755..c491a6fb5798e 100644 --- a/hw/top_darjeeling/ip_autogen/rv_core_ibex/doc/registers.md +++ b/hw/top_darjeeling/ip_autogen/rv_core_ibex/doc/registers.md @@ -5,274 +5,276 @@ A number of memory-mapped registers are available to control Ibex-related functi ## Summary -| Name | Offset | Length | Description | -|:------------------------------------------------------------|:---------|---------:|:------------------------------------------------------------------------------| -| rv_core_ibex.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | -| rv_core_ibex.[`SW_RECOV_ERR`](#sw_recov_err) | 0x4 | 4 | Software recoverable error | -| rv_core_ibex.[`SW_FATAL_ERR`](#sw_fatal_err) | 0x8 | 4 | Software fatal error | -| rv_core_ibex.[`IBUS_REGWEN_0`](#ibus_regwen) | 0xc | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_1`](#ibus_regwen) | 0x10 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_2`](#ibus_regwen) | 0x14 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_3`](#ibus_regwen) | 0x18 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_4`](#ibus_regwen) | 0x1c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_5`](#ibus_regwen) | 0x20 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_6`](#ibus_regwen) | 0x24 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_7`](#ibus_regwen) | 0x28 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_8`](#ibus_regwen) | 0x2c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_9`](#ibus_regwen) | 0x30 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_10`](#ibus_regwen) | 0x34 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_11`](#ibus_regwen) | 0x38 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_12`](#ibus_regwen) | 0x3c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_13`](#ibus_regwen) | 0x40 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_14`](#ibus_regwen) | 0x44 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_15`](#ibus_regwen) | 0x48 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_16`](#ibus_regwen) | 0x4c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_17`](#ibus_regwen) | 0x50 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_18`](#ibus_regwen) | 0x54 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_19`](#ibus_regwen) | 0x58 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_20`](#ibus_regwen) | 0x5c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_21`](#ibus_regwen) | 0x60 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_22`](#ibus_regwen) | 0x64 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_23`](#ibus_regwen) | 0x68 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_24`](#ibus_regwen) | 0x6c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_25`](#ibus_regwen) | 0x70 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_26`](#ibus_regwen) | 0x74 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_27`](#ibus_regwen) | 0x78 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_28`](#ibus_regwen) | 0x7c | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_29`](#ibus_regwen) | 0x80 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_30`](#ibus_regwen) | 0x84 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_31`](#ibus_regwen) | 0x88 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_ADDR_EN_0`](#ibus_addr_en) | 0x8c | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_1`](#ibus_addr_en) | 0x90 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_2`](#ibus_addr_en) | 0x94 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_3`](#ibus_addr_en) | 0x98 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_4`](#ibus_addr_en) | 0x9c | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_5`](#ibus_addr_en) | 0xa0 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_6`](#ibus_addr_en) | 0xa4 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_7`](#ibus_addr_en) | 0xa8 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_8`](#ibus_addr_en) | 0xac | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_9`](#ibus_addr_en) | 0xb0 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_10`](#ibus_addr_en) | 0xb4 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_11`](#ibus_addr_en) | 0xb8 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_12`](#ibus_addr_en) | 0xbc | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_13`](#ibus_addr_en) | 0xc0 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_14`](#ibus_addr_en) | 0xc4 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_15`](#ibus_addr_en) | 0xc8 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_16`](#ibus_addr_en) | 0xcc | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_17`](#ibus_addr_en) | 0xd0 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_18`](#ibus_addr_en) | 0xd4 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_19`](#ibus_addr_en) | 0xd8 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_20`](#ibus_addr_en) | 0xdc | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_21`](#ibus_addr_en) | 0xe0 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_22`](#ibus_addr_en) | 0xe4 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_23`](#ibus_addr_en) | 0xe8 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_24`](#ibus_addr_en) | 0xec | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_25`](#ibus_addr_en) | 0xf0 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_26`](#ibus_addr_en) | 0xf4 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_27`](#ibus_addr_en) | 0xf8 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_28`](#ibus_addr_en) | 0xfc | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_29`](#ibus_addr_en) | 0x100 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_30`](#ibus_addr_en) | 0x104 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_31`](#ibus_addr_en) | 0x108 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching) | 0x10c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_1`](#ibus_addr_matching) | 0x110 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_2`](#ibus_addr_matching) | 0x114 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_3`](#ibus_addr_matching) | 0x118 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_4`](#ibus_addr_matching) | 0x11c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_5`](#ibus_addr_matching) | 0x120 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_6`](#ibus_addr_matching) | 0x124 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_7`](#ibus_addr_matching) | 0x128 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_8`](#ibus_addr_matching) | 0x12c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_9`](#ibus_addr_matching) | 0x130 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_10`](#ibus_addr_matching) | 0x134 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_11`](#ibus_addr_matching) | 0x138 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_12`](#ibus_addr_matching) | 0x13c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_13`](#ibus_addr_matching) | 0x140 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_14`](#ibus_addr_matching) | 0x144 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_15`](#ibus_addr_matching) | 0x148 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_16`](#ibus_addr_matching) | 0x14c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_17`](#ibus_addr_matching) | 0x150 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_18`](#ibus_addr_matching) | 0x154 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_19`](#ibus_addr_matching) | 0x158 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_20`](#ibus_addr_matching) | 0x15c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_21`](#ibus_addr_matching) | 0x160 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_22`](#ibus_addr_matching) | 0x164 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_23`](#ibus_addr_matching) | 0x168 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_24`](#ibus_addr_matching) | 0x16c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_25`](#ibus_addr_matching) | 0x170 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_26`](#ibus_addr_matching) | 0x174 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_27`](#ibus_addr_matching) | 0x178 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_28`](#ibus_addr_matching) | 0x17c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_29`](#ibus_addr_matching) | 0x180 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_30`](#ibus_addr_matching) | 0x184 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_31`](#ibus_addr_matching) | 0x188 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_0`](#ibus_remap_addr) | 0x18c | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_1`](#ibus_remap_addr) | 0x190 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_2`](#ibus_remap_addr) | 0x194 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_3`](#ibus_remap_addr) | 0x198 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_4`](#ibus_remap_addr) | 0x19c | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_5`](#ibus_remap_addr) | 0x1a0 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_6`](#ibus_remap_addr) | 0x1a4 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_7`](#ibus_remap_addr) | 0x1a8 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_8`](#ibus_remap_addr) | 0x1ac | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_9`](#ibus_remap_addr) | 0x1b0 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_10`](#ibus_remap_addr) | 0x1b4 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_11`](#ibus_remap_addr) | 0x1b8 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_12`](#ibus_remap_addr) | 0x1bc | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_13`](#ibus_remap_addr) | 0x1c0 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_14`](#ibus_remap_addr) | 0x1c4 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_15`](#ibus_remap_addr) | 0x1c8 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_16`](#ibus_remap_addr) | 0x1cc | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_17`](#ibus_remap_addr) | 0x1d0 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_18`](#ibus_remap_addr) | 0x1d4 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_19`](#ibus_remap_addr) | 0x1d8 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_20`](#ibus_remap_addr) | 0x1dc | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_21`](#ibus_remap_addr) | 0x1e0 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_22`](#ibus_remap_addr) | 0x1e4 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_23`](#ibus_remap_addr) | 0x1e8 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_24`](#ibus_remap_addr) | 0x1ec | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_25`](#ibus_remap_addr) | 0x1f0 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_26`](#ibus_remap_addr) | 0x1f4 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_27`](#ibus_remap_addr) | 0x1f8 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_28`](#ibus_remap_addr) | 0x1fc | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_29`](#ibus_remap_addr) | 0x200 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_30`](#ibus_remap_addr) | 0x204 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_31`](#ibus_remap_addr) | 0x208 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`DBUS_REGWEN_0`](#dbus_regwen) | 0x20c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_1`](#dbus_regwen) | 0x210 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_2`](#dbus_regwen) | 0x214 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_3`](#dbus_regwen) | 0x218 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_4`](#dbus_regwen) | 0x21c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_5`](#dbus_regwen) | 0x220 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_6`](#dbus_regwen) | 0x224 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_7`](#dbus_regwen) | 0x228 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_8`](#dbus_regwen) | 0x22c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_9`](#dbus_regwen) | 0x230 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_10`](#dbus_regwen) | 0x234 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_11`](#dbus_regwen) | 0x238 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_12`](#dbus_regwen) | 0x23c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_13`](#dbus_regwen) | 0x240 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_14`](#dbus_regwen) | 0x244 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_15`](#dbus_regwen) | 0x248 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_16`](#dbus_regwen) | 0x24c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_17`](#dbus_regwen) | 0x250 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_18`](#dbus_regwen) | 0x254 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_19`](#dbus_regwen) | 0x258 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_20`](#dbus_regwen) | 0x25c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_21`](#dbus_regwen) | 0x260 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_22`](#dbus_regwen) | 0x264 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_23`](#dbus_regwen) | 0x268 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_24`](#dbus_regwen) | 0x26c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_25`](#dbus_regwen) | 0x270 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_26`](#dbus_regwen) | 0x274 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_27`](#dbus_regwen) | 0x278 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_28`](#dbus_regwen) | 0x27c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_29`](#dbus_regwen) | 0x280 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_30`](#dbus_regwen) | 0x284 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_31`](#dbus_regwen) | 0x288 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_ADDR_EN_0`](#dbus_addr_en) | 0x28c | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_1`](#dbus_addr_en) | 0x290 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_2`](#dbus_addr_en) | 0x294 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_3`](#dbus_addr_en) | 0x298 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_4`](#dbus_addr_en) | 0x29c | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_5`](#dbus_addr_en) | 0x2a0 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_6`](#dbus_addr_en) | 0x2a4 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_7`](#dbus_addr_en) | 0x2a8 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_8`](#dbus_addr_en) | 0x2ac | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_9`](#dbus_addr_en) | 0x2b0 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_10`](#dbus_addr_en) | 0x2b4 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_11`](#dbus_addr_en) | 0x2b8 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_12`](#dbus_addr_en) | 0x2bc | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_13`](#dbus_addr_en) | 0x2c0 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_14`](#dbus_addr_en) | 0x2c4 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_15`](#dbus_addr_en) | 0x2c8 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_16`](#dbus_addr_en) | 0x2cc | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_17`](#dbus_addr_en) | 0x2d0 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_18`](#dbus_addr_en) | 0x2d4 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_19`](#dbus_addr_en) | 0x2d8 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_20`](#dbus_addr_en) | 0x2dc | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_21`](#dbus_addr_en) | 0x2e0 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_22`](#dbus_addr_en) | 0x2e4 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_23`](#dbus_addr_en) | 0x2e8 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_24`](#dbus_addr_en) | 0x2ec | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_25`](#dbus_addr_en) | 0x2f0 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_26`](#dbus_addr_en) | 0x2f4 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_27`](#dbus_addr_en) | 0x2f8 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_28`](#dbus_addr_en) | 0x2fc | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_29`](#dbus_addr_en) | 0x300 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_30`](#dbus_addr_en) | 0x304 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_31`](#dbus_addr_en) | 0x308 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_0`](#dbus_addr_matching) | 0x30c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_1`](#dbus_addr_matching) | 0x310 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_2`](#dbus_addr_matching) | 0x314 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_3`](#dbus_addr_matching) | 0x318 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_4`](#dbus_addr_matching) | 0x31c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_5`](#dbus_addr_matching) | 0x320 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_6`](#dbus_addr_matching) | 0x324 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_7`](#dbus_addr_matching) | 0x328 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_8`](#dbus_addr_matching) | 0x32c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_9`](#dbus_addr_matching) | 0x330 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_10`](#dbus_addr_matching) | 0x334 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_11`](#dbus_addr_matching) | 0x338 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_12`](#dbus_addr_matching) | 0x33c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_13`](#dbus_addr_matching) | 0x340 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_14`](#dbus_addr_matching) | 0x344 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_15`](#dbus_addr_matching) | 0x348 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_16`](#dbus_addr_matching) | 0x34c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_17`](#dbus_addr_matching) | 0x350 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_18`](#dbus_addr_matching) | 0x354 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_19`](#dbus_addr_matching) | 0x358 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_20`](#dbus_addr_matching) | 0x35c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_21`](#dbus_addr_matching) | 0x360 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_22`](#dbus_addr_matching) | 0x364 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_23`](#dbus_addr_matching) | 0x368 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_24`](#dbus_addr_matching) | 0x36c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_25`](#dbus_addr_matching) | 0x370 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_26`](#dbus_addr_matching) | 0x374 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_27`](#dbus_addr_matching) | 0x378 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_28`](#dbus_addr_matching) | 0x37c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_29`](#dbus_addr_matching) | 0x380 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_30`](#dbus_addr_matching) | 0x384 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_31`](#dbus_addr_matching) | 0x388 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_0`](#dbus_remap_addr) | 0x38c | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_1`](#dbus_remap_addr) | 0x390 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_2`](#dbus_remap_addr) | 0x394 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_3`](#dbus_remap_addr) | 0x398 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_4`](#dbus_remap_addr) | 0x39c | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_5`](#dbus_remap_addr) | 0x3a0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_6`](#dbus_remap_addr) | 0x3a4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_7`](#dbus_remap_addr) | 0x3a8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_8`](#dbus_remap_addr) | 0x3ac | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_9`](#dbus_remap_addr) | 0x3b0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_10`](#dbus_remap_addr) | 0x3b4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_11`](#dbus_remap_addr) | 0x3b8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_12`](#dbus_remap_addr) | 0x3bc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_13`](#dbus_remap_addr) | 0x3c0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_14`](#dbus_remap_addr) | 0x3c4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_15`](#dbus_remap_addr) | 0x3c8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_16`](#dbus_remap_addr) | 0x3cc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_17`](#dbus_remap_addr) | 0x3d0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_18`](#dbus_remap_addr) | 0x3d4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_19`](#dbus_remap_addr) | 0x3d8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_20`](#dbus_remap_addr) | 0x3dc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_21`](#dbus_remap_addr) | 0x3e0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_22`](#dbus_remap_addr) | 0x3e4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_23`](#dbus_remap_addr) | 0x3e8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_24`](#dbus_remap_addr) | 0x3ec | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_25`](#dbus_remap_addr) | 0x3f0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_26`](#dbus_remap_addr) | 0x3f4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_27`](#dbus_remap_addr) | 0x3f8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_28`](#dbus_remap_addr) | 0x3fc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_29`](#dbus_remap_addr) | 0x400 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_30`](#dbus_remap_addr) | 0x404 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_31`](#dbus_remap_addr) | 0x408 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`NMI_ENABLE`](#nmi_enable) | 0x40c | 4 | Enable mask for NMI. | -| rv_core_ibex.[`NMI_STATE`](#nmi_state) | 0x410 | 4 | Current NMI state | -| rv_core_ibex.[`ERR_STATUS`](#err_status) | 0x414 | 4 | error status | -| rv_core_ibex.[`RND_DATA`](#rnd_data) | 0x418 | 4 | Random data from EDN | -| rv_core_ibex.[`RND_STATUS`](#rnd_status) | 0x41c | 4 | Status of random data in [`RND_DATA`](#rnd_data) | -| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x420 | 4 | FPGA build timestamp info. | -| rv_core_ibex.[`DV_SIM_WINDOW`](#dv_sim_window) | 0x440 | 32 | Exposed tlul window for DV only purposes. | +| Name | Offset | Length | Description | +|:-------------------------------------------------------------------------|:---------|---------:|:------------------------------------------------------------------------------| +| rv_core_ibex.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | +| rv_core_ibex.[`SW_RECOV_ERR`](#sw_recov_err) | 0x4 | 4 | Software recoverable error | +| rv_core_ibex.[`SW_FATAL_ERR`](#sw_fatal_err) | 0x8 | 4 | Software fatal error | +| rv_core_ibex.[`IBUS_REGWEN_0`](#ibus_regwen) | 0xc | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_1`](#ibus_regwen) | 0x10 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_2`](#ibus_regwen) | 0x14 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_3`](#ibus_regwen) | 0x18 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_4`](#ibus_regwen) | 0x1c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_5`](#ibus_regwen) | 0x20 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_6`](#ibus_regwen) | 0x24 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_7`](#ibus_regwen) | 0x28 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_8`](#ibus_regwen) | 0x2c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_9`](#ibus_regwen) | 0x30 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_10`](#ibus_regwen) | 0x34 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_11`](#ibus_regwen) | 0x38 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_12`](#ibus_regwen) | 0x3c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_13`](#ibus_regwen) | 0x40 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_14`](#ibus_regwen) | 0x44 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_15`](#ibus_regwen) | 0x48 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_16`](#ibus_regwen) | 0x4c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_17`](#ibus_regwen) | 0x50 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_18`](#ibus_regwen) | 0x54 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_19`](#ibus_regwen) | 0x58 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_20`](#ibus_regwen) | 0x5c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_21`](#ibus_regwen) | 0x60 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_22`](#ibus_regwen) | 0x64 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_23`](#ibus_regwen) | 0x68 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_24`](#ibus_regwen) | 0x6c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_25`](#ibus_regwen) | 0x70 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_26`](#ibus_regwen) | 0x74 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_27`](#ibus_regwen) | 0x78 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_28`](#ibus_regwen) | 0x7c | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_29`](#ibus_regwen) | 0x80 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_30`](#ibus_regwen) | 0x84 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_31`](#ibus_regwen) | 0x88 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_ADDR_EN_0`](#ibus_addr_en) | 0x8c | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_1`](#ibus_addr_en) | 0x90 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_2`](#ibus_addr_en) | 0x94 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_3`](#ibus_addr_en) | 0x98 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_4`](#ibus_addr_en) | 0x9c | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_5`](#ibus_addr_en) | 0xa0 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_6`](#ibus_addr_en) | 0xa4 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_7`](#ibus_addr_en) | 0xa8 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_8`](#ibus_addr_en) | 0xac | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_9`](#ibus_addr_en) | 0xb0 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_10`](#ibus_addr_en) | 0xb4 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_11`](#ibus_addr_en) | 0xb8 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_12`](#ibus_addr_en) | 0xbc | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_13`](#ibus_addr_en) | 0xc0 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_14`](#ibus_addr_en) | 0xc4 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_15`](#ibus_addr_en) | 0xc8 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_16`](#ibus_addr_en) | 0xcc | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_17`](#ibus_addr_en) | 0xd0 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_18`](#ibus_addr_en) | 0xd4 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_19`](#ibus_addr_en) | 0xd8 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_20`](#ibus_addr_en) | 0xdc | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_21`](#ibus_addr_en) | 0xe0 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_22`](#ibus_addr_en) | 0xe4 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_23`](#ibus_addr_en) | 0xe8 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_24`](#ibus_addr_en) | 0xec | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_25`](#ibus_addr_en) | 0xf0 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_26`](#ibus_addr_en) | 0xf4 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_27`](#ibus_addr_en) | 0xf8 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_28`](#ibus_addr_en) | 0xfc | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_29`](#ibus_addr_en) | 0x100 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_30`](#ibus_addr_en) | 0x104 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_31`](#ibus_addr_en) | 0x108 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching) | 0x10c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_1`](#ibus_addr_matching) | 0x110 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_2`](#ibus_addr_matching) | 0x114 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_3`](#ibus_addr_matching) | 0x118 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_4`](#ibus_addr_matching) | 0x11c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_5`](#ibus_addr_matching) | 0x120 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_6`](#ibus_addr_matching) | 0x124 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_7`](#ibus_addr_matching) | 0x128 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_8`](#ibus_addr_matching) | 0x12c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_9`](#ibus_addr_matching) | 0x130 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_10`](#ibus_addr_matching) | 0x134 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_11`](#ibus_addr_matching) | 0x138 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_12`](#ibus_addr_matching) | 0x13c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_13`](#ibus_addr_matching) | 0x140 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_14`](#ibus_addr_matching) | 0x144 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_15`](#ibus_addr_matching) | 0x148 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_16`](#ibus_addr_matching) | 0x14c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_17`](#ibus_addr_matching) | 0x150 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_18`](#ibus_addr_matching) | 0x154 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_19`](#ibus_addr_matching) | 0x158 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_20`](#ibus_addr_matching) | 0x15c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_21`](#ibus_addr_matching) | 0x160 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_22`](#ibus_addr_matching) | 0x164 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_23`](#ibus_addr_matching) | 0x168 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_24`](#ibus_addr_matching) | 0x16c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_25`](#ibus_addr_matching) | 0x170 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_26`](#ibus_addr_matching) | 0x174 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_27`](#ibus_addr_matching) | 0x178 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_28`](#ibus_addr_matching) | 0x17c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_29`](#ibus_addr_matching) | 0x180 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_30`](#ibus_addr_matching) | 0x184 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_31`](#ibus_addr_matching) | 0x188 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_0`](#ibus_remap_addr) | 0x18c | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_1`](#ibus_remap_addr) | 0x190 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_2`](#ibus_remap_addr) | 0x194 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_3`](#ibus_remap_addr) | 0x198 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_4`](#ibus_remap_addr) | 0x19c | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_5`](#ibus_remap_addr) | 0x1a0 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_6`](#ibus_remap_addr) | 0x1a4 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_7`](#ibus_remap_addr) | 0x1a8 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_8`](#ibus_remap_addr) | 0x1ac | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_9`](#ibus_remap_addr) | 0x1b0 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_10`](#ibus_remap_addr) | 0x1b4 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_11`](#ibus_remap_addr) | 0x1b8 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_12`](#ibus_remap_addr) | 0x1bc | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_13`](#ibus_remap_addr) | 0x1c0 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_14`](#ibus_remap_addr) | 0x1c4 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_15`](#ibus_remap_addr) | 0x1c8 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_16`](#ibus_remap_addr) | 0x1cc | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_17`](#ibus_remap_addr) | 0x1d0 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_18`](#ibus_remap_addr) | 0x1d4 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_19`](#ibus_remap_addr) | 0x1d8 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_20`](#ibus_remap_addr) | 0x1dc | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_21`](#ibus_remap_addr) | 0x1e0 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_22`](#ibus_remap_addr) | 0x1e4 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_23`](#ibus_remap_addr) | 0x1e8 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_24`](#ibus_remap_addr) | 0x1ec | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_25`](#ibus_remap_addr) | 0x1f0 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_26`](#ibus_remap_addr) | 0x1f4 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_27`](#ibus_remap_addr) | 0x1f8 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_28`](#ibus_remap_addr) | 0x1fc | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_29`](#ibus_remap_addr) | 0x200 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_30`](#ibus_remap_addr) | 0x204 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_31`](#ibus_remap_addr) | 0x208 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`DBUS_REGWEN_0`](#dbus_regwen) | 0x20c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_1`](#dbus_regwen) | 0x210 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_2`](#dbus_regwen) | 0x214 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_3`](#dbus_regwen) | 0x218 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_4`](#dbus_regwen) | 0x21c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_5`](#dbus_regwen) | 0x220 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_6`](#dbus_regwen) | 0x224 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_7`](#dbus_regwen) | 0x228 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_8`](#dbus_regwen) | 0x22c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_9`](#dbus_regwen) | 0x230 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_10`](#dbus_regwen) | 0x234 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_11`](#dbus_regwen) | 0x238 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_12`](#dbus_regwen) | 0x23c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_13`](#dbus_regwen) | 0x240 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_14`](#dbus_regwen) | 0x244 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_15`](#dbus_regwen) | 0x248 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_16`](#dbus_regwen) | 0x24c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_17`](#dbus_regwen) | 0x250 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_18`](#dbus_regwen) | 0x254 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_19`](#dbus_regwen) | 0x258 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_20`](#dbus_regwen) | 0x25c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_21`](#dbus_regwen) | 0x260 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_22`](#dbus_regwen) | 0x264 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_23`](#dbus_regwen) | 0x268 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_24`](#dbus_regwen) | 0x26c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_25`](#dbus_regwen) | 0x270 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_26`](#dbus_regwen) | 0x274 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_27`](#dbus_regwen) | 0x278 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_28`](#dbus_regwen) | 0x27c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_29`](#dbus_regwen) | 0x280 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_30`](#dbus_regwen) | 0x284 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_31`](#dbus_regwen) | 0x288 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_ADDR_EN_0`](#dbus_addr_en) | 0x28c | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_1`](#dbus_addr_en) | 0x290 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_2`](#dbus_addr_en) | 0x294 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_3`](#dbus_addr_en) | 0x298 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_4`](#dbus_addr_en) | 0x29c | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_5`](#dbus_addr_en) | 0x2a0 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_6`](#dbus_addr_en) | 0x2a4 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_7`](#dbus_addr_en) | 0x2a8 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_8`](#dbus_addr_en) | 0x2ac | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_9`](#dbus_addr_en) | 0x2b0 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_10`](#dbus_addr_en) | 0x2b4 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_11`](#dbus_addr_en) | 0x2b8 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_12`](#dbus_addr_en) | 0x2bc | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_13`](#dbus_addr_en) | 0x2c0 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_14`](#dbus_addr_en) | 0x2c4 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_15`](#dbus_addr_en) | 0x2c8 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_16`](#dbus_addr_en) | 0x2cc | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_17`](#dbus_addr_en) | 0x2d0 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_18`](#dbus_addr_en) | 0x2d4 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_19`](#dbus_addr_en) | 0x2d8 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_20`](#dbus_addr_en) | 0x2dc | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_21`](#dbus_addr_en) | 0x2e0 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_22`](#dbus_addr_en) | 0x2e4 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_23`](#dbus_addr_en) | 0x2e8 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_24`](#dbus_addr_en) | 0x2ec | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_25`](#dbus_addr_en) | 0x2f0 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_26`](#dbus_addr_en) | 0x2f4 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_27`](#dbus_addr_en) | 0x2f8 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_28`](#dbus_addr_en) | 0x2fc | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_29`](#dbus_addr_en) | 0x300 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_30`](#dbus_addr_en) | 0x304 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_31`](#dbus_addr_en) | 0x308 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_0`](#dbus_addr_matching) | 0x30c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_1`](#dbus_addr_matching) | 0x310 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_2`](#dbus_addr_matching) | 0x314 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_3`](#dbus_addr_matching) | 0x318 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_4`](#dbus_addr_matching) | 0x31c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_5`](#dbus_addr_matching) | 0x320 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_6`](#dbus_addr_matching) | 0x324 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_7`](#dbus_addr_matching) | 0x328 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_8`](#dbus_addr_matching) | 0x32c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_9`](#dbus_addr_matching) | 0x330 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_10`](#dbus_addr_matching) | 0x334 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_11`](#dbus_addr_matching) | 0x338 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_12`](#dbus_addr_matching) | 0x33c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_13`](#dbus_addr_matching) | 0x340 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_14`](#dbus_addr_matching) | 0x344 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_15`](#dbus_addr_matching) | 0x348 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_16`](#dbus_addr_matching) | 0x34c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_17`](#dbus_addr_matching) | 0x350 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_18`](#dbus_addr_matching) | 0x354 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_19`](#dbus_addr_matching) | 0x358 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_20`](#dbus_addr_matching) | 0x35c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_21`](#dbus_addr_matching) | 0x360 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_22`](#dbus_addr_matching) | 0x364 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_23`](#dbus_addr_matching) | 0x368 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_24`](#dbus_addr_matching) | 0x36c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_25`](#dbus_addr_matching) | 0x370 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_26`](#dbus_addr_matching) | 0x374 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_27`](#dbus_addr_matching) | 0x378 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_28`](#dbus_addr_matching) | 0x37c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_29`](#dbus_addr_matching) | 0x380 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_30`](#dbus_addr_matching) | 0x384 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_31`](#dbus_addr_matching) | 0x388 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_0`](#dbus_remap_addr) | 0x38c | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_1`](#dbus_remap_addr) | 0x390 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_2`](#dbus_remap_addr) | 0x394 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_3`](#dbus_remap_addr) | 0x398 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_4`](#dbus_remap_addr) | 0x39c | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_5`](#dbus_remap_addr) | 0x3a0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_6`](#dbus_remap_addr) | 0x3a4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_7`](#dbus_remap_addr) | 0x3a8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_8`](#dbus_remap_addr) | 0x3ac | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_9`](#dbus_remap_addr) | 0x3b0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_10`](#dbus_remap_addr) | 0x3b4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_11`](#dbus_remap_addr) | 0x3b8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_12`](#dbus_remap_addr) | 0x3bc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_13`](#dbus_remap_addr) | 0x3c0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_14`](#dbus_remap_addr) | 0x3c4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_15`](#dbus_remap_addr) | 0x3c8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_16`](#dbus_remap_addr) | 0x3cc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_17`](#dbus_remap_addr) | 0x3d0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_18`](#dbus_remap_addr) | 0x3d4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_19`](#dbus_remap_addr) | 0x3d8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_20`](#dbus_remap_addr) | 0x3dc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_21`](#dbus_remap_addr) | 0x3e0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_22`](#dbus_remap_addr) | 0x3e4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_23`](#dbus_remap_addr) | 0x3e8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_24`](#dbus_remap_addr) | 0x3ec | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_25`](#dbus_remap_addr) | 0x3f0 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_26`](#dbus_remap_addr) | 0x3f4 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_27`](#dbus_remap_addr) | 0x3f8 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_28`](#dbus_remap_addr) | 0x3fc | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_29`](#dbus_remap_addr) | 0x400 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_30`](#dbus_remap_addr) | 0x404 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_31`](#dbus_remap_addr) | 0x408 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`NMI_ENABLE`](#nmi_enable) | 0x40c | 4 | Enable mask for NMI. | +| rv_core_ibex.[`NMI_STATE`](#nmi_state) | 0x410 | 4 | Current NMI state | +| rv_core_ibex.[`ERR_STATUS`](#err_status) | 0x414 | 4 | error status | +| rv_core_ibex.[`RND_DATA`](#rnd_data) | 0x418 | 4 | Random data from EDN | +| rv_core_ibex.[`RND_STATUS`](#rnd_status) | 0x41c | 4 | Status of random data in [`RND_DATA`](#rnd_data) | +| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x420 | 4 | FPGA build timestamp info. | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) | 0x424 | 4 | Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE`](#mcounteren_writable) | 0x428 | 4 | Controls whether Ibex mcounteren CSR is writable by software. | +| rv_core_ibex.[`DV_SIM_WINDOW`](#dv_sim_window) | 0x440 | 32 | Exposed tlul window for DV only purposes. | ## ALERT_TEST Alert Test Register @@ -916,6 +918,50 @@ This register only contains valid data for fpga, for all other variants it is si |:------:|:------:|:-------:|:-------|:----------------------------------| | 31:0 | ro | 0x0 | VAL | FPGA build timestamp information. | +## MCOUNTEREN_WRITABLE_REGWEN +Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) +- Offset: `0x424` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [EN](#mcounteren_writable_regwen--en) | + +### MCOUNTEREN_WRITABLE_REGWEN . EN +Write enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) Once set to 0, it can no longer be configured to 1. + +| Value | Name | Description | +|:--------|:--------|:------------------------------------------------------------------| +| 0x0 | locked | MCOUNTEREN_WRITABLE can no longer be configured until next reset. | +| 0x1 | enabled | MCOUNTEREN_WRITABLE can still be configured. | + + +## MCOUNTEREN_WRITABLE +Controls whether Ibex mcounteren CSR is writable by software. +- Offset: `0x428` +- Reset default: `0x6` +- Reset mask: `0xf` +- Register enable: [`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------------------------------------------------------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x6 | EN | When set to kMultiBitBool4True, the mcounteren CSR is writable by software. Drives the mcounteren_writable_i input on ibex_top. | + ## DV_SIM_WINDOW Exposed tlul window for DV only purposes. diff --git a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv index 549e537dfc438..6e5af27ab185d 100644 --- a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv +++ b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv @@ -224,6 +224,8 @@ module rv_core_ibex logic [ 3:0] rvfi_mem_wmask; logic [31:0] rvfi_mem_rdata; logic [31:0] rvfi_mem_wdata; + logic rvfi_ext_expanded_insn_valid; + logic [15:0] rvfi_ext_expanded_insn; `endif import tlul_pkg::tl_h2d_t; @@ -420,6 +422,14 @@ module rv_core_ibex lc_ctrl_pkg::lc_tx_and_hi(lc_cpu_en[0], pwrmgr_cpu_en[0])); + prim_mubi_pkg::mubi4_t mcounteren_writable_mubi4; + ibex_pkg::ibex_mubi_t mcounteren_writable_ibex; + assign mcounteren_writable_mubi4 = prim_mubi_pkg::mubi4_t'(reg2hw.mcounteren_writable.q); + // Convert the mubi4 to ibex_mubi. They are both four bit, but with different encodings. + // This conversion should be a simple wire crossing. + assign mcounteren_writable_ibex = mcounteren_writable_mubi4 == prim_mubi_pkg::MuBi4True ? + ibex_pkg::IbexMuBiOn : ibex_pkg::IbexMuBiOff; + ibex_pkg::crash_dump_t crash_dump; ibex_top #( .PMPEnable ( PMPEnable ), @@ -547,21 +557,26 @@ module rv_core_ibex .rvfi_mem_rdata, .rvfi_mem_wdata, // Unused ports from the RVFI interface - .rvfi_ext_pre_mip (), - .rvfi_ext_post_mip (), - .rvfi_ext_nmi (), - .rvfi_ext_nmi_int (), - .rvfi_ext_debug_req (), - .rvfi_ext_debug_mode (), - .rvfi_ext_rf_wr_suppress (), - .rvfi_ext_mcycle (), - .rvfi_ext_mhpmcounters (), - .rvfi_ext_mhpmcountersh (), - .rvfi_ext_ic_scr_key_valid(), - .rvfi_ext_irq_valid (), + .rvfi_ext_pre_mip (), + .rvfi_ext_post_mip (), + .rvfi_ext_nmi (), + .rvfi_ext_nmi_int (), + .rvfi_ext_debug_req (), + .rvfi_ext_debug_mode (), + .rvfi_ext_rf_wr_suppress (), + .rvfi_ext_mcycle (), + .rvfi_ext_minstret (), + .rvfi_ext_mhpmcounters (), + .rvfi_ext_mhpmcountersh (), + .rvfi_ext_ic_scr_key_valid (), + .rvfi_ext_irq_valid (), + .rvfi_ext_expanded_insn_valid(), + .rvfi_ext_expanded_insn (), + .rvfi_ext_expanded_insn_last (), `endif // SEC_CM: FETCH.CTRL.LC_GATED .fetch_enable_i (fetch_enable), + .mcounteren_writable_i (mcounteren_writable_ibex), .alert_minor_o (alert_minor), .alert_major_internal_o (alert_major_internal), .alert_major_bus_o (alert_major_bus), @@ -814,7 +829,9 @@ module rv_core_ibex .rvfi_mem_rmask, .rvfi_mem_wmask, .rvfi_mem_rdata, - .rvfi_mem_wdata + .rvfi_mem_wdata, + .rvfi_ext_expanded_insn_valid, + .rvfi_ext_expanded_insn ); `endif @@ -1086,7 +1103,8 @@ module rv_core_ibex assign unused_reg2hw_shadow = ^{reg2hw_shadow.alert_test, reg2hw_shadow.nmi_enable, reg2hw_shadow.nmi_state, reg2hw_shadow.rnd_data, - reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err}; + reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err, + reg2hw_shadow.mcounteren_writable}; ///////////////////////////////////////////////////////////////// // Shadow Core Data Address Translation Unit and TL-UL Adapter // diff --git a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv index f83c4364799c7..d7a4734b070cb 100644 --- a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv +++ b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv @@ -57,9 +57,9 @@ module rv_core_ibex_cfg_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [264:0] reg_we_check; + logic [266:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(265) + .OneHotWidth(267) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -975,6 +975,12 @@ module rv_core_ibex_cfg_reg_top ( logic rnd_status_rnd_data_fips_qs; logic fpga_info_re; logic [31:0] fpga_info_qs; + logic mcounteren_writable_regwen_we; + logic mcounteren_writable_regwen_qs; + logic mcounteren_writable_regwen_wd; + logic mcounteren_writable_we; + logic [3:0] mcounteren_writable_qs; + logic [3:0] mcounteren_writable_wd; // Register instances // R[alert_test]: V(True) @@ -11692,8 +11698,67 @@ module rv_core_ibex_cfg_reg_top ( ); + // R[mcounteren_writable_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mcounteren_writable_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mcounteren_writable_regwen_we), + .wd (mcounteren_writable_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), - logic [264:0] addr_hit; + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mcounteren_writable_regwen_qs) + ); + + + // R[mcounteren_writable]: V(False) + // Create REGWEN-gated WE signal + logic mcounteren_writable_gated_we; + assign mcounteren_writable_gated_we = mcounteren_writable_we & mcounteren_writable_regwen_qs; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h6), + .Mubi (1'b1) + ) u_mcounteren_writable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mcounteren_writable_gated_we), + .wd (mcounteren_writable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mcounteren_writable.q), + .ds (), + + // to register interface (read) + .qs (mcounteren_writable_qs) + ); + + + + logic [266:0] addr_hit; always_comb begin addr_hit[ 0] = (reg_addr == RV_CORE_IBEX_ALERT_TEST_OFFSET); addr_hit[ 1] = (reg_addr == RV_CORE_IBEX_SW_RECOV_ERR_OFFSET); @@ -11960,6 +12025,8 @@ module rv_core_ibex_cfg_reg_top ( addr_hit[262] = (reg_addr == RV_CORE_IBEX_RND_DATA_OFFSET); addr_hit[263] = (reg_addr == RV_CORE_IBEX_RND_STATUS_OFFSET); addr_hit[264] = (reg_addr == RV_CORE_IBEX_FPGA_INFO_OFFSET); + addr_hit[265] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET); + addr_hit[266] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -12231,7 +12298,9 @@ module rv_core_ibex_cfg_reg_top ( (addr_hit[261] & (|(RV_CORE_IBEX_CFG_PERMIT[261] & ~reg_be))) | (addr_hit[262] & (|(RV_CORE_IBEX_CFG_PERMIT[262] & ~reg_be))) | (addr_hit[263] & (|(RV_CORE_IBEX_CFG_PERMIT[263] & ~reg_be))) | - (addr_hit[264] & (|(RV_CORE_IBEX_CFG_PERMIT[264] & ~reg_be))))); + (addr_hit[264] & (|(RV_CORE_IBEX_CFG_PERMIT[264] & ~reg_be))) | + (addr_hit[265] & (|(RV_CORE_IBEX_CFG_PERMIT[265] & ~reg_be))) | + (addr_hit[266] & (|(RV_CORE_IBEX_CFG_PERMIT[266] & ~reg_be))))); end // Generate write-enables @@ -13040,6 +13109,12 @@ module rv_core_ibex_cfg_reg_top ( assign rnd_data_re = addr_hit[262] & reg_re & !reg_error; assign rnd_status_re = addr_hit[263] & reg_re & !reg_error; assign fpga_info_re = addr_hit[264] & reg_re & !reg_error; + assign mcounteren_writable_regwen_we = addr_hit[265] & reg_we & !reg_error; + + assign mcounteren_writable_regwen_wd = reg_wdata[0]; + assign mcounteren_writable_we = addr_hit[266] & reg_we & !reg_error; + + assign mcounteren_writable_wd = reg_wdata[3:0]; // Assign write-enables to checker logic vector. always_comb begin @@ -13308,6 +13383,8 @@ module rv_core_ibex_cfg_reg_top ( reg_we_check[262] = 1'b0; reg_we_check[263] = 1'b0; reg_we_check[264] = 1'b0; + reg_we_check[265] = mcounteren_writable_regwen_we; + reg_we_check[266] = mcounteren_writable_gated_we; end // Read data return @@ -14383,6 +14460,14 @@ module rv_core_ibex_cfg_reg_top ( reg_rdata_next[31:0] = fpga_info_qs; end + addr_hit[265]: begin + reg_rdata_next[0] = mcounteren_writable_regwen_qs; + end + + addr_hit[266]: begin + reg_rdata_next[3:0] = mcounteren_writable_qs; + end + default: begin reg_rdata_next = '1; end diff --git a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv index 136b23b8acdce..9506730750015 100644 --- a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv +++ b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv @@ -16,7 +16,7 @@ package rv_core_ibex_reg_pkg; parameter int CfgAw = 11; // Number of registers for every interface - parameter int NumRegsCfg = 265; + parameter int NumRegsCfg = 267; // Alert indices typedef enum int { @@ -110,6 +110,10 @@ package rv_core_ibex_reg_pkg; logic re; } rv_core_ibex_reg2hw_rnd_data_reg_t; + typedef struct packed { + logic [3:0] q; + } rv_core_ibex_reg2hw_mcounteren_writable_reg_t; + typedef struct packed { logic [3:0] d; logic de; @@ -164,18 +168,19 @@ package rv_core_ibex_reg_pkg; // Register -> HW type for cfg interface typedef struct packed { - rv_core_ibex_reg2hw_alert_test_reg_t alert_test; // [4404:4397] - rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [4396:4393] - rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [4392:4389] - rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [31:0] ibus_addr_en; // [4388:4325] - rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [31:0] ibus_addr_matching; // [4324:3269] - rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [31:0] ibus_remap_addr; // [3268:2213] - rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [31:0] dbus_addr_en; // [2212:2149] - rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [31:0] dbus_addr_matching; // [2148:1093] - rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [31:0] dbus_remap_addr; // [1092:37] - rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [36:35] - rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [34:33] - rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [32:0] + rv_core_ibex_reg2hw_alert_test_reg_t alert_test; // [4408:4401] + rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [4400:4397] + rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [4396:4393] + rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [31:0] ibus_addr_en; // [4392:4329] + rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [31:0] ibus_addr_matching; // [4328:3273] + rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [31:0] ibus_remap_addr; // [3272:2217] + rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [31:0] dbus_addr_en; // [2216:2153] + rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [31:0] dbus_addr_matching; // [2152:1097] + rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [31:0] dbus_remap_addr; // [1096:41] + rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [40:39] + rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [38:37] + rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [36:4] + rv_core_ibex_reg2hw_mcounteren_writable_reg_t mcounteren_writable; // [3:0] } rv_core_ibex_cfg_reg2hw_t; // HW -> register type for cfg interface @@ -454,6 +459,8 @@ package rv_core_ibex_reg_pkg; parameter logic [CfgAw-1:0] RV_CORE_IBEX_RND_DATA_OFFSET = 11'h 418; parameter logic [CfgAw-1:0] RV_CORE_IBEX_RND_STATUS_OFFSET = 11'h 41c; parameter logic [CfgAw-1:0] RV_CORE_IBEX_FPGA_INFO_OFFSET = 11'h 420; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET = 11'h 424; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET = 11'h 428; // Reset values for hwext registers and their fields for cfg interface parameter logic [3:0] RV_CORE_IBEX_ALERT_TEST_RESVAL = 4'h 0; @@ -740,11 +747,13 @@ package rv_core_ibex_reg_pkg; RV_CORE_IBEX_ERR_STATUS, RV_CORE_IBEX_RND_DATA, RV_CORE_IBEX_RND_STATUS, - RV_CORE_IBEX_FPGA_INFO + RV_CORE_IBEX_FPGA_INFO, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE } rv_core_ibex_cfg_id_e; // Register width information to check illegal writes for cfg interface - parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [265] = '{ + parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [267] = '{ 4'b 0001, // index[ 0] RV_CORE_IBEX_ALERT_TEST 4'b 0001, // index[ 1] RV_CORE_IBEX_SW_RECOV_ERR 4'b 0001, // index[ 2] RV_CORE_IBEX_SW_FATAL_ERR @@ -1009,7 +1018,9 @@ package rv_core_ibex_reg_pkg; 4'b 0011, // index[261] RV_CORE_IBEX_ERR_STATUS 4'b 1111, // index[262] RV_CORE_IBEX_RND_DATA 4'b 0001, // index[263] RV_CORE_IBEX_RND_STATUS - 4'b 1111 // index[264] RV_CORE_IBEX_FPGA_INFO + 4'b 1111, // index[264] RV_CORE_IBEX_FPGA_INFO + 4'b 0001, // index[265] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN + 4'b 0001 // index[266] RV_CORE_IBEX_MCOUNTEREN_WRITABLE }; endpackage diff --git a/hw/top_earlgrey/data/ip/chip_rv_core_ibex_testplan.hjson b/hw/top_earlgrey/data/ip/chip_rv_core_ibex_testplan.hjson index 4660d7867f390..d6bb6a3371413 100644 --- a/hw/top_earlgrey/data/ip/chip_rv_core_ibex_testplan.hjson +++ b/hw/top_earlgrey/data/ip/chip_rv_core_ibex_testplan.hjson @@ -226,6 +226,16 @@ tests: ["chip_sw_rv_core_ibex_lockstep_glitch"] bazel: [] } + { + name: chip_sw_rv_core_ibex_mcounteren_writable + desc: '''Verifies that the mcounteren_writable register is lockable. + ''' + stage: V2 + si_stage: SV1 + lc_states: ["PROD"] + tests: ["chip_sw_rv_core_ibex_mcounteren_writable"] + bazel: ["//sw/device/tests:rv_core_ibex_mcounteren_writable_test"] + } { name: chip_sw_rv_core_ibex_alerts desc: '''Inject and verify all available faults in rv_core_ibex / ibex_top. diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index f89efcc9d156d..c350b2818a9ae 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -2047,6 +2047,13 @@ sw_images: ["//sw/device/tests:rv_core_ibex_icache_invalidate_test:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } + { + name: chip_sw_rv_core_ibex_mcounteren_writable + uvm_test_seq: chip_sw_base_vseq + sw_images: ["//sw/device/tests:rv_core_ibex_mcounteren_writable_test:1:new_rules"] + en_run_modes: ["sw_test_mode_test_rom"] + run_opts: ["+sw_test_timeout_ns=7_000_000"] + } { name: chip_sw_usb_ast_clk_calib uvm_test_seq: "chip_sw_usb_ast_clk_calib_vseq" diff --git a/hw/top_earlgrey/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson b/hw/top_earlgrey/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson index ce77f3dade637..4670c106d457a 100644 --- a/hw/top_earlgrey/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson +++ b/hw/top_earlgrey/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson @@ -1098,6 +1098,47 @@ ] }, + { name: "MCOUNTEREN_WRITABLE_REGWEN", + desc: "Register write-enable for !!MCOUNTEREN_WRITABLE.", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1", + desc: "Write enable for !!MCOUNTEREN_WRITABLE. Once set to 0, it can no longer be configured to 1.", + enum: [ + { value: "0", + name: "locked", + desc: "MCOUNTEREN_WRITABLE can no longer be configured until next reset." + }, + { value: "1", + name: "enabled", + desc: "MCOUNTEREN_WRITABLE can still be configured." + }, + ] + }, + ], + }, + + { name: "MCOUNTEREN_WRITABLE", + desc: "Controls whether Ibex mcounteren CSR is writable by software.", + swaccess: "rw", + hwaccess: "hro", + regwen: "MCOUNTEREN_WRITABLE_REGWEN", + fields: [ + { bits: "3:0", + mubi: true, + name: "EN", + resval: true, + desc: ''' + When set to kMultiBitBool4True, the mcounteren CSR is writable by software. + Drives the mcounteren_writable_i input on ibex_top. + ''' + }, + ], + }, + // dv simulation window { window: { name: "DV_SIM_WINDOW", diff --git a/hw/top_earlgrey/ip_autogen/rv_core_ibex/doc/registers.md b/hw/top_earlgrey/ip_autogen/rv_core_ibex/doc/registers.md index 8d6076b1e434a..88fe348c9837f 100644 --- a/hw/top_earlgrey/ip_autogen/rv_core_ibex/doc/registers.md +++ b/hw/top_earlgrey/ip_autogen/rv_core_ibex/doc/registers.md @@ -5,34 +5,36 @@ A number of memory-mapped registers are available to control Ibex-related functi ## Summary -| Name | Offset | Length | Description | -|:-----------------------------------------------------------|:---------|---------:|:------------------------------------------------------------------------------| -| rv_core_ibex.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | -| rv_core_ibex.[`SW_RECOV_ERR`](#sw_recov_err) | 0x4 | 4 | Software recoverable error | -| rv_core_ibex.[`SW_FATAL_ERR`](#sw_fatal_err) | 0x8 | 4 | Software fatal error | -| rv_core_ibex.[`IBUS_REGWEN_0`](#ibus_regwen) | 0xc | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_1`](#ibus_regwen) | 0x10 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_ADDR_EN_0`](#ibus_addr_en) | 0x14 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_1`](#ibus_addr_en) | 0x18 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching) | 0x1c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_1`](#ibus_addr_matching) | 0x20 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_0`](#ibus_remap_addr) | 0x24 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_1`](#ibus_remap_addr) | 0x28 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`DBUS_REGWEN_0`](#dbus_regwen) | 0x2c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_1`](#dbus_regwen) | 0x30 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_ADDR_EN_0`](#dbus_addr_en) | 0x34 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_1`](#dbus_addr_en) | 0x38 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_0`](#dbus_addr_matching) | 0x3c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_1`](#dbus_addr_matching) | 0x40 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_0`](#dbus_remap_addr) | 0x44 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_1`](#dbus_remap_addr) | 0x48 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`NMI_ENABLE`](#nmi_enable) | 0x4c | 4 | Enable mask for NMI. | -| rv_core_ibex.[`NMI_STATE`](#nmi_state) | 0x50 | 4 | Current NMI state | -| rv_core_ibex.[`ERR_STATUS`](#err_status) | 0x54 | 4 | error status | -| rv_core_ibex.[`RND_DATA`](#rnd_data) | 0x58 | 4 | Random data from EDN | -| rv_core_ibex.[`RND_STATUS`](#rnd_status) | 0x5c | 4 | Status of random data in [`RND_DATA`](#rnd_data) | -| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x60 | 4 | FPGA build timestamp info. | -| rv_core_ibex.[`DV_SIM_WINDOW`](#dv_sim_window) | 0x80 | 32 | Exposed tlul window for DV only purposes. | +| Name | Offset | Length | Description | +|:-------------------------------------------------------------------------|:---------|---------:|:------------------------------------------------------------------------------| +| rv_core_ibex.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | +| rv_core_ibex.[`SW_RECOV_ERR`](#sw_recov_err) | 0x4 | 4 | Software recoverable error | +| rv_core_ibex.[`SW_FATAL_ERR`](#sw_fatal_err) | 0x8 | 4 | Software fatal error | +| rv_core_ibex.[`IBUS_REGWEN_0`](#ibus_regwen) | 0xc | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_1`](#ibus_regwen) | 0x10 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_ADDR_EN_0`](#ibus_addr_en) | 0x14 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_1`](#ibus_addr_en) | 0x18 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching) | 0x1c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_1`](#ibus_addr_matching) | 0x20 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_0`](#ibus_remap_addr) | 0x24 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_1`](#ibus_remap_addr) | 0x28 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`DBUS_REGWEN_0`](#dbus_regwen) | 0x2c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_1`](#dbus_regwen) | 0x30 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_ADDR_EN_0`](#dbus_addr_en) | 0x34 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_1`](#dbus_addr_en) | 0x38 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_0`](#dbus_addr_matching) | 0x3c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_1`](#dbus_addr_matching) | 0x40 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_0`](#dbus_remap_addr) | 0x44 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_1`](#dbus_remap_addr) | 0x48 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`NMI_ENABLE`](#nmi_enable) | 0x4c | 4 | Enable mask for NMI. | +| rv_core_ibex.[`NMI_STATE`](#nmi_state) | 0x50 | 4 | Current NMI state | +| rv_core_ibex.[`ERR_STATUS`](#err_status) | 0x54 | 4 | error status | +| rv_core_ibex.[`RND_DATA`](#rnd_data) | 0x58 | 4 | Random data from EDN | +| rv_core_ibex.[`RND_STATUS`](#rnd_status) | 0x5c | 4 | Status of random data in [`RND_DATA`](#rnd_data) | +| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x60 | 4 | FPGA build timestamp info. | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) | 0x64 | 4 | Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE`](#mcounteren_writable) | 0x68 | 4 | Controls whether Ibex mcounteren CSR is writable by software. | +| rv_core_ibex.[`DV_SIM_WINDOW`](#dv_sim_window) | 0x80 | 32 | Exposed tlul window for DV only purposes. | ## ALERT_TEST Alert Test Register @@ -436,6 +438,50 @@ This register only contains valid data for fpga, for all other variants it is si |:------:|:------:|:-------:|:-------|:----------------------------------| | 31:0 | ro | 0x0 | VAL | FPGA build timestamp information. | +## MCOUNTEREN_WRITABLE_REGWEN +Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) +- Offset: `0x64` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [EN](#mcounteren_writable_regwen--en) | + +### MCOUNTEREN_WRITABLE_REGWEN . EN +Write enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) Once set to 0, it can no longer be configured to 1. + +| Value | Name | Description | +|:--------|:--------|:------------------------------------------------------------------| +| 0x0 | locked | MCOUNTEREN_WRITABLE can no longer be configured until next reset. | +| 0x1 | enabled | MCOUNTEREN_WRITABLE can still be configured. | + + +## MCOUNTEREN_WRITABLE +Controls whether Ibex mcounteren CSR is writable by software. +- Offset: `0x68` +- Reset default: `0x6` +- Reset mask: `0xf` +- Register enable: [`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------------------------------------------------------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x6 | EN | When set to kMultiBitBool4True, the mcounteren CSR is writable by software. Drives the mcounteren_writable_i input on ibex_top. | + ## DV_SIM_WINDOW Exposed tlul window for DV only purposes. diff --git a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv index 549e537dfc438..6e5af27ab185d 100644 --- a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv +++ b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv @@ -224,6 +224,8 @@ module rv_core_ibex logic [ 3:0] rvfi_mem_wmask; logic [31:0] rvfi_mem_rdata; logic [31:0] rvfi_mem_wdata; + logic rvfi_ext_expanded_insn_valid; + logic [15:0] rvfi_ext_expanded_insn; `endif import tlul_pkg::tl_h2d_t; @@ -420,6 +422,14 @@ module rv_core_ibex lc_ctrl_pkg::lc_tx_and_hi(lc_cpu_en[0], pwrmgr_cpu_en[0])); + prim_mubi_pkg::mubi4_t mcounteren_writable_mubi4; + ibex_pkg::ibex_mubi_t mcounteren_writable_ibex; + assign mcounteren_writable_mubi4 = prim_mubi_pkg::mubi4_t'(reg2hw.mcounteren_writable.q); + // Convert the mubi4 to ibex_mubi. They are both four bit, but with different encodings. + // This conversion should be a simple wire crossing. + assign mcounteren_writable_ibex = mcounteren_writable_mubi4 == prim_mubi_pkg::MuBi4True ? + ibex_pkg::IbexMuBiOn : ibex_pkg::IbexMuBiOff; + ibex_pkg::crash_dump_t crash_dump; ibex_top #( .PMPEnable ( PMPEnable ), @@ -547,21 +557,26 @@ module rv_core_ibex .rvfi_mem_rdata, .rvfi_mem_wdata, // Unused ports from the RVFI interface - .rvfi_ext_pre_mip (), - .rvfi_ext_post_mip (), - .rvfi_ext_nmi (), - .rvfi_ext_nmi_int (), - .rvfi_ext_debug_req (), - .rvfi_ext_debug_mode (), - .rvfi_ext_rf_wr_suppress (), - .rvfi_ext_mcycle (), - .rvfi_ext_mhpmcounters (), - .rvfi_ext_mhpmcountersh (), - .rvfi_ext_ic_scr_key_valid(), - .rvfi_ext_irq_valid (), + .rvfi_ext_pre_mip (), + .rvfi_ext_post_mip (), + .rvfi_ext_nmi (), + .rvfi_ext_nmi_int (), + .rvfi_ext_debug_req (), + .rvfi_ext_debug_mode (), + .rvfi_ext_rf_wr_suppress (), + .rvfi_ext_mcycle (), + .rvfi_ext_minstret (), + .rvfi_ext_mhpmcounters (), + .rvfi_ext_mhpmcountersh (), + .rvfi_ext_ic_scr_key_valid (), + .rvfi_ext_irq_valid (), + .rvfi_ext_expanded_insn_valid(), + .rvfi_ext_expanded_insn (), + .rvfi_ext_expanded_insn_last (), `endif // SEC_CM: FETCH.CTRL.LC_GATED .fetch_enable_i (fetch_enable), + .mcounteren_writable_i (mcounteren_writable_ibex), .alert_minor_o (alert_minor), .alert_major_internal_o (alert_major_internal), .alert_major_bus_o (alert_major_bus), @@ -814,7 +829,9 @@ module rv_core_ibex .rvfi_mem_rmask, .rvfi_mem_wmask, .rvfi_mem_rdata, - .rvfi_mem_wdata + .rvfi_mem_wdata, + .rvfi_ext_expanded_insn_valid, + .rvfi_ext_expanded_insn ); `endif @@ -1086,7 +1103,8 @@ module rv_core_ibex assign unused_reg2hw_shadow = ^{reg2hw_shadow.alert_test, reg2hw_shadow.nmi_enable, reg2hw_shadow.nmi_state, reg2hw_shadow.rnd_data, - reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err}; + reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err, + reg2hw_shadow.mcounteren_writable}; ///////////////////////////////////////////////////////////////// // Shadow Core Data Address Translation Unit and TL-UL Adapter // diff --git a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv index 74e938c4913cb..bd489909982fa 100644 --- a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv +++ b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv @@ -57,9 +57,9 @@ module rv_core_ibex_cfg_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [24:0] reg_we_check; + logic [26:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(25) + .OneHotWidth(27) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -255,6 +255,12 @@ module rv_core_ibex_cfg_reg_top ( logic rnd_status_rnd_data_fips_qs; logic fpga_info_re; logic [31:0] fpga_info_qs; + logic mcounteren_writable_regwen_we; + logic mcounteren_writable_regwen_qs; + logic mcounteren_writable_regwen_wd; + logic mcounteren_writable_we; + logic [3:0] mcounteren_writable_qs; + logic [3:0] mcounteren_writable_wd; // Register instances // R[alert_test]: V(True) @@ -1312,8 +1318,67 @@ module rv_core_ibex_cfg_reg_top ( ); + // R[mcounteren_writable_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mcounteren_writable_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mcounteren_writable_regwen_we), + .wd (mcounteren_writable_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), - logic [24:0] addr_hit; + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mcounteren_writable_regwen_qs) + ); + + + // R[mcounteren_writable]: V(False) + // Create REGWEN-gated WE signal + logic mcounteren_writable_gated_we; + assign mcounteren_writable_gated_we = mcounteren_writable_we & mcounteren_writable_regwen_qs; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h6), + .Mubi (1'b1) + ) u_mcounteren_writable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mcounteren_writable_gated_we), + .wd (mcounteren_writable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mcounteren_writable.q), + .ds (), + + // to register interface (read) + .qs (mcounteren_writable_qs) + ); + + + + logic [26:0] addr_hit; always_comb begin addr_hit[ 0] = (reg_addr == RV_CORE_IBEX_ALERT_TEST_OFFSET); addr_hit[ 1] = (reg_addr == RV_CORE_IBEX_SW_RECOV_ERR_OFFSET); @@ -1340,6 +1405,8 @@ module rv_core_ibex_cfg_reg_top ( addr_hit[22] = (reg_addr == RV_CORE_IBEX_RND_DATA_OFFSET); addr_hit[23] = (reg_addr == RV_CORE_IBEX_RND_STATUS_OFFSET); addr_hit[24] = (reg_addr == RV_CORE_IBEX_FPGA_INFO_OFFSET); + addr_hit[25] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET); + addr_hit[26] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1371,7 +1438,9 @@ module rv_core_ibex_cfg_reg_top ( (addr_hit[21] & (|(RV_CORE_IBEX_CFG_PERMIT[21] & ~reg_be))) | (addr_hit[22] & (|(RV_CORE_IBEX_CFG_PERMIT[22] & ~reg_be))) | (addr_hit[23] & (|(RV_CORE_IBEX_CFG_PERMIT[23] & ~reg_be))) | - (addr_hit[24] & (|(RV_CORE_IBEX_CFG_PERMIT[24] & ~reg_be))))); + (addr_hit[24] & (|(RV_CORE_IBEX_CFG_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(RV_CORE_IBEX_CFG_PERMIT[25] & ~reg_be))) | + (addr_hit[26] & (|(RV_CORE_IBEX_CFG_PERMIT[26] & ~reg_be))))); end // Generate write-enables @@ -1460,6 +1529,12 @@ module rv_core_ibex_cfg_reg_top ( assign rnd_data_re = addr_hit[22] & reg_re & !reg_error; assign rnd_status_re = addr_hit[23] & reg_re & !reg_error; assign fpga_info_re = addr_hit[24] & reg_re & !reg_error; + assign mcounteren_writable_regwen_we = addr_hit[25] & reg_we & !reg_error; + + assign mcounteren_writable_regwen_wd = reg_wdata[0]; + assign mcounteren_writable_we = addr_hit[26] & reg_we & !reg_error; + + assign mcounteren_writable_wd = reg_wdata[3:0]; // Assign write-enables to checker logic vector. always_comb begin @@ -1488,6 +1563,8 @@ module rv_core_ibex_cfg_reg_top ( reg_we_check[22] = 1'b0; reg_we_check[23] = 1'b0; reg_we_check[24] = 1'b0; + reg_we_check[25] = mcounteren_writable_regwen_we; + reg_we_check[26] = mcounteren_writable_gated_we; end // Read data return @@ -1603,6 +1680,14 @@ module rv_core_ibex_cfg_reg_top ( reg_rdata_next[31:0] = fpga_info_qs; end + addr_hit[25]: begin + reg_rdata_next[0] = mcounteren_writable_regwen_qs; + end + + addr_hit[26]: begin + reg_rdata_next[3:0] = mcounteren_writable_qs; + end + default: begin reg_rdata_next = '1; end diff --git a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv index d29bd9279f0cd..2fe6515143947 100644 --- a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv +++ b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv @@ -16,7 +16,7 @@ package rv_core_ibex_reg_pkg; parameter int CfgAw = 8; // Number of registers for every interface - parameter int NumRegsCfg = 25; + parameter int NumRegsCfg = 27; // Alert indices typedef enum int { @@ -110,6 +110,10 @@ package rv_core_ibex_reg_pkg; logic re; } rv_core_ibex_reg2hw_rnd_data_reg_t; + typedef struct packed { + logic [3:0] q; + } rv_core_ibex_reg2hw_mcounteren_writable_reg_t; + typedef struct packed { logic [3:0] d; logic de; @@ -164,18 +168,19 @@ package rv_core_ibex_reg_pkg; // Register -> HW type for cfg interface typedef struct packed { - rv_core_ibex_reg2hw_alert_test_reg_t alert_test; // [324:317] - rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [316:313] - rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [312:309] - rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [1:0] ibus_addr_en; // [308:305] - rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [1:0] ibus_addr_matching; // [304:239] - rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [1:0] ibus_remap_addr; // [238:173] - rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [1:0] dbus_addr_en; // [172:169] - rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [1:0] dbus_addr_matching; // [168:103] - rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [1:0] dbus_remap_addr; // [102:37] - rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [36:35] - rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [34:33] - rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [32:0] + rv_core_ibex_reg2hw_alert_test_reg_t alert_test; // [328:321] + rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [320:317] + rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [316:313] + rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [1:0] ibus_addr_en; // [312:309] + rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [1:0] ibus_addr_matching; // [308:243] + rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [1:0] ibus_remap_addr; // [242:177] + rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [1:0] dbus_addr_en; // [176:173] + rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [1:0] dbus_addr_matching; // [172:107] + rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [1:0] dbus_remap_addr; // [106:41] + rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [40:39] + rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [38:37] + rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [36:4] + rv_core_ibex_reg2hw_mcounteren_writable_reg_t mcounteren_writable; // [3:0] } rv_core_ibex_cfg_reg2hw_t; // HW -> register type for cfg interface @@ -214,6 +219,8 @@ package rv_core_ibex_reg_pkg; parameter logic [CfgAw-1:0] RV_CORE_IBEX_RND_DATA_OFFSET = 8'h 58; parameter logic [CfgAw-1:0] RV_CORE_IBEX_RND_STATUS_OFFSET = 8'h 5c; parameter logic [CfgAw-1:0] RV_CORE_IBEX_FPGA_INFO_OFFSET = 8'h 60; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET = 8'h 64; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET = 8'h 68; // Reset values for hwext registers and their fields for cfg interface parameter logic [3:0] RV_CORE_IBEX_ALERT_TEST_RESVAL = 4'h 0; @@ -260,11 +267,13 @@ package rv_core_ibex_reg_pkg; RV_CORE_IBEX_ERR_STATUS, RV_CORE_IBEX_RND_DATA, RV_CORE_IBEX_RND_STATUS, - RV_CORE_IBEX_FPGA_INFO + RV_CORE_IBEX_FPGA_INFO, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE } rv_core_ibex_cfg_id_e; // Register width information to check illegal writes for cfg interface - parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [25] = '{ + parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [27] = '{ 4'b 0001, // index[ 0] RV_CORE_IBEX_ALERT_TEST 4'b 0001, // index[ 1] RV_CORE_IBEX_SW_RECOV_ERR 4'b 0001, // index[ 2] RV_CORE_IBEX_SW_FATAL_ERR @@ -289,7 +298,9 @@ package rv_core_ibex_reg_pkg; 4'b 0011, // index[21] RV_CORE_IBEX_ERR_STATUS 4'b 1111, // index[22] RV_CORE_IBEX_RND_DATA 4'b 0001, // index[23] RV_CORE_IBEX_RND_STATUS - 4'b 1111 // index[24] RV_CORE_IBEX_FPGA_INFO + 4'b 1111, // index[24] RV_CORE_IBEX_FPGA_INFO + 4'b 0001, // index[25] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN + 4'b 0001 // index[26] RV_CORE_IBEX_MCOUNTEREN_WRITABLE }; endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson index ce77f3dade637..4670c106d457a 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson +++ b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson @@ -1098,6 +1098,47 @@ ] }, + { name: "MCOUNTEREN_WRITABLE_REGWEN", + desc: "Register write-enable for !!MCOUNTEREN_WRITABLE.", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1", + desc: "Write enable for !!MCOUNTEREN_WRITABLE. Once set to 0, it can no longer be configured to 1.", + enum: [ + { value: "0", + name: "locked", + desc: "MCOUNTEREN_WRITABLE can no longer be configured until next reset." + }, + { value: "1", + name: "enabled", + desc: "MCOUNTEREN_WRITABLE can still be configured." + }, + ] + }, + ], + }, + + { name: "MCOUNTEREN_WRITABLE", + desc: "Controls whether Ibex mcounteren CSR is writable by software.", + swaccess: "rw", + hwaccess: "hro", + regwen: "MCOUNTEREN_WRITABLE_REGWEN", + fields: [ + { bits: "3:0", + mubi: true, + name: "EN", + resval: true, + desc: ''' + When set to kMultiBitBool4True, the mcounteren CSR is writable by software. + Drives the mcounteren_writable_i input on ibex_top. + ''' + }, + ], + }, + // dv simulation window { window: { name: "DV_SIM_WINDOW", diff --git a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/doc/registers.md b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/doc/registers.md index 8297d0489ff2b..16ad07f8053dc 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/doc/registers.md +++ b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/doc/registers.md @@ -5,34 +5,36 @@ A number of memory-mapped registers are available to control Ibex-related functi ## Summary -| Name | Offset | Length | Description | -|:-----------------------------------------------------------|:---------|---------:|:------------------------------------------------------------------------------| -| rv_core_ibex.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | -| rv_core_ibex.[`SW_RECOV_ERR`](#sw_recov_err) | 0x4 | 4 | Software recoverable error | -| rv_core_ibex.[`SW_FATAL_ERR`](#sw_fatal_err) | 0x8 | 4 | Software fatal error | -| rv_core_ibex.[`IBUS_REGWEN_0`](#ibus_regwen) | 0xc | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_REGWEN_1`](#ibus_regwen) | 0x10 | 4 | Ibus address control regwen. | -| rv_core_ibex.[`IBUS_ADDR_EN_0`](#ibus_addr_en) | 0x14 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_EN_1`](#ibus_addr_en) | 0x18 | 4 | Enable Ibus address matching | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching) | 0x1c | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_ADDR_MATCHING_1`](#ibus_addr_matching) | 0x20 | 4 | Matching region programming for ibus. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_0`](#ibus_remap_addr) | 0x24 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`IBUS_REMAP_ADDR_1`](#ibus_remap_addr) | 0x28 | 4 | The remap address after a match has been made. | -| rv_core_ibex.[`DBUS_REGWEN_0`](#dbus_regwen) | 0x2c | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_REGWEN_1`](#dbus_regwen) | 0x30 | 4 | Dbus address control regwen. | -| rv_core_ibex.[`DBUS_ADDR_EN_0`](#dbus_addr_en) | 0x34 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_EN_1`](#dbus_addr_en) | 0x38 | 4 | Enable dbus address matching | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_0`](#dbus_addr_matching) | 0x3c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_ADDR_MATCHING_1`](#dbus_addr_matching) | 0x40 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_0`](#dbus_remap_addr) | 0x44 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`DBUS_REMAP_ADDR_1`](#dbus_remap_addr) | 0x48 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | -| rv_core_ibex.[`NMI_ENABLE`](#nmi_enable) | 0x4c | 4 | Enable mask for NMI. | -| rv_core_ibex.[`NMI_STATE`](#nmi_state) | 0x50 | 4 | Current NMI state | -| rv_core_ibex.[`ERR_STATUS`](#err_status) | 0x54 | 4 | error status | -| rv_core_ibex.[`RND_DATA`](#rnd_data) | 0x58 | 4 | Random data from EDN | -| rv_core_ibex.[`RND_STATUS`](#rnd_status) | 0x5c | 4 | Status of random data in [`RND_DATA`](#rnd_data) | -| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x60 | 4 | FPGA build timestamp info. | -| rv_core_ibex.[`DV_SIM_WINDOW`](#dv_sim_window) | 0x80 | 32 | Exposed tlul window for DV only purposes. | +| Name | Offset | Length | Description | +|:-------------------------------------------------------------------------|:---------|---------:|:------------------------------------------------------------------------------| +| rv_core_ibex.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | +| rv_core_ibex.[`SW_RECOV_ERR`](#sw_recov_err) | 0x4 | 4 | Software recoverable error | +| rv_core_ibex.[`SW_FATAL_ERR`](#sw_fatal_err) | 0x8 | 4 | Software fatal error | +| rv_core_ibex.[`IBUS_REGWEN_0`](#ibus_regwen) | 0xc | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_REGWEN_1`](#ibus_regwen) | 0x10 | 4 | Ibus address control regwen. | +| rv_core_ibex.[`IBUS_ADDR_EN_0`](#ibus_addr_en) | 0x14 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_EN_1`](#ibus_addr_en) | 0x18 | 4 | Enable Ibus address matching | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching) | 0x1c | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_ADDR_MATCHING_1`](#ibus_addr_matching) | 0x20 | 4 | Matching region programming for ibus. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_0`](#ibus_remap_addr) | 0x24 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`IBUS_REMAP_ADDR_1`](#ibus_remap_addr) | 0x28 | 4 | The remap address after a match has been made. | +| rv_core_ibex.[`DBUS_REGWEN_0`](#dbus_regwen) | 0x2c | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_REGWEN_1`](#dbus_regwen) | 0x30 | 4 | Dbus address control regwen. | +| rv_core_ibex.[`DBUS_ADDR_EN_0`](#dbus_addr_en) | 0x34 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_EN_1`](#dbus_addr_en) | 0x38 | 4 | Enable dbus address matching | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_0`](#dbus_addr_matching) | 0x3c | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_ADDR_MATCHING_1`](#dbus_addr_matching) | 0x40 | 4 | See [`IBUS_ADDR_MATCHING_0`](#ibus_addr_matching_0) for detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_0`](#dbus_remap_addr) | 0x44 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`DBUS_REMAP_ADDR_1`](#dbus_remap_addr) | 0x48 | 4 | See [`IBUS_REMAP_ADDR_0`](#ibus_remap_addr_0) for a detailed description. | +| rv_core_ibex.[`NMI_ENABLE`](#nmi_enable) | 0x4c | 4 | Enable mask for NMI. | +| rv_core_ibex.[`NMI_STATE`](#nmi_state) | 0x50 | 4 | Current NMI state | +| rv_core_ibex.[`ERR_STATUS`](#err_status) | 0x54 | 4 | error status | +| rv_core_ibex.[`RND_DATA`](#rnd_data) | 0x58 | 4 | Random data from EDN | +| rv_core_ibex.[`RND_STATUS`](#rnd_status) | 0x5c | 4 | Status of random data in [`RND_DATA`](#rnd_data) | +| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x60 | 4 | FPGA build timestamp info. | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) | 0x64 | 4 | Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE`](#mcounteren_writable) | 0x68 | 4 | Controls whether Ibex mcounteren CSR is writable by software. | +| rv_core_ibex.[`DV_SIM_WINDOW`](#dv_sim_window) | 0x80 | 32 | Exposed tlul window for DV only purposes. | ## ALERT_TEST Alert Test Register @@ -436,6 +438,50 @@ This register only contains valid data for fpga, for all other variants it is si |:------:|:------:|:-------:|:-------|:----------------------------------| | 31:0 | ro | 0x0 | VAL | FPGA build timestamp information. | +## MCOUNTEREN_WRITABLE_REGWEN +Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) +- Offset: `0x64` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [EN](#mcounteren_writable_regwen--en) | + +### MCOUNTEREN_WRITABLE_REGWEN . EN +Write enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) Once set to 0, it can no longer be configured to 1. + +| Value | Name | Description | +|:--------|:--------|:------------------------------------------------------------------| +| 0x0 | locked | MCOUNTEREN_WRITABLE can no longer be configured until next reset. | +| 0x1 | enabled | MCOUNTEREN_WRITABLE can still be configured. | + + +## MCOUNTEREN_WRITABLE +Controls whether Ibex mcounteren CSR is writable by software. +- Offset: `0x68` +- Reset default: `0x6` +- Reset mask: `0xf` +- Register enable: [`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------------------------------------------------------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x6 | EN | When set to kMultiBitBool4True, the mcounteren CSR is writable by software. Drives the mcounteren_writable_i input on ibex_top. | + ## DV_SIM_WINDOW Exposed tlul window for DV only purposes. diff --git a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv index 549e537dfc438..6e5af27ab185d 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv +++ b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv @@ -224,6 +224,8 @@ module rv_core_ibex logic [ 3:0] rvfi_mem_wmask; logic [31:0] rvfi_mem_rdata; logic [31:0] rvfi_mem_wdata; + logic rvfi_ext_expanded_insn_valid; + logic [15:0] rvfi_ext_expanded_insn; `endif import tlul_pkg::tl_h2d_t; @@ -420,6 +422,14 @@ module rv_core_ibex lc_ctrl_pkg::lc_tx_and_hi(lc_cpu_en[0], pwrmgr_cpu_en[0])); + prim_mubi_pkg::mubi4_t mcounteren_writable_mubi4; + ibex_pkg::ibex_mubi_t mcounteren_writable_ibex; + assign mcounteren_writable_mubi4 = prim_mubi_pkg::mubi4_t'(reg2hw.mcounteren_writable.q); + // Convert the mubi4 to ibex_mubi. They are both four bit, but with different encodings. + // This conversion should be a simple wire crossing. + assign mcounteren_writable_ibex = mcounteren_writable_mubi4 == prim_mubi_pkg::MuBi4True ? + ibex_pkg::IbexMuBiOn : ibex_pkg::IbexMuBiOff; + ibex_pkg::crash_dump_t crash_dump; ibex_top #( .PMPEnable ( PMPEnable ), @@ -547,21 +557,26 @@ module rv_core_ibex .rvfi_mem_rdata, .rvfi_mem_wdata, // Unused ports from the RVFI interface - .rvfi_ext_pre_mip (), - .rvfi_ext_post_mip (), - .rvfi_ext_nmi (), - .rvfi_ext_nmi_int (), - .rvfi_ext_debug_req (), - .rvfi_ext_debug_mode (), - .rvfi_ext_rf_wr_suppress (), - .rvfi_ext_mcycle (), - .rvfi_ext_mhpmcounters (), - .rvfi_ext_mhpmcountersh (), - .rvfi_ext_ic_scr_key_valid(), - .rvfi_ext_irq_valid (), + .rvfi_ext_pre_mip (), + .rvfi_ext_post_mip (), + .rvfi_ext_nmi (), + .rvfi_ext_nmi_int (), + .rvfi_ext_debug_req (), + .rvfi_ext_debug_mode (), + .rvfi_ext_rf_wr_suppress (), + .rvfi_ext_mcycle (), + .rvfi_ext_minstret (), + .rvfi_ext_mhpmcounters (), + .rvfi_ext_mhpmcountersh (), + .rvfi_ext_ic_scr_key_valid (), + .rvfi_ext_irq_valid (), + .rvfi_ext_expanded_insn_valid(), + .rvfi_ext_expanded_insn (), + .rvfi_ext_expanded_insn_last (), `endif // SEC_CM: FETCH.CTRL.LC_GATED .fetch_enable_i (fetch_enable), + .mcounteren_writable_i (mcounteren_writable_ibex), .alert_minor_o (alert_minor), .alert_major_internal_o (alert_major_internal), .alert_major_bus_o (alert_major_bus), @@ -814,7 +829,9 @@ module rv_core_ibex .rvfi_mem_rmask, .rvfi_mem_wmask, .rvfi_mem_rdata, - .rvfi_mem_wdata + .rvfi_mem_wdata, + .rvfi_ext_expanded_insn_valid, + .rvfi_ext_expanded_insn ); `endif @@ -1086,7 +1103,8 @@ module rv_core_ibex assign unused_reg2hw_shadow = ^{reg2hw_shadow.alert_test, reg2hw_shadow.nmi_enable, reg2hw_shadow.nmi_state, reg2hw_shadow.rnd_data, - reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err}; + reg2hw_shadow.sw_fatal_err, reg2hw_shadow.sw_recov_err, + reg2hw_shadow.mcounteren_writable}; ///////////////////////////////////////////////////////////////// // Shadow Core Data Address Translation Unit and TL-UL Adapter // diff --git a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv index 74e938c4913cb..bd489909982fa 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv +++ b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv @@ -57,9 +57,9 @@ module rv_core_ibex_cfg_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [24:0] reg_we_check; + logic [26:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(25) + .OneHotWidth(27) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -255,6 +255,12 @@ module rv_core_ibex_cfg_reg_top ( logic rnd_status_rnd_data_fips_qs; logic fpga_info_re; logic [31:0] fpga_info_qs; + logic mcounteren_writable_regwen_we; + logic mcounteren_writable_regwen_qs; + logic mcounteren_writable_regwen_wd; + logic mcounteren_writable_we; + logic [3:0] mcounteren_writable_qs; + logic [3:0] mcounteren_writable_wd; // Register instances // R[alert_test]: V(True) @@ -1312,8 +1318,67 @@ module rv_core_ibex_cfg_reg_top ( ); + // R[mcounteren_writable_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mcounteren_writable_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mcounteren_writable_regwen_we), + .wd (mcounteren_writable_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), - logic [24:0] addr_hit; + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mcounteren_writable_regwen_qs) + ); + + + // R[mcounteren_writable]: V(False) + // Create REGWEN-gated WE signal + logic mcounteren_writable_gated_we; + assign mcounteren_writable_gated_we = mcounteren_writable_we & mcounteren_writable_regwen_qs; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h6), + .Mubi (1'b1) + ) u_mcounteren_writable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mcounteren_writable_gated_we), + .wd (mcounteren_writable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mcounteren_writable.q), + .ds (), + + // to register interface (read) + .qs (mcounteren_writable_qs) + ); + + + + logic [26:0] addr_hit; always_comb begin addr_hit[ 0] = (reg_addr == RV_CORE_IBEX_ALERT_TEST_OFFSET); addr_hit[ 1] = (reg_addr == RV_CORE_IBEX_SW_RECOV_ERR_OFFSET); @@ -1340,6 +1405,8 @@ module rv_core_ibex_cfg_reg_top ( addr_hit[22] = (reg_addr == RV_CORE_IBEX_RND_DATA_OFFSET); addr_hit[23] = (reg_addr == RV_CORE_IBEX_RND_STATUS_OFFSET); addr_hit[24] = (reg_addr == RV_CORE_IBEX_FPGA_INFO_OFFSET); + addr_hit[25] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET); + addr_hit[26] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1371,7 +1438,9 @@ module rv_core_ibex_cfg_reg_top ( (addr_hit[21] & (|(RV_CORE_IBEX_CFG_PERMIT[21] & ~reg_be))) | (addr_hit[22] & (|(RV_CORE_IBEX_CFG_PERMIT[22] & ~reg_be))) | (addr_hit[23] & (|(RV_CORE_IBEX_CFG_PERMIT[23] & ~reg_be))) | - (addr_hit[24] & (|(RV_CORE_IBEX_CFG_PERMIT[24] & ~reg_be))))); + (addr_hit[24] & (|(RV_CORE_IBEX_CFG_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(RV_CORE_IBEX_CFG_PERMIT[25] & ~reg_be))) | + (addr_hit[26] & (|(RV_CORE_IBEX_CFG_PERMIT[26] & ~reg_be))))); end // Generate write-enables @@ -1460,6 +1529,12 @@ module rv_core_ibex_cfg_reg_top ( assign rnd_data_re = addr_hit[22] & reg_re & !reg_error; assign rnd_status_re = addr_hit[23] & reg_re & !reg_error; assign fpga_info_re = addr_hit[24] & reg_re & !reg_error; + assign mcounteren_writable_regwen_we = addr_hit[25] & reg_we & !reg_error; + + assign mcounteren_writable_regwen_wd = reg_wdata[0]; + assign mcounteren_writable_we = addr_hit[26] & reg_we & !reg_error; + + assign mcounteren_writable_wd = reg_wdata[3:0]; // Assign write-enables to checker logic vector. always_comb begin @@ -1488,6 +1563,8 @@ module rv_core_ibex_cfg_reg_top ( reg_we_check[22] = 1'b0; reg_we_check[23] = 1'b0; reg_we_check[24] = 1'b0; + reg_we_check[25] = mcounteren_writable_regwen_we; + reg_we_check[26] = mcounteren_writable_gated_we; end // Read data return @@ -1603,6 +1680,14 @@ module rv_core_ibex_cfg_reg_top ( reg_rdata_next[31:0] = fpga_info_qs; end + addr_hit[25]: begin + reg_rdata_next[0] = mcounteren_writable_regwen_qs; + end + + addr_hit[26]: begin + reg_rdata_next[3:0] = mcounteren_writable_qs; + end + default: begin reg_rdata_next = '1; end diff --git a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv index d29bd9279f0cd..2fe6515143947 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv +++ b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv @@ -16,7 +16,7 @@ package rv_core_ibex_reg_pkg; parameter int CfgAw = 8; // Number of registers for every interface - parameter int NumRegsCfg = 25; + parameter int NumRegsCfg = 27; // Alert indices typedef enum int { @@ -110,6 +110,10 @@ package rv_core_ibex_reg_pkg; logic re; } rv_core_ibex_reg2hw_rnd_data_reg_t; + typedef struct packed { + logic [3:0] q; + } rv_core_ibex_reg2hw_mcounteren_writable_reg_t; + typedef struct packed { logic [3:0] d; logic de; @@ -164,18 +168,19 @@ package rv_core_ibex_reg_pkg; // Register -> HW type for cfg interface typedef struct packed { - rv_core_ibex_reg2hw_alert_test_reg_t alert_test; // [324:317] - rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [316:313] - rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [312:309] - rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [1:0] ibus_addr_en; // [308:305] - rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [1:0] ibus_addr_matching; // [304:239] - rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [1:0] ibus_remap_addr; // [238:173] - rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [1:0] dbus_addr_en; // [172:169] - rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [1:0] dbus_addr_matching; // [168:103] - rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [1:0] dbus_remap_addr; // [102:37] - rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [36:35] - rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [34:33] - rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [32:0] + rv_core_ibex_reg2hw_alert_test_reg_t alert_test; // [328:321] + rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [320:317] + rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [316:313] + rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [1:0] ibus_addr_en; // [312:309] + rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [1:0] ibus_addr_matching; // [308:243] + rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [1:0] ibus_remap_addr; // [242:177] + rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [1:0] dbus_addr_en; // [176:173] + rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [1:0] dbus_addr_matching; // [172:107] + rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [1:0] dbus_remap_addr; // [106:41] + rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [40:39] + rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [38:37] + rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [36:4] + rv_core_ibex_reg2hw_mcounteren_writable_reg_t mcounteren_writable; // [3:0] } rv_core_ibex_cfg_reg2hw_t; // HW -> register type for cfg interface @@ -214,6 +219,8 @@ package rv_core_ibex_reg_pkg; parameter logic [CfgAw-1:0] RV_CORE_IBEX_RND_DATA_OFFSET = 8'h 58; parameter logic [CfgAw-1:0] RV_CORE_IBEX_RND_STATUS_OFFSET = 8'h 5c; parameter logic [CfgAw-1:0] RV_CORE_IBEX_FPGA_INFO_OFFSET = 8'h 60; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET = 8'h 64; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET = 8'h 68; // Reset values for hwext registers and their fields for cfg interface parameter logic [3:0] RV_CORE_IBEX_ALERT_TEST_RESVAL = 4'h 0; @@ -260,11 +267,13 @@ package rv_core_ibex_reg_pkg; RV_CORE_IBEX_ERR_STATUS, RV_CORE_IBEX_RND_DATA, RV_CORE_IBEX_RND_STATUS, - RV_CORE_IBEX_FPGA_INFO + RV_CORE_IBEX_FPGA_INFO, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE } rv_core_ibex_cfg_id_e; // Register width information to check illegal writes for cfg interface - parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [25] = '{ + parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [27] = '{ 4'b 0001, // index[ 0] RV_CORE_IBEX_ALERT_TEST 4'b 0001, // index[ 1] RV_CORE_IBEX_SW_RECOV_ERR 4'b 0001, // index[ 2] RV_CORE_IBEX_SW_FATAL_ERR @@ -289,7 +298,9 @@ package rv_core_ibex_reg_pkg; 4'b 0011, // index[21] RV_CORE_IBEX_ERR_STATUS 4'b 1111, // index[22] RV_CORE_IBEX_RND_DATA 4'b 0001, // index[23] RV_CORE_IBEX_RND_STATUS - 4'b 1111 // index[24] RV_CORE_IBEX_FPGA_INFO + 4'b 1111, // index[24] RV_CORE_IBEX_FPGA_INFO + 4'b 0001, // index[25] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN + 4'b 0001 // index[26] RV_CORE_IBEX_MCOUNTEREN_WRITABLE }; endpackage diff --git a/hw/vendor/lowrisc_ibex.lock.hjson b/hw/vendor/lowrisc_ibex.lock.hjson index 3a1687915278e..4beb9c735ae6a 100644 --- a/hw/vendor/lowrisc_ibex.lock.hjson +++ b/hw/vendor/lowrisc_ibex.lock.hjson @@ -8,7 +8,7 @@ { upstream: { - url: https://github.com/lowRISC/ibex.git - rev: ac911ec101c7e9df5eeb2317ec3db664023b1c24 + url: https://github.com/samuelriedel/ibex.git + rev: c799da7a4de7e88e6db9768707541b79b610e3e1 } } diff --git a/hw/vendor/lowrisc_ibex.vendor.hjson b/hw/vendor/lowrisc_ibex.vendor.hjson index c9a2aeb65255a..633a299832ea3 100644 --- a/hw/vendor/lowrisc_ibex.vendor.hjson +++ b/hw/vendor/lowrisc_ibex.vendor.hjson @@ -7,8 +7,8 @@ patch_dir: "patches/lowrisc_ibex", upstream: { - url: "https://github.com/lowRISC/ibex.git", - rev: "master", + url: "https://github.com/samuelriedel/ibex.git", + rev: "mcounteren", }, mapping: [ diff --git a/hw/vendor/lowrisc_ibex/doc/01_overview/compliance.rst b/hw/vendor/lowrisc_ibex/doc/01_overview/compliance.rst index f9436be88d996..4a34db18795aa 100644 --- a/hw/vendor/lowrisc_ibex/doc/01_overview/compliance.rst +++ b/hw/vendor/lowrisc_ibex/doc/01_overview/compliance.rst @@ -43,6 +43,10 @@ In addition, the following instruction set extensions are available. - 2.0 - always enabled + * - **"Zicntr" and "Zihpm"**: Extensions for Counters and Hardware Performance Counters in User mode + - 2.0 + - always enabled + * - **Zifencei**: Instruction-Fetch Fence - 2.0 - always enabled diff --git a/hw/vendor/lowrisc_ibex/doc/03_reference/performance_counters.rst b/hw/vendor/lowrisc_ibex/doc/03_reference/performance_counters.rst index 35c347cd62282..9225c8a64bccc 100644 --- a/hw/vendor/lowrisc_ibex/doc/03_reference/performance_counters.rst +++ b/hw/vendor/lowrisc_ibex/doc/03_reference/performance_counters.rst @@ -3,10 +3,13 @@ Performance Counters ==================== -Ibex implements performance counters according to the RISC-V Privileged Specification, version 1.11 (see Hardware Performance Monitor, Section 3.1.11). +Ibex implements performance counters according to the RISC-V Privileged Specification, version 1.11 (see Hardware Performance Monitor, Section 3.1.11) and supports the **Zihpm** (Hardware Performance Counters) extension. The performance counters are placed inside the Control and Status Registers (CSRs) and can be accessed with the ``CSRRW(I)`` and ``CSRRS/C(I)`` instructions. -Ibex implements the clock cycle counter ``mcycle(h)``, the retired instruction counter ``minstret(h)``, as well as the 29 event counters ``mhpmcounter3(h)`` - ``mhpmcounter31(h)`` and the corresponding event selector CSRs ``mhpmevent3`` - ``mhpmevent31``, and the ``mcountinhibit`` CSR to individually enable/disable the counters. +Ibex implements the machine-mode clock cycle counter ``mcycle(h)``, the retired instruction counter ``minstret(h)``, as well as the 29 event counters ``mhpmcounter3(h)`` - ``mhpmcounter31(h)`` and the corresponding event selector CSRs ``mhpmevent3`` - ``mhpmevent31``, and the ``mcountinhibit`` CSR to individually enable/disable the counters. + +Additionally, Ibex implements the Zicntr and Zihpm extensions which provide User-mode (U-mode) aliases for these performance counters: ``cycle(h)``, ``instret(h)``, and ``hpmcounter3(h)`` - ``hpmcounter31(h)``. These aliases provide read-only access to the exact same underlying hardware counters configured in M-mode. + ``mcycle(h)`` and ``minstret(h)`` are always available and 64 bit wide. The ``mhpmcounter`` performance counters are optional (unavailable by default) and parametrizable in width. @@ -60,6 +63,19 @@ In particular, to enable/disable ``mcycle(h)``, bit 0 must be written. For ``min The lower 32 bits of all counters can be accessed through the base register, whereas the upper 32 bits are accessed through the ``h``-register. Reads to all these registers are non-destructive. +User-Mode Counter Access (mcounteren) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Access to the U-mode counter aliases (``cycle(h)``, ``instret(h)``, and ``hpmcounterX(h)``) is controlled via the Machine Counter-Enable CSR (``mcounteren``). This register can gate access to the counters from less privileged modes to prevent benchmarking the core if desired. + +* **Bit 0** controls access to ``cycle(h)``. +* **Bit 2** controls access to ``instret(h)``. +* **Bit X** controls access to ``hpmcounterX(h)``. + +When a bit in ``mcounteren`` is clear (0), any attempt to read the corresponding counter alias from U-mode will trigger an illegal instruction exception. + +To secure this mechanism, the ``mcounteren`` register can be locked against software modifications using a MUBI input signal called ``mcounteren_writeable``. When this signal disables writes, any attempt by software to modify the contents of ``mcounteren`` is ignored. + Parametrization at synthesis time --------------------------------- diff --git a/hw/vendor/lowrisc_ibex/doc/04_developer/concierge.rst b/hw/vendor/lowrisc_ibex/doc/04_developer/concierge.rst index d0c0dfb434659..3091ce6e0d855 100644 --- a/hw/vendor/lowrisc_ibex/doc/04_developer/concierge.rst +++ b/hw/vendor/lowrisc_ibex/doc/04_developer/concierge.rst @@ -8,14 +8,7 @@ The Ibex Concierge The Ibex Concierge is the friendly caretaker of the Ibex project. It's a rotating duty shared by experienced contributors to help newcomers find their way around the project, and to stay on top of the various small tasks necessary to keep the project going. -The Ibex CPU project is a reasonably large open source project. -Like all projects we experience two challenges: -we want to lend a helping hand to new developers, answering their questions or helping them with code contributions. -And we need to stay on top of our "caretaker" tasks, like fixing problems with our continuous integration setup, triaging issues and pull requests, etc. -The Ibex Concierge combines these two duties in one person. - -Please reach out to the Ibex Concierge if you have trouble finding your way around the Ibex project. -You can find today's Ibex Concierge in the calendar below. +The best way to reach the Ibex Concierge team is by creating an issue on our repository. Who is Ibex Concierge today? @@ -24,14 +17,11 @@ Who is Ibex Concierge today? The concierge duties rotate between several core developers on a weekly basis. You can find today's concierge on duty in a `public calendar `_. -Besides the concierge on duty you can also contact the following people for urgent matters: +Besides the concierge on duty you can also contact the following people for urgent matters and for prioritisation: * Marno van der Maas (`@marnovandermaas `_) * Rupert Swarbrick (`@rswarbrick `_) -You can be Ibex Concierge, too. -Please talk to any of the current concierges to discuss! - .. raw:: html @@ -41,32 +31,31 @@ Ibex Concierge duties --------------------- The Ibex Concierge is aware of what's happening in the Ibex project, and helps to ensure that everyone feels welcome and is able to work productively. -The list of duties includes, but isn't strictly limited to the following tasks. +The list of duties includes, but isn't strictly limited to the following tasks: * Triage incoming issues and pull requests. * Assign labels to them. - * Give initial feedback with an indication of what the next steps are. - - * Answer questions if possible. - * Ask for clarifications where necessary. - * Redirect to the right developers as needed. + * Give initial feedback with an indication of what the next steps are, this does not mean detailed feedback. -* Track progress of open issues and pull requests. - Ensure contributors always know what's going on, and are informed if things take longer. + * Where more detailed feedback is necessary redirect this to one of the core developers for prioritisation. -* Welcome new contributors, and provide (hands-on) help to get them up to speed. - For example, help them get their commits into good shape, etc. +* When time permits, track progress of open issues and pull requests. -* Fix or coordinate fixes to necessary infrastructure, such as the continuous integration setup in a timely manner. + * Try to ensure that contributors know what's going on, and are informed if things take longer or are de-prioritised. -* Go through the list of open pull requests: ping developers if information or action is needed, close abandoned pull requests, etc. + * If you find any abandoned pull requests, close them. -* Assist with the review and update of open issues. +* Check the continuous integration runs and make sure that faults are reported immediately. + If applicable, coordinate fixes to necessary infrastructure. * At the end of the week, hand over to the next Ibex Concierge on the rota. + Best thing to do is have a hand-over meeting of no more than half an hour. -Note the obvious: it is not the job of the Ibex Concierge to fix all bugs, implement all incoming feature requests, or be available 24/7. +Note the obvious: +It is not the job of the Ibex Concierge to fix all bugs, implement all incoming feature requests, or be available 24/7. +We expect the Ibex Concierge to spend less than half a day a week on their duties. +Anything beyond that needs to fit into broader priorities. diff --git a/hw/vendor/lowrisc_ibex/dv/cosim/cosim.h b/hw/vendor/lowrisc_ibex/dv/cosim/cosim.h index 4a5c63c75be80..305af005d5db2 100644 --- a/hw/vendor/lowrisc_ibex/dv/cosim/cosim.h +++ b/hw/vendor/lowrisc_ibex/dv/cosim/cosim.h @@ -128,6 +128,17 @@ class Cosim { // A full 64-bit value is provided setting both the mcycle and mcycleh CSRs. virtual void set_mcycle(uint64_t mcycle) = 0; + // Set the value of minstret. + // + // The co-simulation model doesn't alter the value of minstret itself (other + // than instructions that do a direct CSR write). minstret should be set to + // the correct value before any `step` call that may execute an instruction + // that observes the value of minstret. + // + // A full 64-bit value is provided setting both the minstret and minstreth + // CSRs. + virtual void set_minstret(uint64_t minstret) = 0; + // Set the value of a CSR. This is used when it is needed to have direct // communication between DUT and Spike (e.g. Performance counters). virtual void set_csr(const int csr_num, const uint32_t new_val) = 0; diff --git a/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.cc b/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.cc index 30a3da74dde38..fac12f79b7607 100644 --- a/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.cc +++ b/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.cc @@ -52,6 +52,13 @@ void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle) { cosim->set_mcycle(mcycle_full); } +void riscv_cosim_set_minstret(Cosim *cosim, svBitVecVal *minstret) { + assert(cosim); + + uint64_t minstret_full = minstret[0] | (uint64_t)minstret[1] << 32; + cosim->set_minstret(minstret_full); +} + void riscv_cosim_set_csr(Cosim *cosim, const int csr_id, const svBitVecVal *csr_val) { assert(cosim); diff --git a/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.h b/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.h index bbadbc5e3c031..f6df9ce27f20d 100644 --- a/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.h +++ b/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.h @@ -23,6 +23,7 @@ void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi); void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int); void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req); void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle); +void riscv_cosim_set_minstret(Cosim *cosim, svBitVecVal *minstret); void riscv_cosim_set_csr(Cosim *cosim, const int csr_id, const svBitVecVal *csr_val); void riscv_cosim_set_ic_scr_key_valid(Cosim *cosim, svBit valid); diff --git a/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.svh b/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.svh index 35ecd3b8cb596..4e8cea072972e 100644 --- a/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.svh +++ b/hw/vendor/lowrisc_ibex/dv/cosim/cosim_dpi.svh @@ -18,6 +18,7 @@ import "DPI-C" function void riscv_cosim_set_nmi(chandle cosim_handle, bit nmi); import "DPI-C" function void riscv_cosim_set_nmi_int(chandle cosim_handle, bit nmi_int); import "DPI-C" function void riscv_cosim_set_debug_req(chandle cosim_handle, bit debug_req); import "DPI-C" function void riscv_cosim_set_mcycle(chandle cosim_handle, bit [63:0] mcycle); +import "DPI-C" function void riscv_cosim_set_minstret(chandle cosim_handle, bit [63:0] minstret); import "DPI-C" function void riscv_cosim_set_csr(chandle cosim_handle, int csr_id, bit [31:0] csr_val); import "DPI-C" function void riscv_cosim_set_ic_scr_key_valid(chandle cosim_handle, bit valid); diff --git a/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.cc b/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.cc index daa400709b647..a5d5caa24b631 100644 --- a/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.cc +++ b/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.cc @@ -39,7 +39,10 @@ SpikeCosim::SpikeCosim(const std::string &isa_string, uint32_t start_pc, uint32_t pmp_num_regions, uint32_t pmp_granularity, uint32_t mhpm_counter_num, uint32_t dm_start_addr, uint32_t dm_end_addr) - : nmi_mode(false), pending_iside_error(false), insn_cnt(0) { + : nmi_mode(false), + pending_iside_error(false), + insn_cnt(0), + mhpm_counter_num(mhpm_counter_num) { FILE *log_file = nullptr; if (trace_log_path.length() != 0) { log = std::make_unique(trace_log_path.c_str()); @@ -747,6 +750,27 @@ void SpikeCosim::set_mcycle(uint64_t mcycle) { // to write all 64 bits at once at least. } +void SpikeCosim::set_minstret(uint64_t minstret) { + uint32_t upper_minstret = minstret >> 32; + uint32_t lower_minstret = minstret & 0xffffffff; + + // Spike decrements the MINSTRET CSR when you write to it. This is the same + // issue as with MCYCLE. See `set_mcycle` for more details. + + // Write the lower half first, incremented twice due to the double decrement + processor->get_state()->csrmap[CSR_MINSTRET]->write(lower_minstret + 2); + + if ((processor->get_state()->csrmap[CSR_MINSTRET]->read() & 0xffffffff) == + 0) { + // If the lower half is 0 at this point then the upper half will get + // decremented, so increment it first. + upper_minstret++; + } + + // Set the upper half + processor->get_state()->csrmap[CSR_MINSTRETH]->write(upper_minstret); +} + void SpikeCosim::set_csr(const int csr_num, const uint32_t new_val) { // Note that this is tested with ibex-cosim-v0.3 version of Spike. 'set_csr' // method might have a hardwired zero for mhpmcounterX registers. @@ -832,6 +856,19 @@ void SpikeCosim::fixup_csr(int csr_num, uint32_t csr_val) { processor->set_csr(csr_num, new_val); #else processor->put_csr(csr_num, new_val); +#endif + break; + } + case CSR_MCOUNTEREN: { + // Bits 3..3+mhpm_counter_num-1 correspond to implemented HPM counters + reg_t hpm_mask = ((1 << mhpm_counter_num) - 1) << 3; + // Bit 0 and 2 are for mcycle and minstret which are always implemented + // Bit 1 is for time which is not implemented, hence the mask 0x5 + reg_t new_val = csr_val & (0x5 | hpm_mask); +#ifdef OLD_SPIKE + processor->set_csr(csr_num, new_val); +#else + processor->put_csr(csr_num, new_val); #endif break; } diff --git a/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.h b/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.h index 68fd2204fb095..9fd603ee5f225 100644 --- a/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.h +++ b/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.h @@ -98,6 +98,7 @@ class SpikeCosim : public simif_t, public Cosim { void misaligned_pmp_fixup(); unsigned int insn_cnt; + uint32_t mhpm_counter_num; public: SpikeCosim(const std::string &isa_string, uint32_t start_pc, @@ -131,6 +132,7 @@ class SpikeCosim : public simif_t, public Cosim { void set_nmi_int(bool nmi_int) override; void set_debug_req(bool debug_req) override; void set_mcycle(uint64_t mcycle) override; + void set_minstret(uint64_t minstret) override; void set_csr(const int csr_num, const uint32_t new_val) override; void set_ic_scr_key_valid(bool valid) override; void notify_dside_access(const DSideAccessInfo &access_info) override; diff --git a/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv b/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv index adea4b6332a4d..8f41c17f9e3ed 100644 --- a/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv +++ b/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv @@ -103,6 +103,7 @@ module top import ibex_pkg::*; #( // CPU Control Signals input ibex_mubi_t fetch_enable_i, + input ibex_mubi_t mcounteren_writable_i, output logic core_sleep_o, output logic alert_minor_o, output logic alert_major_internal_o, @@ -162,7 +163,9 @@ NotDebug: assume property (!ibex_top_i.u_ibex_core.debug_mode & !debug_req_i); ConstantBoot: assume property (boot_addr_i == $past(boot_addr_i)); // 3. Always fetch enable FetchEnable: assume property (fetch_enable_i == IbexMuBiOn); -// 4. Never try to sleep if we couldn't ever wake up +// 4. Always have mcounteren writable +McounterenWritable: assume property (mcounteren_writable_i == IbexMuBiOn); +// 5. Never try to sleep if we couldn't ever wake up WFIStart: assume property (`IDC.ctrl_fsm_cs == SLEEP |-> ( `CSR.mie_q.irq_software | `CSR.mie_q.irq_timer | @@ -441,18 +444,25 @@ logic ex_is_checkable_csr; assign ex_is_checkable_csr = ~( ((CSR_MHPMCOUNTER3H <= `CSR_ADDR) && (`CSR_ADDR <= CSR_MHPMCOUNTER31H)) | ((CSR_MHPMCOUNTER3 <= `CSR_ADDR) && (`CSR_ADDR <= CSR_MHPMCOUNTER31)) | + ((CSR_HPMCOUNTER3H <= `CSR_ADDR) && (`CSR_ADDR <= CSR_HPMCOUNTER31H)) | + ((CSR_HPMCOUNTER3 <= `CSR_ADDR) && (`CSR_ADDR <= CSR_HPMCOUNTER31)) | ((CSR_MHPMEVENT3 <= `CSR_ADDR) && (`CSR_ADDR <= CSR_MHPMEVENT31)) | (`CSR_ADDR == CSR_CPUCTRLSTS) | (`CSR_ADDR == CSR_SECURESEED) | (`CSR_ADDR == CSR_MIE) | (`CSR_ADDR == CSR_MCYCLE) | (`CSR_ADDR == CSR_MCYCLEH) | + (`CSR_ADDR == CSR_CYCLE) | (`CSR_ADDR == CSR_CYCLEH) | // TODO: (`CSR_ADDR == CSR_MINSTRET) | (`CSR_ADDR == CSR_MINSTRETH) | + (`CSR_ADDR == CSR_INSTRET) | (`CSR_ADDR == CSR_INSTRETH) | (`CSR_ADDR == CSR_MCOUNTINHIBIT) ); `undef INSTR +// Force mcounteren to always be zero to match the current Sail model. +McounterenStubbedZero: assume property (`CSR.mcounteren_q == 32'h0); + ////////////////////// Decompression Invariant Defs ////////////////////// // These will be used to show that the decompressed instruction stored is in fact the decompressed version of the compressed instruction. diff --git a/hw/vendor/lowrisc_ibex/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv b/hw/vendor/lowrisc_ibex/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv index ea53592d21cb7..48ab742dc6d61 100644 --- a/hw/vendor/lowrisc_ibex/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv +++ b/hw/vendor/lowrisc_ibex/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv @@ -216,6 +216,7 @@ module ibex_riscv_compliance ( .double_fault_seen_o ( ), .fetch_enable_i (ibex_pkg::IbexMuBiOn ), + .mcounteren_writable_i (ibex_pkg::IbexMuBiOn ), .alert_minor_o ( ), .alert_major_internal_o ( ), .alert_major_bus_o ( ), diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv index f55e1936f64ca..04f056150d1a9 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv @@ -151,6 +151,7 @@ class ibex_cosim_scoreboard extends uvm_scoreboard; riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int); riscv_cosim_set_mip(cosim_handle, rvfi_instr.pre_mip, rvfi_instr.post_mip); riscv_cosim_set_mcycle(cosim_handle, rvfi_instr.mcycle); + riscv_cosim_set_minstret(cosim_handle, rvfi_instr.minstret); // Set performance counters through a pseudo-backdoor write for (int i=0; i < 10; i++) begin diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv index 0bf50116e7ff1..d68b5222c8e92 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv @@ -44,6 +44,7 @@ class ibex_rvfi_monitor extends uvm_monitor; trans_collected.debug_req = vif.monitor_cb.ext_debug_req; trans_collected.rf_wr_suppress = vif.monitor_cb.ext_rf_wr_suppress; trans_collected.mcycle = vif.monitor_cb.ext_mcycle; + trans_collected.minstret = vif.monitor_cb.ext_minstret; trans_collected.ic_scr_key_valid = vif.monitor_cb.ext_ic_scr_key_valid; for (int i=0; i < 10; i++) begin diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv index dceba31c47191..c8a6ee5fd02d4 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv @@ -16,6 +16,7 @@ class ibex_rvfi_seq_item extends uvm_sequence_item; bit debug_req; bit rf_wr_suppress; bit [63:0] mcycle; + bit [63:0] minstret; bit [31:0] mhpmcounters [10]; bit [31:0] mhpmcountersh [10]; @@ -34,6 +35,7 @@ class ibex_rvfi_seq_item extends uvm_sequence_item; `uvm_field_int (debug_req, UVM_DEFAULT) `uvm_field_int (rf_wr_suppress, UVM_DEFAULT) `uvm_field_int (mcycle, UVM_DEFAULT) + `uvm_field_int (minstret, UVM_DEFAULT) `uvm_field_sarray_int (mhpmcounters, UVM_DEFAULT) `uvm_field_sarray_int (mhpmcountersh, UVM_DEFAULT) `uvm_field_int (ic_scr_key_valid, UVM_DEFAULT) diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml index 2517f54a7ee4d..49eee3562a51e 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml @@ -60,6 +60,23 @@ test_srcs: empty/empty.S config: riscv-tests +- test: mcounteren_test + desc: > + Tests the mcounteren CSR: reset value, hardwired-zero bit 1 (time), + and U-mode counter access gating. + iterations: 1 + test_srcs: mcounteren_test/mcounteren_test.S + config: riscv-tests + +- test: mcounteren_lock_test + desc: > + Tests that mcounteren retains its value after mcounteren_writable_i is + de-asserted mid-simulation (write-lock). + iterations: 1 + rtl_test: core_ibex_mcounteren_lock_test + test_srcs: mcounteren_test/mcounteren_lock_test.S + config: riscv-tests + - test: pmp_mseccfg_test_rlb1_l0_0_u0 desc: > mseccfg test diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/gen_testlist.py b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/gen_testlist.py index c9226081408d1..91516761c005e 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/gen_testlist.py +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/gen_testlist.py @@ -80,6 +80,23 @@ def add_configs_and_handwritten_directed_tests(): test_srcs: empty/empty.S config: riscv-tests +- test: mcounteren_test + desc: > + Tests the mcounteren CSR: reset value, hardwired-zero bit 1 (time), + and U-mode counter access gating. + iterations: 1 + test_srcs: mcounteren_test/mcounteren_test.S + config: riscv-tests + +- test: mcounteren_lock_test + desc: > + Tests that mcounteren retains its value after mcounteren_writable_i is + de-asserted mid-simulation (write-lock). + iterations: 1 + rtl_test: core_ibex_mcounteren_lock_test + test_srcs: mcounteren_test/mcounteren_lock_test.S + config: riscv-tests + - test: pmp_mseccfg_test_rlb1_l0_0_u0 desc: > mseccfg test @@ -469,11 +486,11 @@ def _main() -> int: add_configs_and_handwritten_directed_tests() if 'riscv-tests' in test_suite_list or test_suite == 'all': - isa_tests = {'rv32mi', 'rv32uc', 'rv32ui', 'rv32um'} + isa_tests = ['rv32mi', 'rv32uc', 'rv32um', 'rv32ui'] append_directed_testlist(isa_tests, '../../../../vendor/riscv-tests/isa/', 'riscv-tests', 1) if 'riscv-arch-tests' in test_suite_list or test_suite == 'all': - arch_tests = {'rv32i_m/B/src', 'rv32i_m/C/src', 'rv32i_m/I/src', 'rv32i_m/M/src', 'rv32i_m/Zifencei/src'} + arch_tests = ['rv32i_m/M/src', 'rv32i_m/C/src', 'rv32i_m/Zifencei/src', 'rv32i_m/I/src', 'rv32i_m/B/src'] append_directed_testlist(arch_tests, '../../../../vendor/riscv-arch-tests/riscv-test-suite/', 'riscv-arch-tests', 1) if 'epmp-tests' in test_suite_list or test_suite == 'all': diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_lock_test.S b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_lock_test.S new file mode 100644 index 0000000000000..30f7fc2511b38 --- /dev/null +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_lock_test.S @@ -0,0 +1,62 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# This test verifies the mcounteren write-lock mechanism by dynamically setting +# the mcounteren_writable_i hardware input. It validates that register updates +# are silently ignored while locked and succeed when unlocked, using immediate +# software readbacks to confirm the state. Inter-process signaling with the UVM +# testbench is achieved by monitoring writes to mcycle (lock command) and +# mcycleh (unlock command). + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV32M +RVTEST_CODE_BEGIN + + # Initial Write (Unlocked) + li s0, 0x5 + csrw mcounteren, s0 + csrr t1, mcounteren + li t2, 0x5 + # If readback != 0x5, fail immediately + bne t1, t2, fail + + # Tell UVM to lock by writing to mcycle, which is monitored by the UVM + # testbench to set `mcounteren_writable` + csrw mcycle, x0 + + # Small delay loop to let the hardware pin force propagate + .rept 5 + nop + .endr + + # Try to overwrite mcounteren with 0x0 while locked + li s1, 0x0 + csrw mcounteren, s1 + csrr t1, mcounteren + bne t1, s0, fail + + # Tell UVM to unlock by writing to mcycleh + csrw mcycleh, x0 + + .rept 5 + nop + .endr + + # Try to overwrite it with 0x0 again. This time while unlocked + li s3, 0x0 + csrw mcounteren, s3 + csrr t1, mcounteren + bne t1, s3, fail + + # Success Exit + j pass + TEST_PASSFAIL + +RVTEST_CODE_END + +RVTEST_DATA_BEGIN + TEST_DATA +RVTEST_DATA_END diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_test.S b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_test.S new file mode 100644 index 0000000000000..816217e4a2635 --- /dev/null +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_test.S @@ -0,0 +1,335 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# This test verifies mcounteren CSR functionality by sweeping multiple bit +# patterns to ensure User-mode access to all 64 performance counters is +# correctly gated. It confirms that allowed registers read successfully, +# while disabled registers securely trigger illegal instruction exceptions. + +#include "custom_macros.h" +#include "riscv_test.h" +#include "test_macros.h" + +# Register Allocation: +# s0: mcounteren WARL readback used by check_counter_aliases +# s1: Expected instruction execution state(1 = should succeed, 0 = should trap) +# s2: Readback snapshot of valid mcounteren bits +# s3: Subroutine return address backup tracking register(ra) +# s4: Label pointing to the next macro boundary +# s5: Subroutine continuation target pointer used upon full block completion + +.macro RUN_CSR_TEST idx, csr_addr + # Check if this counter is configured to be accessible + # Get position at which to check mcounteren bit for this counter + li t0, \csr_addr + andi t0, t0, 0x1F + # Create mask from position + li t1, 1 + sll t1, t1, t0 + and t1, s2, t1 + # s1 = 1 if counter is enabled and should succeed cleanly + snez s1, t1 + + # Set next test label for the handler + la s4, next_test_\idx + + # Read counter.This should trap if s1 == 0 and succeed if s1 == 1 + csrr t0, \csr_addr + # If the counter was supposed to trap but didn't, fail immediately + beqz s1, fail + # Continue to next test +next_test_\idx: +.endm + +.macro RUN_ALL_CSR_TESTS + # Lower 32 Bits of Performance Counters + RUN_CSR_TEST 0, 0xC00 # cycle + RUN_CSR_TEST 1, 0xC01 # time + RUN_CSR_TEST 2, 0xC02 # instret + RUN_CSR_TEST 3, 0xC03 # hpmcounter3 + RUN_CSR_TEST 4, 0xC04 + RUN_CSR_TEST 5, 0xC05 + RUN_CSR_TEST 6, 0xC06 + RUN_CSR_TEST 7, 0xC07 + RUN_CSR_TEST 8, 0xC08 + RUN_CSR_TEST 9, 0xC09 + RUN_CSR_TEST 10, 0xC0A + RUN_CSR_TEST 11, 0xC0B + RUN_CSR_TEST 12, 0xC0C + RUN_CSR_TEST 13, 0xC0D + RUN_CSR_TEST 14, 0xC0E + RUN_CSR_TEST 15, 0xC0F + RUN_CSR_TEST 16, 0xC10 + RUN_CSR_TEST 17, 0xC11 + RUN_CSR_TEST 18, 0xC12 + RUN_CSR_TEST 19, 0xC13 + RUN_CSR_TEST 20, 0xC14 + RUN_CSR_TEST 21, 0xC15 + RUN_CSR_TEST 22, 0xC16 + RUN_CSR_TEST 23, 0xC17 + RUN_CSR_TEST 24, 0xC18 + RUN_CSR_TEST 25, 0xC19 + RUN_CSR_TEST 26, 0xC1A + RUN_CSR_TEST 27, 0xC1B + RUN_CSR_TEST 28, 0xC1C + RUN_CSR_TEST 29, 0xC1D + RUN_CSR_TEST 30, 0xC1E + RUN_CSR_TEST 31, 0xC1F # hpmcounter31 + # Upper 32 Bits of Performance Counters + RUN_CSR_TEST 32, 0xC80 # cycleh + RUN_CSR_TEST 33, 0xC81 # timeh + RUN_CSR_TEST 34, 0xC82 # instreth + RUN_CSR_TEST 35, 0xC83 # hpmcounter3h + RUN_CSR_TEST 36, 0xC84 + RUN_CSR_TEST 37, 0xC85 + RUN_CSR_TEST 38, 0xC86 + RUN_CSR_TEST 39, 0xC87 + RUN_CSR_TEST 40, 0xC88 + RUN_CSR_TEST 41, 0xC89 + RUN_CSR_TEST 42, 0xC8A + RUN_CSR_TEST 43, 0xC8B + RUN_CSR_TEST 44, 0xC8C + RUN_CSR_TEST 45, 0xC8D + RUN_CSR_TEST 46, 0xC8E + RUN_CSR_TEST 47, 0xC8F + RUN_CSR_TEST 48, 0xC90 + RUN_CSR_TEST 49, 0xC91 + RUN_CSR_TEST 50, 0xC92 + RUN_CSR_TEST 51, 0xC93 + RUN_CSR_TEST 52, 0xC94 + RUN_CSR_TEST 53, 0xC95 + RUN_CSR_TEST 54, 0xC96 + RUN_CSR_TEST 55, 0xC97 + RUN_CSR_TEST 56, 0xC98 + RUN_CSR_TEST 57, 0xC99 + RUN_CSR_TEST 58, 0xC9A + RUN_CSR_TEST 59, 0xC9B + RUN_CSR_TEST 60, 0xC9C + RUN_CSR_TEST 61, 0xC9D + RUN_CSR_TEST 62, 0xC9E + RUN_CSR_TEST 63, 0xC9F # hpmcounter31h +.endm + +# Freeze one HPM counter, write it, drop to U-mode to read the user-mode alias, +# then verify the values match. +# s0 is the mcounteren readback on entry +# s1 carries the M-mode read. +# s2 carries the U-mode read. +.macro CHECK_HPM_ALIAS_ONE idx, mhpmcsr, hpmcsr + li t0, (1 << \idx) + and t1, t0, s0 + beqz t1, skip_hpm_alias_\hpmcsr + + csrs mcountinhibit, t0 + li t0, (0x12345678 ^ \idx) + csrw \mhpmcsr, t0 + csrr s1, \mhpmcsr + + la s5, after_hpm_alias_\hpmcsr + SWITCH_TO_U_MODE_LABEL(hpm_alias_u_\hpmcsr) + +.balign 4 +hpm_alias_u_\hpmcsr: + csrr s2, \hpmcsr + ecall + +after_hpm_alias_\hpmcsr: + bne s2, s1, fail + li t0, (1 << \idx) + csrc mcountinhibit, t0 + +skip_hpm_alias_\hpmcsr: +.endm + +# ----------------------------------------------------------------------- +# Main Verification Blocks +# ----------------------------------------------------------------------- + +RVTEST_RV32M +RVTEST_CODE_BEGIN + + la t0, mtvec_handler + csrw mtvec, t0 + + # Verify default power - on reset state + csrr t0, mcounteren + bnez t0, fail + + # Verify that we can write to mcounteren and read back the expected value + li t0, 0x1 + csrw mcounteren, t0 + csrr t1, mcounteren + bne t1, t0, fail + + # Verify time enable bit is hardwired to zero while other bits are sticky + li t0, 0x7 + csrw mcounteren, t0 + csrr t1, mcounteren + xori t1, t1, 0x5 + bnez t1, fail + + # Sweep with all implemented counters enabled + li t0, 0xFFFFFFFF + csrw mcounteren, t0 + csrr s2, mcounteren + jal ra, run_all_csr_tests + + # Sweep with all counters disabled + csrwi mcounteren, 0 + csrr s2, mcounteren + jal ra, run_all_csr_tests + + # Sweep using alternating bits + li t0, 0x55555555 + csrw mcounteren, t0 + csrr s2, mcounteren + jal ra, run_all_csr_tests + + # Sweep using arbitrary custom mask + li t0, 0xCD609E2D + csrw mcounteren, t0 + csrr s2, mcounteren + jal ra, run_all_csr_tests + + # Re-enable all counters and verify U-mode CSRs alias their M-mode counterparts. + li t0, 0xFFFFFFFF + csrw mcounteren, t0 + csrr s0, mcounteren + jal ra, check_counter_aliases + + # If execution hits this line, all pattern sweeps successfully completed + csrwi mcounteren, 0 + j pass + + TEST_PASSFAIL + +# ----------------------------------------------------------------------- +# Evaluation Subroutine +# ----------------------------------------------------------------------- +run_all_csr_tests: + mv s3, ra + la s5, post_all_tests + # Drop to U-mode once per pattern to execute the continuous instruction stream + SWITCH_TO_U_MODE_LABEL(u_mode_sweep_entry) + +.balign 4 +u_mode_sweep_entry: + RUN_ALL_CSR_TESTS + + # Reaching this line implies all 32 checks passed cleanly + ecall + +post_all_tests: + mv ra, s3 + ret + +# ----------------------------------------------------------------------- +# Counter Alias Verification Subroutine +# ----------------------------------------------------------------------- +# Verifies that the user-mode counter CSRs alias their M-mode counterparts. +# cycle and instret are checked by the cosim. +check_counter_aliases: + mv s3, ra + + # HPM alias: iterate over each HPM counter (bits 3-31) that mcounteren + # reports as implemented. Each counter is frozen with mcountinhibit, set to a + # value through the m-mode counter, and read back via the U-mode alias CSR. + CHECK_HPM_ALIAS_ONE 3, mhpmcounter3, hpmcounter3 + CHECK_HPM_ALIAS_ONE 4, mhpmcounter4, hpmcounter4 + CHECK_HPM_ALIAS_ONE 5, mhpmcounter5, hpmcounter5 + CHECK_HPM_ALIAS_ONE 6, mhpmcounter6, hpmcounter6 + CHECK_HPM_ALIAS_ONE 7, mhpmcounter7, hpmcounter7 + CHECK_HPM_ALIAS_ONE 8, mhpmcounter8, hpmcounter8 + CHECK_HPM_ALIAS_ONE 9, mhpmcounter9, hpmcounter9 + CHECK_HPM_ALIAS_ONE 10, mhpmcounter10, hpmcounter10 + CHECK_HPM_ALIAS_ONE 11, mhpmcounter11, hpmcounter11 + CHECK_HPM_ALIAS_ONE 12, mhpmcounter12, hpmcounter12 + CHECK_HPM_ALIAS_ONE 13, mhpmcounter13, hpmcounter13 + CHECK_HPM_ALIAS_ONE 14, mhpmcounter14, hpmcounter14 + CHECK_HPM_ALIAS_ONE 15, mhpmcounter15, hpmcounter15 + CHECK_HPM_ALIAS_ONE 16, mhpmcounter16, hpmcounter16 + CHECK_HPM_ALIAS_ONE 17, mhpmcounter17, hpmcounter17 + CHECK_HPM_ALIAS_ONE 18, mhpmcounter18, hpmcounter18 + CHECK_HPM_ALIAS_ONE 19, mhpmcounter19, hpmcounter19 + CHECK_HPM_ALIAS_ONE 20, mhpmcounter20, hpmcounter20 + CHECK_HPM_ALIAS_ONE 21, mhpmcounter21, hpmcounter21 + CHECK_HPM_ALIAS_ONE 22, mhpmcounter22, hpmcounter22 + CHECK_HPM_ALIAS_ONE 23, mhpmcounter23, hpmcounter23 + CHECK_HPM_ALIAS_ONE 24, mhpmcounter24, hpmcounter24 + CHECK_HPM_ALIAS_ONE 25, mhpmcounter25, hpmcounter25 + CHECK_HPM_ALIAS_ONE 26, mhpmcounter26, hpmcounter26 + CHECK_HPM_ALIAS_ONE 27, mhpmcounter27, hpmcounter27 + CHECK_HPM_ALIAS_ONE 28, mhpmcounter28, hpmcounter28 + CHECK_HPM_ALIAS_ONE 29, mhpmcounter29, hpmcounter29 + CHECK_HPM_ALIAS_ONE 30, mhpmcounter30, hpmcounter30 + CHECK_HPM_ALIAS_ONE 31, mhpmcounter31, hpmcounter31 + CHECK_HPM_ALIAS_ONE 3, mhpmcounter3h, hpmcounter3h + CHECK_HPM_ALIAS_ONE 4, mhpmcounter4h, hpmcounter4h + CHECK_HPM_ALIAS_ONE 5, mhpmcounter5h, hpmcounter5h + CHECK_HPM_ALIAS_ONE 6, mhpmcounter6h, hpmcounter6h + CHECK_HPM_ALIAS_ONE 7, mhpmcounter7h, hpmcounter7h + CHECK_HPM_ALIAS_ONE 8, mhpmcounter8h, hpmcounter8h + CHECK_HPM_ALIAS_ONE 9, mhpmcounter9h, hpmcounter9h + CHECK_HPM_ALIAS_ONE 10, mhpmcounter10h, hpmcounter10h + CHECK_HPM_ALIAS_ONE 11, mhpmcounter11h, hpmcounter11h + CHECK_HPM_ALIAS_ONE 12, mhpmcounter12h, hpmcounter12h + CHECK_HPM_ALIAS_ONE 13, mhpmcounter13h, hpmcounter13h + CHECK_HPM_ALIAS_ONE 14, mhpmcounter14h, hpmcounter14h + CHECK_HPM_ALIAS_ONE 15, mhpmcounter15h, hpmcounter15h + CHECK_HPM_ALIAS_ONE 16, mhpmcounter16h, hpmcounter16h + CHECK_HPM_ALIAS_ONE 17, mhpmcounter17h, hpmcounter17h + CHECK_HPM_ALIAS_ONE 18, mhpmcounter18h, hpmcounter18h + CHECK_HPM_ALIAS_ONE 19, mhpmcounter19h, hpmcounter19h + CHECK_HPM_ALIAS_ONE 20, mhpmcounter20h, hpmcounter20h + CHECK_HPM_ALIAS_ONE 21, mhpmcounter21h, hpmcounter21h + CHECK_HPM_ALIAS_ONE 22, mhpmcounter22h, hpmcounter22h + CHECK_HPM_ALIAS_ONE 23, mhpmcounter23h, hpmcounter23h + CHECK_HPM_ALIAS_ONE 24, mhpmcounter24h, hpmcounter24h + CHECK_HPM_ALIAS_ONE 25, mhpmcounter25h, hpmcounter25h + CHECK_HPM_ALIAS_ONE 26, mhpmcounter26h, hpmcounter26h + CHECK_HPM_ALIAS_ONE 27, mhpmcounter27h, hpmcounter27h + CHECK_HPM_ALIAS_ONE 28, mhpmcounter28h, hpmcounter28h + CHECK_HPM_ALIAS_ONE 29, mhpmcounter29h, hpmcounter29h + CHECK_HPM_ALIAS_ONE 30, mhpmcounter30h, hpmcounter30h + CHECK_HPM_ALIAS_ONE 31, mhpmcounter31h, hpmcounter31h + + mv ra, s3 + ret + +# ----------------------------------------------------------------------- +# Exception Trap Handler +# ----------------------------------------------------------------------- +.balign 256 +mtvec_handler: + csrr t0, mcause + + # mcause 8 = Environment Call from U-mode (stream finished successfully) + li t1, 8 + beq t0, t1, handle_ecall + + # mcause 2 = Illegal Instruction + li t1, 2 + # Drop out to failure trap on all unexpected exceptions + bne t0, t1, fail + + # If the register was supposed to be accessible (s1 == 1) but faulted, fail + bnez s1, fail + + # Valid hardware restriction exception. Safely continue to next macro block + csrw mepc, s4 + mret + +handle_ecall: + # All unrolled checks passed. Safely return back to M-mode context runner + csrw mepc, s5 + li t0, 0x1800 + csrs mstatus, t0 + mret + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + TEST_DATA +RVTEST_DATA_END diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv index 2de5d8fffe810..a1e0bc8b17afa 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv @@ -18,6 +18,7 @@ interface core_ibex_dut_probe_if(input logic clk); logic dret; logic mret; ibex_pkg::ibex_mubi_t fetch_enable; + ibex_pkg::ibex_mubi_t mcounteren_writable; logic core_sleep; logic alert_minor; logic alert_major_internal; @@ -59,6 +60,7 @@ interface core_ibex_dut_probe_if(input logic clk); clocking dut_cb @(posedge clk); output fetch_enable; output debug_req; + output mcounteren_writable; input reset; input illegal_instr; input ecall; @@ -91,7 +93,8 @@ interface core_ibex_dut_probe_if(input logic clk); endclocking initial begin - debug_req = 1'b0; + debug_req = 1'b0; + mcounteren_writable = ibex_pkg::IbexMuBiOn; end `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_ren_a, rf_ren_a) diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv index 0199b87f76b3e..a3034dbf83481 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv @@ -33,6 +33,7 @@ interface core_ibex_rvfi_if(input logic clk); logic [31:0] ext_debug_req; logic [31:0] ext_rf_wr_suppress; logic [63:0] ext_mcycle; + logic [63:0] ext_minstret; logic ext_irq_valid; logic [31:0] ext_mhpmcounters [10]; @@ -70,6 +71,7 @@ interface core_ibex_rvfi_if(input logic clk); input ext_debug_req; input ext_rf_wr_suppress; input ext_mcycle; + input ext_minstret; input ext_mhpmcounters; input ext_mhpmcountersh; input ext_ic_scr_key_valid; diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index a2658d12390fe..9bc8754a130bf 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv @@ -169,6 +169,7 @@ module core_ibex_tb_top; .double_fault_seen_o (dut_if.double_fault_seen ), .fetch_enable_i (dut_if.fetch_enable ), + .mcounteren_writable_i (dut_if.mcounteren_writable ), .alert_minor_o (dut_if.alert_minor ), .alert_major_internal_o (dut_if.alert_major_internal), .alert_major_bus_o (dut_if.alert_major_bus ), @@ -248,6 +249,7 @@ module core_ibex_tb_top; assign rvfi_if.ext_debug_req = dut.rvfi_ext_debug_req; assign rvfi_if.ext_rf_wr_suppress = dut.rvfi_ext_rf_wr_suppress; assign rvfi_if.ext_mcycle = dut.rvfi_ext_mcycle; + assign rvfi_if.ext_minstret = dut.rvfi_ext_minstret; assign rvfi_if.ext_mhpmcounters = dut.rvfi_ext_mhpmcounters; assign rvfi_if.ext_mhpmcountersh = dut.rvfi_ext_mhpmcountersh; assign rvfi_if.ext_ic_scr_key_valid = dut.rvfi_ext_ic_scr_key_valid; diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv index 5794dde7ce0e0..0186201c604aa 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv @@ -2025,3 +2025,44 @@ class core_ibex_assorted_traps_interrupts_debug_test extends core_ibex_directed_ endtask endclass + +class core_ibex_mcounteren_lock_test extends core_ibex_base_test; + `uvm_component_utils(core_ibex_mcounteren_lock_test) + `uvm_component_new + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + // Relaxes co-simulation tracking so mismatches during lock don't abort + cosim_cfg.relax_cosim_check = 1'b1; + endfunction + + virtual task send_stimulus(); + // Fork the binary execution in the background + fork + vseq.start(env.vseqr); + join_none + + // Wait for a write to MCYCLE to indicate locking the mcounteren CSRs + wait_for_live_csr_write(CSR_MCYCLE); + dut_vif.dut_cb.mcounteren_writable <= ibex_pkg::IbexMuBiOff; + `uvm_info(`gfn, "Write to MCYCLE: locking mcounteren!", UVM_LOW) + + // Wait for a write to MCYCLEH to indicate unlocking the mcounteren CSRs + wait_for_live_csr_write(CSR_MCYCLEH); + dut_vif.dut_cb.mcounteren_writable <= ibex_pkg::IbexMuBiOn; + `uvm_info(`gfn, "Write to MCYCLEH: unlocking mcounteren!", UVM_LOW) + endtask + + // Snoop the CSR interface to catch writes to the specified CSR addresses + task wait_for_live_csr_write(bit [11:0] addr); + forever begin + @(csr_vif.csr_cb); + if (csr_vif.csr_cb.csr_access === 1'b1 && + csr_vif.csr_cb.csr_addr === addr && + csr_vif.csr_cb.csr_op != CSR_OP_READ) begin + break; + end + end + endtask + +endclass diff --git a/hw/vendor/lowrisc_ibex/ibex_top.core b/hw/vendor/lowrisc_ibex/ibex_top.core index b772066a92da4..82edbe133db3f 100644 --- a/hw/vendor/lowrisc_ibex/ibex_top.core +++ b/hw/vendor/lowrisc_ibex/ibex_top.core @@ -27,6 +27,11 @@ filesets: - rtl/ibex_top.sv file_type: systemVerilogSource + # Map the prims listed above to the prim_generic implementations for linting + files_map_prim_generic: + depend: + - lowrisc:prim_generic:all + files_lint_verilator: files: - lint/verilator_waiver.vlt: {file_type: vlt} @@ -161,6 +166,7 @@ targets: default: &default_target filesets: - tool_verilator ? (files_lint_verilator) + - tool_verilator ? (files_map_prim_generic) - files_rtl - files_check_tool_requirements toplevel: ibex_top @@ -168,6 +174,8 @@ targets: - tool_vivado ? (FPGA_XILINX=true) lint: <<: *default_target + filesets: + - files_map_prim_generic parameters: - SYNTHESIS=true - RVFI=true diff --git a/hw/vendor/lowrisc_ibex/ibex_top_tracing.core b/hw/vendor/lowrisc_ibex/ibex_top_tracing.core index 799fb956d68ba..6c7e3d11bbf9f 100644 --- a/hw/vendor/lowrisc_ibex/ibex_top_tracing.core +++ b/hw/vendor/lowrisc_ibex/ibex_top_tracing.core @@ -9,6 +9,7 @@ filesets: depend: - lowrisc:ibex:ibex_top - lowrisc:ibex:ibex_tracer + # Map the prims in ibex_top to prim_generic implementations for simulation and linting - "fileset_partner ? (partner:prim_generic:all)" - "!fileset_partner ? (lowrisc:prim_generic:all)" files: diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv index 79eef6976959b..0f0556c86967b 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv @@ -156,6 +156,7 @@ module ibex_core import ibex_pkg::*; #( output logic rvfi_ext_debug_mode, output logic rvfi_ext_rf_wr_suppress, output logic [63:0] rvfi_ext_mcycle, + output logic [63:0] rvfi_ext_minstret, output logic [31:0] rvfi_ext_mhpmcounters [10], output logic [31:0] rvfi_ext_mhpmcountersh [10], output logic rvfi_ext_ic_scr_key_valid, @@ -168,6 +169,7 @@ module ibex_core import ibex_pkg::*; #( // CPU Control Signals // SEC_CM: FETCH.CTRL.LC_GATED input ibex_mubi_t fetch_enable_i, + input ibex_mubi_t mcounteren_writable_i, output logic alert_minor_o, output logic alert_major_internal_o, output logic alert_major_bus_o, @@ -1135,6 +1137,7 @@ module ibex_core import ibex_pkg::*; #( .icache_enable_o (icache_enable), .csr_shadow_err_o (csr_shadow_err), .ic_scr_key_valid_i (ic_scr_key_valid_i), + .mcounteren_writable_i(mcounteren_writable_i), .csr_save_if_i (csr_save_if), .csr_save_id_i (csr_save_id), @@ -1314,6 +1317,7 @@ module ibex_core import ibex_pkg::*; #( logic rvfi_ext_stage_debug_req [RVFI_STAGES+1]; logic rvfi_ext_stage_debug_mode [RVFI_STAGES]; logic [63:0] rvfi_ext_stage_mcycle [RVFI_STAGES]; + logic [63:0] rvfi_ext_stage_minstret [RVFI_STAGES]; logic [31:0] rvfi_ext_stage_mhpmcounters [RVFI_STAGES][10]; logic [31:0] rvfi_ext_stage_mhpmcountersh [RVFI_STAGES][10]; logic rvfi_ext_stage_ic_scr_key_valid [RVFI_STAGES]; @@ -1382,6 +1386,7 @@ module ibex_core import ibex_pkg::*; #( assign rvfi_ext_debug_req = rvfi_ext_stage_debug_req [RVFI_STAGES]; assign rvfi_ext_debug_mode = rvfi_ext_stage_debug_mode [RVFI_STAGES-1]; assign rvfi_ext_mcycle = rvfi_ext_stage_mcycle [RVFI_STAGES-1]; + assign rvfi_ext_minstret = rvfi_ext_stage_minstret [RVFI_STAGES-1]; assign rvfi_ext_mhpmcounters = rvfi_ext_stage_mhpmcounters [RVFI_STAGES-1]; assign rvfi_ext_mhpmcountersh = rvfi_ext_stage_mhpmcountersh [RVFI_STAGES-1]; assign rvfi_ext_ic_scr_key_valid = rvfi_ext_stage_ic_scr_key_valid [RVFI_STAGES-1]; @@ -1605,6 +1610,7 @@ module ibex_core import ibex_pkg::*; #( rvfi_ext_stage_debug_req[i+1] <= '0; rvfi_ext_stage_debug_mode[i] <= '0; rvfi_ext_stage_mcycle[i] <= '0; + rvfi_ext_stage_minstret[i] <= '0; rvfi_ext_stage_ic_scr_key_valid[i] <= '0; rvfi_ext_stage_expanded_insn_valid[i] <= '0; rvfi_ext_stage_expanded_insn[i] <= '0; @@ -1659,6 +1665,7 @@ module ibex_core import ibex_pkg::*; #( rvfi_stage_mem_addr[i] <= rvfi_mem_addr_d; rvfi_ext_stage_debug_mode[i] <= debug_mode; rvfi_ext_stage_mcycle[i] <= cs_registers_i.mcycle_counter_i.counter_val_o; + rvfi_ext_stage_minstret[i] <= cs_registers_i.mhpmcounter[2]; rvfi_ext_stage_ic_scr_key_valid[i] <= cs_registers_i.cpuctrlsts_ic_scr_key_valid_q; rvfi_ext_stage_expanded_insn_valid[i] <= rvfi_expanded_insn_valid; rvfi_ext_stage_expanded_insn[i] <= rvfi_expanded_insn; @@ -1729,6 +1736,7 @@ module ibex_core import ibex_pkg::*; #( rvfi_ext_stage_debug_mode[i] <= rvfi_ext_stage_debug_mode[i-1]; rvfi_ext_stage_mcycle[i] <= rvfi_ext_stage_mcycle[i-1]; + rvfi_ext_stage_minstret[i] <= rvfi_ext_stage_minstret[i-1]; rvfi_ext_stage_ic_scr_key_valid[i] <= rvfi_ext_stage_ic_scr_key_valid[i-1]; rvfi_ext_stage_mhpmcounters[i] <= rvfi_ext_stage_mhpmcounters[i-1]; rvfi_ext_stage_mhpmcountersh[i] <= rvfi_ext_stage_mhpmcountersh[i-1]; diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv index 11c181b8cef1a..961909360deae 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv @@ -98,6 +98,7 @@ module ibex_cs_registers import ibex_pkg::*; #( output logic icache_enable_o, output logic csr_shadow_err_o, input logic ic_scr_key_valid_i, + input ibex_mubi_t mcounteren_writable_i, // Exception save/restore input logic csr_save_if_i, @@ -258,6 +259,11 @@ module ibex_cs_registers import ibex_pkg::*; #( logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q; logic mcountinhibit_we; + // mcounteren: machine counter enable (controls U-mode counter access) + logic [31:0] mcounteren; + logic [MHPMCounterNum+3-1:0] mcounteren_d, mcounteren_q; + logic mcounteren_we; + // mhpmcounter flops are elaborated below providing only the precise number that is required based // on MHPMCounterNum/MHPMCounterWidth. This signal connects to the Q output of these flops // where they exist and is otherwise 0. @@ -374,9 +380,7 @@ module ibex_cs_registers import ibex_pkg::*; #( end // mcounteren: machine counter enable - CSR_MCOUNTEREN: begin - csr_rdata_int = '0; - end + CSR_MCOUNTEREN: csr_rdata_int = mcounteren; CSR_MSCRATCH: csr_rdata_int = mscratch_q; @@ -504,6 +508,35 @@ module ibex_cs_registers import ibex_pkg::*; #( csr_rdata_int = mhpmcounter[mhpmcounter_idx][63:32]; end + // Unprivileged Counter/Timers (readable from U-mode subject to mcounteren) + CSR_CYCLE, + CSR_INSTRET, + CSR_HPMCOUNTER3, + CSR_HPMCOUNTER4, CSR_HPMCOUNTER5, CSR_HPMCOUNTER6, CSR_HPMCOUNTER7, + CSR_HPMCOUNTER8, CSR_HPMCOUNTER9, CSR_HPMCOUNTER10, CSR_HPMCOUNTER11, + CSR_HPMCOUNTER12, CSR_HPMCOUNTER13, CSR_HPMCOUNTER14, CSR_HPMCOUNTER15, + CSR_HPMCOUNTER16, CSR_HPMCOUNTER17, CSR_HPMCOUNTER18, CSR_HPMCOUNTER19, + CSR_HPMCOUNTER20, CSR_HPMCOUNTER21, CSR_HPMCOUNTER22, CSR_HPMCOUNTER23, + CSR_HPMCOUNTER24, CSR_HPMCOUNTER25, CSR_HPMCOUNTER26, CSR_HPMCOUNTER27, + CSR_HPMCOUNTER28, CSR_HPMCOUNTER29, CSR_HPMCOUNTER30, CSR_HPMCOUNTER31: begin + csr_rdata_int = mhpmcounter[mhpmcounter_idx][31:0]; + illegal_csr = (priv_lvl_q == PRIV_LVL_U) && !mcounteren[mhpmcounter_idx]; + end + + CSR_CYCLEH, + CSR_INSTRETH, + CSR_HPMCOUNTER3H, + CSR_HPMCOUNTER4H, CSR_HPMCOUNTER5H, CSR_HPMCOUNTER6H, CSR_HPMCOUNTER7H, + CSR_HPMCOUNTER8H, CSR_HPMCOUNTER9H, CSR_HPMCOUNTER10H, CSR_HPMCOUNTER11H, + CSR_HPMCOUNTER12H, CSR_HPMCOUNTER13H, CSR_HPMCOUNTER14H, CSR_HPMCOUNTER15H, + CSR_HPMCOUNTER16H, CSR_HPMCOUNTER17H, CSR_HPMCOUNTER18H, CSR_HPMCOUNTER19H, + CSR_HPMCOUNTER20H, CSR_HPMCOUNTER21H, CSR_HPMCOUNTER22H, CSR_HPMCOUNTER23H, + CSR_HPMCOUNTER24H, CSR_HPMCOUNTER25H, CSR_HPMCOUNTER26H, CSR_HPMCOUNTER27H, + CSR_HPMCOUNTER28H, CSR_HPMCOUNTER29H, CSR_HPMCOUNTER30H, CSR_HPMCOUNTER31H: begin + csr_rdata_int = mhpmcounter[mhpmcounter_idx][63:32]; + illegal_csr = (priv_lvl_q == PRIV_LVL_U) && !mcounteren[mhpmcounter_idx]; + end + // Debug triggers CSR_TSELECT: begin csr_rdata_int = tselect_rdata; @@ -598,6 +631,7 @@ module ibex_cs_registers import ibex_pkg::*; #( mstack_cause_d = mcause_q; mcountinhibit_we = 1'b0; + mcounteren_we = 1'b0; mhpmcounter_we = '0; mhpmcounterh_we = '0; @@ -675,6 +709,7 @@ module ibex_cs_registers import ibex_pkg::*; #( CSR_DSCRATCH1: dscratch1_en = 1'b1; // machine counter/timers + CSR_MCOUNTEREN: mcounteren_we = mcounteren_writable_i == IbexMuBiOn; CSR_MCOUNTINHIBIT: mcountinhibit_we = 1'b1; CSR_MCYCLE, @@ -1277,6 +1312,15 @@ module ibex_cs_registers import ibex_pkg::*; #( end end + always_comb begin : mcounteren_update + if (mcounteren_we == 1'b1) begin + // bit 1 must always be 0 (no time CSR implemented) + mcounteren_d = {csr_wdata_int[MHPMCounterNum+2:2], 1'b0, csr_wdata_int[0]}; + end else begin + mcounteren_d = mcounteren_q; + end + end + // event selection (hardwired) & control always_comb begin : gen_mhpmcounter_incr @@ -1434,6 +1478,25 @@ module ibex_cs_registers import ibex_pkg::*; #( end end + if (MHPMCounterNum < 29) begin : g_mcounteren_reduced + assign mcounteren = {{29 - MHPMCounterNum{1'b0}}, mcounteren_q}; + end else begin : g_mcounteren_full + assign mcounteren = mcounteren_q; + end + + ibex_csr #( + .Width (MHPMCounterNum+3), + .ShadowCopy(1'b0), + .ResetValue('0) + ) u_mcounteren_csr ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .wr_data_i (mcounteren_d), + .wr_en_i (mcounteren_we), + .rd_data_o (mcounteren_q), + .rd_error_o() + ); + ///////////////////////////// // Debug trigger registers // ///////////////////////////// diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv index f83f3061f2a30..8f1b69c083dfd 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv @@ -104,6 +104,7 @@ module ibex_lockstep import ibex_pkg::*; #( input logic double_fault_seen_i, input ibex_mubi_t fetch_enable_i, + input ibex_mubi_t mcounteren_writable_i, output logic alert_minor_o, output logic alert_major_internal_o, output logic alert_major_bus_o, @@ -247,6 +248,7 @@ module ibex_lockstep import ibex_pkg::*; #( logic irq_nm; logic debug_req; ibex_mubi_t fetch_enable; + ibex_mubi_t mcounteren_writable; logic ic_scr_key_valid; } delayed_inputs_t; @@ -310,24 +312,25 @@ module ibex_lockstep import ibex_pkg::*; #( end // Assign the inputs to the delay structure - assign shadow_inputs_in.instr_gnt = instr_gnt_i; - assign shadow_inputs_in.instr_rvalid = instr_rvalid_i; - assign shadow_inputs_in.instr_rdata = instr_rdata_i; - assign shadow_inputs_in.instr_err = instr_err_i; - assign shadow_inputs_in.data_gnt = data_gnt_i; - assign shadow_inputs_in.data_rvalid = data_rvalid_i; - assign shadow_inputs_in.data_rdata = data_rdata_i; - assign shadow_inputs_in.data_err = data_err_i; - assign shadow_inputs_in.rf_rdata_a = rf_rdata_a_i; - assign shadow_inputs_in.rf_rdata_b = rf_rdata_b_i; - assign shadow_inputs_in.irq_software = irq_software_i; - assign shadow_inputs_in.irq_timer = irq_timer_i; - assign shadow_inputs_in.irq_external = irq_external_i; - 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; - assign shadow_inputs_in.ic_scr_key_valid = ic_scr_key_valid_i; + assign shadow_inputs_in.instr_gnt = instr_gnt_i; + assign shadow_inputs_in.instr_rvalid = instr_rvalid_i; + assign shadow_inputs_in.instr_rdata = instr_rdata_i; + assign shadow_inputs_in.instr_err = instr_err_i; + assign shadow_inputs_in.data_gnt = data_gnt_i; + assign shadow_inputs_in.data_rvalid = data_rvalid_i; + assign shadow_inputs_in.data_rdata = data_rdata_i; + assign shadow_inputs_in.data_err = data_err_i; + assign shadow_inputs_in.rf_rdata_a = rf_rdata_a_i; + assign shadow_inputs_in.rf_rdata_b = rf_rdata_b_i; + assign shadow_inputs_in.irq_software = irq_software_i; + assign shadow_inputs_in.irq_timer = irq_timer_i; + assign shadow_inputs_in.irq_external = irq_external_i; + 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; + assign shadow_inputs_in.mcounteren_writable = mcounteren_writable_i; + assign shadow_inputs_in.ic_scr_key_valid = ic_scr_key_valid_i; /////////////////// // Output delays // @@ -544,6 +547,7 @@ module ibex_lockstep import ibex_pkg::*; #( .rvfi_ext_debug_mode (), .rvfi_ext_rf_wr_suppress (), .rvfi_ext_mcycle (), + .rvfi_ext_minstret (), .rvfi_ext_mhpmcounters (), .rvfi_ext_mhpmcountersh (), .rvfi_ext_ic_scr_key_valid (), @@ -554,6 +558,7 @@ module ibex_lockstep import ibex_pkg::*; #( `endif .fetch_enable_i (shadow_inputs_q[0].fetch_enable), + .mcounteren_writable_i (shadow_inputs_q[0].mcounteren_writable), .alert_minor_o (shadow_alert_minor), .alert_major_internal_o (shadow_alert_major_internal), .alert_major_bus_o (shadow_alert_major_bus), diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv index fbe63b91cfc8a..45b406444c812 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv @@ -608,6 +608,69 @@ package ibex_pkg; CSR_MHPMCOUNTER29H = 12'hB9D, CSR_MHPMCOUNTER30H = 12'hB9E, CSR_MHPMCOUNTER31H = 12'hB9F, + // Unprivileged Counter/Timers (readable from U-mode subject to mcounteren) + CSR_CYCLE = 12'hC00, + CSR_INSTRET = 12'hC02, + CSR_HPMCOUNTER3 = 12'hC03, + CSR_HPMCOUNTER4 = 12'hC04, + CSR_HPMCOUNTER5 = 12'hC05, + CSR_HPMCOUNTER6 = 12'hC06, + CSR_HPMCOUNTER7 = 12'hC07, + CSR_HPMCOUNTER8 = 12'hC08, + CSR_HPMCOUNTER9 = 12'hC09, + CSR_HPMCOUNTER10 = 12'hC0A, + CSR_HPMCOUNTER11 = 12'hC0B, + CSR_HPMCOUNTER12 = 12'hC0C, + CSR_HPMCOUNTER13 = 12'hC0D, + CSR_HPMCOUNTER14 = 12'hC0E, + CSR_HPMCOUNTER15 = 12'hC0F, + CSR_HPMCOUNTER16 = 12'hC10, + CSR_HPMCOUNTER17 = 12'hC11, + CSR_HPMCOUNTER18 = 12'hC12, + CSR_HPMCOUNTER19 = 12'hC13, + CSR_HPMCOUNTER20 = 12'hC14, + CSR_HPMCOUNTER21 = 12'hC15, + CSR_HPMCOUNTER22 = 12'hC16, + CSR_HPMCOUNTER23 = 12'hC17, + CSR_HPMCOUNTER24 = 12'hC18, + CSR_HPMCOUNTER25 = 12'hC19, + CSR_HPMCOUNTER26 = 12'hC1A, + CSR_HPMCOUNTER27 = 12'hC1B, + CSR_HPMCOUNTER28 = 12'hC1C, + CSR_HPMCOUNTER29 = 12'hC1D, + CSR_HPMCOUNTER30 = 12'hC1E, + CSR_HPMCOUNTER31 = 12'hC1F, + CSR_CYCLEH = 12'hC80, + CSR_INSTRETH = 12'hC82, + CSR_HPMCOUNTER3H = 12'hC83, + CSR_HPMCOUNTER4H = 12'hC84, + CSR_HPMCOUNTER5H = 12'hC85, + CSR_HPMCOUNTER6H = 12'hC86, + CSR_HPMCOUNTER7H = 12'hC87, + CSR_HPMCOUNTER8H = 12'hC88, + CSR_HPMCOUNTER9H = 12'hC89, + CSR_HPMCOUNTER10H = 12'hC8A, + CSR_HPMCOUNTER11H = 12'hC8B, + CSR_HPMCOUNTER12H = 12'hC8C, + CSR_HPMCOUNTER13H = 12'hC8D, + CSR_HPMCOUNTER14H = 12'hC8E, + CSR_HPMCOUNTER15H = 12'hC8F, + CSR_HPMCOUNTER16H = 12'hC90, + CSR_HPMCOUNTER17H = 12'hC91, + CSR_HPMCOUNTER18H = 12'hC92, + CSR_HPMCOUNTER19H = 12'hC93, + CSR_HPMCOUNTER20H = 12'hC94, + CSR_HPMCOUNTER21H = 12'hC95, + CSR_HPMCOUNTER22H = 12'hC96, + CSR_HPMCOUNTER23H = 12'hC97, + CSR_HPMCOUNTER24H = 12'hC98, + CSR_HPMCOUNTER25H = 12'hC99, + CSR_HPMCOUNTER26H = 12'hC9A, + CSR_HPMCOUNTER27H = 12'hC9B, + CSR_HPMCOUNTER28H = 12'hC9C, + CSR_HPMCOUNTER29H = 12'hC9D, + CSR_HPMCOUNTER30H = 12'hC9E, + CSR_HPMCOUNTER31H = 12'hC9F, CSR_CPUCTRLSTS = 12'h7C0, CSR_SECURESEED = 12'h7C1 } csr_num_e; diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv index 1a0712c4fb9e8..99c72eb839e5e 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv @@ -149,6 +149,7 @@ module ibex_top import ibex_pkg::*; #( output logic rvfi_ext_debug_mode, output logic rvfi_ext_rf_wr_suppress, output logic [63:0] rvfi_ext_mcycle, + output logic [63:0] rvfi_ext_minstret, output logic [31:0] rvfi_ext_mhpmcounters [10], output logic [31:0] rvfi_ext_mhpmcountersh [10], output logic rvfi_ext_ic_scr_key_valid, @@ -160,6 +161,7 @@ module ibex_top import ibex_pkg::*; #( // CPU Control Signals input ibex_mubi_t fetch_enable_i, + input ibex_mubi_t mcounteren_writable_i, output logic alert_minor_o, output logic alert_major_internal_o, output logic alert_major_bus_o, @@ -244,6 +246,7 @@ module ibex_top import ibex_pkg::*; #( logic scramble_req_d, scramble_req_q; ibex_mubi_t fetch_enable_buf; + ibex_mubi_t mcounteren_writable_buf; ///////////////////// // Main clock gate // @@ -296,6 +299,11 @@ module ibex_top import ibex_pkg::*; #( .out_o(fetch_enable_buf) ); + prim_buf #(.Width($bits(ibex_mubi_t))) u_mcounteren_writable_buf ( + .in_i (mcounteren_writable_i), + .out_o(mcounteren_writable_buf) + ); + // ibex_core takes integrity and data bits together. Combine the separate integrity and data // inputs here. assign data_rdata_core[31:0] = data_rdata_i; @@ -439,6 +447,7 @@ module ibex_top import ibex_pkg::*; #( .rvfi_ext_debug_mode, .rvfi_ext_rf_wr_suppress, .rvfi_ext_mcycle, + .rvfi_ext_minstret, .rvfi_ext_mhpmcounters, .rvfi_ext_mhpmcountersh, .rvfi_ext_ic_scr_key_valid, @@ -449,6 +458,7 @@ module ibex_top import ibex_pkg::*; #( `endif .fetch_enable_i (fetch_enable_buf), + .mcounteren_writable_i (mcounteren_writable_buf), .alert_minor_o (core_alert_minor), .alert_major_internal_o(core_alert_major_internal), .alert_major_bus_o (core_alert_major_bus), @@ -829,6 +839,7 @@ module ibex_top import ibex_pkg::*; #( crash_dump_o, double_fault_seen_o, fetch_enable_i, + mcounteren_writable_i, core_busy_d }); @@ -879,6 +890,7 @@ module ibex_top import ibex_pkg::*; #( crash_dump_t crash_dump_local; logic double_fault_seen_local; ibex_mubi_t fetch_enable_local; + ibex_mubi_t mcounteren_writable_local; ibex_mubi_t core_busy_local; @@ -922,6 +934,7 @@ module ibex_top import ibex_pkg::*; #( crash_dump_o, double_fault_seen_o, fetch_enable_i, + mcounteren_writable_i, core_busy_d }; @@ -965,6 +978,7 @@ module ibex_top import ibex_pkg::*; #( crash_dump_local, double_fault_seen_local, fetch_enable_local, + mcounteren_writable_local, core_busy_local } = buf_out; @@ -1083,6 +1097,7 @@ module ibex_top import ibex_pkg::*; #( .double_fault_seen_i (double_fault_seen_local), .fetch_enable_i (fetch_enable_local), + .mcounteren_writable_i (mcounteren_writable_local), .alert_minor_o (lockstep_alert_minor_local), .alert_major_internal_o (lockstep_alert_major_internal_local), .alert_major_bus_o (lockstep_alert_major_bus_local), diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv index a5f37d1d61137..5e37cf80c9f9c 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv @@ -96,6 +96,7 @@ module ibex_top_tracing import ibex_pkg::*; #( // CPU Control Signals input ibex_mubi_t fetch_enable_i, + input ibex_mubi_t mcounteren_writable_i, output logic alert_minor_o, output logic alert_major_internal_o, output logic alert_major_bus_o, @@ -153,6 +154,7 @@ module ibex_top_tracing import ibex_pkg::*; #( logic rvfi_ext_debug_mode; logic rvfi_ext_rf_wr_suppress; logic [63:0] rvfi_ext_mcycle; + logic [63:0] rvfi_ext_minstret; logic [31:0] rvfi_ext_mhpmcounters [10]; logic [31:0] rvfi_ext_mhpmcountersh [10]; @@ -174,6 +176,7 @@ module ibex_top_tracing import ibex_pkg::*; #( logic unused_rvfi_ext_debug_mode; logic unused_rvfi_ext_rf_wr_suppress; logic [63:0] unused_rvfi_ext_mcycle; + logic [63:0] unused_rvfi_ext_minstret; logic unused_rvfi_ext_ic_scr_key_valid; logic unused_rvfi_ext_irq_valid; logic unused_rvfi_ext_expanded_insn_last; @@ -188,6 +191,7 @@ module ibex_top_tracing import ibex_pkg::*; #( assign unused_rvfi_ext_debug_mode = rvfi_ext_debug_mode; assign unused_rvfi_ext_rf_wr_suppress = rvfi_ext_rf_wr_suppress; assign unused_rvfi_ext_mcycle = rvfi_ext_mcycle; + assign unused_rvfi_ext_minstret = rvfi_ext_minstret; assign unused_perf_regs = rvfi_ext_mhpmcounters; assign unused_perf_regsh = rvfi_ext_mhpmcountersh; assign unused_rvfi_ext_ic_scr_key_valid = rvfi_ext_ic_scr_key_valid; @@ -304,6 +308,7 @@ module ibex_top_tracing import ibex_pkg::*; #( .rvfi_ext_debug_mode, .rvfi_ext_rf_wr_suppress, .rvfi_ext_mcycle, + .rvfi_ext_minstret, .rvfi_ext_mhpmcounters, .rvfi_ext_mhpmcountersh, .rvfi_ext_ic_scr_key_valid, @@ -313,6 +318,7 @@ module ibex_top_tracing import ibex_pkg::*; #( .rvfi_ext_expanded_insn_last, .fetch_enable_i, + .mcounteren_writable_i, .alert_minor_o, .alert_major_internal_o, .alert_major_bus_o, diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index def53643bdca9..18d8dc4e1d9e2 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -7273,6 +7273,19 @@ test_suite( ], ) +opentitan_test( + name = "rv_core_ibex_mcounteren_writable_test", + srcs = ["rv_core_ibex_mcounteren_writable_test.c"], + exec_env = EARLGREY_TEST_ENVS, + deps = [ + "//hw/top_earlgrey/sw/autogen:top_earlgrey", + "//sw/device/lib/base:mmio", + "//sw/device/lib/base:multibits", + "//sw/device/lib/testing/test_framework:check", + "//sw/device/lib/testing/test_framework:ottf_main", + ], +) + opentitan_test( name = "rv_core_ibex_epmp_test_functest", srcs = ["//sw/device/silicon_creator/manuf/tests:idle_functest.c"], diff --git a/sw/device/tests/rv_core_ibex_mcounteren_writable_test.c b/sw/device/tests/rv_core_ibex_mcounteren_writable_test.c new file mode 100644 index 0000000000000..05a92eb942682 --- /dev/null +++ b/sw/device/tests/rv_core_ibex_mcounteren_writable_test.c @@ -0,0 +1,156 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Verifies that the mcounteren_writable register properly locks the mcounteren +// CSR and that the register is write-protected when locked. + +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/base/multibits.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_main.h" + +#include "hw/top/rv_core_ibex_regs.h" +#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" + +#define MCOUNTERS_DISABLE (0x0) +#define MCOUNTERS_ENABLE (0x5) + +OTTF_DEFINE_TEST_CONFIG(); + +// Helper functions for accessing the mcounteren CSR +static inline uint32_t csr_read_mcounteren(void) { + uint32_t val; + asm volatile("csrr %0, mcounteren" : "=r"(val)); + return val; +} + +static inline void csr_write_mcounteren(uint32_t val) { + asm volatile("csrw mcounteren, %0" ::"r"(val)); +} + +bool test_main(void) { + uint32_t mcounteren_val; + uint32_t mcounteren_writable_val; + uint32_t regwen; + + mmio_region_t ibex_cfg = + mmio_region_from_addr(TOP_EARLGREY_RV_CORE_IBEX_CFG_BASE_ADDR); + + // Initialize mcounteren to a known value for testing. + csr_write_mcounteren(MCOUNTERS_DISABLE); + + // Check defaults + // MCOUNTEREN_WRITABLE should default to kMultiBitBool4True. + mcounteren_writable_val = + mmio_region_read32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET); + CHECK(mcounteren_writable_val == kMultiBitBool4True, + "MCOUNTEREN_WRITABLE default should be MuBi4True (0x%x), got 0x%x", + kMultiBitBool4True, mcounteren_writable_val); + // REGWEN should be enabled by default. + regwen = mmio_region_read32( + ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_REG_OFFSET); + CHECK(regwen == 1, "MCOUNTEREN_WRITABLE_REGWEN default should be 1, got 0x%x", + regwen); + + // Since MCOUNTEREN_WRITABLE is True, writes to mcounteren should succeed. + csr_write_mcounteren(MCOUNTERS_ENABLE); + mcounteren_val = csr_read_mcounteren(); + CHECK(mcounteren_val == MCOUNTERS_ENABLE, + "mcounteren should be writable when MCOUNTEREN_WRITABLE is True. " + "Expected 0x%x, got 0x%x", + MCOUNTERS_ENABLE, mcounteren_val); + + // Locking should succeed while REGWEN is enabled. + mmio_region_write32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET, + kMultiBitBool4False); + mcounteren_writable_val = + mmio_region_read32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET); + CHECK(mcounteren_writable_val == kMultiBitBool4False, + "MCOUNTEREN_WRITABLE write should succeed when unlocked, got 0x%x", + mcounteren_writable_val); + + // Since MCOUNTEREN_WRITABLE is now False, writes to mcounteren should be + // ignored. + csr_write_mcounteren(MCOUNTERS_DISABLE); + mcounteren_val = csr_read_mcounteren(); + CHECK(mcounteren_val == MCOUNTERS_ENABLE, + "mcounteren writes should be blocked when MCOUNTEREN_WRITABLE is " + "False. Expected 0x%x, got 0x%x", + MCOUNTERS_ENABLE, mcounteren_val); + + // Unlocking should succeed while REGWEN is enabled. + mmio_region_write32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET, + kMultiBitBool4True); + mcounteren_writable_val = + mmio_region_read32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET); + CHECK(mcounteren_writable_val == kMultiBitBool4True, + "MCOUNTEREN_WRITABLE write should succeed when unlocked, got 0x%x", + mcounteren_writable_val); + + // Ensure mcounteren is writable again after restoring MCOUNTEREN_WRITABLE to + // True. + csr_write_mcounteren(MCOUNTERS_DISABLE); + mcounteren_val = csr_read_mcounteren(); + CHECK(mcounteren_val == MCOUNTERS_DISABLE, + "mcounteren should be writable again after restoring config. Expected " + "0x%x, got 0x%x", + MCOUNTERS_DISABLE, mcounteren_val); + + // Lock again, which should succeed. + mmio_region_write32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET, + kMultiBitBool4False); + mcounteren_writable_val = + mmio_region_read32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET); + CHECK(mcounteren_writable_val == kMultiBitBool4False, + "MCOUNTEREN_WRITABLE write should succeed when unlocked, got 0x%x", + mcounteren_writable_val); + + // Clear REGWEN to lock MCOUNTEREN_WRITABLE. + mmio_region_write32(ibex_cfg, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_REG_OFFSET, 0); + regwen = mmio_region_read32( + ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_REG_OFFSET); + CHECK(regwen == 0, + "MCOUNTEREN_WRITABLE_REGWEN should read 0 after clearing, got 0x%x", + regwen); + + // Write to MCOUNTEREN_WRITABLE while locked should have no effect. + mmio_region_write32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET, + kMultiBitBool4True); + mcounteren_writable_val = + mmio_region_read32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET); + CHECK(mcounteren_writable_val == kMultiBitBool4False, + "MCOUNTEREN_WRITABLE should be unchanged when locked, got 0x%x", + mcounteren_writable_val); + + // Since the attempt to flip MCOUNTEREN_WRITABLE to True was + // ignored, writes to mcounteren should be ignored. + csr_write_mcounteren(MCOUNTERS_ENABLE); + mcounteren_val = csr_read_mcounteren(); + CHECK(mcounteren_val == MCOUNTERS_DISABLE, + "mcounteren writes should be blocked when MCOUNTEREN_WRITABLE is " + "False. Expected 0x%x, got 0x%x", + MCOUNTERS_DISABLE, mcounteren_val); + + // Attempt to re-enable REGWEN should fail + mmio_region_write32(ibex_cfg, + RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_REG_OFFSET, 1); + regwen = mmio_region_read32( + ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_REG_OFFSET); + CHECK(regwen == 0, + "MCOUNTEREN_WRITABLE_REGWEN should remain 0 after attempted " + "re-enable, got 0x%x", + regwen); + + // Write to MCOUNTEREN_WRITABLE while locked should have no effect. + mmio_region_write32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET, + kMultiBitBool4True); + mcounteren_writable_val = + mmio_region_read32(ibex_cfg, RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REG_OFFSET); + CHECK(mcounteren_writable_val == kMultiBitBool4False, + "MCOUNTEREN_WRITABLE should be unchanged when locked, got 0x%x", + mcounteren_writable_val); + + return true; +}