87 lines
5.0 KiB
Plaintext
87 lines
5.0 KiB
Plaintext
<<<
|
|
:sectnums:
|
|
==== True Random-Number Generator (TRNG)
|
|
|
|
[cols="<3,<3,<4"]
|
|
[frame="topbot",grid="none"]
|
|
|=======================
|
|
| Hardware source file(s): | neorv32_trng.vhd |
|
|
| Software driver file(s): | neorv32_trng.c |
|
|
| | neorv32_trng.h |
|
|
| Top entity port: | 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 15 | TRNG FIFO level interrupt (see <<_processor_interrupts>>)
|
|
|=======================
|
|
|
|
|
|
**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**
|
|
|
|
The TRNG provides a single interrupt channel that can be programmed to trigger on certain FIFO fill-level conditions.
|
|
This feature can be used to inform the CPU that a certain amount of entropy is available for further processing. Using
|
|
the control register's `TRNG_CTRL_IRQ_*` bits the IRQ can be configured to trigger if the data FIFO is empty
|
|
(`TRNG_CTRL_IRQ_FIFO_NEMPTY`), if the data FIFO is at least half full (`TRNG_CTRL_IRQ_FIFO_HALF`) or if the data FIFO is
|
|
entirely full (`TRNG_CTRL_IRQ_FIFO_NEMPTY`). Note that all enabled interrupt conditions are logically OR-ed.
|
|
|
|
Once the TRNG interrupt has fired it remains pending until the actual cause of the interrupt is resolved. Furthermore,
|
|
an active TRNG interrupt has to be explicitly cleared again by writing zero to the according <<_mip>> CSR bit.
|
|
|
|
|
|
**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
|
|
.11+<| `0xfffffa00` .11+<| `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`)
|
|
<|`25:20` - ^| r/- <| reserved, read as zero
|
|
<|`26` `TRNG_CTRL_IRQ_FIFO_NEMPTY` ^| r/w <| IRQ if data FIFO is not empty
|
|
<|`26` `TRNG_CTRL_IRQ_FIFO_HALF` ^| r/w <| IRQ if data FIFO is at least half full
|
|
<|`27` `TRNG_CTRL_IRQ_FIFO_FULL` ^| r/w <| IRQ if data FIFO is full
|
|
<|`28` `TRNG_CTRL_FIFO_CLR` ^| -/w <| flush random data FIFO when set; 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
|
|
|=======================
|