From 065f39f7c2ecb6be3df1371cba2b35c4f01440aa Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:28:07 +0100 Subject: [PATCH 1/6] [rtl] update version to v1.9.7.3 --- rtl/core/neorv32_package.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 21174ba3e..88735582a 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -52,7 +52,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090702"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090703"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width From 2d4b337893f57007d26d1850670b982277c510f7 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:32:59 +0100 Subject: [PATCH 2/6] [rtl] SDI: minor rtl edits --- rtl/core/neorv32_sdi.vhd | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/rtl/core/neorv32_sdi.vhd b/rtl/core/neorv32_sdi.vhd index bc2d74233..356c0556c 100644 --- a/rtl/core/neorv32_sdi.vhd +++ b/rtl/core/neorv32_sdi.vhd @@ -229,6 +229,7 @@ begin -- read access (SDI) -- tx_fifo.re <= serial.start; + -- RX -- rx_fifo_inst: entity neorv32.neorv32_fifo generic map ( @@ -262,6 +263,21 @@ begin rx_fifo.re <= '1' when (bus_req_i.stb = '1') and (bus_req_i.rw = '0') and (bus_req_i.addr(2) = '1') else '0'; + -- Interrupt Generator -- + irq_generator: process(rstn_i, clk_i) + begin + if (rstn_i = '0') then + irq_o <= '0'; + elsif rising_edge(clk_i) then + irq_o <= ctrl.enable and ( + (ctrl.irq_rx_avail and rx_fifo.avail) or -- RX FIFO not empty + (ctrl.irq_rx_half and rx_fifo.half) or -- RX FIFO at least half full + (ctrl.irq_rx_full and (not rx_fifo.free)) or -- RX FIFO full + (ctrl.irq_tx_empty and (not tx_fifo.avail))); -- TX FIFO empty + end if; + end process irq_generator; + + -- Input Synchronizer --------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- synchronizer: process(rstn_i, clk_i) @@ -351,20 +367,4 @@ begin sdi_dat_o <= serial.sreg(serial.sreg'left); - -- Interrupt Generator -------------------------------------------------------------------- - -- ------------------------------------------------------------------------------------------- - irq_generator: process(rstn_i, clk_i) - begin - if (rstn_i = '0') then - irq_o <= '0'; - elsif rising_edge(clk_i) then - irq_o <= ctrl.enable and ( - (ctrl.irq_rx_avail and rx_fifo.avail) or -- RX FIFO not empty - (ctrl.irq_rx_half and rx_fifo.half) or -- RX FIFO at least half full - (ctrl.irq_rx_full and (not rx_fifo.free)) or -- RX FIFO full - (ctrl.irq_tx_empty and (not tx_fifo.avail))); -- TX FIFO empty - end if; - end process irq_generator; - - end neorv32_sdi_rtl; From 14fa4b34ea76f03736cf00e2621dff4ad24c9547 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:33:10 +0100 Subject: [PATCH 3/6] [rtl] CFS: minor comment edits --- rtl/core/neorv32_cfs.vhd | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rtl/core/neorv32_cfs.vhd b/rtl/core/neorv32_cfs.vhd index c4911b339..2e31b48c4 100644 --- a/rtl/core/neorv32_cfs.vhd +++ b/rtl/core/neorv32_cfs.vhd @@ -139,9 +139,7 @@ begin -- Interrupt ------------------------------------------------------------------------------ -- ------------------------------------------------------------------------------------------- -- The CFS features a single interrupt signal, which is connected to the CPU's "fast interrupt" channel 1 (FIRQ1). - -- The interrupt is triggered by a one-cycle high-level. After triggering, the interrupt appears as "pending" in the CPU's - -- mip CSR ready to trigger execution of the according interrupt handler. It is the task of the application to programmer - -- to enable/clear the CFS interrupt using the CPU's mie and mip registers when required. + -- The according CPU interrupt becomes pending as long as is high. irq_o <= '0'; -- not used for this minimal example From 2103ea12da80da462cbaefc1576688debda2da2f Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:33:52 +0100 Subject: [PATCH 4/6] [rtl] rework GPTMR interrupt keep interrupt pending until explicitly cleared by writing zero to interrupt trigger state bit(s) --- rtl/core/neorv32_gptmr.vhd | 52 +++++++++++++------------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/rtl/core/neorv32_gptmr.vhd b/rtl/core/neorv32_gptmr.vhd index 58bc57952..4e4334a9d 100644 --- a/rtl/core/neorv32_gptmr.vhd +++ b/rtl/core/neorv32_gptmr.vhd @@ -58,7 +58,7 @@ end neorv32_gptmr; architecture neorv32_gptmr_rtl of neorv32_gptmr is -- control register -- - constant ctrl_en_c : natural := 0; -- r/w: GPTMR enable + constant ctrl_en_c : natural := 0; -- r/w: global enable constant ctrl_prsc0_c : natural := 1; -- r/w: clock prescaler select bit 0 constant ctrl_prsc1_c : natural := 2; -- r/w: clock prescaler select bit 1 constant ctrl_prsc2_c : natural := 3; -- r/w: clock prescaler select bit 2 @@ -122,25 +122,23 @@ begin bus_rsp_o.data <= (others => '0'); timer.cnt_we <= '0'; - -- trigger flags -- - trig_match <= ctrl(ctrl_en_c) and (trig_match or timer.trigger); - trig_capture <= ctrl(ctrl_en_c) and (trig_capture or capture.trigger); + -- IRQ trigger -- + trig_match <= ctrl(ctrl_en_c) and ctrl(ctrl_irqm_c) and (trig_match or timer.trigger); + trig_capture <= ctrl(ctrl_en_c) and ctrl(ctrl_irqc_c) and (trig_capture or capture.trigger); -- actual bus access -- if (bus_req_i.stb = '1') then - - -- write access -- - if (bus_req_i.rw = '1') then + if (bus_req_i.rw = '1') then -- write access if (bus_req_i.addr(3 downto 2) = "00") then -- control register - ctrl(ctrl_en_c) <= bus_req_i.data(ctrl_en_c); - ctrl(ctrl_prsc0_c) <= bus_req_i.data(ctrl_prsc0_c); - ctrl(ctrl_prsc1_c) <= bus_req_i.data(ctrl_prsc1_c); - ctrl(ctrl_prsc2_c) <= bus_req_i.data(ctrl_prsc2_c); - ctrl(ctrl_irqm_c) <= bus_req_i.data(ctrl_irqm_c); - ctrl(ctrl_irqc_c) <= bus_req_i.data(ctrl_irqc_c); - ctrl(ctrl_rise_c) <= bus_req_i.data(ctrl_rise_c); - ctrl(ctrl_fall_c) <= bus_req_i.data(ctrl_fall_c); - ctrl(ctrl_filter_c) <= bus_req_i.data(ctrl_filter_c); + ctrl(ctrl_en_c) <= bus_req_i.data(ctrl_en_c); + ctrl(ctrl_prsc0_c) <= bus_req_i.data(ctrl_prsc0_c); + ctrl(ctrl_prsc1_c) <= bus_req_i.data(ctrl_prsc1_c); + ctrl(ctrl_prsc2_c) <= bus_req_i.data(ctrl_prsc2_c); + ctrl(ctrl_irqm_c) <= bus_req_i.data(ctrl_irqm_c); + ctrl(ctrl_irqc_c) <= bus_req_i.data(ctrl_irqc_c); + ctrl(ctrl_rise_c) <= bus_req_i.data(ctrl_rise_c); + ctrl(ctrl_fall_c) <= bus_req_i.data(ctrl_fall_c); + ctrl(ctrl_filter_c) <= bus_req_i.data(ctrl_filter_c); if (bus_req_i.data(ctrl_trigm_c) = '0') then -- clear by writing zero trig_match <= '0'; end if; @@ -154,9 +152,7 @@ begin if (bus_req_i.addr(3 downto 2) = "10") then -- counter register timer.cnt_we <= '1'; end if; - - -- read access -- - else + else -- read access case bus_req_i.addr(3 downto 2) is when "00" => -- control register bus_rsp_o.data(ctrl_en_c) <= ctrl(ctrl_en_c); @@ -179,11 +175,13 @@ begin bus_rsp_o.data <= capture.count; end case; end if; - end if; end if; end process bus_access; + -- interrupt request -- + irq_o <= trig_match or trig_capture; + -- Timer Core ----------------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- @@ -274,18 +272,4 @@ begin (ctrl(ctrl_fall_c) and capture.falling); -- falling-edge trigger - -- Interrupt Generator -------------------------------------------------------------------- - -- ------------------------------------------------------------------------------------------- - irq_generator: process(rstn_i, clk_i) - begin - if (rstn_i = '0') then - irq_o <= '0'; - elsif rising_edge(clk_i) then - irq_o <= ctrl(ctrl_en_c) and - ((ctrl(ctrl_irqm_c) and timer.trigger) or -- timer-match interrupt - (ctrl(ctrl_irqc_c) and capture.trigger)); -- capture interrupt - end if; - end process irq_generator; - - end neorv32_gptmr_rtl; From 4238516399a12bdbf3139b9c8aa0c3e9f9bfa7a6 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:34:11 +0100 Subject: [PATCH 5/6] [changelog] add v1.9.7.3 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9ab6d75d..f08365298 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 | Link | |:----:|:-------:|:--------|:----:| +| 23.03.2024 | 1.9.7.3 | :warning: **interrupt system rework**: rework ONEWIRE and GPTMR interrupts | [#859](https://github.com/stnolting/neorv32/pull/859) | | 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** | | From 2322027fcb26424075894c955afcecf2add63a3c Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:35:18 +0100 Subject: [PATCH 6/6] [onewire] reqork interrupt interrupt will stay active as long as the module is in idle state --- docs/datasheet/soc_onewire.adoc | 7 +++---- rtl/core/neorv32_onewire.vhd | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/docs/datasheet/soc_onewire.adoc b/docs/datasheet/soc_onewire.adoc index 612a6cad9..2e08f35b8 100644 --- a/docs/datasheet/soc_onewire.adoc +++ b/docs/datasheet/soc_onewire.adoc @@ -163,10 +163,9 @@ time **T~base~** (and by eventually changing the hardwired timing configuration **Interrupt** -A single interrupt is provided by the ONEWIRE module to signal "operation done" condition to the CPU. Whenever the -controller completes a "generate reset pulse", a "transfer single-bit" or a "transfer full-byte" operation the -interrupt is triggered. Once triggered, the interrupt has to be _explicitly_ cleared again by writing zero to the -according <<_mip>> CSR FIRQ bit. +A single interrupt is provided by the ONEWIRE module to signal "idle" condition to the CPU. Whenever the +controller is idle (again) the interrupt becomes active. Once triggered, the interrupt has to be _explicitly_ +cleared again by writing zero to the according <<_mip>> CSR FIRQ bit. **Register Map** diff --git a/rtl/core/neorv32_onewire.vhd b/rtl/core/neorv32_onewire.vhd index 999bd37de..3c173ce45 100644 --- a/rtl/core/neorv32_onewire.vhd +++ b/rtl/core/neorv32_onewire.vhd @@ -6,7 +6,7 @@ -- # * generate reset pulse and check for device presence # -- # * transfer single bit (read-while-write) # -- # * transfer full byte (read-while-write) # --- # After completing any of the operations the interrupt signal is triggered. # +-- # The module's interrupt fires whenever the module is idle (again). # -- # The base time for bus interactions is configured using a 2-bit clock prescaler and a 8-bit # -- # clock divider. All bus operations are timed using (hardwired) multiples of this base time. # -- # ********************************************************************************************* # @@ -121,7 +121,6 @@ architecture neorv32_onewire_rtl of neorv32_onewire is tick : std_ulogic; tick_ff : std_ulogic; sreg : std_ulogic_vector(7 downto 0); - done : std_ulogic; wire_in : std_ulogic_vector(1 downto 0); wire_lo : std_ulogic; wire_hi : std_ulogic; @@ -238,7 +237,6 @@ begin begin if (rstn_i = '0') then serial.wire_in <= (others => '0'); - serial.done <= '0'; serial.wire_lo <= '0'; serial.wire_hi <= '0'; serial.state <= (others => '0'); @@ -259,7 +257,6 @@ begin end if; -- defaults -- - serial.done <= '0'; serial.wire_lo <= '0'; serial.wire_hi <= '0'; @@ -309,7 +306,6 @@ begin serial.sreg <= serial.sample & serial.sreg(7 downto 1); -- new bit; LSB first serial.bit_cnt <= serial.bit_cnt - 1; if (serial.bit_cnt = "000") then -- all done - serial.done <= '1'; -- operation done serial.state(1 downto 0) <= "00"; -- go back to IDLE else -- next bit serial.wire_lo <= '1'; -- force bus to low again @@ -333,7 +329,6 @@ begin end if; -- end of presence phase -- if (serial.tick_cnt = t_presence_end_c) then - serial.done <= '1'; -- operation done serial.state(1 downto 0) <= "00"; -- go back to IDLE end if; @@ -350,8 +345,21 @@ begin -- serial engine busy? -- serial.busy <= '0' when (serial.state(1 downto 0) = "00") else '1'; - -- operation done interrupt -- - irq_o <= serial.done; + + -- Interrupt Generator -------------------------------------------------------------------- + -- ------------------------------------------------------------------------------------------- + irq_generator: process(rstn_i, clk_i) + begin + if (rstn_i = '0') then + irq_o <= '0'; + elsif rising_edge(clk_i) then + if (serial.state = "100") then -- enabled and in idle state + irq_o <= '1'; + else + irq_o <= '0'; + end if; + end if; + end process irq_generator; end neorv32_onewire_rtl;