Hardware
This page summarizes the hardware architecture and gives help for HDL simulation, FPGA compilation and target programmation.
Hardware architecture
As illustrated in figure below, the top.vhd
architecture contains the PTRNG including the digital noise source (more information on its configuration).
A communication chain is enabled from the PC to the PTRNG with the help of an UART, and a simple interpreter for read/write commands that performs transactions on the register map.
The register map is required to:
- send control and configurations to the PTRNG,
- read statuses from the PTRNG,
- read random data generated by the PTRNG in the FIFO.
Digital noise source
The digital noise source is mainly composed of a bank of 2 ring-oscillators a least and a digitizer block responsible to sample the relative phase noise of the oscillators.
Ring-oscillators
The generic ring-oscillators are described in ring.vhd
located in the directory hardware/target/common/generic
. They are based on loop of inverters and a NAND gate to allow the oscillation to be enabled and disabled.
On FPGA ring-oscillators a made of Lookup-tables (LUT): one LUT2
for the NAND, several LUT1
for the inverters (or buffers).
It is crucial to give the synthesis tool specific constraints to allow combinatorial loops. The place and route tool also need physical constraints in order to guarantee the quality of the signal (mainly to limit crosstalks from other parts of the design through the cells or nets).
As illustrated in the following floorplan picture:
- ring-oscillators are isolated from each other in the bank,
- the digitizer block, that responsible of clock-domain-crossing (RO to system clock), is close to the rings,
- the ditital noise block is isolated by a forbidden area all around.
All the constraints are given in the file constraints.xdc
located in hardware/config/digitalnoise
. This file is generated by a script, detailed in the digital noise configuration section.
Digitizer
The digitizer comes with the following sampling architectures: ERO, MURO and COSO.
ERO
The Elementary Ring-Oscillator (ERO) TRNG is the simpliest sampling architecture. It instanciates two ring-oscillators:
RO0
frequency is divided by factor K in order to accumulate jitter (i.e. phase noise),RO1
that is sampled by the previously divided ring-oscillator.
This architecture benefits from a simple design, however the division factor required to accumulated enough noise makes the output bitrate very slow. As instance with a 100MHz ring-oscillator and a division factor of K=1000, the output rate is limited to 100kbit/s.
MURO
The MUlti Ring-Oscillator (MURO) TRNG is designed to improve the entropy rate by accumulating noise from several ring-oscillators that are XORed and the sampled with the same principle as for ERO.
With lower accumulation time, the MURO benefits from higher throughput. However, instanciating multiple ring-oscillators increase the risk of locking phenomenon that would cancel all captured noise.
COSO
The COherent Sampling Oscillator (COSO) TRNG samples directly RO1
with RO0
. The sampled output is called the beat
signal and is the image of the accumulated jitter between the two oscillators. The beat
signal period is measured with a counter that is incremented in steps of RO0
. In other words, this counter measures the accumulation of the phase noise. The less significant bit (LSB) of the counter final value is taken as output for the random bit.
The COSO architecture benefits from small footprint, a relevant output rate and has an intrinsic failure alarm. However, the COSO needs the frequencies ratio to be controlled.
Dependencies
OpenTRNG projects depends on the following submodules:
GitHub | Descrition |
---|---|
vhdl-extras | Provides a set of standard and common VHDL entities. |
fluart | The feature-less UART to provide communication between PC and target. |
cmd_proc | handle simple read-write adress/data packet processing on the UART. |
We also use the Corsair tool to generate the register map (see this section).
Simulate HDL sources
Testbenches for simulating HDL sources are scripted using cocotb in Python, and are located in the hardware/sim
directory. Each testbench comprises multiple test cases. The python ring-oscillator emulator is used to generate noisy clock signals for the testcases.
For example, to run the simulation of the COSO testbench, use the following commands:
$ cd hardware/sim/test_coso
$ make
The summary of the testbench simulation is displayed in the terminal:
********************************************************************************************
** TEST STATUS SIM TIME (ns) REAL TIME (s) RATIO (ns/s) **
********************************************************************************************
** test_coso.test_total_failure_alarm PASS 10010.00 0.09 113097.26 **
** test_coso.test_gen_random_100 PASS 63706.73 3.67 17337.83 **
********************************************************************************************
** TESTS=2 PASS=2 FAIL=0 SKIP=0 73716.73 4.04 18252.38 **
********************************************************************************************
Thanks to ghdl
simulator, all testbenches record their waveforms in the waves.vcd
file. Waveform files can be visualized using tools like GTKWave or Wavedrom, for example.
Compile for FPGA
The VHDL provided in the hardware/hdl
directory is target agnostic, it can be synthetized for all FPGA vendors (even ASIC). On the contrary, ring-oscillator implementations are specific to the target. As instance, the directory target/common/xilinx
provides a ring.vhd
dedicated implementation for Xilinx FPGAs.
FPGA targets
As of now OpenTRNG supports the Digilent Arty A7 35T board, based on Xilinx Artix-7 FPGA.
Please follow these instructions to add the support for a new Xilinx target:
- create a new directory in
hardware/target/fpga
and jump into, - then create a
target.vhd
for the global top for the target, - create a
target.xdc
to specify the physical constraints (such as pinout, clocking, IO settings…), - then call the script
generate_vivado_project.tcl
as explained in the next section to create the Vivado project.
Synthetize, place route and program device
Scaffold script generate_vivado_project.tcl
is provided to generate Xilinx Vivado projects for any targets, the tcl
script is located here hardware/target/fpga
. Use the following command to generate the Vivado project opentrng_arty_a7_35t.xpr
in the directory arty_a7_35t
for the target xc7a35ticsg324-1L
:
$ cd hardware/target/fpga
$ vivado -mode tcl -source generate_vivado_project.tcl -tclargs arty_a7_35t xc7a35ticsg324-1L
The start Vivado with the command:
$ vivado -mode gui arty_a7_35t/opentrng_arty_a7_35t.xpr
After runing Vivado’s Synthesis, Implementation and Bitstream generation you will be able to program your target with the help of the Hardware Manager.
Design configurations
Some part of the design is generated with scripts (eg. register map) or configured with script (such as for digital noise).
Register map configuration
The PTRNG block exposes several configuration, status and data registers as ports of the entity. These registers are wrapped into a register map, that allows to access the registers from the PC with simple read and write operations. All the code (target side and PC side) is generated with Corsair, taking as input the registers.yml
configuration file located in hardware/config/registers
.
The register map specification is available here in the PTRNG repository.
Digital noise configuration
The digitalnoise
entity described in the file digitalnoise.vhd
necessitate to be configured. On the supported targets, this entity comes with a default configuration.
The configuration consists in generating:
- the
settings.vhd
VHDL packages which describes the size and the number of ring-oscillators and also defines the type of sampling architecture, - the
constraints.xdc
(for Xilinx) that describes the physical constraints for ring-oscillator place and route.
The script generate.py
is located in hardware/config/digitalnoise
, and is usable with these parameters:
$ python ./generate.py -h
usage: generate.py [-h] -vendor {xilinx} -luts LUTS [-fixedlutpin FIXEDLUTPIN] -x X -y Y -maxwidth MAXWIDTH -maxheight MAXHEIGHT -border BORDER -ringwidth RINGWIDTH -digitheight DIGITHEIGHT -digittype {TEST,COSO} -hpad HPAD -vpad VPAD -fmax FMAX -len
LEN [LEN ...]
Generate configuration files for the digitalnoise entity. More specifically it generates: 'settings.vhd' that contains HDL constants and 'placeroute.*' that contains all timing/place/route constraints for digitalnoise (extension depending on vendor).
options:
-h, --help show this help message and exit
-vendor {xilinx} target vendor (for selecting the templates)
-luts LUTS number of LUT per item (per slice for Xilinx, per LE for Intel Altera)
-fixedlutpin FIXEDLUTPIN
optional parameter to fix the input pin for all LUTs (the value is the name of the pin)
-x X origin abscissa for the reserved area
-y Y origin ordinate for the reserved area
-maxwidth MAXWIDTH maximum width for the reserved area
-maxheight MAXHEIGHT maximum height for the reserved area
-border BORDER forbidden border all around inside the reserved area
-ringwidth RINGWIDTH column width for a ring-oscillator
-digitheight DIGITHEIGHT
height for the digitizer block
-digittype {TEST,COSO}
choice of the sampling architecture for the digitizer
-hpad HPAD horizontal padding between ROs
-vpad VPAD vertical padding between ROs
-fmax FMAX maximum estimated frequency for all ring-oscillators (Hz)
-len LEN [LEN ...] number of elements in each ring-oscillator
The default configuration for the Digilent Arty7 board is generated with:
$ python generate.py -vendor xilinx -luts 4 -x 12 -y 102 -maxwidth 15 -maxheight 22 -border 2 -digittype COSO -digitheight 8 -ringwidth 2 -hpad 2 -vpad 2 -fmax 220e6 -len 20 21