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 primarily consists of at least two ring-oscillators and a digitizer block, which is responsible for sampling the relative phase noise of the oscillators.
Ring-oscillators
A generic ring oscillator is defined in ring.vhd
, located in hardware/target/common/generic
. The loop consists of inverters and a NAND gate, which enables and disables the oscillation.
In FPGA implementations, ring oscillators are composed of Lookup Tables (LUTs): one LUT2
for the NAND gate and several LUT1
units for the inverters (or buffers).
It is essential to provide the synthesis tool with specific constraints to enable combinatorial loops. Additionally, the place and route tool requires physical constraints to ensure signal integrity, particularly to minimize crosstalk from other parts of the design via cells or nets.
As shown in the following floorplan:
- Ring oscillators are isolated within their respective bank.
- The digitizer block, responsible for clock-domain crossing (from RO to system clock), is positioned near the ring oscillators.
- The digital noise block is surrounded by a forbidden area to ensure isolation.
All constraints are defined in the constraints.xdc
file, located in hardware/config/digitalnoise
. This file is generated by a script, as 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. |
The Corsair tool is also used to generate the register map (see the register map configuration section).
Simulate HDL sources
Testbenches for simulating HDL sources are scripted in Python using cocotb and are stored in the hardware/sim
directory. Each testbench contains multiple test cases. The Python-based ring-oscillator emulator is used to generate noisy clock signals for these test cases.
For example, to run the simulation for the COSO testbench, use the following commands:
$ cd hardware/sim/test_coso
$ make
For instance, the summary of the testbench simulation is displayed in the terminal as follows:
*************************************************************
** TEST STATUS SIM TIME (ns)
*************************************************************
** test_coso.test_total_failure_alarm PASS 10010.00
** test_coso.test_gen_random_100 PASS 63706.73
*************************************************************
** TESTS=2 PASS=2 FAIL=0 SKIP=0 73716.73
*************************************************************
Thanks to the ghdl
simulator, all testbenches store their waveforms in the waves.vcd file. These waveform files can be visualized using tools such as GTKWave or Wavedrom, among others.
Compile for FPGA
The VHDL provided in the hardware/hdl
directory is target-agnostic and can be synthesized for all FPGA vendors (and even ASICs). In contrast, the ring-oscillator implementations are target-specific. For example, the target/common/xilinx
directory contains a dedicated ring.vhd
implementation for Xilinx FPGAs.
FPGA targets
Currently, OpenTRNG supports the Digilent Arty A7 35T board, which is based on the 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.
To add support for a new Xilinx target, please follow these steps:
- Create a new directory under
hardware/target/fpga
and navigate into it. - Create a
target.vhd
file for the global top module for the target. - Create a
target.xdc
file to define the physical constraints (e.g., pinout, clocking, I/O settings, etc.). - Run the
generate_vivado_project.tcl
script, as explained in the next section, to generate 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
:
The boilerplate script generate_vivado_project.tcl
is provided to generate Xilinx Vivado projects for any target. The tcl script is located in hardware/target/fpga
. To generate the Vivado project opentrng_arty_a7_35t.xpr
in the arty_a7_35t
directory for the target xc7a35ticsg324-1L
, use the following command:
$ cd hardware/target/fpga
$ vivado -mode tcl -source generate_vivado_project.tcl -tclargs arty_a7_35t xc7a35ticsg324-1L
Then 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, the target can be programmed using the Hardware Manager.
Design configurations
Some part of the design are generated using scripts (eg. register map) or configured via scripts (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 organized into a register map, enabling simple read and write operations to access them from the PC. All the code, both target-side and PC-side, is generated using Corsair, with the registers.yml
configuration file located in hardware/config/registers
as input.
The register map specification can be found here in the PTRNG repository.
Digital noise configuration
The digitalnoise
entity, described in the file digitalnoise.vhd
, requires configuration. On the supported targets, this entity comes with a default configuration.
The configuration process generates:
- The
settings.vhd
VHDL package, which defines the size and number of ring oscillators, as well as the type of sampling architecture. - The
constraints.xdc
file (for Xilinx), which specifies the physical constraints for the place and route of the ring oscillators.
The generate.py
script, located in hardware/config/digitalnoise
, can be used with the following parameters:
$ python generate.py -h
usage: generate.py [-h] [-args ARGS] [-verbose] [-vendor {xilinx}] [-luts LUTS] [-fixedlutpin FIXEDLUTPIN] [-x X]
[-y Y] [-maxwidth MAXWIDTH] [-maxheight MAXHEIGHT] [-border BORDER] [-ringwidth RINGWIDTH]
[-digitheight DIGITHEIGHT] [-digittype {TEST,ERO,MURO,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
-args ARGS load all arguments from file
-verbose add verbosity to the output
-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,ERO,MURO,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 configurations for the Digilent Arty7 board can be loaded with the following commands:
$ python generate.py -args ../../target/fpga/xilinx/arty_a7_35t/generate_ero.args
$ python generate.py -args ../../target/fpga/xilinx/arty_a7_35t/generate_muro.args
$ python generate.py -args ../../target/fpga/xilinx/arty_a7_35t/generate_coso.args