Skip to content

Commit d0c3cfa

Browse files
authored
🐛 Fix write access to mip.firq CSR bits (#821)
2 parents 0885938 + 76cdb7d commit d0c3cfa

File tree

5 files changed

+35
-27
lines changed

5 files changed

+35
-27
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
3030

3131
| Date | Version | Comment | Link |
3232
|:----:|:-------:|:--------|:----:|
33+
| 20.02.2024 | 1.9.5.6 | :bug: fix bug in `mip.firq` CSR access; `mip.firq` bits are now read-write - software can trigger FIRQs by writing `1` to the according CSR bit | [#821](https://github.com/stnolting/neorv32/pull/821) |
3334
| 19.02.2024 | 1.9.5.5 | SLINK: add native hardware support for AXI-stream's "tlast" signal | [#815](https://github.com/stnolting/neorv32/pull/815) |
3435
| 19.02.2024 | 1.9.5.4 | :warning: remove support of `Smcntrpmf` ISA extension (counter privilege mode filtering) | [#814](https://github.com/stnolting/neorv32/pull/814) |
3536
| 17.02.2024 | 1.9.5.3 | :warning: reworked CPU's hardware performance monitor (HPMs) events | [#811](https://github.com/stnolting/neorv32/pull/811) |

docs/datasheet/cpu_csr.adoc

+5-5
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,7 @@ However, any write-access will be ignored and will not cause an exception to mai
432432
| Address | `0x344`
433433
| Reset value | `0x00000000`
434434
| ISA | `Zicsr`
435-
| Description | The `mip` CSR shows currently _pending_ machine-mode interrupt requests. The bits for the standard RISC-V
436-
machine-mode interrupts (`MEIP`, `MTIP`, `MSIP`) are read-only. Hence, these interrupts cannot be
437-
cleared/set using the `mip` register. These interrupts are cleared/acknowledged by mechanism that are
438-
specific for the interrupt-causing modules. the according interrupt-generating device.
435+
| Description | The `mip` CSR shows currently _pending_ machine-mode interrupt requests.
439436
|=======================
440437

441438
.`mip` CSR bits
@@ -446,14 +443,17 @@ specific for the interrupt-causing modules. the according interrupt-generating d
446443
| 3 | `CSR_MIP_MSIP` | r/- | **MSIP**: Machine _software_ interrupt pending; _cleared by platform-defined mechanism_
447444
| 7 | `CSR_MIP_MTIP` | r/- | **MTIP**: Machine _timer_ interrupt pending; _cleared by platform-defined mechanism_
448445
| 11 | `CSR_MIP_MEIP` | r/- | **MEIP**: Machine _external_ interrupt pending; _cleared by platform-defined mechanism_
449-
| 31:16 | `CSR_MIP_FIRQ15P` : `CSR_MIP_FIRQ0P` | r/c | **FIRQxP**: Fast interrupt channel 15..0 pending; has to be cleared manually by writing zero
446+
| 31:16 | `CSR_MIP_FIRQ15P` : `CSR_MIP_FIRQ0P` | r/w | **FIRQxP**: Fast interrupt channel 15..0 pending; has to be cleared manually by writing zero
450447
|=======================
451448

452449
.FIRQ Channel Mapping
453450
[TIP]
454451
See section <<_neorv32_specific_fast_interrupt_requests>> for the mapping of the FIRQ channels and the according
455452
interrupt-triggering processor module.
456453

454+
[NOTE]
455+
The FIRQ channels can be triggered manually by software by writing `1` to the according `mip` bit.
456+
457457

458458
{empty} +
459459
[discrete]

rtl/core/neorv32_cpu_control.vhd

+12-5
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
255255
mie_mei : std_ulogic; -- machine external interrupt enable
256256
mie_mti : std_ulogic; -- machine timer interrupt enable
257257
mie_firq : std_ulogic_vector(15 downto 0); -- fast interrupt enable
258-
mip_firq_nclr : std_ulogic_vector(15 downto 0); -- clear pending FIRQ (active-low)
258+
mip_firq_wdata : std_ulogic_vector(15 downto 0); -- fast interrupt pending write data
259+
mip_firq_we : std_ulogic; -- fast interrupt pending write enable
259260
--
260261
privilege : std_ulogic; -- current privilege mode
261262
privilege_eff : std_ulogic; -- current *effective* privilege mode
@@ -1451,7 +1452,11 @@ begin
14511452

14521453
-- NEORV32-specific fast interrupts --
14531454
for i in 0 to 15 loop
1454-
trap_ctrl.irq_pnd(irq_firq_0_c+i) <= (trap_ctrl.irq_pnd(irq_firq_0_c+i) and csr.mip_firq_nclr(i)) or firq_i(i);
1455+
if (csr.mip_firq_we = '1') then -- write access to MIP(.FIRQ) CSR
1456+
trap_ctrl.irq_pnd(irq_firq_0_c+i) <= firq_i(i) or csr.mip_firq_wdata(i); -- keep buffering incoming FIRQs
1457+
else
1458+
trap_ctrl.irq_pnd(irq_firq_0_c+i) <= firq_i(i) or trap_ctrl.irq_pnd(irq_firq_0_c+i); -- keep pending FIRQs alive
1459+
end if;
14551460
end loop;
14561461

14571462
-- debug-mode entry --
@@ -1637,7 +1642,8 @@ begin
16371642
csr.mtinst <= (others => '0');
16381643
csr.mcounteren <= '0';
16391644
csr.mcountinhibit <= (others => '0');
1640-
csr.mip_firq_nclr <= (others => '0');
1645+
csr.mip_firq_wdata <= (others => '0');
1646+
csr.mip_firq_we <= '0';
16411647
csr.dcsr_ebreakm <= '0';
16421648
csr.dcsr_ebreaku <= '0';
16431649
csr.dcsr_step <= '0';
@@ -1654,7 +1660,7 @@ begin
16541660

16551661
-- defaults --
16561662
csr.we <= csr.we_nxt and (not trap_ctrl.exc_buf(exc_illegal_c)); -- write if not an illegal instruction
1657-
csr.mip_firq_nclr <= (others => '1'); -- inactive FIRQ clear (active low)
1663+
csr.mip_firq_we <= '0'; -- no write to MIP.FIRQ by default
16581664
csr.tdata1_hit_clr <= '0';
16591665

16601666
-- ********************************************************************************
@@ -1715,7 +1721,8 @@ begin
17151721
csr.mcause <= csr.wdata(31) & csr.wdata(4 downto 0); -- type (exception/interrupt) & identifier
17161722

17171723
when csr_mip_c => -- machine interrupt pending
1718-
csr.mip_firq_nclr <= csr.wdata(31 downto 16); -- set low to clear according bit (FIRQs only)
1724+
csr.mip_firq_wdata <= csr.wdata(31 downto 16);
1725+
csr.mip_firq_we <= '1'; -- trigger MIP.FIRQ write
17191726

17201727
-- --------------------------------------------------------------------
17211728
-- machine counter setup --

rtl/core/neorv32_package.vhd

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ package neorv32_package is
5353

5454
-- Architecture Constants -----------------------------------------------------------------
5555
-- -------------------------------------------------------------------------------------------
56-
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090505"; -- hardware version
56+
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090506"; -- hardware version
5757
constant archid_c : natural := 19; -- official RISC-V architecture ID
5858
constant XLEN : natural := 32; -- native data path width
5959

sw/lib/include/neorv32_cpu_csr.h

+16-16
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,22 @@ enum NEORV32_CSR_MIP_enum {
304304
CSR_MIP_MEIP = 11, /**< CPU mip CSR (11): MEIP - Machine external interrupt pending (r/-) */
305305

306306
/* NEORV32-specific extension: Fast Interrupt Requests (FIRQ) */
307-
CSR_MIP_FIRQ0P = 16, /**< CPU mip CSR (16): FIRQ0P - Fast interrupt channel 0 pending (r/c) */
308-
CSR_MIP_FIRQ1P = 17, /**< CPU mip CSR (17): FIRQ1P - Fast interrupt channel 1 pending (r/c) */
309-
CSR_MIP_FIRQ2P = 18, /**< CPU mip CSR (18): FIRQ2P - Fast interrupt channel 2 pending (r/c) */
310-
CSR_MIP_FIRQ3P = 19, /**< CPU mip CSR (19): FIRQ3P - Fast interrupt channel 3 pending (r/c) */
311-
CSR_MIP_FIRQ4P = 20, /**< CPU mip CSR (20): FIRQ4P - Fast interrupt channel 4 pending (r/c) */
312-
CSR_MIP_FIRQ5P = 21, /**< CPU mip CSR (21): FIRQ5P - Fast interrupt channel 5 pending (r/c) */
313-
CSR_MIP_FIRQ6P = 22, /**< CPU mip CSR (22): FIRQ6P - Fast interrupt channel 6 pending (r/c) */
314-
CSR_MIP_FIRQ7P = 23, /**< CPU mip CSR (23): FIRQ7P - Fast interrupt channel 7 pending (r/c) */
315-
CSR_MIP_FIRQ8P = 24, /**< CPU mip CSR (24): FIRQ8P - Fast interrupt channel 8 pending (r/c) */
316-
CSR_MIP_FIRQ9P = 25, /**< CPU mip CSR (25): FIRQ9P - Fast interrupt channel 9 pending (r/c) */
317-
CSR_MIP_FIRQ10P = 26, /**< CPU mip CSR (26): FIRQ10P - Fast interrupt channel 10 pending (r/c) */
318-
CSR_MIP_FIRQ11P = 27, /**< CPU mip CSR (27): FIRQ11P - Fast interrupt channel 11 pending (r/c) */
319-
CSR_MIP_FIRQ12P = 28, /**< CPU mip CSR (28): FIRQ12P - Fast interrupt channel 12 pending (r/c) */
320-
CSR_MIP_FIRQ13P = 29, /**< CPU mip CSR (29): FIRQ13P - Fast interrupt channel 13 pending (r/c) */
321-
CSR_MIP_FIRQ14P = 30, /**< CPU mip CSR (30): FIRQ14P - Fast interrupt channel 14 pending (r/c) */
322-
CSR_MIP_FIRQ15P = 31 /**< CPU mip CSR (31): FIRQ15P - Fast interrupt channel 15 pending (r/c) */
307+
CSR_MIP_FIRQ0P = 16, /**< CPU mip CSR (16): FIRQ0P - Fast interrupt channel 0 pending (r/w) */
308+
CSR_MIP_FIRQ1P = 17, /**< CPU mip CSR (17): FIRQ1P - Fast interrupt channel 1 pending (r/w) */
309+
CSR_MIP_FIRQ2P = 18, /**< CPU mip CSR (18): FIRQ2P - Fast interrupt channel 2 pending (r/w) */
310+
CSR_MIP_FIRQ3P = 19, /**< CPU mip CSR (19): FIRQ3P - Fast interrupt channel 3 pending (r/w) */
311+
CSR_MIP_FIRQ4P = 20, /**< CPU mip CSR (20): FIRQ4P - Fast interrupt channel 4 pending (r/w) */
312+
CSR_MIP_FIRQ5P = 21, /**< CPU mip CSR (21): FIRQ5P - Fast interrupt channel 5 pending (r/w) */
313+
CSR_MIP_FIRQ6P = 22, /**< CPU mip CSR (22): FIRQ6P - Fast interrupt channel 6 pending (r/w) */
314+
CSR_MIP_FIRQ7P = 23, /**< CPU mip CSR (23): FIRQ7P - Fast interrupt channel 7 pending (r/w) */
315+
CSR_MIP_FIRQ8P = 24, /**< CPU mip CSR (24): FIRQ8P - Fast interrupt channel 8 pending (r/w) */
316+
CSR_MIP_FIRQ9P = 25, /**< CPU mip CSR (25): FIRQ9P - Fast interrupt channel 9 pending (r/w) */
317+
CSR_MIP_FIRQ10P = 26, /**< CPU mip CSR (26): FIRQ10P - Fast interrupt channel 10 pending (r/w) */
318+
CSR_MIP_FIRQ11P = 27, /**< CPU mip CSR (27): FIRQ11P - Fast interrupt channel 11 pending (r/w) */
319+
CSR_MIP_FIRQ12P = 28, /**< CPU mip CSR (28): FIRQ12P - Fast interrupt channel 12 pending (r/w) */
320+
CSR_MIP_FIRQ13P = 29, /**< CPU mip CSR (29): FIRQ13P - Fast interrupt channel 13 pending (r/w) */
321+
CSR_MIP_FIRQ14P = 30, /**< CPU mip CSR (30): FIRQ14P - Fast interrupt channel 14 pending (r/w) */
322+
CSR_MIP_FIRQ15P = 31 /**< CPU mip CSR (31): FIRQ15P - Fast interrupt channel 15 pending (r/w) */
323323
};
324324

325325

0 commit comments

Comments
 (0)