From e36d3a18549b1bdc0901733efabb4be481e4e095 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Fri, 29 May 2026 09:29:48 +0200 Subject: [PATCH 1/3] [rv_core_ibex] Add `mcounteren_writable` register This register allows locking/unlocking the mcounteren CSR in Ibex to control which performance counters are available in U-mode. Signed-off-by: Samuel Riedel --- .../rv_core_ibex/data/rv_core_ibex.hjson.tpl | 41 ++ .../rv_core_ibex/rtl/rv_core_ibex.sv.tpl | 11 +- .../rv_core_ibex/data/rv_core_ibex.hjson | 41 ++ .../ip_autogen/rv_core_ibex/doc/registers.md | 582 ++++++++++-------- .../rv_core_ibex/rtl/rv_core_ibex.sv | 11 +- .../rtl/rv_core_ibex_cfg_reg_top.sv | 93 ++- .../rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv | 43 +- .../rv_core_ibex/data/rv_core_ibex.hjson | 41 ++ .../ip_autogen/rv_core_ibex/doc/registers.md | 102 ++- .../rv_core_ibex/rtl/rv_core_ibex.sv | 11 +- .../rtl/rv_core_ibex_cfg_reg_top.sv | 93 ++- .../rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv | 43 +- .../rv_core_ibex/data/rv_core_ibex.hjson | 41 ++ .../ip_autogen/rv_core_ibex/doc/registers.md | 102 ++- .../rv_core_ibex/rtl/rv_core_ibex.sv | 11 +- .../rtl/rv_core_ibex_cfg_reg_top.sv | 93 ++- .../rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv | 43 +- 17 files changed, 1014 insertions(+), 388 deletions(-) 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..0082a276c5c1a 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 @@ -433,6 +433,13 @@ 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. + 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 ), @@ -575,6 +582,7 @@ module ${module_instance_name} `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), @@ -1111,7 +1119,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..48f5288af6ff6 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 @@ -420,6 +420,13 @@ 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. + 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 ), @@ -562,6 +569,7 @@ module rv_core_ibex `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), @@ -1086,7 +1094,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/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..48f5288af6ff6 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 @@ -420,6 +420,13 @@ 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. + 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 ), @@ -562,6 +569,7 @@ module rv_core_ibex `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), @@ -1086,7 +1094,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..48f5288af6ff6 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 @@ -420,6 +420,13 @@ 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. + 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 ), @@ -562,6 +569,7 @@ module rv_core_ibex `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), @@ -1086,7 +1094,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 From 0d45447979931f1557c4f950170c875ea3b3ac94 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Thu, 11 Jun 2026 15:05:07 +0200 Subject: [PATCH 2/3] Update lowrisc_ibex to lowRISC/ibex@aae4809a Update code from upstream repository https://github.com/lowRISC/ibex.git to revision aae4809aea170fc605bdaa64a70a13efd2408829 * [dv] Check u-mode counter alias the correct m-mode counter (Samuel Riedel) * [formal] Exclude u-mode counters from formal verification (Samuel Riedel) * [doc] Document the newly added performance counters (Samuel Riedel) * [dv] Add directed test for mcounteren lock signal (Samuel Riedel) * [dv] Add `mcounteren` directed test (Samuel Riedel) * [dv] Fix ordering in `directed_testlist.yml` (Samuel Riedel) * [dv] Implement Ibex-specific mcounteren behavior in cosim (Samuel Riedel) * [rtl] Add input to lock mcounteren (Samuel Riedel) * [rtl] Add unpriviledged counter/timers (Samuel Riedel) * [rtl] Add register for `mcounteren` (Samuel Riedel) * [rtl] Fix incrementing `minstret` after setting it (Samuel Riedel) * [rtl] Fix speculative increment of `minstret` (Samuel Riedel) * [syn] Fix scripts for new vendored lowrisc_ip (Harry Callahan) * [syn] Add nix devShell for example synthesis flow (Harry Callahan) * [dv] Fixup explicit static lifetime on initializer by seperating decl from assign. (Harry Callahan) * [vendor/google_riscv-dv] Add VCS -Xcflags to suppress build warnings (Harry Callahan) * [vendor/google_riscv-dv] use env bash and non-absolute bash paths (Harry Callahan) * [rtl] Explicitly define mapping to `prim_generic` for linter targets (Samuel Riedel) * [rtl] Fix prim_generic mapping in ibex_top (Samuel Riedel) * [rtl] Move prim_generic dependency to ibex_top (Samuel Riedel) * [doc] Ibex Concierge updated (Marno van der Maas) Signed-off-by: Samuel Riedel --- .../rv_core_ibex/rtl/rv_core_ibex.sv.tpl | 33 +- .../rv_core_ibex/rtl/rv_core_ibex.sv | 33 +- .../rv_core_ibex/rtl/rv_core_ibex.sv | 33 +- .../rv_core_ibex/rtl/rv_core_ibex.sv | 33 +- hw/vendor/lowrisc_ibex.lock.hjson | 2 +- .../doc/01_overview/compliance.rst | 4 + .../doc/03_reference/performance_counters.rst | 20 +- .../doc/04_developer/concierge.rst | 41 +- .../lowrisc_ibex/dv/cosim/spike_cosim.cc | 18 +- hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.h | 1 + hw/vendor/lowrisc_ibex/dv/formal/check/top.sv | 12 +- .../rtl/ibex_riscv_compliance.sv | 1 + .../directed_tests/directed_testlist.yaml | 17 + .../core_ibex/directed_tests/gen_testlist.py | 21 +- .../mcounteren_test/mcounteren_lock_test.S | 62 +++ .../mcounteren_test/mcounteren_test.S | 353 ++++++++++++++++++ .../core_ibex/env/core_ibex_dut_probe_if.sv | 5 +- .../dv/uvm/core_ibex/tb/core_ibex_tb_top.sv | 1 + .../uvm/core_ibex/tests/core_ibex_test_lib.sv | 41 ++ .../dv/uvm/core_ibex/yaml/rtl_simulation.yaml | 1 + hw/vendor/lowrisc_ibex/ibex_top.core | 8 + hw/vendor/lowrisc_ibex/ibex_top_tracing.core | 1 + hw/vendor/lowrisc_ibex/rtl/ibex_core.sv | 2 + .../lowrisc_ibex/rtl/ibex_cs_registers.sv | 98 ++++- hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv | 10 +- hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv | 40 +- hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv | 63 ++++ hw/vendor/lowrisc_ibex/rtl/ibex_top.sv | 13 + .../lowrisc_ibex/rtl/ibex_top_tracing.sv | 2 + hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv | 10 +- hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv | 2 +- hw/vendor/lowrisc_ibex/syn/README.md | 32 +- .../{syn_setup.example.sh => syn_setup.sh} | 7 +- hw/vendor/lowrisc_ibex/syn/syn_yosys.sh | 11 +- .../lowrisc_ibex/syn/tcl/yosys_run_synth.tcl | 16 +- .../google_riscv-dv/scripts/check-status | 2 +- .../vendor/google_riscv-dv/scripts/lib.py | 4 +- .../verilog_style/build-verible.sh | 2 +- .../google_riscv-dv/yaml/simulator.yaml | 1 + 39 files changed, 905 insertions(+), 151 deletions(-) create mode 100644 hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_lock_test.S create mode 100644 hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_test.S rename hw/vendor/lowrisc_ibex/syn/{syn_setup.example.sh => syn_setup.sh} (67%) 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 0082a276c5c1a..57e5121a35fd4 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; @@ -567,18 +569,21 @@ 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_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), @@ -835,7 +840,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 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 48f5288af6ff6..eddb743aeed2e 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; @@ -554,18 +556,21 @@ 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_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), @@ -822,7 +827,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 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 48f5288af6ff6..eddb743aeed2e 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; @@ -554,18 +556,21 @@ 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_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), @@ -822,7 +827,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 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 48f5288af6ff6..eddb743aeed2e 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; @@ -554,18 +556,21 @@ 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_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), @@ -822,7 +827,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 diff --git a/hw/vendor/lowrisc_ibex.lock.hjson b/hw/vendor/lowrisc_ibex.lock.hjson index 3a1687915278e..49aa7dcf98bc2 100644 --- a/hw/vendor/lowrisc_ibex.lock.hjson +++ b/hw/vendor/lowrisc_ibex.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/lowRISC/ibex.git - rev: ac911ec101c7e9df5eeb2317ec3db664023b1c24 + rev: aae4809aea170fc605bdaa64a70a13efd2408829 } } 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/spike_cosim.cc b/hw/vendor/lowrisc_ibex/dv/cosim/spike_cosim.cc index daa400709b647..32537875edf94 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()); @@ -832,6 +835,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..2849206e0c9b0 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, 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/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..2ae1487121aea 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..373349fa0bfe3 --- /dev/null +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/directed_tests/mcounteren_test/mcounteren_test.S @@ -0,0 +1,353 @@ +# 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 is checked by the cosim. +check_counter_aliases: + mv s3, ra + + # Custom minstret test + # instret should be exactly 2 more than minstret. + csrr t0, minstret + nop + csrr t1, instret + addi t2, t0, 2 + bne t1, t2, fail + + # Reset minstret to zero. The write should suppress the automatic retirement + # increment, so the immediate read-back will be 0. Reading instret next counts + # the one csr read. + csrwi minstret, 0 + csrr t0, minstret + csrr t1, instret + bnez t0, fail + li t2, 1 + bne t1, t2, fail + + # 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/tb/core_ibex_tb_top.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index a2658d12390fe..270ddac024fec 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 ), 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/dv/uvm/core_ibex/yaml/rtl_simulation.yaml b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml index e3877babdfcf2..84247f23176e2 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml @@ -41,6 +41,7 @@ -CFLAGS '--std=c99 -fno-extended-identifiers' -lca -kdb -debug_access+f + -Xcflags='-Wno-error=implicit-function-declaration -Wno-error=int-conversion' cov_opts: >- -cm line+tgl+assert+fsm+branch 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..85c623abc4c4e 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv @@ -168,6 +168,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 +1136,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), diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv index 11c181b8cef1a..641db2208b420 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, @@ -148,6 +149,8 @@ module ibex_cs_registers import ibex_pkg::*; #( localparam int unsigned RV32BExtra = (RV32B != RV32BNone) ? 1 : 0; localparam int unsigned RV32MEnabled = (RV32M == RV32MNone) ? 0 : 1; localparam int unsigned PMPAddrWidth = (PMPGranularity > 0) ? PMP_ADDR_MSB - PMPGranularity : 32; + // Base index of the first HPM counter (0=cycle, 1=time, 2=instret) + localparam int unsigned MHPMCOUNTER_BASE = 3; // misa localparam logic [31:0] MISA_VALUE = @@ -253,10 +256,15 @@ module ibex_cs_registers import ibex_pkg::*; #( pmp_mseccfg_t pmp_mseccfg; // Hardware performance monitor signals - logic [31:0] mcountinhibit; + logic [31:0] mcountinhibit; // Only have mcountinhibit flops for counters that actually exist - logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q; - logic mcountinhibit_we; + logic [MHPMCounterNum+MHPMCOUNTER_BASE-1:0] mcountinhibit_d, mcountinhibit_q; + logic mcountinhibit_we; + + // mcounteren: machine counter enable (controls U-mode counter access) + logic [31:0] mcounteren; + logic [MHPMCounterNum+MHPMCOUNTER_BASE-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 @@ -374,9 +382,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 +510,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 +633,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 +711,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, @@ -1271,12 +1308,23 @@ module ibex_cs_registers import ibex_pkg::*; #( always_comb begin : mcountinhibit_update if (mcountinhibit_we == 1'b1) begin // bit 1 must always be 0 - mcountinhibit_d = {csr_wdata_int[MHPMCounterNum+2:2], 1'b0, csr_wdata_int[0]}; + mcountinhibit_d = csr_wdata_int[MHPMCounterNum+MHPMCOUNTER_BASE-1:0]; + mcountinhibit_d[1] = 1'b0; end else begin mcountinhibit_d = mcountinhibit_q; 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+MHPMCOUNTER_BASE-1:0]; + mcounteren_d[1] = 1'b0; + end else begin + mcounteren_d = mcounteren_q; + end + end + // event selection (hardwired) & control always_comb begin : gen_mhpmcounter_incr @@ -1312,14 +1360,15 @@ module ibex_cs_registers import ibex_pkg::*; #( for (int i = 0; i < 32; i++) begin : gen_mhpmevent_active mhpmevent[i] = '0; - if (i >= 3) begin - mhpmevent[i][i - 3] = 1'b1; + if (i >= MHPMCOUNTER_BASE) begin + mhpmevent[i][i - MHPMCOUNTER_BASE] = 1'b1; end end // deactivate mhpmevent[1] = '0; // not existing, reserved - for (int unsigned i = 3 + MHPMCounterNum; i < 32; i++) begin : gen_mhpmevent_inactive + for (int unsigned i = MHPMCOUNTER_BASE + MHPMCounterNum; i < 32; i++) + begin : gen_mhpmevent_inactive mhpmevent[i] = '0; end end @@ -1370,8 +1419,8 @@ module ibex_cs_registers import ibex_pkg::*; #( assign unused_mhpmcounter_incr_1 = mhpmcounter_incr[1]; // Iterate through optionally included counters (MHPMCounterNum controls how many are included) - for (genvar i = 0; i < 29; i++) begin : gen_cntrs - localparam int Cnt = i + 3; + for (genvar i = 0; i < 32 - MHPMCOUNTER_BASE; i++) begin : gen_cntrs + localparam int Cnt = i + MHPMCOUNTER_BASE; if (i < MHPMCounterNum) begin : gen_imp logic [63:0] mhpmcounter_raw, mhpmcounter_next; @@ -1419,9 +1468,9 @@ module ibex_cs_registers import ibex_pkg::*; #( assign mcountinhibit = {{29 - MHPMCounterNum{1'b0}}, mcountinhibit_q}; // Lint tieoffs for unused bits - assign unused_mhphcounter_we = mhpmcounter_we[31:MHPMCounterNum+3]; - assign unused_mhphcounterh_we = mhpmcounterh_we[31:MHPMCounterNum+3]; - assign unused_mhphcounter_incr = mhpmcounter_incr[31:MHPMCounterNum+3]; + assign unused_mhphcounter_we = mhpmcounter_we[31:MHPMCounterNum+MHPMCOUNTER_BASE]; + assign unused_mhphcounterh_we = mhpmcounterh_we[31:MHPMCounterNum+MHPMCOUNTER_BASE]; + assign unused_mhphcounter_incr = mhpmcounter_incr[31:MHPMCounterNum+MHPMCOUNTER_BASE]; end else begin : g_mcountinhibit_full assign mcountinhibit = mcountinhibit_q; end @@ -1434,6 +1483,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+MHPMCOUNTER_BASE), + .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_id_stage.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv index 81fe19253f22d..a7c27f7683fc7 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv @@ -1076,9 +1076,15 @@ module ibex_id_stage #( end // Signal which instructions to count as retired in minstret, all traps along with ebrk and - // ecall instructions are not counted. + // ecall instructions are not counted. Writes to minstret/minstreth themselves are also excluded + // to avoid incrementing right after a write. + logic minstret_write; + assign minstret_write = csr_access_o & + (csr_op_o inside {CSR_OP_WRITE, CSR_OP_SET, CSR_OP_CLEAR}) & + (csr_addr_o inside {CSR_MINSTRET, CSR_MINSTRETH}); + assign instr_perf_count_id_o = ~ebrk_insn & ~ecall_insn_dec & ~illegal_insn_dec & - ~illegal_csr_insn_i & ~instr_fetch_err_i; + ~illegal_csr_insn_i & ~instr_fetch_err_i & ~minstret_write; // An instruction is ready to move to the writeback stage (or retire if there is no writeback // stage) diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv index f83f3061f2a30..b0fb5ed7b7f18 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 // @@ -554,6 +557,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..0f6419a89d3a2 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv @@ -160,6 +160,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 +245,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 +298,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; @@ -449,6 +456,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 +837,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 +888,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 +932,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 +976,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 +1095,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..3823dd219e756 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, @@ -313,6 +314,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/hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv index 789cb1ca8dba2..3c55b7161c6ac 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv @@ -853,7 +853,8 @@ module ibex_tracer ( // as a blocking assignment to xx. They then complain about the mixture with that an the // non-blocking assignment we use when opening the file. The bug is fixed with recent versions // of Verilator, but this hack is probably worth it for now. - static int fh = file_handle; + int fh; + fh = file_handle; $fclose(fh); end end @@ -861,10 +862,13 @@ module ibex_tracer ( // log execution always @(posedge clk_i) begin if (rvfi_valid && trace_log_enable) begin - static int fh = file_handle; + + int fh; + fh = file_handle; if (fh == 32'h0) begin - static string file_name_base = "trace_core"; + string file_name_base; + file_name_base = "trace_core"; void'($value$plusargs("ibex_tracer_file_base=%s", file_name_base)); $sformat(file_name, "%s_%h.log", file_name_base, hart_id_i); diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv index 38ce421ca0a2f..5c8075de4e3c0 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv @@ -155,7 +155,7 @@ module ibex_wb_stage #( // Speculative versions of the signals do not factor in exceptions and whether the instruction // is done yet. These are used to get correct values for instructions reading the relevant // performance counters in the ID stage. - assign perf_instr_ret_wb_spec_o = wb_count_q; + assign perf_instr_ret_wb_spec_o = wb_count_q & wb_valid_q; assign perf_instr_ret_compressed_wb_spec_o = perf_instr_ret_wb_spec_o & wb_compressed_q; assign perf_instr_ret_wb_o = instr_done_wb_o & wb_count_q & ~(lsu_resp_valid_i & lsu_resp_err_i); diff --git a/hw/vendor/lowrisc_ibex/syn/README.md b/hw/vendor/lowrisc_ibex/syn/README.md index 0c5792b09dbd1..1e198189bb58a 100644 --- a/hw/vendor/lowrisc_ibex/syn/README.md +++ b/hw/vendor/lowrisc_ibex/syn/README.md @@ -2,6 +2,23 @@ tape-out quality netlists and area/timing numbers it generates are not representative of what would be achievable with a tape-out quality flow** +# Quick start with Nix + +If you have Nix with flakes enabled, all dependencies and the Nangate45 cell +library are provided automatically via the `syn_shell` devShell. Enter the +shell and run the flow: + +```sh +nix develop .#syn_shell +cd syn +./syn_yosys.sh +``` + +No further setup is needed — `syn_setup.sh` is pre-configured and +`LR_SYNTH_CELL_LIBRARY_PATH`/`LR_SYNTH_CELL_LIBRARY_NAME` are exported by the +shell hook. The remaining sections describe manual installation for non-Nix +environments. + # Yosys/OpenSTA Ibex Synthesis Flow This is a synthesis-only implementation flow using Yosys for Synthesis and @@ -39,13 +56,14 @@ format. The following Open Libraries can be used: # Synthesis flow setup -The synthesis flow is configured via environment variables. The `syn_setup.sh` -file is used to set the environment variables for the flow and any changes made -should be placed there. An example `syn_setup.example.sh` is included. A copy -of this named `syn_setup.sh` must be made and the values in it set appropriately -for the flow to work. +The synthesis flow is configured via environment variables. `syn_setup.sh` sets +the environment variables for the flow. + +When using `nix develop .#syn_shell`, the cell library variables below are +exported automatically by the shell hook and no edits to `syn_setup.sh` are +needed. For non-Nix environments, set them manually in `syn_setup.sh`. -The environment variables that must be set in `syn_setup.sh` are +The environment variables that must be set are: * `LR_SYNTH_CELL_LIBRARY_PATH` - The path to the standard cell library, this should point to the absolute path of the Nangate45 library @@ -56,7 +74,7 @@ The environment variables that must be set in `syn_setup.sh` are # Running the synthesis flow -Once `syn_setup.sh` has been created, call `syn_yosys.sh` to run the entire +Once the environment is configured, call `syn_yosys.sh` to run the entire flow. All outputs are placed under the `syn/syn_out` directory with the prefix `ibex_` with the current date/time forming the rest of the name, e.g. `syn/syn_out/ibex_06_01_2020_11_19_15` diff --git a/hw/vendor/lowrisc_ibex/syn/syn_setup.example.sh b/hw/vendor/lowrisc_ibex/syn/syn_setup.sh similarity index 67% rename from hw/vendor/lowrisc_ibex/syn/syn_setup.example.sh rename to hw/vendor/lowrisc_ibex/syn/syn_setup.sh index 5d9a07d099887..b90ba82aac206 100755 --- a/hw/vendor/lowrisc_ibex/syn/syn_setup.example.sh +++ b/hw/vendor/lowrisc_ibex/syn/syn_setup.sh @@ -18,7 +18,10 @@ fi export LR_SYNTH_TIMING_RUN=1 export LR_SYNTH_FLATTEN=1 -# SETUP CELL LIBRARY PATH -# Uncomment the lines below and set the path to an appropriate .lib file +# When using `nix develop .#syn_shell`, the following are set automatically by +# the shell hook (via nix/syn.nix): +# LR_SYNTH_CELL_LIBRARY_PATH (path to NangateOpenCellLibrary_typical.lib) +# LR_SYNTH_CELL_LIBRARY_NAME (nangate) +# For non-Nix environments, uncomment and set these manually: # export LR_SYNTH_CELL_LIBRARY_PATH=/path/to/NangateOpenCellLibrary_typical.lib # export LR_SYNTH_CELL_LIBRARY_NAME=nangate diff --git a/hw/vendor/lowrisc_ibex/syn/syn_yosys.sh b/hw/vendor/lowrisc_ibex/syn/syn_yosys.sh index 6281dde62bb74..c4b2c748b4117 100755 --- a/hw/vendor/lowrisc_ibex/syn/syn_yosys.sh +++ b/hw/vendor/lowrisc_ibex/syn/syn_yosys.sh @@ -37,10 +37,10 @@ LR_DEP_SOURCES=( "../vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_dec.sv" "../vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_enc.sv" "../vendor/lowrisc_ip/ip/prim/rtl/prim_lfsr.sv" - "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_and2.sv" - "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_buf.sv" - "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_clock_mux2.sv" - "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_flop.sv" + "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_and2.sv" + "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_buf.sv" + "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_clock_mux2.sv" + "../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_flop.sv" ) mkdir -p "$LR_SYNTH_OUT_DIR/generated" @@ -78,8 +78,9 @@ for file in ../rtl/*.sv; do sv2v \ --define=SYNTHESIS --define=YOSYS \ ../rtl/*_pkg.sv \ - ../vendor/lowrisc_ip/ip/prim/rtl/prim_ram_1p_pkg.sv \ + ../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_ram_1p_pkg.sv \ ../vendor/lowrisc_ip/ip/prim/rtl/prim_secded_pkg.sv \ + ../vendor/lowrisc_ip/ip/prim/rtl/prim_util_pkg.sv \ -I../vendor/lowrisc_ip/ip/prim/rtl \ -I../vendor/lowrisc_ip/dv/sv/dv_utils \ "$file" \ diff --git a/hw/vendor/lowrisc_ibex/syn/tcl/yosys_run_synth.tcl b/hw/vendor/lowrisc_ibex/syn/tcl/yosys_run_synth.tcl index 01de2d64a14bd..6aff7f7ade487 100644 --- a/hw/vendor/lowrisc_ibex/syn/tcl/yosys_run_synth.tcl +++ b/hw/vendor/lowrisc_ibex/syn/tcl/yosys_run_synth.tcl @@ -35,10 +35,10 @@ if { $lr_synth_ibex_secure_ibex } { # Place keep_hierarchy contraints on relevant modules to prevent aggressive # synthesis optimzations across the boundaries of these modules. yosys "hierarchy -check -top $lr_synth_top_module" - yosys "setattr -mod -set keep_hierarchy 1 *prim_generic_and2*" - yosys "setattr -mod -set keep_hierarchy 1 *prim_generic_buf*" - yosys "setattr -mod -set keep_hierarchy 1 *prim_generic_clock_mux2*" - yosys "setattr -mod -set keep_hierarchy 1 *prim_generic_flop*" + yosys "setattr -mod -set keep_hierarchy 1 *prim_and2*" + yosys "setattr -mod -set keep_hierarchy 1 *prim_buf*" + yosys "setattr -mod -set keep_hierarchy 1 *prim_clock_mux2*" + yosys "setattr -mod -set keep_hierarchy 1 *prim_flop*" } yosys "synth $flatten_opt -top $lr_synth_top_module" @@ -63,10 +63,10 @@ if { $lr_synth_timing_run } { if { $lr_synth_ibex_secure_ibex } { # Remove keep_hierarchy constraints before the final flattening step. # We're done optimizing. - yosys "setattr -mod -set keep_hierarchy 0 *prim_generic_and2*" - yosys "setattr -mod -set keep_hierarchy 0 *prim_generic_buf*" - yosys "setattr -mod -set keep_hierarchy 0 *prim_generic_clock_mux2*" - yosys "setattr -mod -set keep_hierarchy 0 *prim_generic_flop*" + yosys "setattr -mod -set keep_hierarchy 0 *prim_and2*" + yosys "setattr -mod -set keep_hierarchy 0 *prim_buf*" + yosys "setattr -mod -set keep_hierarchy 0 *prim_clock_mux2*" + yosys "setattr -mod -set keep_hierarchy 0 *prim_flop*" } # Final flattening. diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/check-status b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/check-status index ec76d7e371b66..b28845597e6b0 100755 --- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/check-status +++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/check-status @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Check the return code of run.py in order to give a pass/fail indication to Metrics echo "run.py return code:" $1 diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/lib.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/lib.py index 872752f0011cf..3636aedbd0faa 100644 --- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/lib.py +++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/scripts/lib.py @@ -106,7 +106,7 @@ def run_cmd(cmd, timeout_s=999, exit_on_error=1, check_return_code=True, try: ps = subprocess.Popen("exec " + cmd, shell=True, - executable='/bin/bash', + executable='bash', universal_newlines=True, start_new_session=True, env=os.environ, @@ -157,7 +157,7 @@ def run_parallel_cmd(cmd_list, timeout_s=999, exit_on_error=0, for cmd in cmd_list: ps = subprocess.Popen("exec " + cmd, shell=True, - executable='/bin/bash', + executable='bash', universal_newlines=True, start_new_session=True, stdout=subprocess.PIPE, diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/verilog_style/build-verible.sh b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/verilog_style/build-verible.sh index 764af22df922a..f466cc822f5d3 100755 --- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/verilog_style/build-verible.sh +++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/verilog_style/build-verible.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Copyright 2019 Google LLC # diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/yaml/simulator.yaml b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/yaml/simulator.yaml index 76dd6f1e64e5b..5b904d982bb21 100644 --- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/yaml/simulator.yaml +++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/yaml/simulator.yaml @@ -28,6 +28,7 @@ -LDFLAGS '-Wl,--no-as-needed' -CFLAGS '--std=c99 -fno-extended-identifiers' -Mdir=/vcs_simv.csrc + -Xcflags='-Wno-error=implicit-function-declaration -Wno-error=int-conversion' -o /vcs_simv " cov_opts: > -cm_dir /test.vdb From 160e316adde33d5de84091e583debbe749726177 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Mon, 18 May 2026 10:33:29 +0200 Subject: [PATCH 3/3] [sw] Add mcounteren_writable test Software test to verify that the `mcounteren_writable` can be set and cleared and locked. This test also verifies that it locks the `mcounteren` CSR in Ibex Signed-off-by: Samuel Riedel --- .../data/ip/chip_rv_core_ibex_testplan.hjson | 10 ++ hw/top_earlgrey/dv/chip_sim_cfg.hjson | 7 + sw/device/tests/BUILD | 14 ++ .../rv_core_ibex_mcounteren_writable_test.c | 164 ++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 sw/device/tests/rv_core_ibex_mcounteren_writable_test.c 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 b63e5d5905e7f..b487fc15dfa0c 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -2046,6 +2046,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/sw/device/tests/BUILD b/sw/device/tests/BUILD index 52445cb30db59..c09a0393dc7d8 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -7299,6 +7299,20 @@ 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:rv_core_ibex_c_regs", + "//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..71e127cd17fa2 --- /dev/null +++ b/sw/device/tests/rv_core_ibex_mcounteren_writable_test.c @@ -0,0 +1,164 @@ +// 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); + + // Enable mcounteren again. + csr_write_mcounteren(MCOUNTERS_ENABLE); + mcounteren_val = csr_read_mcounteren(); + CHECK(mcounteren_val == MCOUNTERS_ENABLE, + "mcounteren should be writable again after restoring config. Expected " + "0x%x, got 0x%x", + MCOUNTERS_ENABLE, 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_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); + + // 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; +}