1 |
60 |
zero_gravi |
<<<
|
2 |
|
|
:sectnums:
|
3 |
|
|
==== Custom Functions Subsystem (CFS)
|
4 |
|
|
|
5 |
|
|
[cols="<3,<3,<4"]
|
6 |
|
|
[frame="topbot",grid="none"]
|
7 |
|
|
|=======================
|
8 |
|
|
| Hardware source file(s): | neorv32_gfs.vhd |
|
9 |
|
|
| Software driver file(s): | neorv32_gfs.c |
|
10 |
|
|
| | neorv32_gfs.h |
|
11 |
|
|
| Top entity port: | `cfs_in_i` | custom input conduit
|
12 |
|
|
| | `cfs_out_o` | custom output conduit
|
13 |
|
|
| Configuration generics: | _IO_CFS_EN_ | implement CFS when _true_
|
14 |
|
|
| | _IO_CFS_CONFIG_ | custom generic conduit
|
15 |
|
|
| | _IO_CFS_IN_SIZE_ | size of `cfs_in_i`
|
16 |
|
|
| | _IO_CFS_OUT_SIZE_ | size of `cfs_out_o`
|
17 |
|
|
| CPU interrupts: | fast IRQ channel 1 | CFS interrupt (see <<_processor_interrupts>>)
|
18 |
|
|
|=======================
|
19 |
|
|
|
20 |
|
|
**Theory of Operation**
|
21 |
|
|
|
22 |
65 |
zero_gravi |
The custom functions subsystem is meant for implementing application-specific user-defined co-processors
|
23 |
|
|
IP footnote:[Intellectual IP; proprietary circuit blocks.] blocks. The CFS provides up to 32x 32-bit memory-mapped
|
24 |
|
|
registers (`REG`, see register map table below) that can be accessed by the CPU via normal load/store operations.
|
25 |
|
|
The actual functionality of these register has to be defined by the hardware designer. Furthermore, the CFS
|
26 |
|
|
provides two IO conduits to implement custom module- or chip-external interfaces.
|
27 |
60 |
zero_gravi |
|
28 |
65 |
zero_gravi |
In contrast to connecting custom hardware accelerators via external memory interfaces (like SPI or the processor's
|
29 |
|
|
external bus interface), the CFS provide a convenient, low-latency and tightly-coupled extension and
|
30 |
|
|
customization option.
|
31 |
60 |
zero_gravi |
|
32 |
65 |
zero_gravi |
Just like any other externally-connected IP, logic implemented within the custom functions subsystem can operate
|
33 |
|
|
_independently_ of the CPU providing true parallel processing capabilities. Potential use cases might include
|
34 |
|
|
dedicated hardware accelerators for en-/decryption (AES), signal processing (FFT) or AI applications
|
35 |
|
|
(CNNs) as well as custom IO systems like fast memory interfaces (DDR) and mass storage (SDIO), networking (CAN)
|
36 |
|
|
or real-time data transport (I2S).
|
37 |
|
|
|
38 |
60 |
zero_gravi |
[INFO]
|
39 |
|
|
Take a look at the template CFS VHDL source file (`rtl/core/neorv32_cfs.vhd`). The file is highly
|
40 |
|
|
commented to illustrate all aspects that are relevant for implementing custom CFS-based co-processor designs.
|
41 |
|
|
|
42 |
65 |
zero_gravi |
|
43 |
60 |
zero_gravi |
**CFS Software Access**
|
44 |
|
|
|
45 |
|
|
The CFS memory-mapped registers can be accessed by software using the provided C-language aliases (see
|
46 |
|
|
register map table below). Note that all interface registers provide 32-bit access data of type `uint32_t`.
|
47 |
|
|
|
48 |
|
|
[source,c]
|
49 |
|
|
----
|
50 |
|
|
// C-code CFS usage example
|
51 |
64 |
zero_gravi |
NEORV32_CFS.REG[0] = (uint32_t)some_data_array(i); // write to CFS register 0
|
52 |
|
|
uint32_t temp = NEORV32_CFS.REG[20]; // read from CFS register 20
|
53 |
60 |
zero_gravi |
----
|
54 |
|
|
|
55 |
65 |
zero_gravi |
|
56 |
60 |
zero_gravi |
**CFS Interrupt**
|
57 |
|
|
|
58 |
69 |
zero_gravi |
The CFS provides a single rising-edge-triggered interrupt request signal mapped to the CPU's fast interrupt channel 1.
|
59 |
|
|
Once triggered, the interrupt becomes pending (if enabled in the `mis` CSR) and has to be explicitly cleared again by setting
|
60 |
|
|
the according `mip` CSR bit. See section <<_processor_interrupts>> for more information.
|
61 |
60 |
zero_gravi |
|
62 |
65 |
zero_gravi |
|
63 |
60 |
zero_gravi |
**CFS Configuration Generic**
|
64 |
|
|
|
65 |
|
|
By default, the CFS provides a single 32-bit `std_(u)logic_vector` configuration generic _IO_CFS_CONFIG_
|
66 |
|
|
that is available in the processor's top entity. This generic can be used to pass custom configuration options
|
67 |
65 |
zero_gravi |
from the top entity directly down to the CFS. The actual definition of the generics and it'S usage inside the
|
68 |
|
|
CFS is left to the hardware designer.
|
69 |
60 |
zero_gravi |
|
70 |
65 |
zero_gravi |
|
71 |
60 |
zero_gravi |
**CFS Custom IOs**
|
72 |
|
|
|
73 |
|
|
By default, the CFS also provides two unidirectional input and output conduits `cfs_in_i` and `cfs_out_o`.
|
74 |
65 |
zero_gravi |
These signals are directly propagated to the processor's top entity. These conduits can be used to implement
|
75 |
|
|
application-specific interfaces like memory or network connections. The actual use case of these signals
|
76 |
|
|
has to be defined by the hardware designer.
|
77 |
|
|
|
78 |
|
|
The size of the input signal conduit `cfs_in_i` is defined via the top's _IO_CFS_IN_SIZE_ configuration
|
79 |
|
|
generic (default = 32-bit). The size of the output signal conduit `cfs_out_o` is defined via the top's
|
80 |
60 |
zero_gravi |
_IO_CFS_OUT_SIZE_ configuration generic (default = 32-bit). If the custom function subsystem is not implemented
|
81 |
|
|
(_IO_CFS_EN_ = false) the `cfs_out_o` signal is tied to all-zero.
|
82 |
|
|
|
83 |
65 |
zero_gravi |
|
84 |
64 |
zero_gravi |
.CFS register map (`struct NEORV32_CFS`)
|
85 |
60 |
zero_gravi |
[cols="^4,<5,^2,^3,<14"]
|
86 |
|
|
[options="header",grid="all"]
|
87 |
|
|
|=======================
|
88 |
|
|
| Address | Name [C] | Bit(s) | R/W | Function
|
89 |
64 |
zero_gravi |
| `0xfffffe00` | `NEORV32_CFS.REG[0]` |`31:0` | (r)/(w) | custom CFS interface register 0
|
90 |
|
|
| `0xfffffe04` | `NEORV32_CFS.REG[1]` |`31:0` | (r)/(w) | custom CFS interface register 1
|
91 |
|
|
| ... | ... |`31:0` | (r)/(w) | ...
|
92 |
|
|
| `0xfffffe78` | `NEORV32_CFS.REG[30]` |`31:0` | (r)/(w) | custom CFS interface register 30
|
93 |
|
|
| `0xfffffe7c` | `NEORV32_CFS.REG[31]` |`31:0` | (r)/(w) | custom CFS interface register 31
|
94 |
60 |
zero_gravi |
|=======================
|