Skip to content

Commit

Permalink
⚠️ remove WDT + TRNG interrupts; 🐛 fix bug in core-complex clocking d…
Browse files Browse the repository at this point in the history
…uring sleep (#858)
  • Loading branch information
stnolting committed Mar 23, 2024
2 parents 1fd901c + 61cc312 commit 1d64f5f
Show file tree
Hide file tree
Showing 19 changed files with 92 additions and 281 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Link |
|:----:|:-------:|:--------|:----:|
| 26.03.2024 | 1.9.7.1 | CPU hardware optimization (reduced hardware footprint, shortened critical path) | [#857](https://github.com/stnolting/neorv32/pull/857) |
| 23.03.2024 | 1.9.7.2 | :warning: **interrupt system rework**: removed WDT and TRNG interrupts; :bug: fix core complex clocking during sleep mode | [#858](https://github.com/stnolting/neorv32/pull/858) |
| 23.03.2024 | 1.9.7.1 | CPU hardware optimization (reduced hardware footprint, shortened critical path) | [#857](https://github.com/stnolting/neorv32/pull/857) |
| 22.03.2024 | [**:rocket:1.9.7**](https://github.com/stnolting/neorv32/releases/tag/v1.9.7) | **New release** | |
| 18.03.2024 | 1.9.6.9 | :sparkles: update CFU example: now implementing the Extended Tiny Encryption Algorithm (XTEA) | [#855](https://github.com/stnolting/neorv32/pull/855) |
| 16.03.2024 | 1.9.6.8 | rework cache system: L1 + L2 caches, all based on the generic cache component | [#853](https://github.com/stnolting/neorv32/pull/853) |
Expand Down
6 changes: 3 additions & 3 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ After executing the `wfi` instruction the CPU's `sleep_o` signal (<<_cpu_top_ent
as soon as the CPU has fully halted ("CPU is sleeping"):

[start=1]
.The front-end (instruction fetch) is stopped. There is no pending instruction fetch bus access.
.The back-end (instruction execution) is stopped. There is no pending data bus access.
.There is not enabled interrupt pending.
.The front-end (instruction fetch) has stopped. There is no pending instruction fetch bus access.
.The back-end (instruction execution) has stopped. There is no pending data bus access.
.There is no enabled interrupt being pending.

CPU-external modules like memories, timers and peripheral interfaces are not affected by this. Furthermore, the CPU will
continue to buffer/enqueue incoming interrupt. The CPU will leave sleep mode as soon as any _enabled (via <<_mie>>)
Expand Down
6 changes: 3 additions & 3 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ the interrupt request is explicitly acknowledged (e.g. writing to a memory-mappe
==== NEORV32-Specific Fast Interrupt Requests

As part of the NEORV32-specific CPU extensions, the processor core features 16 fast interrupt request signals
(`FIRQ0` - `FIRQ15`) providing dedicated bits in the <<_mip>> and <<_mie>> CSRs and custom <<_mcause>> trap codes.
(`FIRQ0` to `FIRQ15`) providing dedicated bits in the <<_mip>> and <<_mie>> CSRs and custom <<_mcause>> trap codes.
The FIRQ signals are reserved for _processor-internal_ modules only (for example for the communication
interfaces to signal "available incoming data" or "ready to send new data").

Expand All @@ -439,7 +439,7 @@ table (the channel number also corresponds to the according FIRQ priority: 0 = h
[options="header",grid="rows"]
|=======================
| Channel | Source | Description
| 0 | <<_watchdog_timer_wdt,WDT>> | watchdog timeout interrupt
| 0 | - | _reserved_
| 1 | <<_custom_functions_subsystem_cfs,CFS>> | custom functions subsystem (CFS) interrupt (user-defined)
| 2 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 RX interrupt
| 3 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 TX interrupt
Expand All @@ -454,7 +454,7 @@ table (the channel number also corresponds to the according FIRQ priority: 0 = h
| 12 | <<_general_purpose_timer_gptmr,GPTMR>> | General purpose timer interrupt
| 13 | <<_one_wire_serial_interface_controller_onewire,ONEWIRE>> | 1-wire operation done interrupt
| 14 | <<_stream_link_interface_slink,SLINK>> | SLINK FIFO level interrupt
| 15 | <<_true_random_number_generator_trng,TRNG>> | TRNG FIFO level interrupt
| 15 | - | _reserved_
|=======================

.Trigger Type
Expand Down
39 changes: 12 additions & 27 deletions docs/datasheet/soc_trng.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_trng.vhd |
| Hardware source file(s): | neorv32_trng.vhd |
| Software driver file(s): | neorv32_trng.c |
| | neorv32_trng.h |
| Top entity port: | none |
| 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>>)
| CPU interrupts: | - | none
|=======================


Expand All @@ -20,7 +20,7 @@
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.
primitives, macros or attributes so it can be synthesized for _any_ FPGA.

.In-Depth Documentation
[TIP]
Expand Down Expand Up @@ -53,34 +53,19 @@ of random data in a short time. The random data FIFO can be cleared at any time
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
.8+<| `0xfffffa00` .8+<| `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
<|`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
|=======================
13 changes: 3 additions & 10 deletions docs/datasheet/soc_wdt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| | neorv32_wdt.h |
| Top entity port: | none |
| Configuration generics: | `IO_WDT_EN` | implement watchdog when `true`
| CPU interrupts: | fast IRQ channel 0 | watchdog timeout (see <<_processor_interrupts>>)
| CPU interrupts: | - | none
|=======================


Expand All @@ -26,22 +26,15 @@ program every now and then to prevent a timeout.
**Configuration**

The watchdog is enabled by setting the control register's `WDT_CTRL_EN` bit. When this bit is cleared, the internal
timeout counter is reset to zero and no interrupt and no system reset can be triggered.
timeout counter is reset to zero and no system reset can be triggered by this module.

The internal 32-bit timeout counter is clocked at 1/4096th of the processor's main clock (f~WDT~[Hz] = f~main~[Hz] / 4096).
Whenever this counter reaches the programmed timeout value (`WDT_CTRL_TIMEOUT` bits in the control register) a
hardware reset is triggered. In order to inform the application of an imminent timeout, an optional CPU interrupt is
triggered when the timeout counter reaches _half_ of the programmed timeout value.
hardware reset is triggered.

The watchdog's timeout counter is reset ("feeding the watchdog") by writing the reset **PASSWORD** to the `RESET` register.
The password is hardwired to hexadecimal `0x709D1AB3`.

.Watchdog Interrupt
[NOTE]
A watchdog interrupt occurs when the watchdog is enabled and the internal counter reaches _exactly_ half of the programmed
timeout value. Hence, the interrupt only fires once. However, a triggered WDT interrupt has to be explicitly cleared by
writing zero to the according <<_mip>> CSR bit.

.Watchdog Operation during Debugging
[IMPORTANT]
By default, the watchdog stops operation when the CPU enters debug mode and will resume normal operation after
Expand Down
Binary file modified docs/figures/neorv32_processor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ package neorv32_package is

-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090701"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090702"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

Expand Down
38 changes: 17 additions & 21 deletions rtl/core/neorv32_top.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ architecture neorv32_top_rtl of neorv32_top is

-- IRQs --
type firq_enum_t is (
FIRQ_WDT, 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_TRNG, FIRQ_SLINK
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
);
type firq_t is array (firq_enum_t) of std_ulogic;
signal firq : firq_t;
Expand Down Expand Up @@ -492,8 +492,16 @@ begin
cg_en(CG_TWI) or cg_en(CG_PWM) or cg_en(CG_WDT) or cg_en(CG_NEOLED) or
cg_en(CG_GPTMR) or cg_en(CG_XIP) or cg_en(CG_ONEWIRE);

end generate; -- /generators


-- Clock Gating ---------------------------------------------------------------------------
-- **************************************************************************************************************************
-- Core Complex
-- **************************************************************************************************************************
core_complex:
if (true) generate

-- CPU Clock Gating -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_clockgate_inst_true:
if CLOCK_GATING_EN generate
Expand All @@ -511,14 +519,6 @@ begin
clk_cpu <= clk_i;
end generate;

end generate; -- /generators


-- **************************************************************************************************************************
-- Core Complex
-- **************************************************************************************************************************
core_complex:
if (true) generate

-- CPU Core -------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -581,7 +581,7 @@ begin
);

-- fast interrupt requests (FIRQs) --
cpu_firq(00) <= firq(FIRQ_WDT); -- highest priority
cpu_firq(00) <= '0'; -- reserved
cpu_firq(01) <= firq(FIRQ_CFS);
cpu_firq(02) <= firq(FIRQ_UART0_RX);
cpu_firq(03) <= firq(FIRQ_UART0_TX);
Expand All @@ -596,7 +596,7 @@ begin
cpu_firq(12) <= firq(FIRQ_GPTMR);
cpu_firq(13) <= firq(FIRQ_ONEWIRE);
cpu_firq(14) <= firq(FIRQ_SLINK);
cpu_firq(15) <= firq(FIRQ_TRNG); -- lowest priority
cpu_firq(15) <= '0'; -- reserved


-- CPU Instruction Cache ------------------------------------------------------------------
Expand All @@ -612,7 +612,7 @@ begin
READ_ONLY => true
)
port map (
clk_i => clk_cpu,
clk_i => clk_i,
rstn_i => rstn_sys,
host_req_i => cpu_i_req,
host_rsp_o => cpu_i_rsp,
Expand Down Expand Up @@ -641,7 +641,7 @@ begin
READ_ONLY => false
)
port map (
clk_i => clk_cpu,
clk_i => clk_i,
rstn_i => rstn_sys,
host_req_i => cpu_d_req,
host_rsp_o => cpu_d_rsp,
Expand All @@ -665,7 +665,7 @@ begin
PORT_B_READ_ONLY => true -- i-fetch is read-only
)
port map (
clk_i => clk_cpu,
clk_i => clk_i,
rstn_i => rstn_sys,
a_req_i => dcache_req, -- prioritized
a_rsp_o => dcache_rsp,
Expand Down Expand Up @@ -1184,15 +1184,13 @@ begin
cpu_sleep_i => cpu_sleep,
clkgen_en_o => cg_en(CG_WDT),
clkgen_i => clk_gen,
irq_o => firq(FIRQ_WDT),
rstn_o => rstn_wdt
);
end generate;

neorv32_wdt_inst_false:
if not IO_WDT_EN generate
iodev_rsp(IODEV_WDT) <= rsp_terminate_c;
firq(FIRQ_WDT) <= '0';
cg_en(CG_WDT) <= '0';
rstn_wdt <= '1';
end generate;
Expand Down Expand Up @@ -1412,15 +1410,13 @@ begin
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;


Expand Down
Loading

0 comments on commit 1d64f5f

Please sign in to comment.