diff --git a/hw/ip/BUILD b/hw/ip/BUILD index fe658908eaa45..bdcc624d5ded4 100644 --- a/hw/ip/BUILD +++ b/hw/ip/BUILD @@ -18,6 +18,7 @@ filegroup( "//hw/ip/aes:rtl_files", "//hw/ip/aon_timer:rtl_files", "//hw/ip/bkdr_loader:rtl_files", + "//hw/ip/cheriot:rtl_files", "//hw/ip/csrng:rtl_files", "//hw/ip/dma:rtl_files", "//hw/ip/edn:rtl_files", diff --git a/hw/ip/README.md b/hw/ip/README.md index 2502c91844a3b..b29652453a284 100644 --- a/hw/ip/README.md +++ b/hw/ip/README.md @@ -9,6 +9,7 @@ | [`aon_timer`] | Wakeup and watchdog timers running on a low-power, always-on clock | | [`ascon`] | Ascon authenticated encryption and decryption engine | | [`bkdr_loader`] | Provides FPGA-only indirect programming to RAMs | +| [`cheriot`] | CHERIoT-aware memory subsystem | | [`csrng`] | Takes entropy bits to produce cryptographically secure random numbers for consumption by hardware blocks and by software | | [`dma`] | DMA Controller for the integrated OpenTitan. | | [`edn`] | Distributes random numbers produced by CSRNG to hardware blocks | @@ -44,6 +45,7 @@ [`aon_timer`]: ./aon_timer/README.md [`ascon`]: ./ascon/README.md [`bkdr_loader`]: ./bkdr_loader/README.md +[`cheriot`]: ./cheriot/README.md [`csrng`]: ./csrng/README.md [`dma`]: ./dma/README.md [`edn`]: ./edn/README.md diff --git a/hw/ip/cheriot/BUILD b/hw/ip/cheriot/BUILD new file mode 100644 index 0000000000000..f6177d819d3df --- /dev/null +++ b/hw/ip/cheriot/BUILD @@ -0,0 +1,30 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "rtl_files", + srcs = glob( + ["**"], + exclude = [ + "dv/**", + "doc/**", + "README.md", + ], + ) + [ + "//hw/ip/cheriot/data:all_files", + ], +) + +filegroup( + name = "doc_files", + srcs = glob( + [ + "**/*.md", + "**/*.svg", + ], + allow_empty = True, + ) + ["//hw/ip/cheriot/data:doc_files"], +) diff --git a/hw/ip/cheriot/README.md b/hw/ip/cheriot/README.md new file mode 100644 index 0000000000000..a191db8fed699 --- /dev/null +++ b/hw/ip/cheriot/README.md @@ -0,0 +1 @@ +# CHERIoT diff --git a/hw/ip/cheriot/cheriot.core b/hw/ip/cheriot/cheriot.core new file mode 100644 index 0000000000000..4afb2de312ae4 --- /dev/null +++ b/hw/ip/cheriot/cheriot.core @@ -0,0 +1,26 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: "lowrisc:ip:cheriot:0.1" +description: "CHERIoT IPs" + +filesets: + files_rtl: + depend: + - lowrisc:prim:all + - lowrisc:ip:tlul + - pulp-platform:common_cells:common_cells + files: + - rtl/cheriot_pkg.sv + - rtl/cheriot_switch.sv + - rtl/cheriot_rmw_filter.sv + - rtl/cheriot_tag_filter.sv + - rtl/cheriot_access_check.sv + - rtl/cheriot.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/ip/cheriot/data/BUILD b/hw/ip/cheriot/data/BUILD new file mode 100644 index 0000000000000..7283123de537c --- /dev/null +++ b/hw/ip/cheriot/data/BUILD @@ -0,0 +1,18 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "all_files", + srcs = glob(["**"]), +) + +filegroup( + name = "doc_files", + srcs = glob( + ["*_testplan.hjson"], + allow_empty = True, + ), +) diff --git a/hw/ip/cheriot/data/cheriot.hjson b/hw/ip/cheriot/data/cheriot.hjson new file mode 100644 index 0000000000000..28272e0a7fbe6 --- /dev/null +++ b/hw/ip/cheriot/data/cheriot.hjson @@ -0,0 +1,166 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "cheriot", + human_name: "CHERIoT Memory Subsystem", + one_line_desc: "CHERIoT-aware memory subsystem", + one_paragraph_desc: ''' + The CHERIoT memory subsystem sits between a CHERIoT-capable Ibex core and the system + interconnect. It enforces capability tag semantics on data-memory accesses, transparently + remapping capability accesses and revocation bitmap reads into a dedicated meta SRAM. + ''' + // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. + cip_id: "47", + version: "1.0.0", + life_stage: "L1", + design_stage: "D1", + verification_stage: "V0", + + clocking: [ + {clock: "clk_i", reset: "rst_ni", primary: true} + ], + + bus_interfaces: [ + {protocol: "tlul", direction: "device", name: "revbm"}, + {protocol: "tlul", direction: "host", name: "cored"} + ], + + /////////////////////////// + // Interrupts and Alerts // + /////////////////////////// + + alert_list: [ + ], + + //////////////// + // Parameters // + //////////////// + + param_list: [ + + ///////////////////// + // Address map // + ///////////////////// + + { name: "MainSramBaseAddr", + desc: "Base address of the main SRAM region (inclusive)", + type: "logic [top_pkg::TL_AW-1:0]", + default: "32'h1000_0000", + local: "false", + expose: "true" + }, + { name: "MainSramTopAddr", + desc: "Top address of the main SRAM region (exclusive).", + type: "logic [top_pkg::TL_AW-1:0]", + default: "32'h1002_0000", + local: "false", + expose: "true" + }, + { name: "NvmBaseAddr", + desc: "Base address of the NVM region (inclusive).", + type: "logic [top_pkg::TL_AW-1:0]", + default: "32'h2000_0000", + local: "false", + expose: "true" + }, + { name: "NvmTopAddr", + desc: "Top address of the NVM region (exclusive).", + type: "logic [top_pkg::TL_AW-1:0]", + default: "32'h2020_0000", + local: "false", + expose: "true" + }, + { name: "MetaSramBaseAddr", + desc: ''' + Base address of the CHERIoT meta SRAM region. + ''', + type: "logic [top_pkg::TL_AW-1:0]", + default: "32'h0000_0000", + local: "false", + expose: "true" + }, + ], + + ////////////// + // Features // + ////////////// + + features: [ + ], + + ///////////////////////////// + // Intermodule Connections // + ///////////////////////////// + + inter_signal_list: [ + // CHERIoT mode enable + { struct: "mubi4", + type: "uni", + name: "cheriot_ena", + act: "rcv", + package: "prim_mubi_pkg", + default: "prim_mubi_pkg::MuBi4False", + desc: "CHERIoT mode enable." + }, + // Data TL-UL interface from the core + { struct: "tl", + type: "req_rsp", + name: "cored_tl_d", + act: "rsp", + package: "tlul_pkg", + desc: "Data port from the core." + }, + // Capability tag sideband - write direction (from core to subsystem) + { struct: "logic", + type: "uni", + name: "cored_tag_h2d", + act: "rcv", + width: "1", + package: "", + default: "1'b0", + desc: "CHERIoT capability tag carried with the A-channel of cored_h." + }, + // Capability tag sideband - read response direction (from subsystem to core) + { struct: "logic", + type: "uni", + name: "cored_tag_d2h", + act: "req", + width: "1", + package: "", + default: "1'b0", + desc: "Capability tag returned on the D-channel of cored_h." + }, + // TRVK revocation bitmap TL-UL host port + { struct: "tl", + type: "req_rsp", + name: "corerevbm_tl", + act: "rsp", + package: "tlul_pkg", + desc: "TRVK (tag revocation) revocation bitmap port from the core." + }, + // Meta SRAM host TL-UL port (to external sram_ctrl RAM interface) + { struct: "tl", + type: "req_rsp", + name: "meta_sram_tl", + act: "req", + package: "tlul_pkg", + desc: "Host TL-UL port to the external meta SRAM controller's RAM interface." + }, + ], + + ///////////////////// + // Countermeasures // + ///////////////////// + + countermeasures: [ + ], + + /////////// + // Memory // + /////////// + + memory: { + revbm: {} + } +} diff --git a/hw/ip/cheriot/defs.bzl b/hw/ip/cheriot/defs.bzl new file mode 100644 index 0000000000000..ba321a596fc89 --- /dev/null +++ b/hw/ip/cheriot/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +CHERIOT = opentitan_ip( + name = "cheriot", + hjson = "//hw/ip/cheriot/data:cheriot.hjson", +) diff --git a/hw/ip/cheriot/rtl/cheriot.sv b/hw/ip/cheriot/rtl/cheriot.sv new file mode 100644 index 0000000000000..f38d975777aee --- /dev/null +++ b/hw/ip/cheriot/rtl/cheriot.sv @@ -0,0 +1,224 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "prim_assert.sv" +`include "prim_fifo_assert.svh" + +// TODO: Implement lockstep operation for this module + +module cheriot #( + // TL-UL address type + parameter type addr_t = logic [top_pkg::TL_AW-1:0], + // Top-level address map parameters + parameter addr_t MainSramBaseAddr = 'h1000_0000, + parameter addr_t MainSramTopAddr = 'h1002_0000, + parameter addr_t NvmBaseAddr = 'h2000_0000, + parameter addr_t NvmTopAddr = 'h2020_0000, + parameter addr_t MetaSramBaseAddr = 'h0 +) ( + + input logic clk_i, + input logic rst_ni, + + // CHERIoT mode enabled + input prim_mubi_pkg::mubi4_t cheriot_ena_i, + + // Core data input port + input tlul_pkg::tl_h2d_t cored_tl_d_i, + input logic cored_tag_h2d_i, + output tlul_pkg::tl_d2h_t cored_tl_d_o, + output logic cored_tag_d2h_o, + + // TRVK revocation bitmap input port + input tlul_pkg::tl_h2d_t corerevbm_tl_i, + output tlul_pkg::tl_d2h_t corerevbm_tl_o, + + // System revocation bitmap port + input tlul_pkg::tl_h2d_t revbm_tl_d_i, + output tlul_pkg::tl_d2h_t revbm_tl_d_o, + + // Core data output port towards interconnect + output tlul_pkg::tl_h2d_t cored_tl_h_o, + input tlul_pkg::tl_d2h_t cored_tl_h_i, + + // Meta SRAM host port (to external sram_ctrl) + output tlul_pkg::tl_h2d_t meta_sram_tl_o, + input tlul_pkg::tl_d2h_t meta_sram_tl_i +); + + ///////////////// + // Address map // + ///////////////// + + // Revocation happens on 64-bit or 8-byte granularity. + localparam int unsigned RevocationGranuleByte = 32'd8; + // Number of heap bytes a single TL word in the meta store can track + localparam int unsigned RevocationBytePerWord = top_pkg::TL_DW * RevocationGranuleByte; + + // A capability is 64 bit or 8 byte wide + localparam int unsigned CapabilitySizeByte = 32'd8; + // Number of capability bytes a single TL word in the meta store can track + localparam int unsigned CapabilityBytePerWord = top_pkg::TL_DW * CapabilitySizeByte; + + // Size of the TRVK revocation bitmap + localparam addr_t RevBmSizeWord = (MainSramTopAddr - MainSramBaseAddr) / RevocationBytePerWord; + localparam addr_t RevBmSizeByte = RevBmSizeWord * (top_pkg::TL_DW / 32'd8); + // Size of the SRAM tag store + localparam addr_t SramTagSizeWord = (MainSramTopAddr - MainSramBaseAddr) / CapabilityBytePerWord; + localparam addr_t SramTagSizeByte = SramTagSizeWord * (top_pkg::TL_DW / 32'd8); + // Size of the NVM tag store + localparam addr_t NvmTagSizeWord = (NvmTopAddr - NvmBaseAddr) / CapabilityBytePerWord; + localparam addr_t NvmTagSizeByte = NvmTagSizeWord * (top_pkg::TL_DW / 32'd8); + + // Address map + localparam addr_t MetaRevBmBase = MetaSramBaseAddr; + localparam addr_t MetaNvmTagBase = MetaRevBmBase + RevBmSizeByte; + localparam addr_t MetaMainSramTagBase = MetaNvmTagBase + NvmTagSizeByte; + localparam addr_t MetaTop = MetaMainSramTagBase + SramTagSizeByte; + + + ///////////// + // Signals // + ///////////// + + tlul_pkg::tl_h2d_t rmw_tl_h2d; + logic rmw_tag_h2d; + tlul_pkg::tl_d2h_t rmw_tl_d2h; + logic rmw_tag_d2h; + + tlul_pkg::tl_h2d_t tags_tl_h2d; + tlul_pkg::tl_d2h_t tags_tl_d2h; + + tlul_pkg::tl_h2d_t meta_mux_in_tl_h2d[32'd3]; + tlul_pkg::tl_d2h_t meta_mux_in_tl_d2h[32'd3]; + + + //////////// + // Filter // + //////////// + + cheriot_access_check #( + .addr_t(addr_t), + .CheriotBaseAddr(MetaRevBmBase), + .CheriotTopAddr(MetaNvmTagBase), + .CheriotSubWordAllowed(1'b0) + ) u_cheriot_access_check_trvk ( + .clk_i, + .rst_ni, + .cheriot_ena_i, + .tl_h_i(corerevbm_tl_i), + .tl_h_o(corerevbm_tl_o), + .tl_d_o(meta_mux_in_tl_h2d[32'd0]), + .tl_d_i(meta_mux_in_tl_d2h[32'd0]) + ); + + cheriot_tag_filter #( + .NumOutstanding(32'd2) + ) u_cheriot_tag_filter ( + .clk_i, + .rst_ni, + .cheriot_ena_i, + .tl_d_i (cored_tl_d_i), + .tag_d_i(cored_tag_h2d_i), + .tl_d_o (cored_tl_d_o), + .tag_d_o(cored_tag_d2h_o), + .tl_m_o (rmw_tl_h2d), + .tag_m_o(rmw_tag_h2d), + .tl_m_i (rmw_tl_d2h), + .tag_m_i(rmw_tag_d2h), + .tl_h_o (cored_tl_h_o), + .tl_h_i (cored_tl_h_i) + ); + + cheriot_rmw_filter #( + .addr_t(addr_t), + .MainSramBaseAddr(MainSramBaseAddr), + .MainSramTopAddr(MainSramTopAddr), + .NvmBaseAddr(NvmBaseAddr), + .NvmTopAddr(NvmTopAddr), + .MetaMainSramTagBase(MetaMainSramTagBase), + .MetaNvmTagBase(MetaNvmTagBase) + ) u_cheriot_rmw_filter ( + .clk_i, + .rst_ni, + .tl_h_i (rmw_tl_h2d), + .tag_h_i (rmw_tag_h2d), + .tl_h_o (rmw_tl_d2h), + .tag_h_o (rmw_tag_d2h), + .tl_d_o (tags_tl_h2d), + .tl_d_i (tags_tl_d2h), + .data_intg_error_o(), // TODO: add alert endpoint and connect error signals + .rsp_intg_error_o (), // TODO: add alert endpoint and connect error signals + .device_error_o () // TODO: add alert endpoint and connect error signals + ); + + cheriot_access_check #( + .addr_t(addr_t), + .CheriotBaseAddr(MetaNvmTagBase), + .CheriotTopAddr(MetaTop), + .CheriotSubWordAllowed(1'b0) + ) u_cheriot_access_check_tags ( + .clk_i, + .rst_ni, + .cheriot_ena_i, + .tl_h_i(tags_tl_h2d), + .tl_h_o(tags_tl_d2h), + .tl_d_o(meta_mux_in_tl_h2d[32'd1]), + .tl_d_i(meta_mux_in_tl_d2h[32'd1]) + ); + + cheriot_access_check #( + .addr_t(addr_t), + .CheriotBaseAddr(MetaRevBmBase), + .CheriotTopAddr(MetaNvmTagBase), + .CheriotSubWordAllowed(1'b0) + ) u_cheriot_access_check_sys ( + .clk_i, + .rst_ni, + .cheriot_ena_i, + .tl_h_i(revbm_tl_d_i), + .tl_h_o(revbm_tl_d_o), + .tl_d_o(meta_mux_in_tl_h2d[32'd2]), + .tl_d_i(meta_mux_in_tl_d2h[32'd2]) + ); + + + /////////////////////// + // Meta multiplexing // + /////////////////////// + + tlul_socket_m1 #( + .M(32'd3), + .HReqDepth('0), + .HRspDepth('0), + .DReqDepth('0), + .DRspDepth('0) + ) u_tlul_socket_m1 ( + .clk_i, + .rst_ni, + .tl_h_i(meta_mux_in_tl_h2d), + .tl_h_o(meta_mux_in_tl_d2h), + .tl_d_o(meta_sram_tl_o), + .tl_d_i(meta_sram_tl_i) + ); + + + //////////////// + // Assertions // + //////////////// + +`ifdef INC_ASSERT + // Tied-off alert and FIFO assertion + prim_alert_pkg::alert_tx_t unused_tag_filter_alert_tx; + assign unused_tag_filter_alert_tx.alert_p = 1'b0; + assign unused_tag_filter_alert_tx.alert_n = 1'b1; + + `ASSERT_PRIM_FIFO_SYNC_ERROR_TRIGGERS_ALERT(CheriotTagFilterFifo_A, + u_cheriot_tag_filter.u_prim_fifo_sync_align, + unused_tag_filter_alert_tx, + 0, + 30) +`endif + +endmodule diff --git a/hw/ip/cheriot/rtl/cheriot_access_check.sv b/hw/ip/cheriot/rtl/cheriot_access_check.sv new file mode 100644 index 0000000000000..f7e8a379eaf17 --- /dev/null +++ b/hw/ip/cheriot/rtl/cheriot_access_check.sv @@ -0,0 +1,118 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module cheriot_access_check #( + // TL-UL address type + parameter type addr_t = logic [top_pkg::TL_AW-1:0], + // Start address (inclusive) + parameter addr_t CheriotBaseAddr = 'h0, + // End address (non-inclusive) + parameter addr_t CheriotTopAddr = 'h1, + // Are we allowed to `PutPartialData` in CHERIoT mode? + parameter bit CheriotSubWordAllowed = 1'b0 +) ( + input logic clk_i, + input logic rst_ni, + + // CHERIoT mode enabled + input prim_mubi_pkg::mubi4_t cheriot_ena_i, + + // TL host port + input tlul_pkg::tl_h2d_t tl_h_i, + output tlul_pkg::tl_d2h_t tl_h_o, + + // TL device port + output tlul_pkg::tl_h2d_t tl_d_o, + input tlul_pkg::tl_d2h_t tl_d_i +); + + import tlul_pkg::*; + + + ///////////// + // Signals // + ///////////// + + tlul_pkg::tl_h2d_t tl_demux_h2d[32'd2]; + tlul_pkg::tl_d2h_t tl_demux_d2h[32'd2]; + + tlul_pkg::tl_h2d_t tl_err_h2d; + tlul_pkg::tl_d2h_t tl_err_d2h; + + logic allow_forward; + logic allowed_operation; + + + //////////////////// + // Access Checker // + //////////////////// + + always_comb begin: proc_allow_forward + + // Default: do not forward + allow_forward = 1'b0; + allowed_operation = 1'b0; + + // CHERIoT mode enabled + if(prim_mubi_pkg::mubi4_test_true_strict(cheriot_ena_i)) begin + + // Check whether we have a valid operation + allowed_operation = CheriotSubWordAllowed ? + tl_h_i.a_opcode inside {PutFullData, PutPartialData, Get} : + tl_h_i.a_opcode inside {PutFullData, Get}; + + // Forward if address range is valid, operation is allowed, and we can use the device in + // the currently active mode. + allow_forward = tl_h_i.a_address >= CheriotBaseAddr && + tl_h_i.a_address < CheriotTopAddr && + allowed_operation; + + // CHERIoT mode disabled: no access + end else if (prim_mubi_pkg::mubi4_test_false_strict(cheriot_ena_i)) begin + allow_forward = 1'b0; + + // Something else; redirect to error response + end else begin + allow_forward = 1'b0; + end + end + + + /////////////// + // TL Muxing // + /////////////// + + tlul_socket_1n #( + .N(32'd2), + .HReqDepth('h0), + .HRspDepth('h0), + .DReqDepth('h0), + .DRspDepth('h0), + .ExplicitErrs(1'b0) + ) u_tlul_socket_1n ( + .clk_i, + .rst_ni, + .tl_h_i ( tl_h_i ), + .tl_h_o ( tl_h_o ), + .tl_d_o ( tl_demux_h2d ), + .tl_d_i ( tl_demux_d2h ), + .dev_select_i( !allow_forward ) + ); + + assign tl_d_o = tl_demux_h2d[0]; + assign tl_err_h2d = tl_demux_h2d[1]; + + assign tl_demux_d2h[0] = tl_d_i; + assign tl_demux_d2h[1] = tl_err_d2h; + + tlul_err_resp #( + .ReturnBlankResp(1'b0) + ) u_tlul_err_resp ( + .clk_i, + .rst_ni, + .tl_h_i(tl_err_h2d), + .tl_h_o(tl_err_d2h) + ); + +endmodule diff --git a/hw/ip/cheriot/rtl/cheriot_pkg.sv b/hw/ip/cheriot/rtl/cheriot_pkg.sv new file mode 100644 index 0000000000000..ae13d10506cd5 --- /dev/null +++ b/hw/ip/cheriot/rtl/cheriot_pkg.sv @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package cheriot_pkg; + + // Encoding generated at commit 1eb8139d51 using Python 3.10.19 with: + // $ ./util/design/sparse-fsm-encode.py --language=sv \ + // --seed 492361 --distance 4 --states 3 --bits 6 + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: |||||||||||||||||||| (100.00%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 4 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 3 + // Maximum Hamming weight: 5 + // + localparam int SwitchStateWidth = 6; + typedef enum logic [SwitchStateWidth-1:0] { + Unlocked = 6'b010110, + LockedEna = 6'b100101, + LockedDis = 6'b111011, + Error = 6'b001000 + } switch_state_e; + +endpackage diff --git a/hw/ip/cheriot/rtl/cheriot_rmw_filter.sv b/hw/ip/cheriot/rtl/cheriot_rmw_filter.sv new file mode 100644 index 0000000000000..4db54db30dae9 --- /dev/null +++ b/hw/ip/cheriot/rtl/cheriot_rmw_filter.sv @@ -0,0 +1,394 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module cheriot_rmw_filter + import cheriot_pkg::*; +#( + // TL-UL address type + parameter type addr_t = logic [top_pkg::TL_AW-1:0], + parameter addr_t MainSramBaseAddr = 'h0, + parameter addr_t MainSramTopAddr = 'h0, + parameter addr_t NvmBaseAddr = 'h0, + parameter addr_t NvmTopAddr = 'h0, + parameter addr_t MetaMainSramTagBase = 'h0, + parameter addr_t MetaNvmTagBase = 'h0 +) ( + input logic clk_i, + input logic rst_ni, + + // Host port + input tlul_pkg::tl_h2d_t tl_h_i, + input logic tag_h_i, + output tlul_pkg::tl_d2h_t tl_h_o, + output logic tag_h_o, + + // Device port + output tlul_pkg::tl_h2d_t tl_d_o, + input tlul_pkg::tl_d2h_t tl_d_i, + + // Error signals + output logic data_intg_error_o, + output logic rsp_intg_error_o, + output logic device_error_o +); + + /////////// + // Types // + /////////// + + // The padding to 57 bit of the BM response fields subject to ECC + localparam int unsigned RspIntgPadding = tlul_pkg::D2HRspMaxWidth - + $bits(tlul_pkg::tl_d2h_rsp_intg_t); + + typedef enum logic [1:0] { + Passthrough = 2'h0, + Fill = 2'h1, + WriteBackReq = 2'h2, + WriteBackAck = 2'h3 + } bit_rmw_state_e; + + typedef struct packed { + logic [31:8] meta_word; + logic [7:3] bit_sel; + logic [2:0] rsvd; + } meta_addr_t; + + + ///////////// + // Signals // + ///////////// + + bit_rmw_state_e state_d, state_q; + + // Signals concerning the multiplexing of the TL-UL H2D requests + logic forward_r_req; + logic emit_r_req; + logic emit_w_req; + + // Signals concerning the multiplexing of the TL-UL H2D responses + logic ack_fill; + logic ack_skip; + logic ack_write_back; + + // We need to keep track of ongoing reads + logic is_read_d, is_read_q; + + // We need to store the address of the access + meta_addr_t meta_addr_d, meta_addr_q; + + // Remapped address + meta_addr_t addr_sel, addr_stem, addr_remap; + + // Unused address signals + logic unused_addr; + + // We need to store whether a capability write had a valid tag bit + logic tag_q; + + // We need to store the word read before writing it back modified + logic [31:0] word_q; + + // Helper signals + logic skip_write_back; + logic update_word; + + // Device response ECC signals + tlul_pkg::tl_d2h_rsp_intg_t rsp_intg; + logic [1:0] rsp_intg_error; + logic [1:0] rsp_data_intg_error; + + + //////////////////// + // Helper Signals // + //////////////////// + + // We assign the address to an internally defined packed struct to gain access to its fields. + assign meta_addr_d = tl_h_i.a_address; + // We can skip the write back operation if the tag to be written matches the current state + assign skip_write_back = tl_d_i.d_data[meta_addr_q.bit_sel] == tag_q; + + + ///////////////// + // Control FSM // + ///////////////// + + always_comb begin : proc_rwm_fsm + + // state stays stable + state_d = state_q; + + forward_r_req = 1'b0; + emit_r_req = 1'b0; + emit_w_req = 1'b0; + + ack_fill = 1'b0; + ack_skip = 1'b0; + ack_write_back = 1'b0; + + is_read_d = 1'b0; + update_word = 1'b0; + + unique case(state_q) + + // The pass-through state allows reads to just be forwarded. Should a properly handshaked + // write arrive request pass, we switch to the Fill state. + Passthrough: begin + if(tl_h_i.a_opcode == tlul_pkg::PutFullData || + tl_h_i.a_opcode == tlul_pkg::PutPartialData) begin + emit_r_req = 1'b1; + if(tl_h_i.a_valid && tl_h_o.a_ready) begin + state_d = Fill; + end + end else if(tl_h_i.a_opcode == tlul_pkg::Get) begin + forward_r_req = 1'b1; + is_read_d = 1'b1; + end + end + + // In fill, we check whether the read data matches the capability bit we intend to write. If + // so, we can omit the write back and return back to pass-through. If not, we have to do + // the modification followed by the write back. + Fill: begin + if(tl_d_i.d_valid) begin + // We don't have to do anything more + if(skip_write_back) begin + ack_skip = 1'b1; + if(tl_h_i.d_ready) begin + state_d = Passthrough; + end + // An update of the SRAM state is required + end else begin + ack_fill = 1'b1; + update_word = 1'b1; + state_d = WriteBackReq; + end + end + end + + // We emit a write request towards the device carrying the updated state. + WriteBackReq: begin + emit_w_req = 1'b1; + if(tl_d_i.a_ready) begin + state_d = WriteBackAck; + end + end + + // We acknowledge the write response from the device and forward it to the host. We are now + // done with the RWM operation and can return to pass-through. + WriteBackAck: begin + ack_write_back = 1'b1; + if(tl_d_i.d_valid && tl_h_i.d_ready) begin + state_d = Passthrough; + end + end + + default:; + endcase + end + + // An enable-FF storing the meta data. This state is updated whenever the host gets a + // request handshaked. + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_request_meta_store + if(!rst_ni) begin + meta_addr_q <= '0; + tag_q <= 1'b0; + end else begin + if (tl_h_i.a_valid && tl_h_o.a_ready) begin + meta_addr_q <= meta_addr_d; + tag_q <= tag_h_i; + end + end + end + + // This enable FF, stores the current state before the modification in the fill state should an + // update be required. + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_word_store + if(!rst_ni) begin + word_q <= '0; + end else begin + if (update_word) begin + word_q <= tl_d_i.d_data; + end + end + end + + // This synchronously clearable, enable FF, stores the state of an ongoing read transaction. + // If clears the state on every completed ack towards the host. It is set on handshaking a + // host read request. + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_read_ongoing_flop + if(!rst_ni) begin + is_read_q <= 1'b0; + end else begin + if (tl_h_o.d_valid && tl_h_i.d_ready) begin + is_read_q <= 1'b0; + end else if (tl_h_i.a_valid && tl_h_o.a_ready) begin + is_read_q <= is_read_d; + end + end + end + + // The state can be updated every cycle + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_fsm_state_store + if(!rst_ni) begin + state_q <= Passthrough; + end else begin + state_q <= state_d; + end + end + + + ///////////////////// + // TL Multiplexing // + ///////////////////// + + // This process is really crammed as a side effect of bundling handshaking and (meta) data signals + // in a single request and response struct. We thus combine here handshaking and data + // multiplexing. + always_comb begin : proc_tl_muxing + + // Default pass-through for all transport signals (except handshaking) + tl_h_o = tl_d_i; + tl_d_o = tl_h_i; + + // Invalid capability as a default + tag_h_o = 1'b0; + + // Inert handshaking is the default + tl_h_o.d_valid = 1'b0; + tl_d_o.a_valid = 1'b0; + tl_h_o.a_ready = 1'b0; + tl_d_o.d_ready = 1'b0; + + // In the case of a read, we just forward the request. We only modify the address to + // point to the word in meta memory holding the capability. + if(forward_r_req) begin + // We are in pass-through case and a request arrives -> we forward it + // but we ensure we divide the address by 64 as one request can track 32 + // capabilities or 64 words. + tl_d_o.a_address = addr_remap; + // Recalculate the command integrity as we have modified the address + tl_d_o.a_user.cmd_intg = tlul_pkg::get_cmd_intg(tl_d_o); + tl_d_o.a_valid = tl_h_i.a_valid; + tl_h_o.a_ready = tl_d_i.a_ready; + + // In the case of a write, we first emit a word read towards meta memory, by forwarding + // a the modified upstream write request, to check whether the corresponding + // capability tag is set. + end else if(emit_r_req) begin + tl_d_o = tlul_pkg::TL_H2D_DEFAULT; + tl_d_o.a_address = addr_remap; + tl_d_o.a_opcode = tlul_pkg::Get; + tl_d_o.a_size = 'd2; + tl_d_o.a_user.cmd_intg = tlul_pkg::get_cmd_intg(tl_d_o); + tl_d_o.a_user.data_intg = tlul_pkg::get_data_intg(tl_d_o.a_data); + tl_d_o.a_valid = tl_h_i.a_valid; + tl_h_o.a_ready = tl_d_i.a_ready; + + // In the case of a write that modifies state, we eventually need to emit a new write. Here we + // don't have to handshake the upstream host request interface. + end else if(emit_w_req) begin + tl_d_o = tlul_pkg::TL_H2D_DEFAULT; + tl_d_o.a_address = addr_remap; + tl_d_o.a_opcode = tlul_pkg::PutFullData; + tl_d_o.a_size = 'd2; + tl_d_o.a_mask = '1; + tl_d_o.a_data = word_q; + tl_d_o.a_data[meta_addr_q.bit_sel] = tag_q; + tl_d_o.a_user.cmd_intg = tlul_pkg::get_cmd_intg(tl_d_o); + tl_d_o.a_user.data_intg = tlul_pkg::get_data_intg(tl_d_o.a_data); + tl_d_o.a_valid = 1'b1; + end + + // In the read case, we return the read response. The corresponding capability tag bit is + // placed on the host's output tag interface. + if(is_read_q) begin + tl_h_o.d_valid = tl_d_i.d_valid; + tl_d_o.d_ready = tl_h_i.d_ready; + tag_h_o = tl_d_i.d_data[meta_addr_q.bit_sel] && !tl_d_i.d_error; + + // We have translated a write request into a read request to inquire the state of the + // tag word. Checking the capability bit, we notice that we don't have to perform an update. + // We thus translate the read response from the meta device into a write response. + end else if(ack_skip) begin + tl_h_o.d_opcode = tlul_pkg::AccessAck; + tl_d_o.d_ready = tl_h_i.d_ready; + tl_h_o.d_valid = 1'b1; + + // When performing a fill and update, we need to acknowledge the downstream device transaction + // without acknowledging the host's response. + end else if(ack_fill) begin + tl_d_o.d_ready = 1'b1; + + // A write back answer arrives from the device; we forward this to the host. + end else if(ack_write_back) begin + tl_h_o.d_valid = tl_d_i.d_valid; + tl_d_o.d_ready = tl_h_i.d_ready; + end + end + + + /////////////////////////// + // Response ECC Checking // + /////////////////////////// + + // Did we receive a device error? + assign device_error_o = tl_d_i.d_valid && tl_d_o.d_ready && tl_d_i.d_error; + + // Get the response fields subject to ECC + assign rsp_intg = tlul_pkg::extract_d2h_rsp_intg(tl_d_i); + + // Check the bitmap response integrity + prim_secded_inv_64_57_dec u_prim_secded_inv_64_57_dec_rsp ( + .data_i ({tl_d_i.d_user.rsp_intg, {RspIntgPadding{1'b0}}, rsp_intg}), + .data_o (/*Not Connected*/), + .syndrome_o(/*Not Connected*/), + .err_o (rsp_intg_error) + ); + + // Mask response integrity error if response is not being handshaked + assign rsp_intg_error_o = tl_d_i.d_valid && tl_d_o.d_ready && (|rsp_intg_error); + + // Check the device response data integrity + prim_secded_inv_39_32_dec u_prim_secded_inv_39_32_dec_rsp_data ( + .data_i ({tl_d_i.d_user.data_intg, tl_d_i.d_data}), + .data_o (/*Not Connected*/), + .syndrome_o(/*Not Connected*/), + .err_o (rsp_data_intg_error) + ); + + // Mask response integrity error if response is not being handshaked + assign data_intg_error_o = tl_d_i.d_valid && tl_d_o.d_ready && (|rsp_data_intg_error); + + + /////////////////////// + // Address Remapping // + /////////////////////// + + always_comb begin: proc_address_remap + // defaults (only happen if something goes wrong, we map to address 0 which should not be + // mapped to anything) + addr_sel = '0; + addr_stem = '0; + addr_remap = '0; + + // select either the address of the currently active host request or the stored value + if(forward_r_req || emit_r_req) begin + addr_sel = meta_addr_d; + end else if(emit_w_req) begin + addr_sel = meta_addr_q; + end + + // remap address + if(addr_sel >= MainSramBaseAddr && addr_sel < MainSramTopAddr) begin + addr_stem = addr_sel - MainSramBaseAddr; + addr_remap = MetaMainSramTagBase + (addr_stem.meta_word << 32'd2); + end else if(addr_sel >= NvmBaseAddr && addr_sel < NvmTopAddr) begin + addr_stem = addr_sel - NvmBaseAddr; + addr_remap = MetaNvmTagBase + (addr_stem.meta_word << 32'd2); + end + end + + assign unused_addr = ^{addr_stem.bit_sel, addr_stem.rsvd}; + +endmodule diff --git a/hw/ip/cheriot/rtl/cheriot_switch.sv b/hw/ip/cheriot/rtl/cheriot_switch.sv new file mode 100644 index 0000000000000..64034d4887ba2 --- /dev/null +++ b/hw/ip/cheriot/rtl/cheriot_switch.sv @@ -0,0 +1,81 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module cheriot_switch + import cheriot_pkg::*; + import prim_mubi_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input mubi4_t ena_i, + input mubi4_t lock_i, + input logic lock_access_i, + output mubi4_t ena_o, + + output logic error_o +); + + switch_state_e switch_state_d, switch_state_q; + + always_comb begin : proc_switch_fsm + + // Default assignments + switch_state_d = Error; + error_o = 1'b0; + ena_o = MuBi4False; + + unique case (switch_state_q) + + // We reset in unlocked + Unlocked: begin + + // The FSM advanced iff the lock register is written to + if (lock_access_i) begin + // If the proper lock value is written and we enable CHERIoT -> Enable state + if (mubi4_test_true_strict(lock_i) && mubi4_test_true_strict(ena_i)) begin + switch_state_d = LockedEna; + // If the proper lock value is written and we disable CHERIoT -> Disable state + end else if (mubi4_test_true_strict(lock_i) && mubi4_test_false_strict(ena_i)) begin + switch_state_d = LockedDis; + // Otherwise we drop into the error state + end else begin + switch_state_d = Error; + end + + // The lock register is not written to, we remain unlocked + end else begin + switch_state_d = Unlocked; + end + end + + LockedEna: begin + switch_state_d = LockedEna; + ena_o = MuBi4True; + end + + LockedDis: begin + switch_state_d = LockedDis; + ena_o = MuBi4False; + end + + // Enable set to MuBi4False is the proper state on error, this means we remain in ePMP mode + // which is secure at the stage of the switch. + Error: begin + switch_state_d = Error; + ena_o = MuBi4False; + error_o = 1'b1; + end + + default: begin + switch_state_d = Error; + ena_o = MuBi4False; + error_o = 1'b1; + end + endcase + end + + `PRIM_FLOP_SPARSE_FSM(u_state_regs, switch_state_d, switch_state_q, switch_state_e, Unlocked) + +endmodule diff --git a/hw/ip/cheriot/rtl/cheriot_tag_filter.sv b/hw/ip/cheriot/rtl/cheriot_tag_filter.sv new file mode 100644 index 0000000000000..aabbb0d645d95 --- /dev/null +++ b/hw/ip/cheriot/rtl/cheriot_tag_filter.sv @@ -0,0 +1,245 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "prim_assert.sv" + +module cheriot_tag_filter #( + // The number of outstanding TL transaction the IP supports + parameter int unsigned NumOutstanding = 32'd4 +)( + input clk_i, + input rst_ni, + + // CHERIoT mode enabled + input prim_mubi_pkg::mubi4_t cheriot_ena_i, + + // Device port + input tlul_pkg::tl_h2d_t tl_d_i, + input logic tag_d_i, + output tlul_pkg::tl_d2h_t tl_d_o, + output logic tag_d_o, + + // Meta port + output tlul_pkg::tl_h2d_t tl_m_o, + output logic tag_m_o, + input tlul_pkg::tl_d2h_t tl_m_i, + input logic tag_m_i, + + // Host port + output tlul_pkg::tl_h2d_t tl_h_o, + input tlul_pkg::tl_d2h_t tl_h_i +); + + /////////// + // Types // + /////////// + + // The meta data type handed between the host's request and response channel + typedef struct packed { + logic cap_store; + logic cap; + logic aligned; + } req_rsp_meta_t; + + + ///////////// + // Signals // + ///////////// + + // Request handshaking signals + logic tl_d_req_ready; + logic tl_m_req_valid; + logic tl_h_req_valid; + + // Input port of the meta FIFO + logic meta_req_valid; + logic meta_req_ready; + req_rsp_meta_t meta_req; + + // Output port of the meta FIFO + logic meta_rsp_valid; + logic meta_rsp_ready; + req_rsp_meta_t meta_rsp; + + // Whether we need to lookup or fork into the meta memory + logic require_lookup; + // Whether we need to join a meta lookup + logic require_join; + + // Response handshaking signals + logic tl_d_rsp_valid; + logic tl_h_rsp_ready; + logic tl_m_rsp_ready; + + // Unused meta response signals + logic unused_m_rsp; + + // Tag bit store. We only do the lookup on the lower word of a capability to safe + // bandwidth into the meta memory. For the directly following meta word, we store + // the capability + logic tag_d_d, tag_d_q; + + logic tl_d_is_read; + logic tl_d_is_write; + logic tl_d_is_aligned; + + + ////////// + // Fork // + ////////// + + assign tl_d_is_read = tl_d_i.a_opcode == tlul_pkg::Get; + assign tl_d_is_write = tl_d_i.a_opcode == tlul_pkg::PutFullData || + tl_d_i.a_opcode == tlul_pkg::PutPartialData; + assign tl_d_is_aligned = !tl_d_i.a_address[2]; + + // We need to perform a lookup on 64-bit-aligned reads where the host hints + // us a valid capability load or on any write. A lookup is only required if CHERIoT is enabled. + assign require_lookup = prim_mubi_pkg::mubi4_test_true_strict(cheriot_ena_i) ? + (tl_d_is_read && // Read, + tl_d_is_aligned && // 64-bit-aligned, + tag_d_i) || // hinted cap + tl_d_is_write : // or write + 1'b0; + + // We only fork the meta channel if a lookup is required + stream_fork_dynamic #( + .N_OUP(32'd3) + ) u_stream_fork_dynamic ( + .clk_i, + .rst_ni, + .valid_i ( tl_d_i.a_valid ), + .ready_o ( tl_d_req_ready ), + .sel_i ( {1'b1, require_lookup, 1'b1} ), + .sel_valid_i( tl_d_i.a_valid ), + .sel_ready_o( /* NOT CONNECTED */ ), + .valid_o ( {meta_req_valid, tl_m_req_valid, tl_h_req_valid} ), + .ready_i ( {meta_req_ready, tl_m_i.a_ready, tl_h_i.a_ready} ) + ); + + + //////////////// + // Meta Store // + //////////////// + + // Assemble meta data between host's request and response channel + assign meta_req = '{ + cap: tag_d_i, + aligned: tl_d_is_aligned, + cap_store: tl_d_is_write + }; + + prim_fifo_sync #( + .Width(32'd3), + .Pass(1'b0), + .Depth(NumOutstanding), + .NeverClears(1'b1), + .Secure(1'b1) + ) u_prim_fifo_sync_align ( + .clk_i, + .rst_ni, + .clr_i ( 1'b0 ), + .wvalid_i( meta_req_valid ), + .wready_o( meta_req_ready ), + .wdata_i ( meta_req ), + .rvalid_o( meta_rsp_valid ), + .rready_i( meta_rsp_ready ), + .rdata_o ( meta_rsp ), + .full_o ( ), + .depth_o ( ), + .err_o ( ) + ); + + + ////////// + // Join // + ////////// + + // We need to join in the response from the meta SRAM if CHERIoT is enabled + // Ibex hints capability reads thus a join is requested through the `meta_rsp.cap` signal. + assign require_join = prim_mubi_pkg::mubi4_test_true_strict(cheriot_ena_i) ? + meta_rsp.cap_store || (meta_rsp.cap && meta_rsp.aligned) : + 1'b0; + + stream_join_dynamic #( + .N_INP(32'd3) + ) u_stream_join_dynamic ( + .inp_valid_i( {meta_rsp_valid, tl_m_i.d_valid, tl_h_i.d_valid} ), + .inp_ready_o( {meta_rsp_ready, tl_m_rsp_ready, tl_h_rsp_ready} ), + .sel_i ( {1'b1, require_join, 1'b1} ), + .oup_valid_o( tl_d_rsp_valid ), + .oup_ready_i( tl_d_i.d_ready ) + ); + + + ////////////////////////// + // Stick Capability Tag // + ////////////////////////// + + assign tag_m_o = tag_d_i; + + always_comb begin: proc_sticky_tag_d_o + tag_d_d = tag_d_q; + tag_d_o = tag_d_q; + if(tl_d_o.d_valid && tl_d_i.d_ready) begin + if(meta_rsp.aligned) begin + tag_d_o = tag_m_i; + tag_d_d = tag_m_i; + end else begin + tag_d_d = 1'b0; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_store_r_cap_tag + if(!rst_ni) begin + tag_d_q <= 1'b0; + end else begin + tag_d_q <= tag_d_d; + end + end + + + //////////////////// + // TL connections // + //////////////////// + + // We forward the host requests to both endpoints + always_comb begin: proc_connect_tl_req + tl_h_o = tl_d_i; + tl_h_o.a_valid = tl_h_req_valid; + tl_h_o.d_ready = tl_h_rsp_ready; + + tl_m_o = tl_d_i; + tl_m_o.a_valid = tl_m_req_valid; + tl_m_o.d_ready = tl_m_rsp_ready; + end + + // We disregard all of the meta SRAM response except for the tag bit and the error bit + always_comb begin: proc_connect_tl_rsp + tl_d_o = tl_h_i; + tl_d_o.d_error = tl_d_o.d_error || tl_m_i.d_error; + tl_d_o.a_ready = tl_d_req_ready; + tl_d_o.d_valid = tl_d_rsp_valid; + end + + // The response and data integrity is not checked, as both the RMW and the tag filter are + // lock-stepped. + assign unused_m_rsp = ^{tl_m_i.d_data, + tl_m_i.d_opcode, + tl_m_i.d_param, + tl_m_i.d_sink, + tl_m_i.d_size, + tl_m_i.d_source, + tl_m_i.d_user + }; + + //////////////// + // Assertions // + //////////////// + + // Meta FIFO has to be valid when device port handshakes its response + `ASSERT(MetaRspValidOnDHs_A, (tl_d_o.d_valid && tl_d_i.d_ready) |-> meta_rsp_valid) + +endmodule 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 41fbd34acaaeb..f7f2b24a7e553 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 @@ -1105,6 +1105,40 @@ ] }, + { name: "CHERIOT_ENA", + desc: ''' + Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). + ''', + swaccess: "wo", + hwaccess: "hro", + fields: [ + { bits: "3:0", + name: "VAL", + resval: "0x0" + desc: ''' + ''' + }, + ] + }, + + { name: "CHERIOT_LOCK", + desc: ''' + Locks the CHERIoT/ePMP mode. + If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. + ''', + swaccess: "wo", + hwaccess: "hro", + hwext: "true", + hwqe: "true", + fields: [ + { bits: "3:0", + name: "VAL", + desc: ''' + ''' + }, + ] + }, + { name: "FPGA_INFO", desc: ''' FPGA build timestamp info. 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 57e5121a35fd4..124af3a96a291 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 @@ -14,6 +14,7 @@ module ${module_instance_name} import rv_core_ibex_pkg::*; import ${module_instance_name}_reg_pkg::*; #( + parameter ibex_pkg::base_isa_e BaseIsa = ibex_pkg::BaseIsaRV32IorCHERIoT, parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, // Number of cycles a differential skew is tolerated on the alert and escalation signal parameter int unsigned AlertSkewCycles = 1, @@ -64,7 +65,9 @@ module ${module_instance_name} % endif parameter logic [tlul_pkg::RsvdWidth-1:0] TlulHostUserRsvdBits = 0, parameter logic [31:0] CsrMvendorId = 32'b0, - parameter logic [31:0] CsrMimpId = 32'b0 + parameter logic [31:0] CsrMimpId = 32'b0, + parameter int unsigned CheriotRevBitmapAddrWidth = 32'd9, + parameter int unsigned CheriotRevBitmapBaseAddr = 32'h0 ) ( // Clock and Reset input logic clk_i, @@ -249,6 +252,11 @@ module ${module_instance_name} // core sleeping logic core_sleep; + // CHERIoT signals + prim_mubi_pkg::mubi4_t cheriot_ena; + logic cheriot_switch_error; + logic unused_cheriot; + // The following intermediate signals are created to aid in simulations. // // If a parent port is connected directly to a port of sub-modules, the implicit wire connection @@ -444,6 +452,7 @@ module ${module_instance_name} ibex_pkg::crash_dump_t crash_dump; ibex_top #( + .BaseIsa ( BaseIsa ), .PMPEnable ( PMPEnable ), .PMPGranularity ( PMPGranularity ), .PMPNumRegions ( PMPNumRegions ), @@ -452,6 +461,8 @@ module ${module_instance_name} .PMPRstCfg ( PMPRstCfg ), .PMPRstAddr ( PMPRstAddr ), .PMPRstMsecCfg ( PMPRstMsecCfg ), + .CheriotRevBitmapAddrWidth ( CheriotRevBitmapAddrWidth), + .CheriotRevBitmapBaseAddr ( CheriotRevBitmapBaseAddr ), .RV32E ( RV32E ), .RV32M ( RV32M ), .RV32B ( RV32B ), @@ -506,6 +517,8 @@ module ${module_instance_name} .hart_id_i, .boot_addr_i, + .trvk_heap_base_addr_i('0), // SRAM base address + .instr_req_o (main_core_instr_req), .instr_gnt_i (main_core_instr_gnt_ibex), .instr_rvalid_i (main_core_instr_rvalid), @@ -522,10 +535,20 @@ module ${module_instance_name} .data_addr_o (main_core_data_addr), .data_wdata_o (main_core_data_wdata), .data_wdata_intg_o (main_core_data_wdata_intg), + .data_tag_o (), .data_rdata_i (main_core_data_rdata), .data_rdata_intg_i (main_core_data_rdata_intg), + .data_tag_i ('0), .data_err_i (main_core_data_err), + .trvk_revbm_req_o (), + .trvk_revbm_gnt_i ('0), + .trvk_revbm_rvalid_i ('0), + .trvk_revbm_addr_o (), + .trvk_revbm_rdata_i ('0), + .trvk_revbm_rdata_intg_i('0), + .trvk_revbm_err_i ('0), + .irq_software_i ( irq_software ), .irq_timer_i ( irq_timer ), .irq_external_i ( irq_external ), @@ -1037,6 +1060,29 @@ module ${module_instance_name} assign hw2reg.rnd_status.rnd_data_valid.d = rnd_valid_q; assign hw2reg.rnd_status.rnd_data_fips.d = rnd_fips_q; + //////////////////// + // CHERIoT switch + //////////////////// + + if (BaseIsa == ibex_pkg::BaseIsaRV32IorCHERIoT) begin : gen_cheriot_switch + cheriot_switch u_cheriot_switch ( + .clk_i, + .rst_ni, + .ena_i (reg2hw.cheriot_ena.q), + .lock_i (reg2hw.cheriot_lock.q), + .lock_access_i(reg2hw.cheriot_lock.qe), + .ena_o (cheriot_ena), + .error_o (cheriot_switch_error) + ); + // For now, tie off all signals + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + + end else begin : gen_no_cheriot_switch + assign cheriot_ena = prim_mubi_pkg::MuBi4False; + assign cheriot_switch_error = 1'b0; + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + end + logic unused_reg2hw; assign unused_reg2hw = |reg2hw.rnd_data.q; @@ -1127,7 +1173,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.mcounteren_writable}; + reg2hw_shadow.mcounteren_writable, + reg2hw_shadow.cheriot_ena, reg2hw_shadow.cheriot_lock}; ///////////////////////////////////////////////////////////////// // Shadow Core Data Address Translation Unit and TL-UL Adapter // diff --git a/hw/ip_templates/rv_core_ibex/rv_core_ibex.core.tpl b/hw/ip_templates/rv_core_ibex/rv_core_ibex.core.tpl index 5a1dc0d38aef1..8985ec594ddb8 100644 --- a/hw/ip_templates/rv_core_ibex/rv_core_ibex.core.tpl +++ b/hw/ip_templates/rv_core_ibex/rv_core_ibex.core.tpl @@ -20,6 +20,7 @@ filesets: - lowrisc:prim:mubi - lowrisc:tlul:adapter_host - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:ip:cheriot % if racl_support: - ${instance_vlnv("lowrisc:constants:top_racl_pkg")} % endif 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 7693497078771..685bfdd250596 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 @@ -1079,6 +1079,40 @@ ] }, + { name: "CHERIOT_ENA", + desc: ''' + Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). + ''', + swaccess: "wo", + hwaccess: "hro", + fields: [ + { bits: "3:0", + name: "VAL", + resval: "0x0" + desc: ''' + ''' + }, + ] + }, + + { name: "CHERIOT_LOCK", + desc: ''' + Locks the CHERIoT/ePMP mode. + If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. + ''', + swaccess: "wo", + hwaccess: "hro", + hwext: "true", + hwqe: "true", + fields: [ + { bits: "3:0", + name: "VAL", + desc: ''' + ''' + }, + ] + }, + { name: "FPGA_INFO", desc: ''' FPGA build timestamp info. 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 c491a6fb5798e..29112607007f3 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,276 +5,278 @@ 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.[`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. | +| 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.[`CHERIOT_ENA`](#cheriot_ena) | 0x420 | 4 | Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). | +| rv_core_ibex.[`CHERIOT_LOCK`](#cheriot_lock) | 0x424 | 4 | Locks the CHERIoT/ePMP mode. | +| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x428 | 4 | FPGA build timestamp info. | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) | 0x42c | 4 | Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE`](#mcounteren_writable) | 0x430 | 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 @@ -901,10 +903,45 @@ Status of random data in [`RND_DATA`](#rnd_data) | 1 | ro | 0x0 | RND_DATA_FIPS | When [`RND_STATUS.RND_DATA_VALID`](#rnd_status) is 1, this bit indicates whether [`RND_DATA`](#rnd_data) is fips quality. When [`RND_STATUS.RND_DATA_VALID`](#rnd_status) is 0, this bit has no meaning. | | 0 | ro | 0x0 | RND_DATA_VALID | When set, the data in [`RND_DATA`](#rnd_data) is valid. When clear an EDN request for new data for [`RND_DATA`](#rnd_data) is pending. | +## CHERIOT_ENA +Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). +- Offset: `0x420` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["wo"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:4 | | | | Reserved | +| 3:0 | wo | 0x0 | VAL | | + +## CHERIOT_LOCK +Locks the CHERIoT/ePMP mode. +If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. +- Offset: `0x424` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["wo"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:4 | | | | Reserved | +| 3:0 | wo | x | VAL | | + ## FPGA_INFO FPGA build timestamp info. This register only contains valid data for fpga, for all other variants it is simply 0. -- Offset: `0x420` +- Offset: `0x428` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -920,7 +957,7 @@ This register only contains valid data for fpga, for all other variants it is si ## MCOUNTEREN_WRITABLE_REGWEN Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) -- Offset: `0x424` +- Offset: `0x42c` - Reset default: `0x1` - Reset mask: `0x1` @@ -946,7 +983,7 @@ Write enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) Once set to 0, i ## MCOUNTEREN_WRITABLE Controls whether Ibex mcounteren CSR is writable by software. -- Offset: `0x428` +- Offset: `0x430` - Reset default: `0x6` - Reset mask: `0xf` - Register enable: [`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) 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 eddb743aeed2e..9627adce607a1 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 @@ -14,6 +14,7 @@ module rv_core_ibex import rv_core_ibex_pkg::*; import rv_core_ibex_reg_pkg::*; #( + parameter ibex_pkg::base_isa_e BaseIsa = ibex_pkg::BaseIsaRV32IorCHERIoT, parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, // Number of cycles a differential skew is tolerated on the alert and escalation signal parameter int unsigned AlertSkewCycles = 1, @@ -57,7 +58,9 @@ module rv_core_ibex parameter int unsigned WidthPingCounter = 16, parameter logic [tlul_pkg::RsvdWidth-1:0] TlulHostUserRsvdBits = 0, parameter logic [31:0] CsrMvendorId = 32'b0, - parameter logic [31:0] CsrMimpId = 32'b0 + parameter logic [31:0] CsrMimpId = 32'b0, + parameter int unsigned CheriotRevBitmapAddrWidth = 32'd9, + parameter int unsigned CheriotRevBitmapBaseAddr = 32'h0 ) ( // Clock and Reset input logic clk_i, @@ -236,6 +239,11 @@ module rv_core_ibex // core sleeping logic core_sleep; + // CHERIoT signals + prim_mubi_pkg::mubi4_t cheriot_ena; + logic cheriot_switch_error; + logic unused_cheriot; + // The following intermediate signals are created to aid in simulations. // // If a parent port is connected directly to a port of sub-modules, the implicit wire connection @@ -431,6 +439,7 @@ module rv_core_ibex ibex_pkg::crash_dump_t crash_dump; ibex_top #( + .BaseIsa ( BaseIsa ), .PMPEnable ( PMPEnable ), .PMPGranularity ( PMPGranularity ), .PMPNumRegions ( PMPNumRegions ), @@ -439,6 +448,8 @@ module rv_core_ibex .PMPRstCfg ( PMPRstCfg ), .PMPRstAddr ( PMPRstAddr ), .PMPRstMsecCfg ( PMPRstMsecCfg ), + .CheriotRevBitmapAddrWidth ( CheriotRevBitmapAddrWidth), + .CheriotRevBitmapBaseAddr ( CheriotRevBitmapBaseAddr ), .RV32E ( RV32E ), .RV32M ( RV32M ), .RV32B ( RV32B ), @@ -493,6 +504,8 @@ module rv_core_ibex .hart_id_i, .boot_addr_i, + .trvk_heap_base_addr_i('0), // SRAM base address + .instr_req_o (main_core_instr_req), .instr_gnt_i (main_core_instr_gnt_ibex), .instr_rvalid_i (main_core_instr_rvalid), @@ -509,10 +522,20 @@ module rv_core_ibex .data_addr_o (main_core_data_addr), .data_wdata_o (main_core_data_wdata), .data_wdata_intg_o (main_core_data_wdata_intg), + .data_tag_o (), .data_rdata_i (main_core_data_rdata), .data_rdata_intg_i (main_core_data_rdata_intg), + .data_tag_i ('0), .data_err_i (main_core_data_err), + .trvk_revbm_req_o (), + .trvk_revbm_gnt_i ('0), + .trvk_revbm_rvalid_i ('0), + .trvk_revbm_addr_o (), + .trvk_revbm_rdata_i ('0), + .trvk_revbm_rdata_intg_i('0), + .trvk_revbm_err_i ('0), + .irq_software_i ( irq_software ), .irq_timer_i ( irq_timer ), .irq_external_i ( irq_external ), @@ -1012,6 +1035,29 @@ module rv_core_ibex assign hw2reg.rnd_status.rnd_data_valid.d = rnd_valid_q; assign hw2reg.rnd_status.rnd_data_fips.d = rnd_fips_q; + //////////////////// + // CHERIoT switch + //////////////////// + + if (BaseIsa == ibex_pkg::BaseIsaRV32IorCHERIoT) begin : gen_cheriot_switch + cheriot_switch u_cheriot_switch ( + .clk_i, + .rst_ni, + .ena_i (reg2hw.cheriot_ena.q), + .lock_i (reg2hw.cheriot_lock.q), + .lock_access_i(reg2hw.cheriot_lock.qe), + .ena_o (cheriot_ena), + .error_o (cheriot_switch_error) + ); + // For now, tie off all signals + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + + end else begin : gen_no_cheriot_switch + assign cheriot_ena = prim_mubi_pkg::MuBi4False; + assign cheriot_switch_error = 1'b0; + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + end + logic unused_reg2hw; assign unused_reg2hw = |reg2hw.rnd_data.q; @@ -1102,7 +1148,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.mcounteren_writable}; + reg2hw_shadow.mcounteren_writable, + reg2hw_shadow.cheriot_ena, reg2hw_shadow.cheriot_lock}; ///////////////////////////////////////////////////////////////// // 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 d7a4734b070cb..ad90d29cf3940 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 [266:0] reg_we_check; + logic [268:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(267) + .OneHotWidth(269) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -973,6 +973,10 @@ module rv_core_ibex_cfg_reg_top ( logic rnd_status_re; logic rnd_status_rnd_data_valid_qs; logic rnd_status_rnd_data_fips_qs; + logic cheriot_ena_we; + logic [3:0] cheriot_ena_wd; + logic cheriot_lock_we; + logic [3:0] cheriot_lock_wd; logic fpga_info_re; logic [31:0] fpga_info_qs; logic mcounteren_writable_regwen_we; @@ -11682,6 +11686,54 @@ module rv_core_ibex_cfg_reg_top ( ); + // R[cheriot_ena]: V(False) + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessWO), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_cheriot_ena ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (cheriot_ena_we), + .wd (cheriot_ena_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.cheriot_ena.q), + .ds (), + + // to register interface (read) + .qs () + ); + + + // R[cheriot_lock]: V(True) + logic cheriot_lock_qe; + logic [0:0] cheriot_lock_flds_we; + assign cheriot_lock_qe = &cheriot_lock_flds_we; + prim_subreg_ext #( + .DW (4) + ) u_cheriot_lock ( + .re (1'b0), + .we (cheriot_lock_we), + .wd (cheriot_lock_wd), + .d ('0), + .qre (), + .qe (cheriot_lock_flds_we[0]), + .q (reg2hw.cheriot_lock.q), + .ds (), + .qs () + ); + assign reg2hw.cheriot_lock.qe = cheriot_lock_qe; + + // R[fpga_info]: V(True) prim_subreg_ext #( .DW (32) @@ -11758,7 +11810,7 @@ module rv_core_ibex_cfg_reg_top ( - logic [266:0] addr_hit; + logic [268: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); @@ -12024,9 +12076,11 @@ module rv_core_ibex_cfg_reg_top ( addr_hit[261] = (reg_addr == RV_CORE_IBEX_ERR_STATUS_OFFSET); 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); + addr_hit[264] = (reg_addr == RV_CORE_IBEX_CHERIOT_ENA_OFFSET); + addr_hit[265] = (reg_addr == RV_CORE_IBEX_CHERIOT_LOCK_OFFSET); + addr_hit[266] = (reg_addr == RV_CORE_IBEX_FPGA_INFO_OFFSET); + addr_hit[267] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET); + addr_hit[268] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -12300,7 +12354,9 @@ module rv_core_ibex_cfg_reg_top ( (addr_hit[263] & (|(RV_CORE_IBEX_CFG_PERMIT[263] & ~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))))); + (addr_hit[266] & (|(RV_CORE_IBEX_CFG_PERMIT[266] & ~reg_be))) | + (addr_hit[267] & (|(RV_CORE_IBEX_CFG_PERMIT[267] & ~reg_be))) | + (addr_hit[268] & (|(RV_CORE_IBEX_CFG_PERMIT[268] & ~reg_be))))); end // Generate write-enables @@ -13108,11 +13164,17 @@ module rv_core_ibex_cfg_reg_top ( assign err_status_recov_core_err_wd = reg_wdata[10]; 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 cheriot_ena_we = addr_hit[264] & reg_we & !reg_error; + + assign cheriot_ena_wd = reg_wdata[3:0]; + assign cheriot_lock_we = addr_hit[265] & reg_we & !reg_error; + + assign cheriot_lock_wd = reg_wdata[3:0]; + assign fpga_info_re = addr_hit[266] & reg_re & !reg_error; + assign mcounteren_writable_regwen_we = addr_hit[267] & 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_we = addr_hit[268] & reg_we & !reg_error; assign mcounteren_writable_wd = reg_wdata[3:0]; @@ -13382,9 +13444,11 @@ module rv_core_ibex_cfg_reg_top ( reg_we_check[261] = err_status_we; 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; + reg_we_check[264] = cheriot_ena_we; + reg_we_check[265] = cheriot_lock_we; + reg_we_check[266] = 1'b0; + reg_we_check[267] = mcounteren_writable_regwen_we; + reg_we_check[268] = mcounteren_writable_gated_we; end // Read data return @@ -14457,14 +14521,22 @@ module rv_core_ibex_cfg_reg_top ( end addr_hit[264]: begin - reg_rdata_next[31:0] = fpga_info_qs; + reg_rdata_next[3:0] = '0; end addr_hit[265]: begin - reg_rdata_next[0] = mcounteren_writable_regwen_qs; + reg_rdata_next[3:0] = '0; end addr_hit[266]: begin + reg_rdata_next[31:0] = fpga_info_qs; + end + + addr_hit[267]: begin + reg_rdata_next[0] = mcounteren_writable_regwen_qs; + end + + addr_hit[268]: begin reg_rdata_next[3:0] = mcounteren_writable_qs; 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 9506730750015..2de65c5013154 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 = 267; + parameter int NumRegsCfg = 269; // Alert indices typedef enum int { @@ -110,6 +110,15 @@ 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_cheriot_ena_reg_t; + + typedef struct packed { + logic [3:0] q; + logic qe; + } rv_core_ibex_reg2hw_cheriot_lock_reg_t; + typedef struct packed { logic [3:0] q; } rv_core_ibex_reg2hw_mcounteren_writable_reg_t; @@ -168,18 +177,20 @@ 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; // [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_alert_test_reg_t alert_test; // [4417:4410] + rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [4409:4406] + rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [4405:4402] + rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [31:0] ibus_addr_en; // [4401:4338] + rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [31:0] ibus_addr_matching; // [4337:3282] + rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [31:0] ibus_remap_addr; // [3281:2226] + rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [31:0] dbus_addr_en; // [2225:2162] + rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [31:0] dbus_addr_matching; // [2161:1106] + rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [31:0] dbus_remap_addr; // [1105:50] + rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [49:48] + rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [47:46] + rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [45:13] + rv_core_ibex_reg2hw_cheriot_ena_reg_t cheriot_ena; // [12:9] + rv_core_ibex_reg2hw_cheriot_lock_reg_t cheriot_lock; // [8:4] rv_core_ibex_reg2hw_mcounteren_writable_reg_t mcounteren_writable; // [3:0] } rv_core_ibex_cfg_reg2hw_t; @@ -458,9 +469,11 @@ package rv_core_ibex_reg_pkg; parameter logic [CfgAw-1:0] RV_CORE_IBEX_ERR_STATUS_OFFSET = 11'h 414; 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; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_CHERIOT_ENA_OFFSET = 11'h 420; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_CHERIOT_LOCK_OFFSET = 11'h 424; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_FPGA_INFO_OFFSET = 11'h 428; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET = 11'h 42c; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET = 11'h 430; // Reset values for hwext registers and their fields for cfg interface parameter logic [3:0] RV_CORE_IBEX_ALERT_TEST_RESVAL = 4'h 0; @@ -473,6 +486,7 @@ package rv_core_ibex_reg_pkg; parameter logic [1:0] RV_CORE_IBEX_RND_STATUS_RESVAL = 2'h 0; parameter logic [0:0] RV_CORE_IBEX_RND_STATUS_RND_DATA_VALID_RESVAL = 1'h 0; parameter logic [0:0] RV_CORE_IBEX_RND_STATUS_RND_DATA_FIPS_RESVAL = 1'h 0; + parameter logic [3:0] RV_CORE_IBEX_CHERIOT_LOCK_RESVAL = 4'h 0; parameter logic [31:0] RV_CORE_IBEX_FPGA_INFO_RESVAL = 32'h 0; parameter logic [31:0] RV_CORE_IBEX_FPGA_INFO_VAL_RESVAL = 32'h 0; @@ -747,13 +761,15 @@ package rv_core_ibex_reg_pkg; RV_CORE_IBEX_ERR_STATUS, RV_CORE_IBEX_RND_DATA, RV_CORE_IBEX_RND_STATUS, + RV_CORE_IBEX_CHERIOT_ENA, + RV_CORE_IBEX_CHERIOT_LOCK, 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 [267] = '{ + parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [269] = '{ 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 @@ -1018,9 +1034,11 @@ 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 0001, // index[265] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN - 4'b 0001 // index[266] RV_CORE_IBEX_MCOUNTEREN_WRITABLE + 4'b 0001, // index[264] RV_CORE_IBEX_CHERIOT_ENA + 4'b 0001, // index[265] RV_CORE_IBEX_CHERIOT_LOCK + 4'b 1111, // index[266] RV_CORE_IBEX_FPGA_INFO + 4'b 0001, // index[267] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN + 4'b 0001 // index[268] RV_CORE_IBEX_MCOUNTEREN_WRITABLE }; endpackage diff --git a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rv_core_ibex.core b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rv_core_ibex.core index 54f14c0372046..9b0997d0313bb 100644 --- a/hw/top_darjeeling/ip_autogen/rv_core_ibex/rv_core_ibex.core +++ b/hw/top_darjeeling/ip_autogen/rv_core_ibex/rv_core_ibex.core @@ -20,6 +20,7 @@ filesets: - lowrisc:prim:mubi - lowrisc:tlul:adapter_host - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:ip:cheriot files: - rtl/rv_core_ibex_reg_pkg.sv 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 4670c106d457a..fde4f3cbfe541 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 @@ -1079,6 +1079,40 @@ ] }, + { name: "CHERIOT_ENA", + desc: ''' + Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). + ''', + swaccess: "wo", + hwaccess: "hro", + fields: [ + { bits: "3:0", + name: "VAL", + resval: "0x0" + desc: ''' + ''' + }, + ] + }, + + { name: "CHERIOT_LOCK", + desc: ''' + Locks the CHERIoT/ePMP mode. + If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. + ''', + swaccess: "wo", + hwaccess: "hro", + hwext: "true", + hwqe: "true", + fields: [ + { bits: "3:0", + name: "VAL", + desc: ''' + ''' + }, + ] + }, + { name: "FPGA_INFO", desc: ''' FPGA build timestamp info. 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 88fe348c9837f..e27b1fcd764c6 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,36 +5,38 @@ 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.[`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. | +| 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.[`CHERIOT_ENA`](#cheriot_ena) | 0x60 | 4 | Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). | +| rv_core_ibex.[`CHERIOT_LOCK`](#cheriot_lock) | 0x64 | 4 | Locks the CHERIoT/ePMP mode. | +| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x68 | 4 | FPGA build timestamp info. | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) | 0x6c | 4 | Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE`](#mcounteren_writable) | 0x70 | 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 @@ -421,10 +423,45 @@ Status of random data in [`RND_DATA`](#rnd_data) | 1 | ro | 0x0 | RND_DATA_FIPS | When [`RND_STATUS.RND_DATA_VALID`](#rnd_status) is 1, this bit indicates whether [`RND_DATA`](#rnd_data) is fips quality. When [`RND_STATUS.RND_DATA_VALID`](#rnd_status) is 0, this bit has no meaning. | | 0 | ro | 0x0 | RND_DATA_VALID | When set, the data in [`RND_DATA`](#rnd_data) is valid. When clear an EDN request for new data for [`RND_DATA`](#rnd_data) is pending. | +## CHERIOT_ENA +Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). +- Offset: `0x60` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["wo"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:4 | | | | Reserved | +| 3:0 | wo | 0x0 | VAL | | + +## CHERIOT_LOCK +Locks the CHERIoT/ePMP mode. +If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. +- Offset: `0x64` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["wo"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:4 | | | | Reserved | +| 3:0 | wo | x | VAL | | + ## FPGA_INFO FPGA build timestamp info. This register only contains valid data for fpga, for all other variants it is simply 0. -- Offset: `0x60` +- Offset: `0x68` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -440,7 +477,7 @@ This register only contains valid data for fpga, for all other variants it is si ## MCOUNTEREN_WRITABLE_REGWEN Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) -- Offset: `0x64` +- Offset: `0x6c` - Reset default: `0x1` - Reset mask: `0x1` @@ -466,7 +503,7 @@ Write enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) Once set to 0, i ## MCOUNTEREN_WRITABLE Controls whether Ibex mcounteren CSR is writable by software. -- Offset: `0x68` +- Offset: `0x70` - Reset default: `0x6` - Reset mask: `0xf` - Register enable: [`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) 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 eddb743aeed2e..9627adce607a1 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 @@ -14,6 +14,7 @@ module rv_core_ibex import rv_core_ibex_pkg::*; import rv_core_ibex_reg_pkg::*; #( + parameter ibex_pkg::base_isa_e BaseIsa = ibex_pkg::BaseIsaRV32IorCHERIoT, parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, // Number of cycles a differential skew is tolerated on the alert and escalation signal parameter int unsigned AlertSkewCycles = 1, @@ -57,7 +58,9 @@ module rv_core_ibex parameter int unsigned WidthPingCounter = 16, parameter logic [tlul_pkg::RsvdWidth-1:0] TlulHostUserRsvdBits = 0, parameter logic [31:0] CsrMvendorId = 32'b0, - parameter logic [31:0] CsrMimpId = 32'b0 + parameter logic [31:0] CsrMimpId = 32'b0, + parameter int unsigned CheriotRevBitmapAddrWidth = 32'd9, + parameter int unsigned CheriotRevBitmapBaseAddr = 32'h0 ) ( // Clock and Reset input logic clk_i, @@ -236,6 +239,11 @@ module rv_core_ibex // core sleeping logic core_sleep; + // CHERIoT signals + prim_mubi_pkg::mubi4_t cheriot_ena; + logic cheriot_switch_error; + logic unused_cheriot; + // The following intermediate signals are created to aid in simulations. // // If a parent port is connected directly to a port of sub-modules, the implicit wire connection @@ -431,6 +439,7 @@ module rv_core_ibex ibex_pkg::crash_dump_t crash_dump; ibex_top #( + .BaseIsa ( BaseIsa ), .PMPEnable ( PMPEnable ), .PMPGranularity ( PMPGranularity ), .PMPNumRegions ( PMPNumRegions ), @@ -439,6 +448,8 @@ module rv_core_ibex .PMPRstCfg ( PMPRstCfg ), .PMPRstAddr ( PMPRstAddr ), .PMPRstMsecCfg ( PMPRstMsecCfg ), + .CheriotRevBitmapAddrWidth ( CheriotRevBitmapAddrWidth), + .CheriotRevBitmapBaseAddr ( CheriotRevBitmapBaseAddr ), .RV32E ( RV32E ), .RV32M ( RV32M ), .RV32B ( RV32B ), @@ -493,6 +504,8 @@ module rv_core_ibex .hart_id_i, .boot_addr_i, + .trvk_heap_base_addr_i('0), // SRAM base address + .instr_req_o (main_core_instr_req), .instr_gnt_i (main_core_instr_gnt_ibex), .instr_rvalid_i (main_core_instr_rvalid), @@ -509,10 +522,20 @@ module rv_core_ibex .data_addr_o (main_core_data_addr), .data_wdata_o (main_core_data_wdata), .data_wdata_intg_o (main_core_data_wdata_intg), + .data_tag_o (), .data_rdata_i (main_core_data_rdata), .data_rdata_intg_i (main_core_data_rdata_intg), + .data_tag_i ('0), .data_err_i (main_core_data_err), + .trvk_revbm_req_o (), + .trvk_revbm_gnt_i ('0), + .trvk_revbm_rvalid_i ('0), + .trvk_revbm_addr_o (), + .trvk_revbm_rdata_i ('0), + .trvk_revbm_rdata_intg_i('0), + .trvk_revbm_err_i ('0), + .irq_software_i ( irq_software ), .irq_timer_i ( irq_timer ), .irq_external_i ( irq_external ), @@ -1012,6 +1035,29 @@ module rv_core_ibex assign hw2reg.rnd_status.rnd_data_valid.d = rnd_valid_q; assign hw2reg.rnd_status.rnd_data_fips.d = rnd_fips_q; + //////////////////// + // CHERIoT switch + //////////////////// + + if (BaseIsa == ibex_pkg::BaseIsaRV32IorCHERIoT) begin : gen_cheriot_switch + cheriot_switch u_cheriot_switch ( + .clk_i, + .rst_ni, + .ena_i (reg2hw.cheriot_ena.q), + .lock_i (reg2hw.cheriot_lock.q), + .lock_access_i(reg2hw.cheriot_lock.qe), + .ena_o (cheriot_ena), + .error_o (cheriot_switch_error) + ); + // For now, tie off all signals + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + + end else begin : gen_no_cheriot_switch + assign cheriot_ena = prim_mubi_pkg::MuBi4False; + assign cheriot_switch_error = 1'b0; + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + end + logic unused_reg2hw; assign unused_reg2hw = |reg2hw.rnd_data.q; @@ -1102,7 +1148,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.mcounteren_writable}; + reg2hw_shadow.mcounteren_writable, + reg2hw_shadow.cheriot_ena, reg2hw_shadow.cheriot_lock}; ///////////////////////////////////////////////////////////////// // 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 bd489909982fa..2003143cc666d 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 [26:0] reg_we_check; + logic [28:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(27) + .OneHotWidth(29) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -253,6 +253,10 @@ module rv_core_ibex_cfg_reg_top ( logic rnd_status_re; logic rnd_status_rnd_data_valid_qs; logic rnd_status_rnd_data_fips_qs; + logic cheriot_ena_we; + logic [3:0] cheriot_ena_wd; + logic cheriot_lock_we; + logic [3:0] cheriot_lock_wd; logic fpga_info_re; logic [31:0] fpga_info_qs; logic mcounteren_writable_regwen_we; @@ -1302,6 +1306,54 @@ module rv_core_ibex_cfg_reg_top ( ); + // R[cheriot_ena]: V(False) + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessWO), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_cheriot_ena ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (cheriot_ena_we), + .wd (cheriot_ena_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.cheriot_ena.q), + .ds (), + + // to register interface (read) + .qs () + ); + + + // R[cheriot_lock]: V(True) + logic cheriot_lock_qe; + logic [0:0] cheriot_lock_flds_we; + assign cheriot_lock_qe = &cheriot_lock_flds_we; + prim_subreg_ext #( + .DW (4) + ) u_cheriot_lock ( + .re (1'b0), + .we (cheriot_lock_we), + .wd (cheriot_lock_wd), + .d ('0), + .qre (), + .qe (cheriot_lock_flds_we[0]), + .q (reg2hw.cheriot_lock.q), + .ds (), + .qs () + ); + assign reg2hw.cheriot_lock.qe = cheriot_lock_qe; + + // R[fpga_info]: V(True) prim_subreg_ext #( .DW (32) @@ -1378,7 +1430,7 @@ module rv_core_ibex_cfg_reg_top ( - logic [26:0] addr_hit; + logic [28: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); @@ -1404,9 +1456,11 @@ module rv_core_ibex_cfg_reg_top ( addr_hit[21] = (reg_addr == RV_CORE_IBEX_ERR_STATUS_OFFSET); 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); + addr_hit[24] = (reg_addr == RV_CORE_IBEX_CHERIOT_ENA_OFFSET); + addr_hit[25] = (reg_addr == RV_CORE_IBEX_CHERIOT_LOCK_OFFSET); + addr_hit[26] = (reg_addr == RV_CORE_IBEX_FPGA_INFO_OFFSET); + addr_hit[27] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET); + addr_hit[28] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1440,7 +1494,9 @@ module rv_core_ibex_cfg_reg_top ( (addr_hit[23] & (|(RV_CORE_IBEX_CFG_PERMIT[23] & ~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))))); + (addr_hit[26] & (|(RV_CORE_IBEX_CFG_PERMIT[26] & ~reg_be))) | + (addr_hit[27] & (|(RV_CORE_IBEX_CFG_PERMIT[27] & ~reg_be))) | + (addr_hit[28] & (|(RV_CORE_IBEX_CFG_PERMIT[28] & ~reg_be))))); end // Generate write-enables @@ -1528,11 +1584,17 @@ module rv_core_ibex_cfg_reg_top ( assign err_status_recov_core_err_wd = reg_wdata[10]; 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 cheriot_ena_we = addr_hit[24] & reg_we & !reg_error; + + assign cheriot_ena_wd = reg_wdata[3:0]; + assign cheriot_lock_we = addr_hit[25] & reg_we & !reg_error; + + assign cheriot_lock_wd = reg_wdata[3:0]; + assign fpga_info_re = addr_hit[26] & reg_re & !reg_error; + assign mcounteren_writable_regwen_we = addr_hit[27] & 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_we = addr_hit[28] & reg_we & !reg_error; assign mcounteren_writable_wd = reg_wdata[3:0]; @@ -1562,9 +1624,11 @@ module rv_core_ibex_cfg_reg_top ( reg_we_check[21] = err_status_we; 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; + reg_we_check[24] = cheriot_ena_we; + reg_we_check[25] = cheriot_lock_we; + reg_we_check[26] = 1'b0; + reg_we_check[27] = mcounteren_writable_regwen_we; + reg_we_check[28] = mcounteren_writable_gated_we; end // Read data return @@ -1677,14 +1741,22 @@ module rv_core_ibex_cfg_reg_top ( end addr_hit[24]: begin - reg_rdata_next[31:0] = fpga_info_qs; + reg_rdata_next[3:0] = '0; end addr_hit[25]: begin - reg_rdata_next[0] = mcounteren_writable_regwen_qs; + reg_rdata_next[3:0] = '0; end addr_hit[26]: begin + reg_rdata_next[31:0] = fpga_info_qs; + end + + addr_hit[27]: begin + reg_rdata_next[0] = mcounteren_writable_regwen_qs; + end + + addr_hit[28]: begin reg_rdata_next[3:0] = mcounteren_writable_qs; 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 2fe6515143947..328d7f99090ea 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 = 27; + parameter int NumRegsCfg = 29; // Alert indices typedef enum int { @@ -110,6 +110,15 @@ 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_cheriot_ena_reg_t; + + typedef struct packed { + logic [3:0] q; + logic qe; + } rv_core_ibex_reg2hw_cheriot_lock_reg_t; + typedef struct packed { logic [3:0] q; } rv_core_ibex_reg2hw_mcounteren_writable_reg_t; @@ -168,18 +177,20 @@ 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; // [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_alert_test_reg_t alert_test; // [337:330] + rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [329:326] + rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [325:322] + rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [1:0] ibus_addr_en; // [321:318] + rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [1:0] ibus_addr_matching; // [317:252] + rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [1:0] ibus_remap_addr; // [251:186] + rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [1:0] dbus_addr_en; // [185:182] + rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [1:0] dbus_addr_matching; // [181:116] + rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [1:0] dbus_remap_addr; // [115:50] + rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [49:48] + rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [47:46] + rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [45:13] + rv_core_ibex_reg2hw_cheriot_ena_reg_t cheriot_ena; // [12:9] + rv_core_ibex_reg2hw_cheriot_lock_reg_t cheriot_lock; // [8:4] rv_core_ibex_reg2hw_mcounteren_writable_reg_t mcounteren_writable; // [3:0] } rv_core_ibex_cfg_reg2hw_t; @@ -218,9 +229,11 @@ package rv_core_ibex_reg_pkg; parameter logic [CfgAw-1:0] RV_CORE_IBEX_ERR_STATUS_OFFSET = 8'h 54; 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; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_CHERIOT_ENA_OFFSET = 8'h 60; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_CHERIOT_LOCK_OFFSET = 8'h 64; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_FPGA_INFO_OFFSET = 8'h 68; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET = 8'h 6c; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET = 8'h 70; // Reset values for hwext registers and their fields for cfg interface parameter logic [3:0] RV_CORE_IBEX_ALERT_TEST_RESVAL = 4'h 0; @@ -233,6 +246,7 @@ package rv_core_ibex_reg_pkg; parameter logic [1:0] RV_CORE_IBEX_RND_STATUS_RESVAL = 2'h 0; parameter logic [0:0] RV_CORE_IBEX_RND_STATUS_RND_DATA_VALID_RESVAL = 1'h 0; parameter logic [0:0] RV_CORE_IBEX_RND_STATUS_RND_DATA_FIPS_RESVAL = 1'h 0; + parameter logic [3:0] RV_CORE_IBEX_CHERIOT_LOCK_RESVAL = 4'h 0; parameter logic [31:0] RV_CORE_IBEX_FPGA_INFO_RESVAL = 32'h 0; parameter logic [31:0] RV_CORE_IBEX_FPGA_INFO_VAL_RESVAL = 32'h 0; @@ -267,13 +281,15 @@ package rv_core_ibex_reg_pkg; RV_CORE_IBEX_ERR_STATUS, RV_CORE_IBEX_RND_DATA, RV_CORE_IBEX_RND_STATUS, + RV_CORE_IBEX_CHERIOT_ENA, + RV_CORE_IBEX_CHERIOT_LOCK, 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 [27] = '{ + parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [29] = '{ 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 @@ -298,9 +314,11 @@ 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 0001, // index[25] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN - 4'b 0001 // index[26] RV_CORE_IBEX_MCOUNTEREN_WRITABLE + 4'b 0001, // index[24] RV_CORE_IBEX_CHERIOT_ENA + 4'b 0001, // index[25] RV_CORE_IBEX_CHERIOT_LOCK + 4'b 1111, // index[26] RV_CORE_IBEX_FPGA_INFO + 4'b 0001, // index[27] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN + 4'b 0001 // index[28] RV_CORE_IBEX_MCOUNTEREN_WRITABLE }; endpackage diff --git a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rv_core_ibex.core b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rv_core_ibex.core index 4010a7415c560..1f7dc1b7f2a8d 100644 --- a/hw/top_earlgrey/ip_autogen/rv_core_ibex/rv_core_ibex.core +++ b/hw/top_earlgrey/ip_autogen/rv_core_ibex/rv_core_ibex.core @@ -20,6 +20,7 @@ filesets: - lowrisc:prim:mubi - lowrisc:tlul:adapter_host - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:ip:cheriot files: - rtl/rv_core_ibex_reg_pkg.sv diff --git a/hw/top_earlgrey/top_earlgrey.core b/hw/top_earlgrey/top_earlgrey.core index 9983dcbd839fc..d33425c835ed4 100644 --- a/hw/top_earlgrey/top_earlgrey.core +++ b/hw/top_earlgrey/top_earlgrey.core @@ -17,6 +17,7 @@ filesets: - lowrisc:ip:rv_dm - lowrisc:ip:rv_timer - lowrisc:ip:tlul + - lowrisc:ip:cheriot - lowrisc:ip:spi_device - lowrisc:ip:spi_host - lowrisc:ip:i2c 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 4670c106d457a..fde4f3cbfe541 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 @@ -1079,6 +1079,40 @@ ] }, + { name: "CHERIOT_ENA", + desc: ''' + Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). + ''', + swaccess: "wo", + hwaccess: "hro", + fields: [ + { bits: "3:0", + name: "VAL", + resval: "0x0" + desc: ''' + ''' + }, + ] + }, + + { name: "CHERIOT_LOCK", + desc: ''' + Locks the CHERIoT/ePMP mode. + If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. + ''', + swaccess: "wo", + hwaccess: "hro", + hwext: "true", + hwqe: "true", + fields: [ + { bits: "3:0", + name: "VAL", + desc: ''' + ''' + }, + ] + }, + { name: "FPGA_INFO", desc: ''' FPGA build timestamp info. 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 16ad07f8053dc..3ccc585432819 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,36 +5,38 @@ 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.[`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. | +| 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.[`CHERIOT_ENA`](#cheriot_ena) | 0x60 | 4 | Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). | +| rv_core_ibex.[`CHERIOT_LOCK`](#cheriot_lock) | 0x64 | 4 | Locks the CHERIoT/ePMP mode. | +| rv_core_ibex.[`FPGA_INFO`](#fpga_info) | 0x68 | 4 | FPGA build timestamp info. | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) | 0x6c | 4 | Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) | +| rv_core_ibex.[`MCOUNTEREN_WRITABLE`](#mcounteren_writable) | 0x70 | 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 @@ -421,10 +423,45 @@ Status of random data in [`RND_DATA`](#rnd_data) | 1 | ro | 0x0 | RND_DATA_FIPS | When [`RND_STATUS.RND_DATA_VALID`](#rnd_status) is 1, this bit indicates whether [`RND_DATA`](#rnd_data) is fips quality. When [`RND_STATUS.RND_DATA_VALID`](#rnd_status) is 0, this bit has no meaning. | | 0 | ro | 0x0 | RND_DATA_VALID | When set, the data in [`RND_DATA`](#rnd_data) is valid. When clear an EDN request for new data for [`RND_DATA`](#rnd_data) is pending. | +## CHERIOT_ENA +Whether to enable (MuBi4True) CHERIoT mode or remain in ePMP mode (MuBi4False). +- Offset: `0x60` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["wo"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:4 | | | | Reserved | +| 3:0 | wo | 0x0 | VAL | | + +## CHERIOT_LOCK +Locks the CHERIoT/ePMP mode. +If CHERIOT_ENA is set to MuBi4True, CHERIoT mode is enabled on write to this register. +- Offset: `0x64` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["wo"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:4 | | | | Reserved | +| 3:0 | wo | x | VAL | | + ## FPGA_INFO FPGA build timestamp info. This register only contains valid data for fpga, for all other variants it is simply 0. -- Offset: `0x60` +- Offset: `0x68` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -440,7 +477,7 @@ This register only contains valid data for fpga, for all other variants it is si ## MCOUNTEREN_WRITABLE_REGWEN Register write-enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) -- Offset: `0x64` +- Offset: `0x6c` - Reset default: `0x1` - Reset mask: `0x1` @@ -466,7 +503,7 @@ Write enable for [`MCOUNTEREN_WRITABLE.`](#mcounteren_writable) Once set to 0, i ## MCOUNTEREN_WRITABLE Controls whether Ibex mcounteren CSR is writable by software. -- Offset: `0x68` +- Offset: `0x70` - Reset default: `0x6` - Reset mask: `0xf` - Register enable: [`MCOUNTEREN_WRITABLE_REGWEN`](#mcounteren_writable_regwen) 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 eddb743aeed2e..9627adce607a1 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 @@ -14,6 +14,7 @@ module rv_core_ibex import rv_core_ibex_pkg::*; import rv_core_ibex_reg_pkg::*; #( + parameter ibex_pkg::base_isa_e BaseIsa = ibex_pkg::BaseIsaRV32IorCHERIoT, parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, // Number of cycles a differential skew is tolerated on the alert and escalation signal parameter int unsigned AlertSkewCycles = 1, @@ -57,7 +58,9 @@ module rv_core_ibex parameter int unsigned WidthPingCounter = 16, parameter logic [tlul_pkg::RsvdWidth-1:0] TlulHostUserRsvdBits = 0, parameter logic [31:0] CsrMvendorId = 32'b0, - parameter logic [31:0] CsrMimpId = 32'b0 + parameter logic [31:0] CsrMimpId = 32'b0, + parameter int unsigned CheriotRevBitmapAddrWidth = 32'd9, + parameter int unsigned CheriotRevBitmapBaseAddr = 32'h0 ) ( // Clock and Reset input logic clk_i, @@ -236,6 +239,11 @@ module rv_core_ibex // core sleeping logic core_sleep; + // CHERIoT signals + prim_mubi_pkg::mubi4_t cheriot_ena; + logic cheriot_switch_error; + logic unused_cheriot; + // The following intermediate signals are created to aid in simulations. // // If a parent port is connected directly to a port of sub-modules, the implicit wire connection @@ -431,6 +439,7 @@ module rv_core_ibex ibex_pkg::crash_dump_t crash_dump; ibex_top #( + .BaseIsa ( BaseIsa ), .PMPEnable ( PMPEnable ), .PMPGranularity ( PMPGranularity ), .PMPNumRegions ( PMPNumRegions ), @@ -439,6 +448,8 @@ module rv_core_ibex .PMPRstCfg ( PMPRstCfg ), .PMPRstAddr ( PMPRstAddr ), .PMPRstMsecCfg ( PMPRstMsecCfg ), + .CheriotRevBitmapAddrWidth ( CheriotRevBitmapAddrWidth), + .CheriotRevBitmapBaseAddr ( CheriotRevBitmapBaseAddr ), .RV32E ( RV32E ), .RV32M ( RV32M ), .RV32B ( RV32B ), @@ -493,6 +504,8 @@ module rv_core_ibex .hart_id_i, .boot_addr_i, + .trvk_heap_base_addr_i('0), // SRAM base address + .instr_req_o (main_core_instr_req), .instr_gnt_i (main_core_instr_gnt_ibex), .instr_rvalid_i (main_core_instr_rvalid), @@ -509,10 +522,20 @@ module rv_core_ibex .data_addr_o (main_core_data_addr), .data_wdata_o (main_core_data_wdata), .data_wdata_intg_o (main_core_data_wdata_intg), + .data_tag_o (), .data_rdata_i (main_core_data_rdata), .data_rdata_intg_i (main_core_data_rdata_intg), + .data_tag_i ('0), .data_err_i (main_core_data_err), + .trvk_revbm_req_o (), + .trvk_revbm_gnt_i ('0), + .trvk_revbm_rvalid_i ('0), + .trvk_revbm_addr_o (), + .trvk_revbm_rdata_i ('0), + .trvk_revbm_rdata_intg_i('0), + .trvk_revbm_err_i ('0), + .irq_software_i ( irq_software ), .irq_timer_i ( irq_timer ), .irq_external_i ( irq_external ), @@ -1012,6 +1035,29 @@ module rv_core_ibex assign hw2reg.rnd_status.rnd_data_valid.d = rnd_valid_q; assign hw2reg.rnd_status.rnd_data_fips.d = rnd_fips_q; + //////////////////// + // CHERIoT switch + //////////////////// + + if (BaseIsa == ibex_pkg::BaseIsaRV32IorCHERIoT) begin : gen_cheriot_switch + cheriot_switch u_cheriot_switch ( + .clk_i, + .rst_ni, + .ena_i (reg2hw.cheriot_ena.q), + .lock_i (reg2hw.cheriot_lock.q), + .lock_access_i(reg2hw.cheriot_lock.qe), + .ena_o (cheriot_ena), + .error_o (cheriot_switch_error) + ); + // For now, tie off all signals + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + + end else begin : gen_no_cheriot_switch + assign cheriot_ena = prim_mubi_pkg::MuBi4False; + assign cheriot_switch_error = 1'b0; + assign unused_cheriot = ^{cheriot_ena, cheriot_switch_error}; + end + logic unused_reg2hw; assign unused_reg2hw = |reg2hw.rnd_data.q; @@ -1102,7 +1148,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.mcounteren_writable}; + reg2hw_shadow.mcounteren_writable, + reg2hw_shadow.cheriot_ena, reg2hw_shadow.cheriot_lock}; ///////////////////////////////////////////////////////////////// // 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 bd489909982fa..2003143cc666d 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 [26:0] reg_we_check; + logic [28:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(27) + .OneHotWidth(29) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -253,6 +253,10 @@ module rv_core_ibex_cfg_reg_top ( logic rnd_status_re; logic rnd_status_rnd_data_valid_qs; logic rnd_status_rnd_data_fips_qs; + logic cheriot_ena_we; + logic [3:0] cheriot_ena_wd; + logic cheriot_lock_we; + logic [3:0] cheriot_lock_wd; logic fpga_info_re; logic [31:0] fpga_info_qs; logic mcounteren_writable_regwen_we; @@ -1302,6 +1306,54 @@ module rv_core_ibex_cfg_reg_top ( ); + // R[cheriot_ena]: V(False) + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessWO), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_cheriot_ena ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (cheriot_ena_we), + .wd (cheriot_ena_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.cheriot_ena.q), + .ds (), + + // to register interface (read) + .qs () + ); + + + // R[cheriot_lock]: V(True) + logic cheriot_lock_qe; + logic [0:0] cheriot_lock_flds_we; + assign cheriot_lock_qe = &cheriot_lock_flds_we; + prim_subreg_ext #( + .DW (4) + ) u_cheriot_lock ( + .re (1'b0), + .we (cheriot_lock_we), + .wd (cheriot_lock_wd), + .d ('0), + .qre (), + .qe (cheriot_lock_flds_we[0]), + .q (reg2hw.cheriot_lock.q), + .ds (), + .qs () + ); + assign reg2hw.cheriot_lock.qe = cheriot_lock_qe; + + // R[fpga_info]: V(True) prim_subreg_ext #( .DW (32) @@ -1378,7 +1430,7 @@ module rv_core_ibex_cfg_reg_top ( - logic [26:0] addr_hit; + logic [28: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); @@ -1404,9 +1456,11 @@ module rv_core_ibex_cfg_reg_top ( addr_hit[21] = (reg_addr == RV_CORE_IBEX_ERR_STATUS_OFFSET); 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); + addr_hit[24] = (reg_addr == RV_CORE_IBEX_CHERIOT_ENA_OFFSET); + addr_hit[25] = (reg_addr == RV_CORE_IBEX_CHERIOT_LOCK_OFFSET); + addr_hit[26] = (reg_addr == RV_CORE_IBEX_FPGA_INFO_OFFSET); + addr_hit[27] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET); + addr_hit[28] = (reg_addr == RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1440,7 +1494,9 @@ module rv_core_ibex_cfg_reg_top ( (addr_hit[23] & (|(RV_CORE_IBEX_CFG_PERMIT[23] & ~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))))); + (addr_hit[26] & (|(RV_CORE_IBEX_CFG_PERMIT[26] & ~reg_be))) | + (addr_hit[27] & (|(RV_CORE_IBEX_CFG_PERMIT[27] & ~reg_be))) | + (addr_hit[28] & (|(RV_CORE_IBEX_CFG_PERMIT[28] & ~reg_be))))); end // Generate write-enables @@ -1528,11 +1584,17 @@ module rv_core_ibex_cfg_reg_top ( assign err_status_recov_core_err_wd = reg_wdata[10]; 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 cheriot_ena_we = addr_hit[24] & reg_we & !reg_error; + + assign cheriot_ena_wd = reg_wdata[3:0]; + assign cheriot_lock_we = addr_hit[25] & reg_we & !reg_error; + + assign cheriot_lock_wd = reg_wdata[3:0]; + assign fpga_info_re = addr_hit[26] & reg_re & !reg_error; + assign mcounteren_writable_regwen_we = addr_hit[27] & 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_we = addr_hit[28] & reg_we & !reg_error; assign mcounteren_writable_wd = reg_wdata[3:0]; @@ -1562,9 +1624,11 @@ module rv_core_ibex_cfg_reg_top ( reg_we_check[21] = err_status_we; 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; + reg_we_check[24] = cheriot_ena_we; + reg_we_check[25] = cheriot_lock_we; + reg_we_check[26] = 1'b0; + reg_we_check[27] = mcounteren_writable_regwen_we; + reg_we_check[28] = mcounteren_writable_gated_we; end // Read data return @@ -1677,14 +1741,22 @@ module rv_core_ibex_cfg_reg_top ( end addr_hit[24]: begin - reg_rdata_next[31:0] = fpga_info_qs; + reg_rdata_next[3:0] = '0; end addr_hit[25]: begin - reg_rdata_next[0] = mcounteren_writable_regwen_qs; + reg_rdata_next[3:0] = '0; end addr_hit[26]: begin + reg_rdata_next[31:0] = fpga_info_qs; + end + + addr_hit[27]: begin + reg_rdata_next[0] = mcounteren_writable_regwen_qs; + end + + addr_hit[28]: begin reg_rdata_next[3:0] = mcounteren_writable_qs; 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 2fe6515143947..328d7f99090ea 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 = 27; + parameter int NumRegsCfg = 29; // Alert indices typedef enum int { @@ -110,6 +110,15 @@ 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_cheriot_ena_reg_t; + + typedef struct packed { + logic [3:0] q; + logic qe; + } rv_core_ibex_reg2hw_cheriot_lock_reg_t; + typedef struct packed { logic [3:0] q; } rv_core_ibex_reg2hw_mcounteren_writable_reg_t; @@ -168,18 +177,20 @@ 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; // [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_alert_test_reg_t alert_test; // [337:330] + rv_core_ibex_reg2hw_sw_recov_err_reg_t sw_recov_err; // [329:326] + rv_core_ibex_reg2hw_sw_fatal_err_reg_t sw_fatal_err; // [325:322] + rv_core_ibex_reg2hw_ibus_addr_en_mreg_t [1:0] ibus_addr_en; // [321:318] + rv_core_ibex_reg2hw_ibus_addr_matching_mreg_t [1:0] ibus_addr_matching; // [317:252] + rv_core_ibex_reg2hw_ibus_remap_addr_mreg_t [1:0] ibus_remap_addr; // [251:186] + rv_core_ibex_reg2hw_dbus_addr_en_mreg_t [1:0] dbus_addr_en; // [185:182] + rv_core_ibex_reg2hw_dbus_addr_matching_mreg_t [1:0] dbus_addr_matching; // [181:116] + rv_core_ibex_reg2hw_dbus_remap_addr_mreg_t [1:0] dbus_remap_addr; // [115:50] + rv_core_ibex_reg2hw_nmi_enable_reg_t nmi_enable; // [49:48] + rv_core_ibex_reg2hw_nmi_state_reg_t nmi_state; // [47:46] + rv_core_ibex_reg2hw_rnd_data_reg_t rnd_data; // [45:13] + rv_core_ibex_reg2hw_cheriot_ena_reg_t cheriot_ena; // [12:9] + rv_core_ibex_reg2hw_cheriot_lock_reg_t cheriot_lock; // [8:4] rv_core_ibex_reg2hw_mcounteren_writable_reg_t mcounteren_writable; // [3:0] } rv_core_ibex_cfg_reg2hw_t; @@ -218,9 +229,11 @@ package rv_core_ibex_reg_pkg; parameter logic [CfgAw-1:0] RV_CORE_IBEX_ERR_STATUS_OFFSET = 8'h 54; 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; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_CHERIOT_ENA_OFFSET = 8'h 60; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_CHERIOT_LOCK_OFFSET = 8'h 64; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_FPGA_INFO_OFFSET = 8'h 68; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN_OFFSET = 8'h 6c; + parameter logic [CfgAw-1:0] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_OFFSET = 8'h 70; // Reset values for hwext registers and their fields for cfg interface parameter logic [3:0] RV_CORE_IBEX_ALERT_TEST_RESVAL = 4'h 0; @@ -233,6 +246,7 @@ package rv_core_ibex_reg_pkg; parameter logic [1:0] RV_CORE_IBEX_RND_STATUS_RESVAL = 2'h 0; parameter logic [0:0] RV_CORE_IBEX_RND_STATUS_RND_DATA_VALID_RESVAL = 1'h 0; parameter logic [0:0] RV_CORE_IBEX_RND_STATUS_RND_DATA_FIPS_RESVAL = 1'h 0; + parameter logic [3:0] RV_CORE_IBEX_CHERIOT_LOCK_RESVAL = 4'h 0; parameter logic [31:0] RV_CORE_IBEX_FPGA_INFO_RESVAL = 32'h 0; parameter logic [31:0] RV_CORE_IBEX_FPGA_INFO_VAL_RESVAL = 32'h 0; @@ -267,13 +281,15 @@ package rv_core_ibex_reg_pkg; RV_CORE_IBEX_ERR_STATUS, RV_CORE_IBEX_RND_DATA, RV_CORE_IBEX_RND_STATUS, + RV_CORE_IBEX_CHERIOT_ENA, + RV_CORE_IBEX_CHERIOT_LOCK, 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 [27] = '{ + parameter logic [3:0] RV_CORE_IBEX_CFG_PERMIT [29] = '{ 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 @@ -298,9 +314,11 @@ 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 0001, // index[25] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN - 4'b 0001 // index[26] RV_CORE_IBEX_MCOUNTEREN_WRITABLE + 4'b 0001, // index[24] RV_CORE_IBEX_CHERIOT_ENA + 4'b 0001, // index[25] RV_CORE_IBEX_CHERIOT_LOCK + 4'b 1111, // index[26] RV_CORE_IBEX_FPGA_INFO + 4'b 0001, // index[27] RV_CORE_IBEX_MCOUNTEREN_WRITABLE_REGWEN + 4'b 0001 // index[28] RV_CORE_IBEX_MCOUNTEREN_WRITABLE }; endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rv_core_ibex.core b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rv_core_ibex.core index 07976e5941dfe..8a8f57d5a8a36 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rv_core_ibex.core +++ b/hw/top_englishbreakfast/ip_autogen/rv_core_ibex/rv_core_ibex.core @@ -20,6 +20,7 @@ filesets: - lowrisc:prim:mubi - lowrisc:tlul:adapter_host - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:ip:cheriot files: - rtl/rv_core_ibex_reg_pkg.sv diff --git a/hw/vendor/lowrisc_ibex.lock.hjson b/hw/vendor/lowrisc_ibex.lock.hjson index 49aa7dcf98bc2..26b7c2df22297 100644 --- a/hw/vendor/lowrisc_ibex.lock.hjson +++ b/hw/vendor/lowrisc_ibex.lock.hjson @@ -8,7 +8,7 @@ { upstream: { - url: https://github.com/lowRISC/ibex.git - rev: aae4809aea170fc605bdaa64a70a13efd2408829 + url: https://github.com/thommythomaso/ibex-tbenz-pub.git + rev: 8348e15c8e6458e858c3f98601366d6880e8455f } } diff --git a/hw/vendor/lowrisc_ibex.vendor.hjson b/hw/vendor/lowrisc_ibex.vendor.hjson index c9a2aeb65255a..15a9bca214828 100644 --- a/hw/vendor/lowrisc_ibex.vendor.hjson +++ b/hw/vendor/lowrisc_ibex.vendor.hjson @@ -7,8 +7,8 @@ patch_dir: "patches/lowrisc_ibex", upstream: { - url: "https://github.com/lowRISC/ibex.git", - rev: "master", + url: "https://github.com/thommythomaso/ibex-tbenz-pub.git", + rev: "tbenz/cheriot-ibex-int", }, mapping: [ diff --git a/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv b/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv index 8f41c17f9e3ed..9ee34f94a8424 100644 --- a/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv +++ b/hw/vendor/lowrisc_ibex/dv/formal/check/top.sv @@ -142,7 +142,33 @@ localparam logic [31:0] CSR_MIMPID_VALUE = 32'b0; default clocking @(posedge clk_i); endclocking +// The TRVK (CHERIoT revocation) filter is only instantiated when BaseIsa is +// BaseIsaRV32IorCHERIoT. The core has no CHERIoT support yet and the formal spec +// is the plain RISC-V Sail model, so select BaseIsaRV32I to bypass the filter +// (a combinational pass-through of the data interface). The filter's ports still +// exist on ibex_top, so provide nets for the `.*` connection below: drive the +// inputs to their inactive values and leave the outputs as sinks. +logic [31:0] trvk_heap_base_addr_i; +logic data_tag_o; +logic data_tag_i; +logic trvk_revbm_req_o; +logic trvk_revbm_gnt_i; +logic trvk_revbm_rvalid_i; +logic [31:0] trvk_revbm_addr_o; +logic [31:0] trvk_revbm_rdata_i; +logic [ 6:0] trvk_revbm_rdata_intg_i; +logic trvk_revbm_err_i; + +assign trvk_heap_base_addr_i = 32'b0; +assign data_tag_i = 1'b0; +assign trvk_revbm_gnt_i = 1'b0; +assign trvk_revbm_rvalid_i = 1'b0; +assign trvk_revbm_rdata_i = 32'b0; +assign trvk_revbm_rdata_intg_i = 7'b0; +assign trvk_revbm_err_i = 1'b0; + ibex_top #( + .BaseIsa(ibex_pkg::BaseIsaRV32I), .DmHaltAddr(DmHaltAddr), .DmExceptionAddr(DmExceptionAddr), .SecureIbex(SecureIbex), 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 48ab742dc6d61..465418fa09543 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 @@ -180,6 +180,8 @@ module ibex_riscv_compliance ( // First instruction executed is at 0x0 + 0x80 .boot_addr_i (32'h00000000 ), + .trvk_heap_base_addr_i (32'h00000000 ), + .instr_req_o (host_req[CoreI] ), .instr_gnt_i (host_gnt[CoreI] ), .instr_rvalid_i (host_rvalid[CoreI] ), @@ -196,10 +198,20 @@ module ibex_riscv_compliance ( .data_addr_o (host_addr[CoreD] ), .data_wdata_o (host_wdata[CoreD] ), .data_wdata_intg_o ( ), + .data_tag_o ( ), .data_rdata_i (host_rdata[CoreD] ), .data_rdata_intg_i (ibex_data_rdata_intg ), + .data_tag_i (1'b0 ), .data_err_i (host_err[CoreD] ), + .trvk_revbm_req_o ( ), + .trvk_revbm_gnt_i (1'b0 ), + .trvk_revbm_rvalid_i (1'b0 ), + .trvk_revbm_addr_o ( ), + .trvk_revbm_rdata_i ('0 ), + .trvk_revbm_rdata_intg_i ('0 ), + .trvk_revbm_err_i (1'b0 ), + .irq_software_i (1'b0 ), .irq_timer_i (1'b0 ), .irq_external_i (1'b0 ), diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/ibex_dv.f b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/ibex_dv.f index 877870069d90f..44de3662af9d0 100644 --- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/ibex_dv.f +++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/ibex_dv.f @@ -50,10 +50,18 @@ ${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_39_32_dec.sv ${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_72_64_enc.sv ${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_72_64_dec.sv +${LOWRISC_IP_DIR}/ip/prim/rtl/prim_fifo_sync_cnt.sv +${LOWRISC_IP_DIR}/ip/prim/rtl/prim_fifo_sync.sv + +// Vendored PULP common cells (used by the TRVK filter) +${PRJ_DIR}/vendor/pulp_common_cells/rtl/stream_fork.sv +${PRJ_DIR}/vendor/pulp_common_cells/rtl/stream_fork_dynamic.sv +${PRJ_DIR}/vendor/pulp_common_cells/rtl/stream_join_dynamic.sv // ibex CORE RTL files +incdir+${PRJ_DIR}/rtl ${PRJ_DIR}/rtl/ibex_pkg.sv +${PRJ_DIR}/rtl/ibex_cheriot_pkg.sv ${PRJ_DIR}/rtl/ibex_tracer_pkg.sv ${PRJ_DIR}/rtl/ibex_tracer.sv ${PRJ_DIR}/rtl/ibex_alu.sv @@ -81,6 +89,7 @@ ${PRJ_DIR}/rtl/ibex_register_file_latch.sv ${PRJ_DIR}/rtl/ibex_pmp.sv ${PRJ_DIR}/rtl/ibex_core.sv +${PRJ_DIR}/rtl/ibex_trvk.sv ${PRJ_DIR}/rtl/ibex_top.sv ${PRJ_DIR}/rtl/ibex_top_tracing.sv 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 270ddac024fec..69472e3d44a6b 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 @@ -132,6 +132,7 @@ module core_ibex_tb_top; .hart_id_i (32'b0 ), .boot_addr_i (BootAddr ), + .trvk_heap_base_addr_i (32'b0 ), .instr_req_o (instr_mem_vif.request ), .instr_gnt_i (instr_mem_vif.grant ), @@ -149,10 +150,20 @@ module core_ibex_tb_top; .data_be_o (data_mem_vif.be ), .data_rdata_i (data_mem_vif.rdata ), .data_rdata_intg_i (data_mem_vif.rintg ), + .data_tag_i (1'b0 ), .data_wdata_o (data_mem_vif.wdata ), .data_wdata_intg_o (data_mem_vif.wintg ), + .data_tag_o ( ), .data_err_i (data_mem_vif.error ), + .trvk_revbm_req_o ( ), + .trvk_revbm_gnt_i (1'b0 ), + .trvk_revbm_rvalid_i (1'b0 ), + .trvk_revbm_addr_o ( ), + .trvk_revbm_rdata_i ('b0 ), + .trvk_revbm_rdata_intg_i ('b0 ), + .trvk_revbm_err_i ( ), + .irq_software_i (irq_vif.irq_software ), .irq_timer_i (irq_vif.irq_timer ), .irq_external_i (irq_vif.irq_external ), diff --git a/hw/vendor/lowrisc_ibex/ibex_core.core b/hw/vendor/lowrisc_ibex/ibex_core.core index ab0ee64e83008..84dd40d49b1dc 100644 --- a/hw/vendor/lowrisc_ibex/ibex_core.core +++ b/hw/vendor/lowrisc_ibex/ibex_core.core @@ -12,6 +12,7 @@ filesets: - lowrisc:prim:clock_gating - lowrisc:prim:lfsr - lowrisc:prim:mubi + - lowrisc:prim:fifo - lowrisc:ibex:ibex_pkg - lowrisc:ibex:ibex_icache - lowrisc:dv:dv_fcov_macros diff --git a/hw/vendor/lowrisc_ibex/ibex_pkg.core b/hw/vendor/lowrisc_ibex/ibex_pkg.core index 17f47e08c4cce..68a512543a865 100644 --- a/hw/vendor/lowrisc_ibex/ibex_pkg.core +++ b/hw/vendor/lowrisc_ibex/ibex_pkg.core @@ -9,6 +9,7 @@ filesets: files_rtl: files: - rtl/ibex_pkg.sv + - rtl/ibex_cheriot_pkg.sv file_type: systemVerilogSource targets: diff --git a/hw/vendor/lowrisc_ibex/ibex_top.core b/hw/vendor/lowrisc_ibex/ibex_top.core index 82edbe133db3f..0bb94c2e3a1e4 100644 --- a/hw/vendor/lowrisc_ibex/ibex_top.core +++ b/hw/vendor/lowrisc_ibex/ibex_top.core @@ -19,10 +19,12 @@ filesets: - lowrisc:prim:onehot_check - lowrisc:prim:onehot - lowrisc:prim:util + - pulp-platform:common_cells:common_cells files: - rtl/ibex_register_file_ff.sv # generic FF-based - rtl/ibex_register_file_fpga.sv # FPGA - rtl/ibex_register_file_latch.sv # ASIC + - rtl/ibex_trvk.sv - rtl/ibex_lockstep.sv - rtl/ibex_top.sv file_type: systemVerilogSource diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_cheriot_pkg.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_cheriot_pkg.sv new file mode 100644 index 0000000000000..d944edf434e79 --- /dev/null +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_cheriot_pkg.sv @@ -0,0 +1,56 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package ibex_cheriot_pkg; + + parameter int unsigned TOP_W = 9; + parameter int unsigned BOT_W = 9; + parameter int unsigned EXP_W = 5; + parameter int unsigned OTYPE_W = 3; + parameter int unsigned CPERMS_W = 6; + + + // Obtain 32-bit representation of top + function automatic logic[32:0] get_bound33(logic [TOP_W-1:0] top, logic [1:0] cor, + logic [EXP_W-1:0] exponent, logic [31:0] addr); + logic [32:0] t1, t2, mask, cor_val; + + if (cor[1]) + // negative sign extension + cor_val = {33{cor[1]}}; + else + cor_val = {32'h0, (~cor[1]) & cor[0]}; + + cor_val = (cor_val << exponent) << TOP_W; + mask = (33'h1_ffff_ffff << exponent) << TOP_W; + + // apply correction and truncate + t1 = ({1'b0, addr} & mask) + cor_val; + // extend to 32 bit + t2 = {24'h0, top}; + t1 = t1 | (t2 << exponent); + + return t1; + endfunction + + + // Update the top/base correction for a cap + function automatic logic [2:0] update_temp_fields(logic [TOP_W-1:0] top, logic [BOT_W-1:0] base, + logic [BOT_W-1:0] addrmi); + logic top_hi, addr_hi; + logic [2:0] res3; + + top_hi = (top < base); + addr_hi = (addrmi < base); + + // top_cor + res3[2:1] = (top_hi == addr_hi)? 2'b00 : ((top_hi && (!addr_hi))? 2'b01 : 2'b11); + + // base_cor + res3[0] = (addr_hi) ? 1'b1 : 1'b0; + + return res3; + endfunction + +endpackage diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv index 45b406444c812..b33311cc2c927 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv @@ -32,6 +32,11 @@ package ibex_pkg; // Parameter Enums // ///////////////////// + typedef enum integer { + BaseIsaRV32I = 0, // only RV32I + BaseIsaRV32IorCHERIoT = 1 // dual base ISA: RV32I/CHERIoT runtime switchable + } base_isa_e; + typedef enum integer { RegFileFF = 0, RegFileFPGA = 1, diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv index 0f6419a89d3a2..75092b79b4850 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_top.sv @@ -13,6 +13,7 @@ * Top level module of the ibex RISC-V core */ module ibex_top import ibex_pkg::*; #( + parameter ibex_pkg::base_isa_e BaseIsa = ibex_pkg::BaseIsaRV32IorCHERIoT, parameter bit PMPEnable = 1'b0, parameter int unsigned PMPGranularity = 0, parameter int unsigned PMPNumRegions = 4, @@ -21,6 +22,8 @@ module ibex_top import ibex_pkg::*; #( parameter ibex_pkg::pmp_cfg_t PMPRstCfg[PMP_MAX_REGIONS] = ibex_pkg::PmpCfgRst, parameter logic [PMP_ADDR_MSB:0] PMPRstAddr[PMP_MAX_REGIONS] = ibex_pkg::PmpAddrRst, parameter ibex_pkg::pmp_mseccfg_t PMPRstMsecCfg = ibex_pkg::PmpMseccfgRst, + parameter int unsigned CheriotRevBitmapAddrWidth = 32'd9, + parameter int unsigned CheriotRevBitmapBaseAddr = 32'h0, parameter bit RV32E = 1'b0, parameter rv32m_e RV32M = RV32MFast, parameter rv32b_e RV32B = RV32BNone, @@ -73,6 +76,8 @@ module ibex_top import ibex_pkg::*; #( input logic [31:0] hart_id_i, input logic [31:0] boot_addr_i, + input logic [31:0] trvk_heap_base_addr_i, + // Instruction memory interface output logic instr_req_o, input logic instr_gnt_i, @@ -91,10 +96,21 @@ module ibex_top import ibex_pkg::*; #( output logic [31:0] data_addr_o, output logic [31:0] data_wdata_o, output logic [6:0] data_wdata_intg_o, + output logic data_tag_o, input logic [31:0] data_rdata_i, input logic [6:0] data_rdata_intg_i, + input logic data_tag_i, input logic data_err_i, + // TRVK revocation bitmap read interface + output logic trvk_revbm_req_o, + input logic trvk_revbm_gnt_i, + input logic trvk_revbm_rvalid_i, + output logic [31:0] trvk_revbm_addr_o, + input logic [31:0] trvk_revbm_rdata_i, + input logic [6:0] trvk_revbm_rdata_intg_i, + input logic trvk_revbm_err_i, + // Interrupt inputs input logic irq_software_i, input logic irq_timer_i, @@ -222,6 +238,23 @@ module ibex_top import ibex_pkg::*; #( logic [MemDataWidth-1:0] data_rdata_core; logic [MemDataWidth-1:0] instr_rdata_core; + // Core <-> TRVK connection + logic trvk_req; + logic trvk_gnt; + logic trvk_rvalid; + logic trvk_we; + logic [3:0] trvk_be; + logic [31:0] trvk_addr; + logic [31:0] trvk_wdata; + logic [6:0] trvk_wdata_intg; + logic trvk_wtag; + logic [31:0] trvk_rdata; + logic [6:0] trvk_rdata_intg; + logic trvk_rtag; + logic trvk_err; + logic trvk_revbm_data_intg_error; + logic trvk_revbm_device_error; + // Core <-> RAMs signals logic [IC_NUM_WAYS-1:0] ic_tag_req; logic ic_tag_write; @@ -305,16 +338,16 @@ module ibex_top import ibex_pkg::*; #( // 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; + assign data_rdata_core[31:0] = trvk_rdata; assign instr_rdata_core[31:0] = instr_rdata_i; if (MemECC) begin : gen_mem_rdata_ecc - assign data_rdata_core[38:32] = data_rdata_intg_i; + assign data_rdata_core[38:32] = trvk_rdata_intg; assign instr_rdata_core[38:32] = instr_rdata_intg_i; end else begin : gen_non_mem_rdata_ecc logic unused_intg; - assign unused_intg = ^{instr_rdata_intg_i, data_rdata_intg_i}; + assign unused_intg = ^{instr_rdata_intg_i, trvk_rdata_intg}; end ibex_core #( @@ -370,15 +403,15 @@ module ibex_top import ibex_pkg::*; #( .instr_rdata_i(instr_rdata_core), .instr_err_i, - .data_req_o, - .data_gnt_i, - .data_rvalid_i, - .data_we_o, - .data_be_o, - .data_addr_o, - .data_wdata_o(data_wdata_core), - .data_rdata_i(data_rdata_core), - .data_err_i, + .data_req_o (trvk_req), + .data_gnt_i (trvk_gnt), + .data_rvalid_i(trvk_rvalid), + .data_we_o (trvk_we), + .data_be_o (trvk_be), + .data_addr_o (trvk_addr), + .data_wdata_o (data_wdata_core), + .data_rdata_i (data_rdata_core), + .data_err_i (trvk_err), .dummy_instr_id_o (dummy_instr_id), .dummy_instr_wb_o (dummy_instr_wb), @@ -777,15 +810,15 @@ module ibex_top import ibex_pkg::*; #( assign icache_data_alert = '{default:'b0}; end - assign data_wdata_o = data_wdata_core[31:0]; + assign trvk_wdata = data_wdata_core[31:0]; if (MemECC) begin : gen_mem_wdata_ecc prim_buf #(.Width(7)) u_prim_buf_data_wdata_intg ( .in_i (data_wdata_core[38:32]), - .out_o(data_wdata_intg_o) + .out_o(trvk_wdata_intg) ); end else begin : gen_no_mem_ecc - assign data_wdata_intg_o = '0; + assign trvk_wdata_intg = '0; end // Redundant lockstep core implementation @@ -806,15 +839,15 @@ module ibex_top import ibex_pkg::*; #( instr_addr_o, instr_rdata_core, instr_err_i, - data_req_o, - data_gnt_i, - data_rvalid_i, - data_we_o, - data_be_o, - data_addr_o, - data_wdata_o, + trvk_req, + trvk_gnt, + trvk_rvalid, + trvk_we, + trvk_be, + trvk_addr, + trvk_wdata, data_rdata_core, - data_err_i, + trvk_err, rf_rdata_a, rf_rdata_b, ic_tag_req, @@ -901,15 +934,15 @@ module ibex_top import ibex_pkg::*; #( instr_addr_o, instr_rdata_core, instr_err_i, - data_req_o, - data_gnt_i, - data_rvalid_i, - data_we_o, - data_be_o, - data_addr_o, - data_wdata_o, + trvk_req, + trvk_gnt, + trvk_rvalid, + trvk_we, + trvk_be, + trvk_addr, + trvk_wdata, data_rdata_core, - data_err_i, + trvk_err, rf_rdata_a, rf_rdata_b, ic_tag_req, @@ -1148,14 +1181,109 @@ module ibex_top import ibex_pkg::*; #( assign unused_scan = scan_rst_ni; end + + ////////// + // TRVK // + ////////// + + if (BaseIsa == BaseIsaRV32IorCHERIoT) begin : gen_cheriot_trvk + ibex_trvk #( + .NumOutstanding(32'd2), + .RevBitmapAddrWidth(CheriotRevBitmapAddrWidth), + .RevBitmapBaseAddr(CheriotRevBitmapBaseAddr) + ) i_ibex_trvk ( + .clk_i (clk), + .rst_ni (rst_ni), + .heap_base_addr_i (trvk_heap_base_addr_i), + .upstream_req_i (trvk_req), + .upstream_gnt_o (trvk_gnt), + .upstream_rvalid_o (trvk_rvalid), + .upstream_we_i (trvk_we), + .upstream_be_i (trvk_be), + .upstream_addr_i (trvk_addr), + .upstream_wdata_i (trvk_wdata), + .upstream_wdata_intg_i (trvk_wdata_intg), + .upstream_rdata_o (trvk_rdata), + .upstream_rdata_intg_o (trvk_rdata_intg), + .upstream_err_o (trvk_err), + .upstream_tag_i (trvk_wtag), + .upstream_tag_o (trvk_rtag), + .downstream_req_o (data_req_o), + .downstream_gnt_i (data_gnt_i), + .downstream_rvalid_i (data_rvalid_i), + .downstream_we_o (data_we_o), + .downstream_be_o (data_be_o), + .downstream_addr_o (data_addr_o), + .downstream_wdata_o (data_wdata_o), + .downstream_wdata_intg_o(data_wdata_intg_o), + .downstream_rdata_i (data_rdata_i), + .downstream_rdata_intg_i(data_rdata_intg_i), + .downstream_err_i (data_err_i), + .downstream_tag_o (data_tag_o), + .downstream_tag_i (data_tag_i), + .revbm_req_o (trvk_revbm_req_o), + .revbm_gnt_i (trvk_revbm_gnt_i), + .revbm_rvalid_i (trvk_revbm_rvalid_i), + .revbm_addr_o (trvk_revbm_addr_o), + .revbm_rdata_i (trvk_revbm_rdata_i), + .revbm_rdata_intg_i (trvk_revbm_rdata_intg_i), + .revbm_err_i (trvk_revbm_err_i), + .revbm_data_intg_error_o(trvk_revbm_data_intg_error), + .revbm_device_error_o (trvk_revbm_device_error) + ); + + // Tag connection towards the core is tied-off for now. This will change as soon as the core + // is updated to feature CHERIoT support. + logic unused_trvk; + assign trvk_wtag = 1'b0; + assign unused_trvk = trvk_rtag; + + end else begin : gen_no_cheriot_trvk + + logic unused_trvk; + + assign trvk_revbm_req_o = '0; + assign trvk_revbm_addr_o = '0; + assign trvk_wtag = 1'b0; + assign data_tag_o = 1'b0; + assign trvk_revbm_data_intg_error = 1'b0; + assign trvk_revbm_device_error = 1'b0; + assign unused_trvk = ^{ + trvk_heap_base_addr_i, + trvk_revbm_gnt_i, + trvk_revbm_rvalid_i, + trvk_revbm_rdata_i, + trvk_revbm_rdata_intg_i, + trvk_revbm_err_i, + trvk_rtag, + data_tag_i + }; + + // Through-connect TRVK + assign data_req_o = trvk_req; + assign trvk_gnt = data_gnt_i; + assign trvk_rvalid = data_rvalid_i; + assign data_we_o = trvk_we; + assign data_be_o = trvk_be; + assign data_addr_o = trvk_addr; + assign data_wdata_o = trvk_wdata; + assign data_wdata_intg_o = trvk_wdata_intg; + assign trvk_rdata = data_rdata_i; + assign trvk_rdata_intg = data_rdata_intg_i; + assign trvk_err = data_err_i; + end + + // Enable or disable iCache multi bit encoding checking error generation. // If enabled and a MuBi encoding error is detected, raise a major alert. logic icache_alert_major_internal; assign icache_alert_major_internal = (|icache_tag_alert) | (|icache_data_alert); - assign alert_major_internal_o = core_alert_major_internal | + assign alert_major_internal_o = core_alert_major_internal | lockstep_alert_major_internal | - icache_alert_major_internal; + icache_alert_major_internal | + trvk_revbm_data_intg_error | + trvk_revbm_device_error; assign alert_major_bus_o = core_alert_major_bus | lockstep_alert_major_bus; assign alert_minor_o = core_alert_minor | lockstep_alert_minor; diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv index 3823dd219e756..a742078142aee 100644 --- a/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv @@ -7,6 +7,7 @@ */ module ibex_top_tracing import ibex_pkg::*; #( + parameter base_isa_e BaseIsa = BaseIsaRV32IorCHERIoT, parameter bit PMPEnable = 1'b0, parameter int unsigned PMPGranularity = 0, parameter int unsigned PMPNumRegions = 4, @@ -49,6 +50,7 @@ module ibex_top_tracing import ibex_pkg::*; #( input prim_ram_1p_pkg::ram_1p_cfg_t ram_cfg_icache_data_i, output prim_ram_1p_pkg::ram_1p_cfg_rsp_t [ibex_pkg::IC_NUM_WAYS-1:0] ram_cfg_rsp_icache_data_o, + input logic [31:0] trvk_heap_base_addr_i, input logic [31:0] hart_id_i, input logic [31:0] boot_addr_i, @@ -71,10 +73,21 @@ module ibex_top_tracing import ibex_pkg::*; #( output logic [31:0] data_addr_o, output logic [31:0] data_wdata_o, output logic [6:0] data_wdata_intg_o, + output logic data_tag_o, input logic [31:0] data_rdata_i, input logic [6:0] data_rdata_intg_i, + input logic data_tag_i, input logic data_err_i, + // TRVK revocation bitmap read interface + output logic trvk_revbm_req_o, + input logic trvk_revbm_gnt_i, + input logic trvk_revbm_rvalid_i, + output logic [31:0] trvk_revbm_addr_o, + input logic [31:0] trvk_revbm_rdata_i, + input logic [6:0] trvk_revbm_rdata_intg_i, + input logic trvk_revbm_err_i, + // Interrupt inputs input logic irq_software_i, input logic irq_timer_i, @@ -196,6 +209,7 @@ module ibex_top_tracing import ibex_pkg::*; #( assign unused_rvfi_ext_expanded_insn_last = rvfi_ext_expanded_insn_last; ibex_top #( + .BaseIsa ( BaseIsa ), .PMPEnable ( PMPEnable ), .PMPGranularity ( PMPGranularity ), .PMPNumRegions ( PMPNumRegions ), @@ -259,6 +273,17 @@ module ibex_top_tracing import ibex_pkg::*; #( .data_rdata_intg_i, .data_err_i, + .trvk_heap_base_addr_i, + .data_tag_o, + .data_tag_i, + .trvk_revbm_req_o, + .trvk_revbm_gnt_i, + .trvk_revbm_rvalid_i, + .trvk_revbm_addr_o, + .trvk_revbm_rdata_i, + .trvk_revbm_rdata_intg_i, + .trvk_revbm_err_i, + .irq_software_i, .irq_timer_i, .irq_external_i, diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_trvk.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_trvk.sv new file mode 100644 index 0000000000000..b02835718862c --- /dev/null +++ b/hw/vendor/lowrisc_ibex/rtl/ibex_trvk.sv @@ -0,0 +1,383 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module ibex_trvk #( + // The number of outstanding transaction the IP supports + parameter int unsigned NumOutstanding = 32'd4, + // The width of the meta memory address space used to store the revocation bits + parameter int unsigned RevBitmapAddrWidth = 32'd9, + // The base address of the meta SRAM holding the revocation bitmap + parameter int unsigned RevBitmapBaseAddr = 32'h0000_0000 +)( + input clk_i, + input rst_ni, + + // The base address of the (heap) memory where to be revocable capabilities point to + input logic [31:0] heap_base_addr_i, + + // Upstream port + input logic upstream_req_i, + output logic upstream_gnt_o, + output logic upstream_rvalid_o, + input logic upstream_we_i, + input logic [3:0] upstream_be_i, + input logic [31:0] upstream_addr_i, + input logic [31:0] upstream_wdata_i, + input logic [6:0] upstream_wdata_intg_i, + output logic [31:0] upstream_rdata_o, + output logic [6:0] upstream_rdata_intg_o, + output logic upstream_err_o, + input logic upstream_tag_i, + output logic upstream_tag_o, + + // Downstream port + output logic downstream_req_o, + input logic downstream_gnt_i, + input logic downstream_rvalid_i, + output logic downstream_we_o, + output logic [3:0] downstream_be_o, + output logic [31:0] downstream_addr_o, + output logic [31:0] downstream_wdata_o, + output logic [6:0] downstream_wdata_intg_o, + input logic [31:0] downstream_rdata_i, + input logic [6:0] downstream_rdata_intg_i, + input logic downstream_err_i, + output logic downstream_tag_o, + input logic downstream_tag_i, + + // Revocation bitmap memory port + output logic revbm_req_o, + input logic revbm_gnt_i, + input logic revbm_rvalid_i, + output logic [31:0] revbm_addr_o, + input logic [31:0] revbm_rdata_i, + input logic [6:0] revbm_rdata_intg_i, + input logic revbm_err_i, + + // Error signals + output logic revbm_data_intg_error_o, + output logic revbm_device_error_o +); + + + /////////// + // Types // + /////////// + + // Expanded exponent (5 bit). Exponent 'd15 stored in memory is mapped to 'd24. + typedef logic [ibex_cheriot_pkg::EXP_W-1:0] cheriot_exp_t; + typedef logic [ibex_cheriot_pkg::BOT_W-1:0] cheriot_bot_t; + typedef logic [ibex_cheriot_pkg::OTYPE_W-1:0] cheriot_otype_t; + typedef logic [ibex_cheriot_pkg::CPERMS_W-1:0] cheriot_cperms_t; + + // Revocation bitmap word address type + typedef logic [RevBitmapAddrWidth-1:0] revbm_addr_t; + + // Local capability metadata type to facilitate parsing of the fields. + typedef struct packed { + cheriot_exp_t exponent; + cheriot_bot_t base; + cheriot_otype_t otype; + cheriot_cperms_t cperms; + } cap_meta_t; + + // Local downstream response type + typedef struct packed { + logic [31:0] data; + logic [6:0] intg; + logic tag; + logic err; + } ds_rsp_t; + + + ///////////// + // Signals // + ///////////// + + // Signals connecting the request to the alignment store. + logic align_fork_valid; + logic align_fork_ready; + + // Alignment store output + logic align_out; + logic align_out_valid; + logic align_out_ready; + + // Pointer store signals + logic [31:0] ptr_store_q; + logic ptr_store_valid_q; + logic ptr_store_enable; + + // Downstream response store output + ds_rsp_t downstream_rsp_in; + ds_rsp_t downstream_rsp_out; + logic downstream_rsp_out_valid; + logic downstream_rsp_out_ready; + + // Base (address) calculation + cap_meta_t cap_meta; + logic unused_cap_meta; + logic is_sealing_cap; + logic [32:0] cap_base_33; + logic unused_cap_base_33; + logic [31:0] cap_base; + cheriot_bot_t addr_mid; + logic [ 2:0] cap_correction; + logic unused_cap_correction; + + // Revocation bitmap addressing + logic [31:0] revbm_cap_addr; + logic [31:0] revbm_bit_addr; + logic [ 4:0] revbm_bit_select; + revbm_addr_t revbm_addr; + logic revbm_out_of_range; + + // Revocation bitmap signals + logic revbm_req_required; + logic revbm_rsp_ready; + logic revbm_outstanding_q; + logic revbm_revoked; + + // Bitmap response ECC signals + logic [1:0] revbm_rsp_data_intg_error; + + + ////////////////////////////// + // Host to Device Intercept // + ////////////////////////////// + + // Both the device and the alignment store need to handshake for + // the stream to advance. + stream_fork #( + .N_OUP(32'd2) + ) u_stream_fork_h2d ( + .clk_i, + .rst_ni, + .valid_i(upstream_req_i), + .ready_o(upstream_gnt_o), + .valid_o({align_fork_valid, downstream_req_o}), + .ready_i({align_fork_ready, downstream_gnt_i}) + ); + + // The host and on lookup the revocation bitmap must handshake to advance the stream + // We use `revbm_req_required` as a section signal here. If there is a bitmap lookup required, + // this signal gets asserted beyond the request handshake completion until the response arrives. + stream_join_dynamic #( + .N_INP(32'd2) + ) u_stream_join_dynamic_d2h ( + .inp_valid_i({revbm_rvalid_i, downstream_rsp_out_valid}), + .inp_ready_o({revbm_rsp_ready, downstream_rsp_out_ready}), + .sel_i ({revbm_req_required, 1'b1 }), + .oup_valid_o(upstream_rvalid_o), + .oup_ready_i(1'b1) + ); + + // Forward OBI payload between host and device + assign downstream_we_o = upstream_we_i; + assign downstream_be_o = upstream_be_i; + assign downstream_addr_o = upstream_addr_i; + assign downstream_wdata_o = upstream_wdata_i; + assign downstream_wdata_intg_o = upstream_wdata_intg_i; + assign upstream_rdata_o = downstream_rsp_out.data; + assign upstream_rdata_intg_o = downstream_rsp_out.intg; + assign upstream_err_o = downstream_rsp_out.err; + + // Forward host to device CHERIoT tag w/o changes + assign downstream_tag_o = upstream_tag_i; + + // Tag handling; always return tag except if we do a revocation bitmap lookup + assign upstream_tag_o = revbm_rvalid_i ? !revbm_revoked : downstream_rsp_out.tag; + + // 64-bit alignment store + prim_fifo_sync #( + .Width(32'd1), + .Pass(1'b0), + .Depth(NumOutstanding), + .NeverClears(1'b1), + .Secure(1'b0) + ) u_prim_fifo_sync_align ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(align_fork_valid), + .wready_o(align_fork_ready), + .wdata_i (upstream_addr_i[2]), + .rvalid_o(align_out_valid), + .rready_i(align_out_ready), + .rdata_o (align_out), + .full_o (), + .depth_o (), + .err_o () + ); + + // Element is consumed, if host handshakes response + assign align_out_ready = upstream_rvalid_o; + + + /////////////////// + // Pointer Store // + /////////////////// + + // Pointer buffer is filled iff tag valid & 64-bit aligned + assign ptr_store_enable = downstream_rsp_out.tag && !align_out && align_out_valid && + align_out_ready; + + // Pointer store + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_pointer_store + if(!rst_ni) begin + ptr_store_q <= '0; + end else begin + if (ptr_store_enable) begin + ptr_store_q <= downstream_rsp_out.data; + end + end + end + + // Pointer valid store + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_pointer_vaild_store + if(!rst_ni) begin + ptr_store_valid_q <= 1'b0; + end else begin + if (align_out_ready) begin + ptr_store_valid_q <= ptr_store_enable; + end + end + end + + + ////////////////////////////////// + // Downstream Response Latching // + ////////////////////////////////// + + // downstream response store + prim_fifo_sync #( + .Width($bits(ds_rsp_t)), + .Pass(1'b1), + .Depth(NumOutstanding), + .NeverClears(1'b1), + .Secure(1'b0) + ) u_prim_fifo_ds_rsp_store ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(downstream_rvalid_i), + .wready_o(), // Not connected as OBI is not configured to use rready + .wdata_i (downstream_rsp_in), + .rvalid_o(downstream_rsp_out_valid), + .rready_i(downstream_rsp_out_ready), + .rdata_o (downstream_rsp_out), + .full_o (), + .depth_o (), + .err_o () + ); + + assign downstream_rsp_in = '{ + data: downstream_rdata_i, + intg: downstream_rdata_intg_i, + tag: downstream_tag_i, + err: downstream_err_i + }; + + + //////////////////////////////// + // Bitmap Address Calculation // + //////////////////////////////// + + // Exponent is expanded (page 70, CHERIoT Architecture specification, Version 1.0) + assign cap_meta = '{ + base: downstream_rsp_out.data[8:0], + exponent: downstream_rsp_out.data[21:18] != 4'hf ? {1'b0, downstream_rsp_out.data[21:18]} : + 5'd24, + otype: downstream_rsp_out.data[24:22], + cperms: downstream_rsp_out.data[30:25] + }; + + // Not all fields are used + assign unused_cap_meta = ^{cap_meta.otype, cap_meta.cperms[5]}; + + // Check if cap is sealing cap + assign is_sealing_cap = (cap_meta.cperms[4:3] == 2'b00) && (|cap_meta.cperms[2:0]); + + // Extract the middle field from the pointer, bounds depend on exponent, width fixed + assign addr_mid = ptr_store_q[cap_meta.exponent +: ibex_cheriot_pkg::BOT_W]; + + // Fetch the correction values, we are only interested in the base correction value (1 bit) + // top-related inputs are set to zero, top-related outputs ignored + assign cap_correction = ibex_cheriot_pkg::update_temp_fields('0, cap_meta.base, addr_mid); + + // Calculate the base address of the capability as a 33-bit value + assign cap_base_33 = ibex_cheriot_pkg::get_bound33(cap_meta.base, {2{cap_correction[0]}}, + cap_meta.exponent, ptr_store_q); + + // We don't need the correction bits corresponding to the top address + assign unused_cap_correction = ^cap_correction[2:1]; + + // The MSB is unused in our case + assign {unused_cap_base_33, cap_base} = cap_base_33; + + // Address in the revocation bitmap + assign revbm_cap_addr = cap_base - heap_base_addr_i; + + // Bit address in the revocation bitmap (every bit corresponds to one 64-bit capability) + assign revbm_bit_addr = revbm_cap_addr >> 32'd3; + + // Word address of the revocation bitmap + assign revbm_addr = revbm_bit_addr[RevBitmapAddrWidth+5-1:5]; + + // Bit select + assign revbm_bit_select = revbm_bit_addr[4:0]; + + // Capability base is outside of the bitmap range + assign revbm_out_of_range = |(revbm_bit_addr[31:RevBitmapAddrWidth+5]); + + + ////////////////////// + // Bitmap Interface // + ////////////////////// + + // We have loaded valid capability pointer, now we see valid metadata, not a sealing cap, + // and are pointing into the revocation bitmap + assign revbm_req_required = !is_sealing_cap && // Not sealing cap + ptr_store_valid_q && // The base pointer stored is valid + downstream_rsp_out.tag && // We are looking at a capability + downstream_rsp_out_valid && // The stored response is valid + align_out && // We are on the second word of the cap + align_out_valid && // The alignment store is valid + !revbm_out_of_range; // We hit the heap range + + // Assemble read-only request + assign revbm_req_o = revbm_req_required && !revbm_outstanding_q; + assign revbm_addr_o = RevBitmapBaseAddr + {{32 - RevBitmapAddrWidth{1'b0}}, revbm_addr}; + + // Is the current capability marked as revoked? + assign revbm_revoked = revbm_rdata_i[revbm_bit_select] || revbm_err_i; + + // Did we receive a device error? + assign revbm_device_error_o = revbm_rvalid_i && revbm_err_i; + + // Check the bitmap response data integrity + prim_secded_inv_39_32_dec u_prim_secded_inv_39_32_dec_bm_rsp_data ( + .data_i ({revbm_rdata_intg_i, revbm_rdata_i}), + .data_o (), + .syndrome_o(), + .err_o (revbm_rsp_data_intg_error) + ); + + // Mask response integrity error if response is not being handshaked + assign revbm_data_intg_error_o = revbm_rvalid_i && (|revbm_rsp_data_intg_error); + + // One outstanding request + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_rev_req_store + if(!rst_ni) begin + revbm_outstanding_q <= 1'b0; + end else begin + if (revbm_rvalid_i && revbm_rsp_ready) begin + revbm_outstanding_q <= 1'b0; + end else if (revbm_req_o && revbm_gnt_i) begin + revbm_outstanding_q <= 1'b1; + end + end + end + +endmodule diff --git a/hw/vendor/lowrisc_ibex/syn/ibex_top_lr_synth_conf.tcl b/hw/vendor/lowrisc_ibex/syn/ibex_top_lr_synth_conf.tcl index f3f8622d6c856..8c3898147294c 100644 --- a/hw/vendor/lowrisc_ibex/syn/ibex_top_lr_synth_conf.tcl +++ b/hw/vendor/lowrisc_ibex/syn/ibex_top_lr_synth_conf.tcl @@ -7,13 +7,13 @@ # # {instr_req_o 70.0} # -# as an output means the instr_req_o output must be stable by 60% of total clock -# cycle +# as an output means the instr_req_o output must be stable by 70% of total clock +# cycle, # # {instr_gnt_i 30.0} # # as an input means the instr_gnt_i input will be stable by 30% of the total -# clock cycle +# clock cycle. # These IO constraints are an educated guess, they effectively assume there's a # bit of external logic on the inputs and outputs but not much before they reach @@ -46,11 +46,11 @@ set lr_synth_inputs [list {test_en_i 0.0 } \ {debug_req_i 10.0} \ {fetch_enable_i 0.0 }] -# clock and reset IO names (at top-level) +# Clock and reset IO names (at top-level). set lr_synth_clk_input clk_i set lr_synth_rst_input rst_ni -# clock period in ps, this gives a 250 MHz clock. using the nangate45 library +# Clock period in ps, this gives a 250 MHz clock. using the nangate45 library # Ibex can happily meet this on all paths with the lr_synth_abc_clk_uprate # setting below. With a lower uprate timing may not be met. set lr_synth_clk_period 4000.0 diff --git a/hw/vendor/patches/pulp_common_cells/stream_fork_dynamic_sv/0001-replace-assertions.patch b/hw/vendor/patches/pulp_common_cells/stream_fork_dynamic_sv/0001-replace-assertions.patch new file mode 100644 index 0000000000000..6d6b7533d5ca8 --- /dev/null +++ b/hw/vendor/patches/pulp_common_cells/stream_fork_dynamic_sv/0001-replace-assertions.patch @@ -0,0 +1,23 @@ +diff --git a/stream_fork_dynamic.sv b/stream_fork_dynamic.sv +index 8da5313d..1aa546b4 100644 +--- a/stream_fork_dynamic.sv ++++ b/stream_fork_dynamic.sv +@@ -11,7 +11,7 @@ + // Authors: + // - Andreas Kurth + +-`include "common_cells/assertions.svh" ++`include "prim_assert.sv" + + /// Dynamic stream fork: Connects the input stream (ready-valid) handshake to a combination of output + /// stream handshake. The combination is determined dynamically through another stream, which +@@ -87,7 +87,6 @@ module stream_fork_dynamic #( + .ready_i ( int_oup_ready ) + ); + +-`ifndef COMMON_CELLS_ASSERTS_OFF +- `ASSERT_INIT(n_oup_0, N_OUP >= 1, "N_OUP must be at least 1!") +-`endif ++ `ASSERT_INIT(NumOutputLargerZero_A, N_OUP >= 1) ++ + endmodule diff --git a/hw/vendor/patches/pulp_common_cells/stream_fork_sv/0001-replace-assertions.patch b/hw/vendor/patches/pulp_common_cells/stream_fork_sv/0001-replace-assertions.patch new file mode 100644 index 0000000000000..408c39eca7992 --- /dev/null +++ b/hw/vendor/patches/pulp_common_cells/stream_fork_sv/0001-replace-assertions.patch @@ -0,0 +1,23 @@ +diff --git a/stream_fork.sv b/stream_fork.sv +index ebe65f9b..7ae27c1a 100644 +--- a/stream_fork.sv ++++ b/stream_fork.sv +@@ -16,7 +16,7 @@ + // This module has no data ports because stream data does not need to be forked: the data of the + // input stream can just be applied at all output streams. + +-`include "common_cells/assertions.svh" ++`include "prim_assert.sv" + + module stream_fork #( + parameter int unsigned N_OUP = 0 // Synopsys DC requires a default value for parameters. +@@ -124,8 +124,6 @@ module stream_fork #( + assign all_ones = '1; // Synthesis fix for Vivado, which does not correctly compute the width + // of the '1 literal when assigned to a port of parametrized width. + +-`ifndef COMMON_CELLS_ASSERTS_OFF +- `ASSERT_INIT(n_oup_0, N_OUP >= 1, "Number of outputs must be at least 1!") +-`endif ++ `ASSERT_INIT(NumOutputLargerZero_A, N_OUP >= 1) + + endmodule diff --git a/hw/vendor/patches/pulp_common_cells/stream_fork_sv/0002-rename-wait-state.patch b/hw/vendor/patches/pulp_common_cells/stream_fork_sv/0002-rename-wait-state.patch new file mode 100644 index 0000000000000..b0e07fa66c688 --- /dev/null +++ b/hw/vendor/patches/pulp_common_cells/stream_fork_sv/0002-rename-wait-state.patch @@ -0,0 +1,46 @@ +diff --git a/stream_fork.sv b/stream_fork.sv +index 7ae27c1a06..e27b6e4549 100644 +--- a/stream_fork.sv ++++ b/stream_fork.sv +@@ -29,7 +29,7 @@ module stream_fork #( + input logic [N_OUP-1:0] ready_i + ); + +- typedef enum logic {READY, WAIT} state_t; ++ typedef enum logic {READY, WAITING} state_t; + + logic [N_OUP-1:0] oup_ready, + all_ones; +@@ -50,13 +50,13 @@ module stream_fork #( + end else begin + ready_o = 1'b0; + // Otherwise, wait for inputs that did not handshake yet. +- inp_state_d = WAIT; ++ inp_state_d = WAITING; + end + end else begin + ready_o = 1'b0; + end + end +- WAIT: begin ++ WAITING: begin + if (valid_i && oup_ready == all_ones) begin + ready_o = 1'b1; + inp_state_d = READY; +@@ -94,14 +94,14 @@ module stream_fork #( + valid_o[i] = 1'b1; + if (ready_i[i]) begin // Output handshake + if (!ready_o) begin // No input handshake yet +- oup_state_d = WAIT; ++ oup_state_d = WAITING; + end + end else begin // No output handshake + oup_ready[i] = 1'b0; + end + end + end +- WAIT: begin ++ WAITING: begin + if (valid_i && ready_o) begin // Input handshake + oup_state_d = READY; + end diff --git a/hw/vendor/patches/pulp_common_cells/stream_join_dynamic_sv/0001-replace-assertions.patch b/hw/vendor/patches/pulp_common_cells/stream_join_dynamic_sv/0001-replace-assertions.patch new file mode 100644 index 0000000000000..76cbb735cafd9 --- /dev/null +++ b/hw/vendor/patches/pulp_common_cells/stream_join_dynamic_sv/0001-replace-assertions.patch @@ -0,0 +1,23 @@ +diff --git a/stream_join_dynamic.sv b/stream_join_dynamic.sv +index 267990b9..0dec8875 100644 +--- a/stream_join_dynamic.sv ++++ b/stream_join_dynamic.sv +@@ -11,7 +11,7 @@ + // Authors: + // - Luca Colagrande + +-`include "common_cells/assertions.svh" ++`include "prim_assert.sv" + + // Stream join dynamic: Joins a parametrizable number of input streams (i.e. valid-ready + // handshaking with dependency rules as in AXI4) to a single output stream. The subset of streams +@@ -39,7 +39,6 @@ module stream_join_dynamic #( + assign inp_ready_o[i] = oup_valid_o & oup_ready_i & sel_i[i]; + end + +-`ifndef COMMON_CELLS_ASSERTS_OFF +- `ASSERT_INIT(n_inp_0, N_INP >= 1, "N_INP must be at least 1!") +-`endif ++ `ASSERT_INIT(NumInputLargerZero_A, N_INP >= 1) ++ + endmodule diff --git a/hw/vendor/pulp_common_cells.core b/hw/vendor/pulp_common_cells.core new file mode 100644 index 0000000000000..c877e01cb74b9 --- /dev/null +++ b/hw/vendor/pulp_common_cells.core @@ -0,0 +1,21 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: "pulp-platform:common_cells:common_cells:0.1" +description: "PULP Common Cells" + +filesets: + files_src: + depend: + - lowrisc:prim:assert + files: + - pulp_common_cells/rtl/stream_fork.sv + - pulp_common_cells/rtl/stream_fork_dynamic.sv + - pulp_common_cells/rtl/stream_join_dynamic.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_src diff --git a/hw/vendor/pulp_common_cells.lock.hjson b/hw/vendor/pulp_common_cells.lock.hjson new file mode 100644 index 0000000000000..df71f11911037 --- /dev/null +++ b/hw/vendor/pulp_common_cells.lock.hjson @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is generated by the util/vendor script. Please do not modify it +// manually. + +{ + upstream: + { + url: https://github.com/pulp-platform/common_cells.git + rev: 63e1b679a70eca3a1d60d686bc1fa170ec08e1ab + } +} diff --git a/hw/vendor/pulp_common_cells.vendor.hjson b/hw/vendor/pulp_common_cells.vendor.hjson new file mode 100644 index 0000000000000..62b16ea1d6d0f --- /dev/null +++ b/hw/vendor/pulp_common_cells.vendor.hjson @@ -0,0 +1,28 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "pulp_common_cells", + target_dir: "pulp_common_cells", + patch_dir: "patches/pulp_common_cells", + + upstream: { + url: "https://github.com/pulp-platform/common_cells.git" + rev: "master" + }, + + mapping: [ + { + from: "src/stream_fork.sv", + to: "rtl/stream_fork.sv", + patch_dir: "stream_fork_sv"}, + { + from: "src/stream_fork_dynamic.sv", + to: "rtl/stream_fork_dynamic.sv", + patch_dir: "stream_fork_dynamic_sv"}, + { + from: "src/stream_join_dynamic.sv", + to: "rtl/stream_join_dynamic.sv", + patch_dir: "stream_join_dynamic_sv"}, + ] +} diff --git a/hw/vendor/pulp_common_cells/rtl/stream_fork.sv b/hw/vendor/pulp_common_cells/rtl/stream_fork.sv new file mode 100644 index 0000000000000..e27b6e45498b8 --- /dev/null +++ b/hw/vendor/pulp_common_cells/rtl/stream_fork.sv @@ -0,0 +1,129 @@ +// Copyright 2018 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// Stream fork: Connects the input stream (ready-valid) handshake to *all* of `N_OUP` output stream +// handshakes. For each input stream handshake, every output stream handshakes exactly once. The +// input stream only handshakes when all output streams have handshaked, but the output streams do +// not have to handshake simultaneously. +// +// This module has no data ports because stream data does not need to be forked: the data of the +// input stream can just be applied at all output streams. + +`include "prim_assert.sv" + +module stream_fork #( + parameter int unsigned N_OUP = 0 // Synopsys DC requires a default value for parameters. +) ( + input logic clk_i, + input logic rst_ni, + input logic valid_i, + output logic ready_o, + output logic [N_OUP-1:0] valid_o, + input logic [N_OUP-1:0] ready_i +); + + typedef enum logic {READY, WAITING} state_t; + + logic [N_OUP-1:0] oup_ready, + all_ones; + + state_t inp_state_d, inp_state_q; + + // Input control FSM + always_comb begin + // ready_o = 1'b0; + inp_state_d = inp_state_q; + + unique case (inp_state_q) + READY: begin + if (valid_i) begin + if (valid_o == all_ones && ready_i == all_ones) begin + // If handshake on all outputs, handshake on input. + ready_o = 1'b1; + end else begin + ready_o = 1'b0; + // Otherwise, wait for inputs that did not handshake yet. + inp_state_d = WAITING; + end + end else begin + ready_o = 1'b0; + end + end + WAITING: begin + if (valid_i && oup_ready == all_ones) begin + ready_o = 1'b1; + inp_state_d = READY; + end else begin + ready_o = 1'b0; + end + end + default: begin + inp_state_d = READY; + ready_o = 1'b0; + end + endcase + end + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (!rst_ni) begin + inp_state_q <= READY; + end else begin + inp_state_q <= inp_state_d; + end + end + + // Output control FSM + for (genvar i = 0; i < N_OUP; i++) begin: gen_oup_state + state_t oup_state_d, oup_state_q; + + always_comb begin + oup_ready[i] = 1'b1; + valid_o[i] = 1'b0; + oup_state_d = oup_state_q; + + unique case (oup_state_q) + READY: begin + if (valid_i) begin + valid_o[i] = 1'b1; + if (ready_i[i]) begin // Output handshake + if (!ready_o) begin // No input handshake yet + oup_state_d = WAITING; + end + end else begin // No output handshake + oup_ready[i] = 1'b0; + end + end + end + WAITING: begin + if (valid_i && ready_o) begin // Input handshake + oup_state_d = READY; + end + end + default: begin + oup_state_d = READY; + end + endcase + end + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (!rst_ni) begin + oup_state_q <= READY; + end else begin + oup_state_q <= oup_state_d; + end + end + end + + assign all_ones = '1; // Synthesis fix for Vivado, which does not correctly compute the width + // of the '1 literal when assigned to a port of parametrized width. + + `ASSERT_INIT(NumOutputLargerZero_A, N_OUP >= 1) + +endmodule diff --git a/hw/vendor/pulp_common_cells/rtl/stream_fork_dynamic.sv b/hw/vendor/pulp_common_cells/rtl/stream_fork_dynamic.sv new file mode 100644 index 0000000000000..1aa546b44a536 --- /dev/null +++ b/hw/vendor/pulp_common_cells/rtl/stream_fork_dynamic.sv @@ -0,0 +1,92 @@ +// Copyright 2020 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// Authors: +// - Andreas Kurth + +`include "prim_assert.sv" + +/// Dynamic stream fork: Connects the input stream (ready-valid) handshake to a combination of output +/// stream handshake. The combination is determined dynamically through another stream, which +/// provides a bitmask for the fork. For each input stream handshake, every output stream handshakes +/// exactly once. The input stream only handshakes when all output streams have handshaked, but the +/// output streams do not have to handshake simultaneously. +/// +/// This module has no data ports because stream data does not need to be forked: the data of the +/// input stream can just be applied at all output streams. +module stream_fork_dynamic #( + /// Number of output streams + parameter int unsigned N_OUP = 32'd0 // Synopsys DC requires a default value for parameters. +) ( + /// Clock + input logic clk_i, + /// Asynchronous reset, active low + input logic rst_ni, + /// Input stream valid handshake, + input logic valid_i, + /// Input stream ready handshake + output logic ready_o, + /// Selection mask for the output handshake + input logic [N_OUP-1:0] sel_i, + /// Selection mask valid + input logic sel_valid_i, + /// Selection mask ready + output logic sel_ready_o, + /// Output streams valid handshakes + output logic [N_OUP-1:0] valid_o, + /// Output streams ready handshakes + input logic [N_OUP-1:0] ready_i +); + + logic int_inp_valid, int_inp_ready; + logic [N_OUP-1:0] int_oup_valid, int_oup_ready; + + // Output handshaking + for (genvar i = 0; i < N_OUP; i++) begin : gen_oups + always_comb begin + valid_o[i] = 1'b0; + int_oup_ready[i] = 1'b0; + if (sel_valid_i) begin + if (sel_i[i]) begin + valid_o[i] = int_oup_valid[i]; + int_oup_ready[i] = ready_i[i]; + end else begin + int_oup_ready[i] = 1'b1; + end + end + end + end + + // Input handshaking + always_comb begin + int_inp_valid = 1'b0; + ready_o = 1'b0; + sel_ready_o = 1'b0; + if (sel_valid_i) begin + int_inp_valid = valid_i; + ready_o = int_inp_ready; + sel_ready_o = int_inp_ready; + end + end + + stream_fork #( + .N_OUP ( N_OUP ) + ) i_fork ( + .clk_i, + .rst_ni, + .valid_i ( int_inp_valid ), + .ready_o ( int_inp_ready ), + .valid_o ( int_oup_valid ), + .ready_i ( int_oup_ready ) + ); + + `ASSERT_INIT(NumOutputLargerZero_A, N_OUP >= 1) + +endmodule diff --git a/hw/vendor/pulp_common_cells/rtl/stream_join_dynamic.sv b/hw/vendor/pulp_common_cells/rtl/stream_join_dynamic.sv new file mode 100644 index 0000000000000..0dec8875e9a99 --- /dev/null +++ b/hw/vendor/pulp_common_cells/rtl/stream_join_dynamic.sv @@ -0,0 +1,44 @@ +// Copyright 2020 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// Authors: +// - Luca Colagrande + +`include "prim_assert.sv" + +// Stream join dynamic: Joins a parametrizable number of input streams (i.e. valid-ready +// handshaking with dependency rules as in AXI4) to a single output stream. The subset of streams +// to join can be configured dynamically via `sel_i`. The output handshake happens only after +// there has been a handshake. The data channel flows outside of this module. +module stream_join_dynamic #( + /// Number of input streams + parameter int unsigned N_INP = 32'd0 // Synopsys DC requires a default value for parameters. +) ( + /// Input streams valid handshakes + input logic [N_INP-1:0] inp_valid_i, + /// Input streams ready handshakes + output logic [N_INP-1:0] inp_ready_o, + /// Selection mask for the output handshake + input logic [N_INP-1:0] sel_i, + /// Output stream valid handshake + output logic oup_valid_o, + /// Output stream ready handshake + input logic oup_ready_i +); + + // Corner case when `sel_i` is all 0s should not generate valid + assign oup_valid_o = &(inp_valid_i | ~sel_i) && |sel_i; + for (genvar i = 0; i < N_INP; i++) begin : gen_inp_ready + assign inp_ready_o[i] = oup_valid_o & oup_ready_i & sel_i[i]; + end + + `ASSERT_INIT(NumInputLargerZero_A, N_INP >= 1) + +endmodule diff --git a/util/reggen/ip_block.py b/util/reggen/ip_block.py index e7c212324f1c7..afa4f3d36817f 100644 --- a/util/reggen/ip_block.py +++ b/util/reggen/ip_block.py @@ -70,7 +70,8 @@ 43: 'racl_ctrl', 44: 'otp_macro', 45: 'rram_ctrl', - 46: 'rram_macro' + 46: 'rram_macro', + 47: 'cheriot', } REQUIRED_ALIAS_FIELDS = {