<<<
:sectnums:
==== Processor-External Bus Interface (XBUS)

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files:  | neorv32_xbus.vhd        | External bus gateway
|                         | neorv32_cache.vhd       | Generic cache module
| Software driver files:  | none                    | _implicitly used_
| Top entity ports:       | `xbus_adr_o`            | address output (32-bit)
|                         | `xbus_dat_o`            | data output (32-bit)
|                         | `xbus_tag_o`            | access tag (3-bit)
|                         | `xbus_we_o`             | write enable (1-bit)
|                         | `xbus_sel_o`            | byte enable (4-bit)
|                         | `xbus_stb_o`            | bus strobe (1-bit)
|                         | `xbus_cyc_o`            | valid cycle (1-bit)
|                         | `xbus_dat_i`            | data input (32-bit)
|                         | `xbus_ack_i`            | acknowledge (1-bit)
|                         | `xbus_err_i`            | bus error (1-bit)
| Configuration generics: | `XBUS_EN`               | enable external bus interface when `true`
|                         | `XBUS_TIMEOUT`          | number of clock cycles after which an unacknowledged external bus access will auto-terminate (0 = disabled)
|                         | `XBUS_REGSTAGE_EN`      | implement XBUS register stages
|                         | `XBUS_CACHE_EN`         | implement the external bus cache
|                         | `XBUS_CACHE_NUM_BLOCKS` | number of blocks ("lines"), has to be a power of two.
|                         | `XBUS_CACHE_BLOCK_SIZE` | size in bytes of each block, has to be a power of two.
| CPU interrupts:         | none |
| Access restrictions:  2+| none
|=======================


**Overview**

The external bus interface provides a **Wishbone b4**-compatible on-chip bus interface that is
implemented if the `XBUS_EN` generic is `true`. This bus interface can be used to attach processor-external
modules like memories, custom hardware accelerators or additional peripheral devices.
An optional cache module ("XCACHE") can be enabled to improve memory access latency.

.Address Mapping
[IMPORTANT]
The external interface is **not** mapped to a specific address space. Instead, all CPU memory accesses that
do not target a specific (and actually implemented) processor-internal address region (hence, accessing the "void";
see section <<_address_space>>) are **redirected** to the external bus interface.

.AXI4-Lite Interface Bridge
[TIP]
A simple bridge that converts the processor's XBUS into an AXI4-lite-compatible host interface can
be found in in `rtl/system_inegration` (`xbus2axi4lite_bridge.vhd`).

.AHB3-Lite Interface Bridge
[TIP]
A simple bridge that converts the processor's XBUS into an AHB3-lite-compatible host interface can
be found in in `rtl/system_inegration` (`xbus2ahblite_bridge.vhd`).


**Wishbone Bus Protocol**

The external bus interface complies to the **pipelined Wishbone b4** protocol. Even though this protocol
was explicitly designed to support pipelined transfers, only a single transfer will be "in fly" at once.
Hence, just two types of bus transactions are generated by the XBUS controller (see images below).

.XBUS/Wishbone Write Transaction
image::xbus_write.png[700]

.XBUS/Wishbone Read Transaction
image::xbus_read.png[700]

.Wishbone "Classic" Protocol
[IMPORTANT]
Native support for the "classic" Wishbone protocol has been deprecated.
However, classic mode can still be _emulated_ by connecting the processor's `xbus_cyc_o` directly to the
device's / bus system's `cyc` and `stb` signals (omitting the processor's `xbus_stb_o` signal).

.Endianness
[NOTE]
Just like the processor itself the XBUS interface uses **little-endian** byte order.

.Wishbone Specs.
[TIP]
A detailed description of the implemented Wishbone bus protocol and the according interface signals
can be found in the data sheet "Wishbone B4 - WISHBONE System-on-Chip (SoC) Interconnection
Architecture for Portable IP Cores". A copy of this document can be found in the `docs` folder of this
project.

An accessed XBUS/Wishbone device does not have to respond immediately to a bus request by sending an `ACK`.
Instead, there is a **time window** where the device has to acknowledge the transfer. This time window
is configured by the `XBUS_TIMEOUT` generic and it defines the maximum time (in clock cycles) a bus access can
be pending before it is automatically terminated raising an bus fault exception. If `XBUS_TIMEOUT` is set to zero,
the timeout is disabled and a bus access can take an arbitrary number of cycles to complete. Note that this is not
recommended as a missing ACK will permanently stall the entire processor!

Furthermore, an accesses XBUS/Wishbone device can signal an error condition at any time by setting the `ERR` signal
high for one cycle. This will also terminate the current bus transaction before raising a CPU bus fault exception.

.Register Stage
[TIP]
An optional register stage can be added to the XBUS gateway to break up the critical path easing timing closure.
When `XBUS_REGSTAGE_EN` is _true_ all outgoing and incoming XBUS signals are registered increasing access latency
by two cycles. Furthermore, all outgoing signals (like the address) will be kept stable if there is no bus access
being initiated.


**Access Tag**

The XBUS tag signal `xbus_tag_o(0)` provides additional information about the current access cycle.
It compatible to the the AXI4 `ARPROT` and `AWPROT` signals.

* `xbus_tag_o(0)` **P**: access is performed from **privileged** mode (machine-mode) when set
* `xbus_tag_o(1)` **NS**: this bit is hardwired to `0` indicating a **secure** access
* `xbus_tag_o(2)` **I**: access is an **instruction** fetch when set; access is a data access when cleared


**External Bus Cache (X-CACHE)**

The XBUS interface provides an optional internal cache that can be used to buffer processor-external accesses.
The x-cache is enabled via the `XBUS_CACHE_EN` generic. The total size of the cache is split into the number of
cache lines or cache blocks (`XBUS_CACHE_NUM_BLOCKS` generic) and the line or block size in bytes
(`XBUS_CACHE_BLOCK_SIZE` generic).

.Simplified X-Cache Architecture
[source,asciiart]
---------------------------------------
                Direct Access         +----------+
          /|------------------------->| Register |------------------------>|\
         | |                          +----------+                         | |
Core --->| |                                                               | |---> XBUS
         | |    +--------------+    +--------------+    +-------------+    | |
          \|--->| Host Arbiter |--->| Cache Memory |<---| Bus Arbiter |--->|/
                +--------------+    +--------------+    +-------------+
---------------------------------------

The cache uses a direct-mapped architecture that implements "write-allocate" and "write-back" strategies.
The **write-allocate** strategy will fetch the entire referenced block from main memory when encountering
a cache write-miss. The **write-back** strategy will gather all writes locally inside the cache until the according
cache block is about to be replaced. In this case, the entire modified cache block is written back to main memory.

.Cached/Uncached Accesses
[NOTE]
The data cache provides direct accesses (= uncached) to memory in order to access memory-mapped IO.
All accesses that target the address range from `0xF0000000` to `0xFFFFFFFF`
will not be cached at all (see section <<_address_space>>). Direct/uncached accesses have **lower** priority than
cache block operations to allow continuous burst transfer and also to maintain logical instruction forward
progress / data coherency. Furthermore, atomic load-reservate and store-conditional instructions (<<_zalrsc_isa_extension>>)
will always **bypass** the cache.
