<<<
:sectnums:
==== True Random-Number Generator (TRNG)

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files:  | neorv32_trng.vhd |
| Software driver files:  | neorv32_trng.c |
|                         | neorv32_trng.h |
| Top entity ports:       | none |
| Configuration generics: | `IO_TRNG_EN`   | implement TRNG when `true`
|                         | `IO_TRNG_FIFO` | data FIFO depth, min 1, has to be a power of two
| CPU interrupts:         | fast IRQ channel 0 | TRNG data available interrupt (see <<_processor_interrupts>>)
| Access restrictions:  2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Overview**

The NEORV32 true random number generator provides _physically_ true random numbers. It is based on free-running
ring-oscillators that generate **phase noise** when being sampled by a constant clock. This phase noise is
used as physical entropy source. The TRNG features a platform independent architecture without FPGA-specific
primitives, macros or attributes so it can be synthesized for _any_ FPGA.

.In-Depth Documentation
[TIP]
For more information about the neoTRNG architecture and an analysis of its random quality check out the
neoTRNG repository: https://github.com/stnolting/neoTRNG

.Inferring Latches
[NOTE]
The synthesis tool might emit warnings regarding **inferred latches** or **combinatorial loops**. However, this
is not design flaw as this is exactly what we want. ;)

.Simulation
[IMPORTANT]
When simulating the processor the TRNG is automatically set to "simulation mode". In this mode the physical entropy
sources (the ring oscillators) are replaced by a simple **pseudo RNG** based on a LFSR providing only
**deterministic pseudo-random** data. The `TRNG_CTRL_SIM_MODE` flag of the control register is set if simulation
mode is active.


**Theory of Operation**

The TRNG features a single control register `CTRL` for control, status check and data access. When the `TRNG_CTRL_EN`
bit is set, the TRNG is enabled and starts operation. As soon as the `TRNG_CTRL_VALID` bit is set a new random data byte
is available and can be obtained from the lowest 8 bits of the `CTRL` register. If this bit is cleared, there is no
valid data available and the lowest 8 bit of the `CTRL` register are set to all-zero.

An internal entropy FIFO can be configured using the `IO_TRNG_FIFO` generic. This FIFO automatically samples
new random data from the TRNG to provide some kind of _random data pool_ for applications, which require a large number
of random data in a short time. The random data FIFO can be cleared at any time either by disabling the TRNG or by
setting the `TRNG_CTRL_FIFO_CLR` flag. The FIFO depth can be retrieved by software via the `TRNG_CTRL_FIFO_*` bits.


**TRNG Interrupt**

As the neoTRNG is a rather slow entropy source, a "data available" interrupt is provided to inform the application
software that new random data is available. This interrupt can be trigger by either of two conditions: trigger the
interrupt if _any_ random data is available (i.e. the data FIFO is not empty; `TRNG_CTRL_IRQ_SEL = 0`) or trigger
the interrupt if the random pool is full (i.e. the data FIFO is full; `TRNG_CTRL_IRQ_SEL = 1`).
Once the TRNG interrupt has fired it remains pending until the actual cause of the interrupt is resolved.


**Register Map**

.TRNG register map (`struct NEORV32_TRNG`)
[cols="<2,<1,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.9+<| `0xfffffa00` .9+<| `CTRL` <|`7:0`   `TRNG_CTRL_DATA_MSB : TRNG_CTRL_DATA_MSB` ^| r/- <| 8-bit random data
                                <|`15:8`   -                                        ^| r/- <| reserved, read as zero
                                <|`19:16` `TRNG_CTRL_FIFO_MSB : TRNG_CTRL_FIFO_MSB` ^| r/- <| FIFO depth, log2(`IO_TRNG_FIFO`)
                                <|`27:20`  -                                        ^| r/- <| reserved, read as zero
                                <|`27`    `TRNG_CTRL_IRQ_SEL`                       ^| r/w <| interrupt trigger select (0 = data available, 1 = FIFO full)
                                <|`28`    `TRNG_CTRL_FIFO_CLR`                      ^| -/w <| flush random data FIFO when set; flag auto-clears
                                <|`29`    `TRNG_CTRL_SIM_MODE`                      ^| r/- <| simulation mode (PRNG!)
                                <|`30`    `TRNG_CTRL_EN`                            ^| r/w <| TRNG enable
                                <|`31`    `TRNG_CTRL_VALID`                         ^| r/- <| random data is valid when set
|=======================
