102 lines
4.7 KiB
Plaintext
102 lines
4.7 KiB
Plaintext
<<<
|
|
:sectnums:
|
|
==== Custom Functions Subsystem (CFS)
|
|
|
|
[cols="<3,<3,<4"]
|
|
[frame="topbot",grid="none"]
|
|
|=======================
|
|
| Hardware source file(s): | neorv32_cfs.vhd |
|
|
| Software driver file(s): | neorv32_cfs.c |
|
|
| | neorv32_cfs.h |
|
|
| Top entity port: | `cfs_in_i` | custom input conduit
|
|
| | `cfs_out_o` | custom output conduit
|
|
| Configuration generics: | `IO_CFS_EN` | implement CFS when `true`
|
|
| | `IO_CFS_CONFIG` | custom generic conduit
|
|
| | `IO_CFS_IN_SIZE` | size of `cfs_in_i`
|
|
| | `IO_CFS_OUT_SIZE` | size of `cfs_out_o`
|
|
| CPU interrupts: | fast IRQ channel 1 | CFS interrupt (see <<_processor_interrupts>>)
|
|
|=======================
|
|
|
|
|
|
**Theory of Operation**
|
|
|
|
The custom functions subsystem is meant for implementing custom tightly-coupled co-processors or interfaces.
|
|
IT provides up to 64 32-bit memory-mapped read/write registers (`REG`, see register map below) that can be
|
|
accessed by the CPU via normal load/store operations. The actual functionality of these register has to be
|
|
defined by the hardware designer. Furthermore, the CFS provides two IO conduits to implement custom on-chip
|
|
or off-chip interfaces.
|
|
|
|
Just like any other externally-connected IP, logic implemented within the custom functions subsystem can operate
|
|
_independently_ of the CPU providing true parallel processing capabilities. Potential use cases might include
|
|
dedicated hardware accelerators for en-/decryption (AES), signal processing (FFT) or AI applications
|
|
(CNNs) as well as custom IO systems like fast memory interfaces (DDR) and mass storage (SDIO), networking (CAN)
|
|
or real-time data transport (I2S).
|
|
|
|
[TIP]
|
|
If you like to implement _custom instructions_ that are executed right within the CPU's ALU
|
|
see the <<_zxcfu_isa_extension>> and the according <<_custom_functions_unit_cfu>>.
|
|
|
|
[TIP]
|
|
Take a look at the template CFS VHDL source file (`rtl/core/neorv32_cfs.vhd`). The file is highly
|
|
commented to illustrate all aspects that are relevant for implementing custom CFS-based co-processor designs.
|
|
|
|
[TIP]
|
|
The CFS can also be used to _replicate_ existing NEORV32 modules - for example to implement several TWI controllers.
|
|
|
|
|
|
**CFS Software Access**
|
|
|
|
The CFS memory-mapped registers can be accessed by software using the provided C-language aliases (see
|
|
register map table below). Note that all interface registers are defined as 32-bit words of type `uint32_t`.
|
|
|
|
.CFS Software Access Example
|
|
[source,c]
|
|
----
|
|
// C-code CFS usage example
|
|
NEORV32_CFS->REG[0] = (uint32_t)some_data_array(i); // write to CFS register 0
|
|
int temp = (int)NEORV32_CFS->REG[20]; // read from CFS register 20
|
|
----
|
|
|
|
|
|
**CFS Interrupt**
|
|
|
|
The CFS provides a single high-level-triggered interrupt request signal mapped to the CPU's fast interrupt channel 1.
|
|
Once triggered, the interrupt becomes pending (if enabled in the <<_mie>> CSR) and has to be explicitly cleared again by
|
|
writing zero to the according <<_mip>> CSR bit. See section <<_processor_interrupts>> for more information.
|
|
|
|
|
|
**CFS Configuration Generic**
|
|
|
|
By default, the CFS provides a single 32-bit `std_ulogic_vector` configuration generic `IO_CFS_CONFIG`
|
|
that is available in the processor's top entity. This generic can be used to pass custom configuration options
|
|
from the top entity directly down to the CFS. The actual definition of the generic and it's usage inside the
|
|
CFS is left to the hardware designer.
|
|
|
|
|
|
**CFS Custom IOs**
|
|
|
|
By default, the CFS also provides two unidirectional input and output conduits `cfs_in_i` and `cfs_out_o`.
|
|
These signals are directly propagated to the processor's top entity. These conduits can be used to implement
|
|
application-specific interfaces like memory or peripheral connections. The actual use case of these signals
|
|
has to be defined by the hardware designer.
|
|
|
|
The size of the input signal conduit `cfs_in_i` is defined via the top's `IO_CFS_IN_SIZE` configuration
|
|
generic (default = 32-bit). The size of the output signal conduit `cfs_out_o` is defined via the top's
|
|
`IO_CFS_OUT_SIZE` configuration generic (default = 32-bit). If the custom function subsystem is not implemented
|
|
(`IO_CFS_EN` = false) the `cfs_out_o` signal is tied to all-zero.
|
|
|
|
|
|
**Register Map**
|
|
|
|
.CFS register map (`struct NEORV32_CFS`)
|
|
[cols="^4,<2,^2,^2,<6"]
|
|
[options="header",grid="all"]
|
|
|=======================
|
|
| Address | Name [C] | Bit(s) | R/W | Function
|
|
| `0xffffeb00` | `REG[0]` |`31:0` | (r)/(w) | custom CFS register 0
|
|
| `0xffffeb04` | `REG[1]` |`31:0` | (r)/(w) | custom CFS register 1
|
|
| ... | ... |`31:0` | (r)/(w) | ...
|
|
| `0xffffebf8` | `REG[62]` |`31:0` | (r)/(w) | custom CFS register 62
|
|
| `0xffffebfc` | `REG[63]` |`31:0` | (r)/(w) | custom CFS register 63
|
|
|=======================
|