From 63bcef63a456840698e300a8cc25e38998f4c7fd Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 23 Jun 2023 13:45:31 +0200 Subject: [PATCH 1/4] [rtl] remove buskeeper status register --- rtl/core/neorv32_bus_keeper.vhd | 108 ++++++-------------------------- rtl/core/neorv32_package.vhd | 12 ++-- rtl/core/neorv32_top.vhd | 6 +- 3 files changed, 25 insertions(+), 101 deletions(-) diff --git a/rtl/core/neorv32_bus_keeper.vhd b/rtl/core/neorv32_bus_keeper.vhd index be512cd41..77a2dc037 100644 --- a/rtl/core/neorv32_bus_keeper.vhd +++ b/rtl/core/neorv32_bus_keeper.vhd @@ -47,8 +47,6 @@ entity neorv32_bus_keeper is port ( clk_i : in std_ulogic; -- global clock line rstn_i : in std_ulogic; -- global reset, low-active, async - cpu_req_i : in bus_req_t; -- control request bus - cpu_rsp_o : out bus_rsp_t; -- control response bus bus_req_i : in bus_req_t; -- monitor request bus bus_rsp_i : in bus_rsp_t; -- monitor response bus bus_err_o : out std_ulogic; -- signal bus error to CPU @@ -60,37 +58,15 @@ end neorv32_bus_keeper; architecture neorv32_bus_keeper_rtl of neorv32_bus_keeper is - -- IO space: module base address -- - constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit - constant lo_abb_c : natural := index_size_f(buskeeper_size_c); -- low address boundary bit - - -- Control register -- - constant ctrl_err_type_c : natural := 0; -- r/-: error type: 0=device error, 1=access timeout - constant ctrl_err_flag_c : natural := 31; -- r/c: bus error encountered, sticky - - -- error codes -- - constant err_device_c : std_ulogic := '0'; -- device access error - constant err_timeout_c : std_ulogic := '1'; -- timeout error - - -- sticky error flags -- - signal err_flag : std_ulogic; - signal err_type : std_ulogic; - - -- access control -- - signal acc_en : std_ulogic; -- module access enable - signal wren : std_ulogic; -- word write enable - signal rden : std_ulogic; -- read enable - -- timeout counter size -- constant cnt_width_c : natural := index_size_f(max_proc_int_response_time_c); -- controller -- type ctrl_t is record - pending : std_ulogic; - timeout : std_ulogic_vector(cnt_width_c-1 downto 0); - err_type : std_ulogic; - bus_err : std_ulogic; - ignore : std_ulogic; + pending : std_ulogic; + timeout : std_ulogic_vector(cnt_width_c-1 downto 0); + bus_err : std_ulogic; + ignore : std_ulogic; end record; signal ctrl : ctrl_t; @@ -102,88 +78,40 @@ begin report "NEORV32 PROCESSOR CONFIG ERROR! Processor-internal bus timeout has to >= 2." severity error; - -- Host Access ---------------------------------------------------------------------------- - -- ------------------------------------------------------------------------------------------- - - -- access control -- - acc_en <= '1' when (cpu_req_i.addr(hi_abb_c downto lo_abb_c) = buskeeper_base_c(hi_abb_c downto lo_abb_c)) else '0'; - wren <= acc_en and cpu_req_i.we; - rden <= acc_en and cpu_req_i.re; - - -- write access -- - write_access: process(rstn_i, clk_i) - begin - if (rstn_i = '0') then - err_flag <= '0'; - err_type <= '0'; - elsif rising_edge(clk_i) then - if (ctrl.bus_err = '1') then -- sticky error flag - err_flag <= '1'; - err_type <= ctrl.err_type; - elsif (wren = '1') or (rden = '1') then -- clear on read or write access - err_flag <= '0'; - end if; - end if; - end process write_access; - - -- read access -- - read_access: process(clk_i) - begin - if rising_edge(clk_i) then - cpu_rsp_o.ack <= wren or rden; -- bus handshake - cpu_rsp_o.data <= (others => '0'); - if (rden = '1') then - cpu_rsp_o.data(ctrl_err_type_c) <= err_type; - cpu_rsp_o.data(ctrl_err_flag_c) <= err_flag; - end if; - end if; - end process read_access; - - -- no access error possible -- - cpu_rsp_o.err <= '0'; - - -- Monitor -------------------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- keeper_control: process(rstn_i, clk_i) begin if (rstn_i = '0') then - ctrl.pending <= '0'; - ctrl.bus_err <= '0'; - ctrl.err_type <= '0'; - ctrl.timeout <= (others => '0'); - ctrl.ignore <= '0'; + ctrl.pending <= '0'; + ctrl.bus_err <= '0'; + ctrl.timeout <= (others => '0'); + ctrl.ignore <= '0'; elsif rising_edge(clk_i) then -- defaults -- ctrl.bus_err <= '0'; - - -- IDLE -- + -- bus idle -- if (ctrl.pending = '0') then ctrl.timeout <= std_ulogic_vector(to_unsigned(max_proc_int_response_time_c-1, cnt_width_c)); ctrl.ignore <= '0'; if (bus_req_i.re = '1') or (bus_req_i.we = '1') then ctrl.pending <= '1'; end if; - -- PENDING -- + -- bus access pending -- else -- countdown timer -- ctrl.timeout <= std_ulogic_vector(unsigned(ctrl.timeout) - 1); -- bus keeper shall ignore internal timeout during this access (because it's "external") -- ctrl.ignore <= ctrl.ignore or (bus_ext_i or bus_xip_i); - -- response handling -- - if (bus_rsp_i.err = '1') then -- error termination by bus system - ctrl.err_type <= err_device_c; -- device error - ctrl.bus_err <= '1'; - ctrl.pending <= '0'; - elsif ((or_reduce_f(ctrl.timeout) = '0') and (ctrl.ignore = '0')) or -- valid INTERNAL access timeout - (bus_tmo_i = '1') then -- EXTERNAL access timeout - ctrl.err_type <= err_timeout_c; -- timeout error - ctrl.bus_err <= '1'; - ctrl.pending <= '0'; + -- response check -- + if (bus_rsp_i.err = '1') or -- error termination by bus system + (bus_tmo_i = '1') or -- EXTERNAL access timeout + ((or_reduce_f(ctrl.timeout) = '0') and (ctrl.ignore = '0')) then -- valid INTERNAL access timeout + ctrl.bus_err <= '1'; + ctrl.pending <= '0'; elsif (bus_rsp_i.ack = '1') then -- normal termination by bus system - ctrl.err_type <= '0'; -- don't care - ctrl.bus_err <= '0'; - ctrl.pending <= '0'; + ctrl.bus_err <= '0'; + ctrl.pending <= '0'; end if; end if; end if; diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index a9e880abb..5f600c060 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -60,7 +60,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080506"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080507"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width, do not change! @@ -232,9 +232,9 @@ package neorv32_package is constant onewire_ctrl_addr_c : std_ulogic_vector(31 downto 0) := x"ffffff70"; constant onewire_data_addr_c : std_ulogic_vector(31 downto 0) := x"ffffff74"; - -- Bus Access Monitor (BUSKEEPER) -- - constant buskeeper_base_c : std_ulogic_vector(31 downto 0) := x"ffffff78"; -- base address - constant buskeeper_size_c : natural := 2*4; -- module's address space size in bytes +---- reserved -- +--constant reserved_base_c : std_ulogic_vector(31 downto 0) := x"ffffff78"; -- base address +--constant reserved_size_c : natural := 2*4; -- module's address space size in bytes -- External Interrupt Controller (XIRQ) -- constant xirq_base_c : std_ulogic_vector(31 downto 0) := x"ffffff80"; -- base address @@ -885,7 +885,7 @@ package neorv32_package is -- ------------------------------------------------------------------------------------------- constant alu_op_add_c : std_ulogic_vector(2 downto 0) := "000"; -- result <= A + B constant alu_op_sub_c : std_ulogic_vector(2 downto 0) := "001"; -- result <= A - B - constant alu_op_cp_c : std_ulogic_vector(2 downto 0) := "010"; -- result <= co-processor + constant alu_op_cp_c : std_ulogic_vector(2 downto 0) := "010"; -- result <= ALU co-processor constant alu_op_slt_c : std_ulogic_vector(2 downto 0) := "011"; -- result <= A < B constant alu_op_movb_c : std_ulogic_vector(2 downto 0) := "100"; -- result <= B constant alu_op_xor_c : std_ulogic_vector(2 downto 0) := "101"; -- result <= A xor B @@ -1594,8 +1594,6 @@ package neorv32_package is port ( clk_i : in std_ulogic; -- global clock line rstn_i : in std_ulogic; -- global reset, low-active, async - cpu_req_i : in bus_req_t; -- control request bus - cpu_rsp_o : out bus_rsp_t; -- control response bus bus_req_i : in bus_req_t; -- monitor request bus bus_rsp_i : in bus_rsp_t; -- monitor response bus bus_err_o : out std_ulogic; -- signal bus error to CPU diff --git a/rtl/core/neorv32_top.vhd b/rtl/core/neorv32_top.vhd index 5ba8e2594..bd81707a5 100644 --- a/rtl/core/neorv32_top.vhd +++ b/rtl/core/neorv32_top.vhd @@ -301,8 +301,8 @@ architecture neorv32_top_rtl of neorv32_top is signal dci_halt_req : std_ulogic; -- internal bus system -- - type device_ids_t is (DEV_BUSKEEPER, DEV_IMEM, DEV_DMEM, DEV_BOOTROM, DEV_WISHBONE, DEV_GPIO, DEV_MTIME, DEV_UART0, - DEV_UART1, DEV_SPI, DEV_TWI, DEV_PWM, DEV_WDT, DEV_TRNG, DEV_CFS, DEV_NEOLED, DEV_SYSINFO, DEV_OCD, + type device_ids_t is (DEV_IMEM, DEV_DMEM, DEV_BOOTROM, DEV_WISHBONE, DEV_GPIO, DEV_MTIME, DEV_UART0, DEV_UART1, + DEV_SPI, DEV_TWI, DEV_PWM, DEV_WDT, DEV_TRNG, DEV_CFS, DEV_NEOLED, DEV_SYSINFO, DEV_OCD, DEV_XIRQ, DEV_GPTMR, DEV_XIP_CT, DEV_XIP_ACC, DEV_ONEWIRE, DEV_SDI, DEV_DMA, DEV_SLINK, DEV_CRC); -- core complex -- @@ -705,8 +705,6 @@ begin port map ( clk_i => clk_i, rstn_i => rstn_int, - cpu_req_i => io_req, - cpu_rsp_o => rsp_bus(DEV_BUSKEEPER), bus_req_i => soc_req, bus_rsp_i => soc_rsp, bus_err_o => bus_error, From 76730ac66937b9f3f80b3b61ec32e3bc9509a1d1 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 23 Jun 2023 13:46:00 +0200 Subject: [PATCH 2/4] [sw] remove buskeeper status register --- sw/example/processor_check/main.c | 10 +---- sw/lib/include/neorv32.h | 2 - sw/lib/include/neorv32_buskeeper.h | 65 ------------------------------ sw/lib/source/neorv32_rte.c | 18 --------- sw/svd/neorv32.svd | 34 ---------------- 5 files changed, 2 insertions(+), 127 deletions(-) delete mode 100644 sw/lib/include/neorv32_buskeeper.h diff --git a/sw/example/processor_check/main.c b/sw/example/processor_check/main.c index 0cd71c0d2..1d26bb0d5 100644 --- a/sw/example/processor_check/main.c +++ b/sw/example/processor_check/main.c @@ -691,8 +691,6 @@ int main() { cnt_test++; - tmp_a = (1 << BUSKEEPER_ERR_FLAG) | (1 << BUSKEEPER_ERR_TYPE); - // load from unreachable aligned address asm volatile ("li %[da], 0xcafe1230 \n" // initialize destination register with known value "lw %[da], 0(%[ad]) " // must not update destination register to to exception @@ -700,8 +698,7 @@ int main() { if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_ACCESS) && // load bus access error exception (neorv32_cpu_csr_read(CSR_MTVAL) == ADDR_UNREACHABLE) && - (tmp_b == 0xcafe1230) && // make sure dest. reg is not updated - (NEORV32_BUSKEEPER->CTRL = tmp_a)) { // buskeeper: error flag + timeout error + (tmp_b == 0xcafe1230)) { // make sure dest. reg is not updated test_ok(); } else { @@ -744,14 +741,11 @@ int main() { cnt_test++; - tmp_a = (1 << BUSKEEPER_ERR_FLAG) | (0 << BUSKEEPER_ERR_TYPE); - // store to unreachable aligned address neorv32_cpu_store_unsigned_word(ADDR_READONLY, 0); if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) && // store bus access error exception - (neorv32_cpu_csr_read(CSR_MTVAL) == ADDR_READONLY) && - (NEORV32_BUSKEEPER->CTRL == tmp_a)) { // buskeeper: error flag + device error + (neorv32_cpu_csr_read(CSR_MTVAL) == ADDR_READONLY)) { test_ok(); } else { diff --git a/sw/lib/include/neorv32.h b/sw/lib/include/neorv32.h index 6e7ca74af..3621d292c 100644 --- a/sw/lib/include/neorv32.h +++ b/sw/lib/include/neorv32.h @@ -210,7 +210,6 @@ enum NEORV32_CLOCK_PRSC_enum { #define NEORV32_PWM_BASE (0xFFFFFF50U) /**< Pulse Width Modulation Controller (PWM) */ #define NEORV32_GPTMR_BASE (0xFFFFFF60U) /**< General Purpose Timer (GPTMR) */ #define NEORV32_ONEWIRE_BASE (0xFFFFFF70U) /**< 1-Wire Interface Controller (ONEWIRE) */ -#define NEORV32_BUSKEEPER_BASE (0xFFFFFF78U) /**< Bus Monitor (BUSKEEPER) */ #define NEORV32_XIRQ_BASE (0xFFFFFF80U) /**< External Interrupt Controller (XIRQ) */ #define NEORV32_MTIME_BASE (0xFFFFFF90U) /**< Machine System Timer (MTIME) */ #define NEORV32_UART0_BASE (0xFFFFFFA0U) /**< Primary Universal Asynchronous Receiver and Transmitter (UART0) */ @@ -240,7 +239,6 @@ enum NEORV32_CLOCK_PRSC_enum { #include "neorv32_rte.h" // IO/peripheral devices -#include "neorv32_buskeeper.h" #include "neorv32_cfs.h" #include "neorv32_crc.h" #include "neorv32_dm.h" diff --git a/sw/lib/include/neorv32_buskeeper.h b/sw/lib/include/neorv32_buskeeper.h deleted file mode 100644 index d0c7d4af9..000000000 --- a/sw/lib/include/neorv32_buskeeper.h +++ /dev/null @@ -1,65 +0,0 @@ -// ################################################################################################# -// # << NEORV32: neorv32_buskeeper.h - Bus Monitor (BUSKEEPER) HW Driver (stub) >> # -// # ********************************************************************************************* # -// # BSD 3-Clause License # -// # # -// # Copyright (c) 2023, Stephan Nolting. All rights reserved. # -// # # -// # Redistribution and use in source and binary forms, with or without modification, are # -// # permitted provided that the following conditions are met: # -// # # -// # 1. Redistributions of source code must retain the above copyright notice, this list of # -// # conditions and the following disclaimer. # -// # # -// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # -// # conditions and the following disclaimer in the documentation and/or other materials # -// # provided with the distribution. # -// # # -// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # -// # endorse or promote products derived from this software without specific prior written # -// # permission. # -// # # -// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # -// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # -// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # -// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # -// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # -// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # -// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # -// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # -// # OF THE POSSIBILITY OF SUCH DAMAGE. # -// # ********************************************************************************************* # -// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # -// ################################################################################################# - - -/**********************************************************************//** - * @file neorv32_buskeeper.h - * @brief Bus Monitor (BUSKEEPER) HW driver header file. - **************************************************************************/ - -#ifndef neorv32_buskeeper_h -#define neorv32_buskeeper_h - -/**********************************************************************//** - * @name IO Device: Bus Monitor (BUSKEEPER) - **************************************************************************/ -/**@{*/ -/** BUSKEEPER module prototype */ -typedef volatile struct __attribute__((packed,aligned(4))) { - uint32_t CTRL; /**< offset 0: control register (#NEORV32_BUSKEEPER_CTRL_enum) */ - const uint32_t reserved ; /**< offset 4: reserved */ -} neorv32_buskeeper_t; - -/** BUSKEEPER module hardware access (#neorv32_buskeeper_t) */ -#define NEORV32_BUSKEEPER ((neorv32_buskeeper_t*) (NEORV32_BUSKEEPER_BASE)) - -/** BUSKEEPER control/data register bits */ -enum NEORV32_BUSKEEPER_CTRL_enum { - BUSKEEPER_ERR_TYPE = 0, /**< BUSKEEPER control register( 0) (r/-): Bus error type: 0=device error, 1=access timeout */ - BUSKEEPER_ERR_FLAG = 31 /**< BUSKEEPER control register(31) (r/-): Sticky error flag, clears after read or write access */ -}; -/**@}*/ - - -#endif // neorv32_buskeeper_h diff --git a/sw/lib/source/neorv32_rte.c b/sw/lib/source/neorv32_rte.c index 2c8ae37b8..304d03061 100644 --- a/sw/lib/source/neorv32_rte.c +++ b/sw/lib/source/neorv32_rte.c @@ -72,9 +72,6 @@ void neorv32_rte_setup(void) { // clear all pending IRQs neorv32_cpu_csr_write(CSR_MIP, 0); - // clear BUSKEEPER error flags - NEORV32_BUSKEEPER->CTRL = 0; - // install debug handler for all trap sources uint8_t id; for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) { @@ -250,21 +247,6 @@ static void __neorv32_rte_debug_handler(void) { if ((trap_cause >= TRAP_CODE_FIRQ_0) && (trap_cause <= TRAP_CODE_FIRQ_15)) { neorv32_cpu_csr_clr(CSR_MIP, 1 << (CSR_MIP_FIRQ0P + (trap_cause & 0xf))); // clear pending FIRQ } - // check specific cause if bus access fault exception - else if ((trap_cause == TRAP_CODE_I_ACCESS) || (trap_cause == TRAP_CODE_L_ACCESS) || (trap_cause == TRAP_CODE_S_ACCESS)) { - uint32_t bus_err = NEORV32_BUSKEEPER->CTRL; - if (bus_err & (1< has to be caused by PMP rule violation - neorv32_uart0_puts(" [PMP_ERR]"); - } - } // instruction address neorv32_uart0_puts(" @ PC="); diff --git a/sw/svd/neorv32.svd b/sw/svd/neorv32.svd index b3fc8d6af..3128b4a5e 100644 --- a/sw/svd/neorv32.svd +++ b/sw/svd/neorv32.svd @@ -769,40 +769,6 @@ - - - BUSKEEPER - Bus keeper - BUSKEEPER - 0xFFFFFF78 - - - 0 - 0x08 - registers - - - - - CTRL - Control register - 0x00 - - - BUSKEEPER_ERR_TYPE - [0:0] - read-only - Bus error type: 0=device error, 1=access timeout - - - BUSKEEPER_ERR_FLAG - [31:31] - Sticky error flag, clears after read or write access - - - - - From 4f318cad290fee4f9b8e1669fe170f56f6422434 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 23 Jun 2023 13:49:36 +0200 Subject: [PATCH 3/4] [CHANGELOG] add v1.8.5.7 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d81b29abd..767f03e04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ mimpid = 0x01080200 => Version 01.08.02.00 => v1.8.2 | Date (*dd.mm.yyyy*) | Version | Comment | |:-------------------:|:-------:|:--------| +| 23.06.2023 | 1.8.5.7 | :warning: remove **buskeeper's status register**; [#635](https://github.com/stnolting/neorv32/pull/635) | | 17.06.2023 | 1.8.5.6 | :sparkles: add new **Cyclic Redundancy Check module (CRC)**; [#632](https://github.com/stnolting/neorv32/pull/632) | | 03.06.2023 | 1.8.5.5 | :sparkles: re-add (simplified) **Stream Link Interface (SLINK)**; [#628](https://github.com/stnolting/neorv32/pull/628) | | 03.06.2023 | 1.8.5.4 | :warning: rearrange bits in **SYSINFO**; [#627](https://github.com/stnolting/neorv32/pull/627) | From 01e3c8a6765e0363f7364c12a34e29d2cb12e303 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 23 Jun 2023 14:18:59 +0200 Subject: [PATCH 4/4] [docs] remove BUSKEEPER status register --- docs/datasheet/soc_buskeeper.adoc | 48 ++++++++++--------------------- docs/datasheet/software_rte.adoc | 21 -------------- 2 files changed, 15 insertions(+), 54 deletions(-) diff --git a/docs/datasheet/soc_buskeeper.adoc b/docs/datasheet/soc_buskeeper.adoc index 76fa379c8..fa9894b93 100644 --- a/docs/datasheet/soc_buskeeper.adoc +++ b/docs/datasheet/soc_buskeeper.adoc @@ -16,39 +16,21 @@ **Theory of Operation** -The Bus Keeper is a fundamental component of the processor's internal bus system that ensures correct bus operations -while maintaining execution safety. It monitors every single bus transactions that is initiated by the CPU. -If an accessed device responds with an error condition or do not respond at all within a specific _access time window_, -an according bus access fault exception is raised. The following exceptions can be raised by the Bus Keeper -(see section <<_traps_exceptions_and_interrupts>> for a list of all available bus access-related exceptions): - -* `TRAP_CODE_I_ACCESS`: error during instruction fetch bus access -* `TRAP_CODE_S_ACCESS`: error during data store bus access -* `TRAP_CODE_L_ACCESS`: error during data load bus access - +The Bus Keeper is a fundamental component of the processor's internal bus system that ensures correct operations +while maintaining execution safety. It operates transparently for the user by monitoring every single bus transactions +that is initiated by the CPU. If an accessed device responds with an error condition or does not respond at all within +a specific **access time window**, an according bus access fault exception is raised. The following exceptions can be +raised by the bus keeper: + +* `TRAP_CODE_I_ACCESS`: error / timeout during instruction fetch bus access +* `TRAP_CODE_S_ACCESS`: error / timeout during data store bus access +* `TRAP_CODE_L_ACCESS`: error / timeout during data load bus access + +.Access Time Window +[IMPORTANT] The **access time window**, in which an accessed device has to respond, is defined by the `max_proc_int_response_time_c` constant from the processor's VHDL package file (`rtl/neorv32_package.vhd`). The default value is **15 clock cycles**. -In case of a bus access fault exception application software can evaluate the Bus Keeper's control register -`CTRL` to retrieve further details regarding the bus exception. The `BUSKEEPER_ERR_FLAG` bit indicates -that an actual bus access fault has occurred. The bit is sticky once set and is automatically cleared when reading or -writing the `NEORV32_BUSKEEPER.CTRL` register. The `BUSKEEPER_ERR_TYPE` bit defines the type of the bus fault: - -* `0` - "Device Error": The bus access exception was cause by the memory-mapped device that -has been accessed (the device asserted it's `err_o`). -* `1` - "Timeout Error": The bus access exception was caused by the Bus Keeper because the -accessed memory-mapped device did not respond within the access time window. Note that this error type can also be raised -by the optional timeout feature of the external bus interface. - - -**Register Map** - -.BUSKEEPER register map (`struct NEORV32_BUSKEEPER`) -[cols="<3,<2,<4,^1,<4"] -[options="header",grid="all"] -|======================= -| Address | Name [C] | Bit(s), Name [C] | R/W | Function -.2+<| `0xffffff78` .2+<| `CTRL` <|`0` `BUSKEEPER_ERR_TYPE` ^| r/- <| Bus error type, valid if _BUSKEEPER_ERR_FLAG_ - <|`31` `BUSKEEPER_ERR_FLAG` ^| r/c <| Sticky error flag, clears after read or write access -| `0xffffff7c` | - | _reserved_ | r/c | _reserved_ (mirrored access to `CTRL`) -|======================= +.Register Map +[NOTE] +The bus keeper does not provide any memory-mapped interface registers at all. diff --git a/docs/datasheet/software_rte.adoc b/docs/datasheet/software_rte.adoc index 3f1df4011..6a9f1cc67 100644 --- a/docs/datasheet/software_rte.adoc +++ b/docs/datasheet/software_rte.adoc @@ -199,24 +199,3 @@ obtained from the <<_mcause>> CSR (see <<_neorv32_trap_listing>>). A full list o | "Fast IRQ 0x0000000f" | `0x8000001f` | "Unknown trap cause" | undefined |======================= - -===== Bus Access Faults - -For bus access faults the RTE default trap handlers also outputs the error code obtained from the -<<_internal_bus_monitor_buskeeper>> to show the cause of the bus fault. One example is shown below. - -.RTE Default Trap Handler Output Example (Load Access Bus Fault) -[source] ----- - Load access fault [TIMEOUT_ERR] @ PC=0x00000150, MTVAL=0xFFFFFF70 ----- - -The additional message encapsulated in `[ ]` shows the actual cause of the bus access fault. -Several different message identifiers are possible here: - -* `[TIMEOUT_ERR]`: The accessed memory-mapped module did not respond within the valid access time window. -In Most cases this is caused by accessing a module that has not been implemented or when accessing -"address space holes" via unused/unmapped addresses (see section <<_bus_interface_protocol>>). -* `[DEVICE_ERR]`: The accesses memory-mapped module asserted its error signal to indicate an invalid access. -For example this can be caused by trying to write to read-only registers. -* `[PMP_ERR]`: This indicates an access right violation caused by the <<_pmp_isa_extension>>.