diff --git a/CHANGELOG.md b/CHANGELOG.md index aa606e4ac..38ea1ded6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12 | Date | Version | Comment | Ticket | |:----:|:-------:|:--------|:------:| +| 14.12.2024 | 1.10.7.3 | :warning: rework TRNG (change HAL; remove interrupt) | [#1120](https://github.com/stnolting/neorv32/pull/1120) | | 12.12.2024 | 1.10.7.2 | add external memory configuration/initialization options to testbench | [#1119](https://github.com/stnolting/neorv32/pull/1119) | | 11.12.2024 | 1.10.7.1 | :test_tube: shrink bootloader's minimal ISA (`rv32e`) and RAM (256 bytes) requirements | [#1118](https://github.com/stnolting/neorv32/pull/1118) | | 10.12.2024 | [**:rocket:1.10.7**](https://github.com/stnolting/neorv32/releases/tag/v1.10.7) | **New release** | | diff --git a/docs/datasheet/soc.adoc b/docs/datasheet/soc.adoc index 3ebee781e..abe61f9d2 100644 --- a/docs/datasheet/soc.adoc +++ b/docs/datasheet/soc.adoc @@ -449,7 +449,7 @@ table (the channel number also corresponds to the according FIRQ priority: 0 = h [options="header",grid="rows"] |======================= | Channel | Source | Description -| 0 | <<_true_random_number_generator_trng,TRNG>> | TRNG data available interrupt +| 0 | _reserved_ | _hardwired to zero_ | 1 | <<_custom_functions_subsystem_cfs,CFS>> | Custom functions subsystem (CFS) interrupt (user-defined) | 2 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 RX FIFO level interrupt | 3 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 TX FIFO level interrupt diff --git a/docs/datasheet/soc_trng.adoc b/docs/datasheet/soc_trng.adoc index cd9161a07..bb1ef47d9 100644 --- a/docs/datasheet/soc_trng.adoc +++ b/docs/datasheet/soc_trng.adoc @@ -11,7 +11,7 @@ | 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>>) +| CPU interrupts: | none | Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored |======================= @@ -33,34 +33,27 @@ neoTRNG repository: https://github.com/stnolting/neoTRNG 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. +The TRNG provides two memory mapped interface register. One control register (`CTRL`) for configuration and +status check and one data register (`DATA`) for obtaining the random data. The TRNG is enabled by setting the +control register's `TRNG_CTRL_EN`. As soon as the `TRNG_CTRL_AVAIL` bit is set a new random data byte is +available and can be obtained from the lowest 8 bits of the `DATA` register. If this bit is cleared, there +is no valid data available and the reading `DATA` will return 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. - +new random data from the TRNG to provide some kind of _random data pool_ for applications which require a +larger 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. +.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. **Register Map** @@ -70,13 +63,11 @@ Once the TRNG interrupt has fired it remains pending until the actual cause of t [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 +.5+<| `0xfffffa00` .5+<| `CTRL` <|`0` `TRNG_CTRL_EN` ^| r/w <| TRNG enable + <|`1` `TRNG_CTRL_FIFO_CLR` ^| -/w <| flush random data FIFO when set; flag auto-clears + <|`5:2` `TRNG_CTRL_FIFO_MSB : TRNG_CTRL_FIFO_LSB` ^| r/- <| FIFO depth, log2(`IO_TRNG_FIFO`) + <|`6` `TRNG_CTRL_SIM_MODE` ^| r/- <| simulation mode (PRNG!) + <|`7` `TRNG_CTRL_AVAIL` ^| r/- <| random data available when set +.2+<| `0xfffffa04` .2+<| `DATA` <|`7:0` `TRNG_DATA_MSB : TRNG_DATA_LSB` ^| r/- <| random data byte + <|`31:8` _reserved_ ^| r/- <| reserved, read as zero |======================= diff --git a/docs/figures/neorv32_processor.png b/docs/figures/neorv32_processor.png index a61578287..f5f1cc010 100644 Binary files a/docs/figures/neorv32_processor.png and b/docs/figures/neorv32_processor.png differ diff --git a/rtl/core/neorv32_cpu_cp_muldiv.vhd b/rtl/core/neorv32_cpu_cp_muldiv.vhd index 313dc0e30..994415943 100644 --- a/rtl/core/neorv32_cpu_cp_muldiv.vhd +++ b/rtl/core/neorv32_cpu_cp_muldiv.vhd @@ -110,7 +110,7 @@ begin elsif rising_edge(clk_i) then -- defaults -- ctrl.out_en <= '0'; - ctrl.cnt <= std_ulogic_vector(to_unsigned(XLEN-2, index_size_f(XLEN))); -- cycle counter initialization + ctrl.cnt <= std_ulogic_vector(to_unsigned(XLEN-2, ctrl.cnt'length)); -- cycle counter initialization -- fsm -- case ctrl.state is diff --git a/rtl/core/neorv32_fifo.vhd b/rtl/core/neorv32_fifo.vhd index 20a16f69d..8578f2e47 100644 --- a/rtl/core/neorv32_fifo.vhd +++ b/rtl/core/neorv32_fifo.vhd @@ -17,8 +17,8 @@ use neorv32.neorv32_package.all; entity neorv32_fifo is generic ( - FIFO_DEPTH : natural := 4; -- number of fifo entries; has to be a power of two; min 1 - FIFO_WIDTH : natural := 32; -- size of data elements in fifo + FIFO_DEPTH : natural := 4; -- number of FIFO entries; has to be a power of two; min 1 + FIFO_WIDTH : natural := 32; -- size of data elements in FIFO FIFO_RSYNC : boolean := false; -- false = async read; true = sync read FIFO_SAFE : boolean := false; -- true = allow read/write only if data available FULL_RESET : boolean := false -- true = reset all memory cells (cannot be mapped to BRAM) @@ -50,7 +50,7 @@ architecture neorv32_fifo_rtl of neorv32_fifo is signal fifo_mem : fifo_mem_t; -- for fifo_depth_c > 1 signal fifo_reg : std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- for fifo_depth_c = 1 - -- Fifo control and status -- + -- FIFO control and status -- signal we, re, match, empty, full, half, free, avail : std_ulogic; -- write/read pointer -- diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 490e6f4ec..2f6916757 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -29,7 +29,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100702"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100703"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width diff --git a/rtl/core/neorv32_top.vhd b/rtl/core/neorv32_top.vhd index c9ada44e3..d0d70ce43 100644 --- a/rtl/core/neorv32_top.vhd +++ b/rtl/core/neorv32_top.vhd @@ -323,7 +323,7 @@ architecture neorv32_top_rtl of neorv32_top is -- IRQs -- type firq_enum_t is ( - FIRQ_TRNG, FIRQ_UART0_RX, FIRQ_UART0_TX, FIRQ_UART1_RX, FIRQ_UART1_TX, FIRQ_SPI, FIRQ_SDI, FIRQ_TWI, + FIRQ_reserved, FIRQ_UART0_RX, FIRQ_UART0_TX, FIRQ_UART1_RX, FIRQ_UART1_TX, FIRQ_SPI, FIRQ_SDI, FIRQ_TWI, FIRQ_CFS, FIRQ_NEOLED, FIRQ_XIRQ, FIRQ_GPTMR, FIRQ_ONEWIRE, FIRQ_DMA, FIRQ_SLINK_RX, FIRQ_SLINK_TX ); type firq_t is array (firq_enum_t) of std_ulogic; @@ -544,7 +544,7 @@ begin ); -- fast interrupt requests (FIRQs) -- - cpu_firq(0) <= firq(FIRQ_TRNG); + cpu_firq(0) <= '0'; -- reserved cpu_firq(1) <= firq(FIRQ_CFS); cpu_firq(2) <= firq(FIRQ_UART0_RX); cpu_firq(3) <= firq(FIRQ_UART0_TX); @@ -1388,21 +1388,19 @@ begin if IO_TRNG_EN generate neorv32_trng_inst: entity neorv32.neorv32_trng generic map ( - IO_TRNG_FIFO => IO_TRNG_FIFO + TRNG_FIFO => IO_TRNG_FIFO ) port map ( clk_i => clk_i, rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_TRNG), - bus_rsp_o => iodev_rsp(IODEV_TRNG), - irq_o => firq(FIRQ_TRNG) + bus_rsp_o => iodev_rsp(IODEV_TRNG) ); end generate; neorv32_trng_inst_false: if not IO_TRNG_EN generate iodev_rsp(IODEV_TRNG) <= rsp_terminate_c; - firq(FIRQ_TRNG) <= '0'; end generate; diff --git a/rtl/core/neorv32_trng.vhd b/rtl/core/neorv32_trng.vhd index 5ffefae18..4cb02df8d 100644 --- a/rtl/core/neorv32_trng.vhd +++ b/rtl/core/neorv32_trng.vhd @@ -19,14 +19,13 @@ use neorv32.neorv32_package.all; entity neorv32_trng is generic ( - IO_TRNG_FIFO : natural range 1 to 2**15 -- RND fifo depth, has to be a power of two, min 1 + TRNG_FIFO : natural range 1 to 2**15 -- FIFO depth, has to be a power of two, min 1 ); port ( clk_i : in std_ulogic; -- global clock line rstn_i : in std_ulogic; -- global reset line, low-active, async bus_req_i : in bus_req_t; -- bus request - bus_rsp_o : out bus_rsp_t; -- bus response - irq_o : out std_ulogic -- data-available interrupt + bus_rsp_o : out bus_rsp_t -- bus response ); end neorv32_trng; @@ -38,17 +37,16 @@ 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_size0_c : natural := 16; -- r/-: log2(FIFO size) bit 0 - constant ctrl_fifo_size3_c : natural := 19; -- r/-: log2(FIFO size) bit 3 - -- - constant ctrl_irq_sel_c : natural := 27; -- r/w: interrupt select (0 = data available, 1 = FIFO full) - constant ctrl_fifo_clr_c : natural := 28; -- -/w: Clear data FIFO (auto clears) - constant ctrl_sim_mode_c : natural := 29; -- r/-: TRNG implemented in pseudo-RNG simulation mode - constant ctrl_en_c : natural := 30; -- r/w: TRNG enable - constant ctrl_valid_c : natural := 31; -- r/-: Output data valid + constant ctrl_en_c : natural := 0; -- r/w: TRNG enable + constant ctrl_fifo_clr_c : natural := 1; -- -/w: Clear data FIFO (auto clears) + constant ctrl_fifo_size0_c : natural := 2; -- r/-: log2(FIFO size) bit 0, LSB + constant ctrl_fifo_size3_c : natural := 5; -- r/-: log2(FIFO size) bit 3, MSB + constant ctrl_sim_mode_c : natural := 6; -- r/-: TRNG implemented in pseudo-RNG simulation mode + constant ctrl_avail_c : natural := 7; -- r/-: Random data available + + -- data register bits -- + constant ctrl_data_lsb_c : natural := 0; -- r/-: random data bit 0, LSB + constant ctrl_data_msb_c : natural := 7; -- r/-: random data bit 7, MSB -- neoTRNG true random number generator -- component neoTRNG @@ -66,10 +64,10 @@ architecture neorv32_trng_rtl of neorv32_trng is ); end component; - -- control -- - signal enable, irq_sel, fifo_clr : std_ulogic; + -- control register -- + signal enable, fifo_clr : std_ulogic; - -- data FIFO -- + -- data FIFO interface -- type fifo_t is record we : std_ulogic; -- write enable re : std_ulogic; -- read enable @@ -91,7 +89,6 @@ begin if (rstn_i = '0') then bus_rsp_o <= rsp_terminate_c; fifo_clr <= '0'; - irq_sel <= '0'; enable <= '0'; elsif rising_edge(clk_i) then -- defaults -- @@ -101,19 +98,22 @@ begin fifo_clr <= '0'; -- auto-clear -- host access -- if (bus_req_i.stb = '1') then - if (bus_req_i.rw = '1') then -- write access - irq_sel <= bus_req_i.data(ctrl_irq_sel_c); - fifo_clr <= bus_req_i.data(ctrl_fifo_clr_c); + if (bus_req_i.rw = '1') then -- write access (control register) enable <= bus_req_i.data(ctrl_en_c); + fifo_clr <= bus_req_i.data(ctrl_fifo_clr_c); else -- read access - bus_rsp_o.data(ctrl_data_msb_c downto ctrl_data_lsb_c) <= fifo.rdata; - -- - bus_rsp_o.data(ctrl_fifo_size3_c downto ctrl_fifo_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(IO_TRNG_FIFO), 4)); - -- - bus_rsp_o.data(ctrl_irq_sel_c) <= irq_sel; - bus_rsp_o.data(ctrl_sim_mode_c) <= bool_to_ulogic_f(is_simulation_c); - bus_rsp_o.data(ctrl_en_c) <= enable; - bus_rsp_o.data(ctrl_valid_c) <= fifo.avail; + if (bus_req_i.addr(2) = '0') then -- control register + bus_rsp_o.data(ctrl_en_c) <= enable; + bus_rsp_o.data(ctrl_fifo_size3_c downto ctrl_fifo_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(TRNG_FIFO), 4)); + bus_rsp_o.data(ctrl_sim_mode_c) <= bool_to_ulogic_f(is_simulation_c); + bus_rsp_o.data(ctrl_avail_c) <= fifo.avail; + else -- data register + if (fifo.avail = '0') then -- output zero if no data available + bus_rsp_o.data(ctrl_data_msb_c downto ctrl_data_lsb_c) <= (others => '0'); + else + bus_rsp_o.data(ctrl_data_msb_c downto ctrl_data_lsb_c) <= fifo.rdata; + end if; + end if; end if; end if; end if; @@ -141,11 +141,11 @@ begin -- ------------------------------------------------------------------------------------------- rnd_pool_fifo_inst: entity neorv32.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 => true, -- sync read - FIFO_SAFE => true, -- safe access - FULL_RESET => false -- no HW reset, try to infer BRAM + FIFO_DEPTH => 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 => true, -- sync read + FIFO_SAFE => true, -- safe access + FULL_RESET => false -- no HW reset, try to infer BRAM ) port map ( -- control -- @@ -164,25 +164,7 @@ begin ); fifo.clear <= '1' when (enable = '0') or (fifo_clr = '1') else '0'; - fifo.re <= '1' when (bus_req_i.stb = '1') and (bus_req_i.rw = '0') else '0'; - - -- IRQ generator -- - irq_generator: process(rstn_i, clk_i) - begin - if (rstn_i = '0') then - irq_o <= '0'; - elsif rising_edge(clk_i) then - if (enable = '1') then - if (irq_sel = '0') then -- fire IRQ if any data is available - irq_o <= fifo.avail; - else -- fire IRQ if data FIFO is full - irq_o <= not fifo.free; - end if; - else - irq_o <= '0'; - end if; - end if; - end process irq_generator; + fifo.re <= '1' when (bus_req_i.stb = '1') and (bus_req_i.rw = '0') and (bus_req_i.addr(2) = '1') else '0'; end neorv32_trng_rtl; diff --git a/rtl/core/neorv32_twi.vhd b/rtl/core/neorv32_twi.vhd index 8aa4f0c6a..c9bf29046 100644 --- a/rtl/core/neorv32_twi.vhd +++ b/rtl/core/neorv32_twi.vhd @@ -1,5 +1,5 @@ -- ================================================================================ -- --- NEORV32 SoC - Two-Wire Interface Controller (TWI) -- +-- NEORV32 SoC - Two-Wire Interface Host Controller (TWI) -- -- -------------------------------------------------------------------------------- -- -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- -- Copyright (c) NEORV32 contributors. -- @@ -38,14 +38,14 @@ architecture neorv32_twi_rtl of neorv32_twi is -- control register -- constant ctrl_en_c : natural := 0; -- r/w: module enable (reset when zero) - constant ctrl_prsc0_c : natural := 1; -- r/w: CLK prsc bit 0 - constant ctrl_prsc2_c : natural := 3; -- r/w: CLK prsc bit 2 + constant ctrl_prsc0_c : natural := 1; -- r/w: clock prescaler bit 0 + constant ctrl_prsc2_c : natural := 3; -- r/w: clock prescaler bit 2 constant ctrl_cdiv0_c : natural := 4; -- r/w: clock divider bit 0 constant ctrl_cdiv3_c : natural := 7; -- r/w: clock divider bit 3 constant ctrl_clkstr_en_c : natural := 8; -- r/w: enable clock stretching -- - constant ctrl_fifo_size0_c : natural := 15; -- r/-: log2(fifo size), bit 0 (lsb) - constant ctrl_fifo_size3_c : natural := 18; -- r/-: log2(fifo size), bit 3 (msb) + constant ctrl_fifo_size0_c : natural := 15; -- r/-: log2(FIFO size), bit 0 (LSB) + constant ctrl_fifo_size3_c : natural := 18; -- r/-: log2(FIFO size), bit 3 (MSB) -- constant ctrl_sense_scl_c : natural := 27; -- r/-: current state of the SCL bus line constant ctrl_sense_sda_c : natural := 28; -- r/-: current state of the SDA bus line diff --git a/rtl/core/neorv32_xbus.vhd b/rtl/core/neorv32_xbus.vhd index e2421e515..526ea96ac 100644 --- a/rtl/core/neorv32_xbus.vhd +++ b/rtl/core/neorv32_xbus.vhd @@ -99,7 +99,7 @@ begin bus_rw <= '0'; elsif rising_edge(clk_i) then if (pending = '0') then -- idle, waiting for request - timeout_cnt <= std_ulogic_vector(to_unsigned(TIMEOUT_VAL, index_size_f(TIMEOUT_VAL)+1)); + timeout_cnt <= std_ulogic_vector(to_unsigned(TIMEOUT_VAL, timeout_cnt'length)); pending <= bus_req.stb; else -- busy, transfer in progress timeout_cnt <= std_ulogic_vector(unsigned(timeout_cnt) - 1); diff --git a/sw/example/demo_trng/main.c b/sw/example/demo_trng/main.c index ce5769a19..f28669498 100644 --- a/sw/example/demo_trng/main.c +++ b/sw/example/demo_trng/main.c @@ -72,8 +72,9 @@ int main(void) { // enable TRNG neorv32_uart0_printf("\nTRNG FIFO depth: %i\n", neorv32_trng_get_fifo_depth()); neorv32_uart0_printf("Starting TRNG...\n"); - neorv32_trng_enable(0); + neorv32_trng_enable(); neorv32_cpu_delay_ms(100); // TRNG "warm up" + neorv32_trng_fifo_clear(); // discard "warm-up" data while(1) { @@ -346,14 +347,13 @@ void compute_rate(void) { const uint32_t n_samples = 16*1024; uint32_t i; - uint32_t tmp; + uint8_t data; uint32_t cycles = neorv32_cpu_csr_read(CSR_CYCLE); i = 0; while (iCTRL; - if (tmp & (1<SOC & (1 << SYSINFO_SOC_IO_TRNG)) { - cnt_test++; - - // enable TRNG, trigger IRQ when FIFO is full - neorv32_trng_enable(1); - - // enable fast interrupt - neorv32_cpu_csr_write(CSR_MIE, 1 << TRNG_FIRQ_ENABLE); - - // sleep until interrupt - neorv32_cpu_sleep(); - - // no more interrupts - neorv32_cpu_csr_write(CSR_MIE, 0); - - if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRNG_TRAP_CODE) { - test_ok(); - } - else { - test_fail(); - } - } - else { - PRINT_STANDARD("[n.a.]\n"); - } + PRINT_STANDARD("[%i] FIRQ0 (reserved) ", cnt_test); + PRINT_STANDARD("[n.a.]\n"); // ---------------------------------------------------------- // Fast interrupt channel 1 (CFS) // ---------------------------------------------------------- + neorv32_cpu_csr_write(CSR_MCAUSE, mcause_never_c); PRINT_STANDARD("[%i] FIRQ1 (CFS) ", cnt_test); PRINT_STANDARD("[n.a.]\n"); diff --git a/sw/lib/include/neorv32.h b/sw/lib/include/neorv32.h index 895cc7a13..4cdc8f8c1 100644 --- a/sw/lib/include/neorv32.h +++ b/sw/lib/include/neorv32.h @@ -83,12 +83,12 @@ extern "C" { * @name Fast Interrupt Requests (FIRQ) device aliases **************************************************************************/ /**@{*/ -/** @name True-Random Number Generator (TRNG) */ +/** @name Reserved */ /**@{*/ -#define TRNG_FIRQ_ENABLE CSR_MIE_FIRQ0E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */ -#define TRNG_FIRQ_PENDING CSR_MIP_FIRQ0P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */ -#define TRNG_RTE_ID RTE_TRAP_FIRQ_0 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */ -#define TRNG_TRAP_CODE TRAP_CODE_FIRQ_0 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */ +//#define RESERVED_FIRQ_ENABLE CSR_MIE_FIRQ0E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */ +//#define RESERVED_FIRQ_PENDING CSR_MIP_FIRQ0P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */ +//#define RESERVED_RTE_ID RTE_TRAP_FIRQ_0 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */ +//#define RESERVED_TRAP_CODE TRAP_CODE_FIRQ_0 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */ /**@}*/ /** @name Custom Functions Subsystem (CFS) */ /**@{*/ diff --git a/sw/lib/include/neorv32_trng.h b/sw/lib/include/neorv32_trng.h index 73ba7d0d5..dd5a045e7 100644 --- a/sw/lib/include/neorv32_trng.h +++ b/sw/lib/include/neorv32_trng.h @@ -27,25 +27,27 @@ /**@{*/ /** TRNG module prototype */ typedef volatile struct __attribute__((packed,aligned(4))) { - uint32_t CTRL; /**< offset 0: control register (#NEORV32_TRNG_CTRL_enum) */ + uint32_t CTRL; /**< offset 0: control register (#NEORV32_TRNG_CTRL_enum) */ + const uint32_t DATA; /**< offset 4: random data register (#NEORV32_TRNG_DATA_enum) */ } neorv32_trng_t; /** TRNG module hardware access (#neorv32_trng_t) */ #define NEORV32_TRNG ((neorv32_trng_t*) (NEORV32_TRNG_BASE)) -/** TRNG control/data register bits */ +/** TRNG control register bits */ enum NEORV32_TRNG_CTRL_enum { - TRNG_CTRL_DATA_LSB = 0, /**< TRNG data/control register(0) (r/-): Random data byte LSB */ - TRNG_CTRL_DATA_MSB = 7, /**< TRNG data/control register(7) (r/-): Random data byte MSB */ - - TRNG_CTRL_FIFO_LSB = 16, /**< TRNG data/control register(16) (r/-): log2(FIFO size), LSB */ - TRNG_CTRL_FIFO_MSB = 19, /**< TRNG data/control register(19) (r/-): log2(FIFO size), MSB */ + TRNG_CTRL_EN = 0, /**< TRNG data register(0) (r/w): TRNG enable */ + TRNG_CTRL_FIFO_CLR = 1, /**< TRNG data register(1) (-/w): Clear data FIFO (auto clears) */ + TRNG_CTRL_FIFO_LSB = 2, /**< TRNG data register(2) (r/-): log2(FIFO size), LSB */ + TRNG_CTRL_FIFO_MSB = 5, /**< TRNG data register(5) (r/-): log2(FIFO size), MSB */ + TRNG_CTRL_SIM_MODE = 6, /**< TRNG data register(6) (r/-): PRNG mode (simulation mode) */ + TRNG_CTRL_AVAIL = 7 /**< TRNG data register(7) (r/-): Random data available */ +}; - TRNG_CTRL_IRQ_SEL = 27, /**< TRNG data/control register(27) (r/w): Interrupt trigger select (0 = data available, 1 = FIFO full) */ - TRNG_CTRL_FIFO_CLR = 28, /**< TRNG data/control register(28) (-/w): Clear data FIFO (auto clears) */ - TRNG_CTRL_SIM_MODE = 29, /**< TRNG data/control register(29) (r/-): PRNG mode (simulation mode) */ - TRNG_CTRL_EN = 30, /**< TRNG data/control register(30) (r/w): TRNG enable */ - TRNG_CTRL_VALID = 31 /**< TRNG data/control register(31) (r/-): Random data output valid */ +/** TRNG data register bits */ +enum NEORV32_TRNG_DATA_enum { + TRNG_DATA_LSB = 0, /**< TRNG control register(0) (r/-): Random data byte, bit 0 */ + TRNG_DATA_MSB = 7 /**< TRNG control register(7) (r/-): Random data byte, bit 7 */ }; /**@}*/ @@ -55,7 +57,7 @@ enum NEORV32_TRNG_CTRL_enum { **************************************************************************/ /**@{*/ int neorv32_trng_available(void); -void neorv32_trng_enable(int irq_sel); +void neorv32_trng_enable(void); void neorv32_trng_disable(void); void neorv32_trng_fifo_clear(void); int neorv32_trng_get_fifo_depth(void); diff --git a/sw/lib/source/neorv32_trng.c b/sw/lib/source/neorv32_trng.c index d7eb8bafe..bd7ca8b7c 100644 --- a/sw/lib/source/neorv32_trng.c +++ b/sw/lib/source/neorv32_trng.c @@ -36,10 +36,8 @@ int neorv32_trng_available(void) { /**********************************************************************//** * Reset, configure and enable TRNG. - * - * @param[in] irq_sel Interrupt trigger select (0 = data available, 1 = FIFO full). **************************************************************************/ -void neorv32_trng_enable(int irq_sel) { +void neorv32_trng_enable(void) { NEORV32_TRNG->CTRL = 0; // disable and reset @@ -49,11 +47,7 @@ void neorv32_trng_enable(int irq_sel) { asm volatile ("nop"); } - uint32_t tmp = 0; - tmp |= (1 << TRNG_CTRL_EN); // enable - tmp |= (((uint32_t)(irq_sel & 1)) << TRNG_CTRL_IRQ_SEL); // interrupt trigger select - tmp |= (1 << TRNG_CTRL_FIFO_CLR); // clear data FIFO - NEORV32_TRNG->CTRL = tmp; + NEORV32_TRNG->CTRL = 1 << TRNG_CTRL_EN; // enable } @@ -95,11 +89,9 @@ int neorv32_trng_get_fifo_depth(void) { **************************************************************************/ int neorv32_trng_get(uint8_t *data) { - uint32_t tmp = NEORV32_TRNG->CTRL; - *data = (uint8_t)(tmp >> TRNG_CTRL_DATA_LSB); - - if (tmp & (1<CTRL & (1<DATA; + return 0; } else { return -1; diff --git a/sw/svd/neorv32.svd b/sw/svd/neorv32.svd index 85039fcf2..9fca3aed9 100644 --- a/sw/svd/neorv32.svd +++ b/sw/svd/neorv32.svd @@ -1324,7 +1324,7 @@ 0 - 0x04 + 0x08 registers @@ -1335,43 +1335,45 @@ 0x00 - TRNG_CTRL_DATA - [7:0] - read-only - Random data - - - TRNG_CTRL_FIFO - [19:16] - read-only - Log2(FIFO size) + TRNG_CTRL_EN + [0:0] + TRNG enable flag - TRNG_CTRL_IRQ_SEL - [27:27] - Interrupt trigger select (0 = data available, 1 = FIFO full) + TRNG_CTRL_FIFO_CLR + [1:1] + Clear data FIFO when set (flag auto clears) - TRNG_CTRL_FIFO_CLR - [28:28] - Clear data FIFO when set (auto clears) + ONEWIRE_CTRL_FIFO_SIZE + [5:2] + read-only + log2(TRNG FIFO size) TRNG_CTRL_SIM_MODE - [29:29] + [6:6] read-only TRNG simulation mode (PRNG!) active - TRNG_CTRL_EN - [30:30] - TRNG enable flag + TRNG_CTRL_AVAIL + [7:7] + read-only + Random data available + + + + DATA + Random data + 0x04 + - TRNG_CTRL_VALID - [31:31] + TRNG_DATA + [7:0] read-only - Random data output valid + Random data