<<<
:sectnums:
==== Custom Functions Subsystem (CFS)

[cols="<3,<3,<4"]
[grid="none"]
|=======================
| Hardware source files:  | neorv32_cfs.vhd    |
| Software driver files:  | neorv32_cfs.c      | link:https://stnolting.github.io/neorv32/sw/neorv32__cfs_8c.html[Online software reference (Doxygen)]
|                         | neorv32_cfs.h      | link:https://stnolting.github.io/neorv32/sw/neorv32__cfs_8h.html[Online software reference (Doxygen)]
| Top entity ports:       | `cfs_in_i`         | custom input conduit, 256-bit
|                         | `cfs_out_o`        | custom output conduit, 256-bit
| Configuration generics: | `IO_CFS_EN`        | implement CFS when `true`
| CPU interrupts:         | fast IRQ channel 1 | CFS interrupt (see <<_processor_interrupts>>)
|=======================

**Key Features**

* Tightly-coupled co-processor unit for custom hardware accelerators
* Can operate independently of the CPU
* CPU access via memory-mapped registers (16kB)
* Custom 256-bit input and output conduits for custom IO


**Overview**

The custom functions subsystem is meant for implementing custom tightly-coupled co-processors or interfaces.
It provides up to 16384 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 input/output 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)
real-time data transport (I2S) or just replication of existent NEORV32 peripherals.

.Custom ISA Instructions
[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>>.

.CFS Template
[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.


**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 Custom IOs**

The CFS provides two unidirectional input and output conduits `cfs_in_i` and `cfs_out_o`. Both signals
are 512 bit wide and are 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.


**CFS Interrupt**

The CFS provides a single high-level-triggered interrupt request signal mapped to the CPU's fast interrupt channel 1.


**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
| `0xffeb0000` | `REG[0]`     |`31:0` | (r)/(w) | custom CFS register 0
| `0xffeb0004` | `REG[1]`     |`31:0` | (r)/(w) | custom CFS register 1
| ...          | ...          |`31:0` | (r)/(w) | ...
| `0xffebfff8` | `REG[16382]` |`31:0` | (r)/(w) | custom CFS register 16382
| `0xffebfffc` | `REG[16383]` |`31:0` | (r)/(w) | custom CFS register 16383
|=======================
