Skip to content

Commit

Permalink
Merge pull request #316 from stnolting/add_trng_fifo
Browse files Browse the repository at this point in the history
[TRNG] add optional/configurable data FIFO
  • Loading branch information
stnolting authored May 18, 2022
2 parents ee70ece + 32dc16b commit 66217a9
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 41 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12

| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 17.05.2022 | 1.7.1.7 | :sparkles: add optional/configurable data FIFO to **TRNG**; new top generic `IO_TRNG_FIFO`; [#316](https://github.com/stnolting/neorv32/pull/316) |
| 13.05.2022 | 1.7.1.6 | :bug: fixed bug in **BUSKEEPER** timeout logic; [#315](https://github.com/stnolting/neorv32/pull/315) |
| 10.05.2022 | 1.7.1.5 | code clean-up and minor optimization of `B` extension (bit-manipulation) CPU co-processor; [#312](https://github.com/stnolting/neorv32/pull/312) |
| 06.05.2022 | 1.7.1.4 | :sparkles: upgrade TRNG module to new [neoTRNG v2](https://github.com/stnolting/neoTRNG); [#311](https://github.com/stnolting/neorv32/pull/311) |
Expand Down
18 changes: 15 additions & 3 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,18 @@ information.
|======


:sectnums!:
===== _IO_TRNG_FIFO_

[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_TRNG_FIFO** | _natural_ | 1
3+| Defines the depth of the TRNG data FIFO. Minimal value is 1;, has to be a power of two.
See section <<_true_random_number_generator_trng>> for more information.
|======


:sectnums!:
===== _IO_CFS_EN_

Expand Down Expand Up @@ -1082,9 +1094,9 @@ specifications. However, bare-metal system can also repurpose these interrupts.
[options="header",grid="rows"]
|=======================
| Top signal | Width | Description
| `mtime_irq_i` | 1 | Machine timer interrupt from _processor-external_ MTIME unit. This IRQ is only available if the processor-internal MTIME unit is not used (<<_io_mtime_en>> = false).
| `msw_irq_i` | 1 | Machine software interrupt. This interrupt is used for inter-processor interrupts in multi-core systems. However, it can also be used for any custom purpose.
| `mext_irq_i` | 1 | Machine external interrupt. This interrupt is used for any processor-external interrupt source (like a platform interrupt controller).
| `mtime_irq_i` | 1 | Machine timer interrupt from _processor-external_ MTIME unit (_MTI_). This IRQ is only available if the processor-internal MTIME unit is not used (<<_io_mtime_en>> = false).
| `msw_irq_i` | 1 | Machine software interrupt (_MSI_). This interrupt is used for inter-processor interrupts in multi-core systems. However, it can also be used for any custom purpose.
| `mext_irq_i` | 1 | Machine external interrupt (_MEI_). This interrupt is used for any processor-external interrupt source (like a platform interrupt controller).
|=======================

.Trigger type
Expand Down
23 changes: 16 additions & 7 deletions docs/datasheet/soc_trng.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
| Software driver file(s): | neorv32_trng.c |
| | neorv32_trng.h |
| Top entity port: | none |
| Configuration generics: | _IO_TRNG_EN_ | implement TRNG when _true_
| 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: | none |
|=======================

Expand All @@ -31,7 +32,7 @@ detailed evaluation of the random number quality can be found it it's repository
.Inferring Latches
[NOTE]
The synthesis tool might emit a warning like _"inferring latches for ... neorv32_trng ..."_. This is no problem
as this is what we actually want (the TRNG is based on latches).
as this is what we actually want: the TRNG is based on latches, which implement the inverters of the ring oscillators.

.Simulation
[IMPORTANT]
Expand All @@ -43,10 +44,17 @@ The _TRNG_CTRL_SIM_MODE_ flag of the control register is set if simulation mode
**Using the TRNG**

The TRNG features a single register for status and data access. When the _TRNG_CTRL_EN_ control register (`CTRL`)
bit is set, the TRNG is enabled and starts operation. As soon as the _TRNG_CTRL_VALID_ bit is set, the currently
sampled 8-bit random data byte can be obtained from the lowest 8 bits of the `CTRL` register
(_TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_LSB_). These bits always keep the latest valid data obtained from the TRNG
entropy source. The _TRNG_CTRL_VALID_ bit is automatically cleared when reading the control register.
bit is set, the TRNG is enabled and starts operation. As soon as the _TRNG_CTRL_VALID_ bit is set a random data byte
is available and can be obtained from the lowest 8 bits of the `CTRL` register
(_TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_LSB_).

An optional random data 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 RND data in a short time. The minimal and default value for <<_io_trng_fifo>> is 1 (implementing a register rather
than a real FIFO); the generic has to be a power of two.

The random data FIFO can be cleared at any time either by disabling the TRNG via the _TRNG_CTRL_EN_ flag or by
setting the _TRNG_CTRL_FIFO_CLR_ flag. Note that this falg is write-only and auto clears after being set.

.TRNG Reset
[NOTE]
Expand All @@ -59,7 +67,8 @@ disabled (=reset) by clearing the _TRNG_CTRL_EN_ and waiting some 1000s clock cy
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.4+<| `0xffffffb8` .4+<| `NEORV32_TRNG.CTRL` <|`7:0` _TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_MSB_ ^| r/- <| 8-bit random data
.5+<| `0xffffffb8` .5+<| `NEORV32_TRNG.CTRL` <|`7:0` _TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_MSB_ ^| r/- <| 8-bit random data
<|`28` _TRNG_CTRL_FIFO_CLR_ ^| -/w <| clear 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
Expand Down
6 changes: 5 additions & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ package neorv32_package is
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070106"; -- NEORV32 version - no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070107"; -- NEORV32 version - no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!

-- Check if we're inside the Matrix -------------------------------------------------------
Expand Down Expand Up @@ -1010,6 +1010,7 @@ package neorv32_package is
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_TRNG_FIFO : natural := 1; -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
Expand Down Expand Up @@ -1789,6 +1790,9 @@ package neorv32_package is
-- Component: True Random Number Generator (TRNG) -----------------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_trng
generic (
IO_TRNG_FIFO : natural := 1 -- RND fifo depth, has to be a power of two, min 1
);
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
Expand Down
4 changes: 4 additions & 0 deletions rtl/core/neorv32_top.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ entity neorv32_top is
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_TRNG_FIFO : natural := 1; -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
Expand Down Expand Up @@ -1308,6 +1309,9 @@ begin
neorv32_trng_inst_true:
if (IO_TRNG_EN = true) generate
neorv32_trng_inst: neorv32_trng
generic map (
IO_TRNG_FIFO => IO_TRNG_FIFO -- RND fifo depth, has to be a power of two, min 1
)
port map (
-- host access --
clk_i => clk_i, -- global clock line
Expand Down
99 changes: 69 additions & 30 deletions rtl/core/neorv32_trng.vhd
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
-- #################################################################################################
-- # << NEORV32 - True Random Number Generator (TRNG) >> #
-- # ********************************************************************************************* #
-- # This processor module instantiates the "neoTRNG" true random number generator. #
-- # This processor module instantiates the "neoTRNG" true random number generator. An optional #
-- # "random pool" FIFO can be configured using the TRNG_FIFO generic. #
-- # See the neoTRNG's documentation for more information: https://github.com/stnolting/neoTRNG #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
Expand Down Expand Up @@ -43,6 +44,9 @@ library neorv32;
use neorv32.neorv32_package.all;

entity neorv32_trng is
generic (
IO_TRNG_FIFO : natural := 1 -- RND fifo depth, has to be a power of two, min 1
);
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
Expand Down Expand Up @@ -70,6 +74,7 @@ architecture neorv32_trng_rtl of neorv32_trng is
-- control register bits --
constant ctrl_data_lsb_c : natural := 0; -- r/-: Random data byte LSB
constant ctrl_data_msb_c : natural := 7; -- r/-: Random data byte MSB
constant ctrl_fifo_clr_c : natural := 28; -- -/w: Clear data FIFO (auto clears)
constant ctrl_sim_mode_c : natural := 29; -- r/-: TRNG implemented in PRNG simulation mode
constant ctrl_en_c : natural := 30; -- r/w: TRNG enable
constant ctrl_valid_c : natural := 31; -- r/-: Output data valid
Expand Down Expand Up @@ -101,17 +106,30 @@ architecture neorv32_trng_rtl of neorv32_trng is
);
end component;

-- TRNG interface --
signal trng_data : std_ulogic_vector(7 downto 0);
signal trng_valid : std_ulogic;

-- arbiter --
signal enable : std_ulogic;
signal valid : std_ulogic;
signal rnd_reg : std_ulogic_vector(7 downto 0);
signal enable : std_ulogic;
signal fifo_clr : std_ulogic;

-- data FIFO --
type fifo_t is record
we : std_ulogic; -- write enable
re : std_ulogic; -- read enable
clear : std_ulogic; -- sync reset, high-active
wdata : std_ulogic_vector(7 downto 0); -- write data
rdata : std_ulogic_vector(7 downto 0); -- read data
avail : std_ulogic; -- data available?
end record;
signal fifo : fifo_t;

begin

-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (IO_TRNG_FIFO < 1) report "NEORV32 PROCESSOR CONFIG ERROR: TRNG FIFO size <IO_TRNG_FIFO> has to be >= 1." severity error;
assert not (is_power_of_two_f(IO_TRNG_FIFO) = false) report "NEORV32 PROCESSOR CONFIG ERROR: TRNG FIFO size <IO_TRNG_FIFO> has to be a power of two." severity error;
assert not (sim_mode_c = true) report "NEORV32 PROCESSOR CONFIG WARNING: TRNG uses SIMULATION mode!" severity warning;


-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = trng_base_c(hi_abb_c downto lo_abb_c)) else '0';
Expand All @@ -127,34 +145,22 @@ begin
-- host bus acknowledge --
ack_o <= wren or rden;

-- defaults --
fifo_clr <= '0';

-- write access --
if (wren = '1') then
enable <= data_i(ctrl_en_c);
enable <= data_i(ctrl_en_c);
fifo_clr <= data_i(ctrl_fifo_clr_c);
end if;

-- read access --
data_o <= (others => '0');
if (rden = '1') then
data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= rnd_reg;
data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= fifo.rdata;
data_o(ctrl_sim_mode_c) <= bool_to_ulogic_f(sim_mode_c);
data_o(ctrl_en_c) <= enable;
data_o(ctrl_valid_c) <= valid;
end if;

-- sample --
if (trng_valid = '1') then
rnd_reg <= trng_data;
end if;

-- data valid? --
if (enable = '0') then -- disabled
valid <= '0';
else
if (trng_valid = '1') then
valid <= '1';
elsif (rden = '1') then
valid <= '0';
end if;
data_o(ctrl_valid_c) <= fifo.avail;
end if;
end if;
end process rw_access;
Expand All @@ -168,17 +174,50 @@ begin
NUM_INV_START => num_inv_start_c,
NUM_INV_INC => num_inv_inc_c,
NUM_INV_DELAY => num_inv_delay_c,
POST_PROC_EN => true, -- post-processing enabled
POST_PROC_EN => true, -- post-processing enabled!
IS_SIM => sim_mode_c
)
port map (
clk_i => clk_i,
enable_i => enable,
data_o => trng_data,
valid_o => trng_valid
data_o => fifo.wdata,
valid_o => fifo.we
);


-- Data FIFO ------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rnd_pool_fifo_inst: neorv32_fifo
generic map (
FIFO_DEPTH => IO_TRNG_FIFO, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 8, -- size of data elements in fifo
FIFO_RSYNC => false, -- async read
FIFO_SAFE => true -- safe access
)
port map (
-- control --
clk_i => clk_i, -- clock, rising edge
rstn_i => '1', -- async reset, low-active
clear_i => fifo.clear, -- sync reset, high-active
level_o => open,
half_o => open,
-- write port --
wdata_i => fifo.wdata, -- write data
we_i => fifo.we, -- write enable
free_o => open, -- at least one entry is free when set
-- read port --
re_i => fifo.re, -- read enable
rdata_o => fifo.rdata, -- read data
avail_o => fifo.avail -- data available when set
);

-- fifo reset --
fifo.clear <= '1' when (enable = '0') or (fifo_clr = '1') else '0';

-- read access --
fifo.re <= '1' when (rden = '1') else '0';


end neorv32_trng_rtl;


Expand Down
2 changes: 2 additions & 0 deletions rtl/system_integration/neorv32_ProcessorTop_stdlogic.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ entity neorv32_ProcessorTop_stdlogic is
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_TRNG_FIFO : natural := 1; -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
Expand Down Expand Up @@ -346,6 +347,7 @@ begin
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
IO_TRNG_FIFO => IO_TRNG_FIFO, -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => IO_CFS_CONFIG_INT, -- custom CFS configuration generic
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits
Expand Down
2 changes: 2 additions & 0 deletions rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ entity neorv32_top_avalonmm is
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_TRNG_FIFO : natural := 1; -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
Expand Down Expand Up @@ -319,6 +320,7 @@ begin
IO_PWM_NUM_CH => IO_PWM_NUM_CH,
IO_WDT_EN => IO_WDT_EN,
IO_TRNG_EN => IO_TRNG_EN,
IO_TRNG_FIFO => IO_TRNG_FIFO,
IO_CFS_EN => IO_CFS_EN,
IO_CFS_CONFIG => IO_CFS_CONFIG,
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE,
Expand Down
2 changes: 2 additions & 0 deletions rtl/system_integration/neorv32_SystemTop_axi4lite.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ entity neorv32_SystemTop_axi4lite is
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := true; -- implement true random number generator (TRNG)?
IO_TRNG_FIFO : natural := 1; -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_logic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
Expand Down Expand Up @@ -344,6 +345,7 @@ begin
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
IO_TRNG_FIFO => IO_TRNG_FIFO, -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => IO_CFS_CONFIG_INT, -- custom CFS configuration generic
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits
Expand Down
1 change: 1 addition & 0 deletions sim/neorv32_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ begin
IO_PWM_NUM_CH => 30, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => true, -- implement watch dog timer (WDT)?
IO_TRNG_EN => true, -- implement true random number generator (TRNG)?
IO_TRNG_FIFO => 4, -- TRNG fifo depth, has to be a power of two, min 1
IO_CFS_EN => true, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => (others => '0'), -- custom CFS configuration generic
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits
Expand Down
Loading

0 comments on commit 66217a9

Please sign in to comment.