OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_xirq.adoc] - Blame information for rev 64

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 61 zero_gravi
<<<
2
:sectnums:
3
==== External Interrupt Controller (XIRQ)
4
 
5
[cols="<3,<3,<4"]
6
[frame="topbot",grid="none"]
7
|=======================
8
| Hardware source file(s): | neorv32_xirq.vhd |
9
| Software driver file(s): | neorv32_xirq.c |
10
|                          | neorv32_xirq.h |
11
| Top entity port:         | `xirq_i` | IRQ input (up to 32-bit)
12
| Configuration generics:  | _XIRQ_NUM_CH_           | Number of IRQs to implement (0..32)
13
|                          | _XIRQ_TRIGGER_TYPE_     | IRQ trigger type configuration
14
|                          | _XIRQ_TRIGGER_POLARITY_ | IRQ trigger polarity configuration
15
| CPU interrupts:          | fast IRQ channel 8 | XIRQ (see <<_processor_interrupts>>)
16
|=======================
17
 
18
The eXternal interrupt controller provides a simple mechanism to implement up to 32 processor-external interrupt
19
request signals. The external IRQ requests are prioritized, queued and signaled to the CPU via a
20
single _CPU fast interrupt request_.
21
 
22
**Theory of Operation**
23
 
24 64 zero_gravi
The XIRQ provides up to 32 interrupt _channels_ (configured via the _XIRQ_NUM_CH_ generic). Each bit in the `xirq_i`
25
input signal vector represents one interrupt channel. An interrupt channel is enabled by setting the according bit in the
26
interrupt enable register `IER`.
27 61 zero_gravi
 
28
If the configured trigger (see below) of an enabled channel fires, the request is stored into an internal buffer.
29 64 zero_gravi
This buffer is available via the interrupt pending register `IPR`. A `1` in this register indicates that the
30
corresponding interrupt channel has fired but has not yet been serviced (so it is pending). An interrupt channel can
31
become pending if the according `IER` bit is set. Pending IRQs can be cleared by writing `0` to the according `IPR`
32
bit. As soon as there is a least one pending interrupt in the buffer, an interrupt request is send to the CPU.
33 61 zero_gravi
 
34 64 zero_gravi
[NOTE]
35
A disabled interrupt channel can still be pending if it has been triggered before clearing the according `IER` bit.
36
 
37
The CPU can determine firing interrupt request either by checking the bits in the `IPR` register, which show all
38
pending interrupt channels, or by reading the interrupt source register `SCR`.
39 61 zero_gravi
This register provides a 5-bit wide ID (0..31) that shows the interrupt request with _highest priority_.
40
Interrupt channel `xirq_i(0)` has highest priority and `xirq_i(_XIRQ_NUM_CH_-1)` has lowest priority.
41
This priority assignment is fixed and cannot be altered by software.
42 64 zero_gravi
The CPU can use the ID from `SCR` to service IRQ according to their priority. To acknowledge the according
43
interrupt the CPU can write `1 << SCR` to `IPR`.
44 61 zero_gravi
 
45 64 zero_gravi
In order to acknowledge the interrupt from the external interrupt controller, the CPU has to write _any_
46
value to interrupt source register `SRC`.
47
 
48
[NOTE]
49
An interrupt handler should clear the interrupt pending bit that caused the interrupt first before
50
acknowledging the interrupt by writing the `SCR` register.
51
 
52 61 zero_gravi
**IRQ Trigger Configuration**
53
 
54
The controller does not provide a configuration option to define the IRQ triggers _during runtime_. Instead, two
55
generics are provided to configure the trigger of each interrupt channel before synthesis: the _XIRQ_TRIGGER_TYPE_
56
and _XIRQ_TRIGGER_POLARITY_ generic. Both generics are 32 bit wide representing one bit per interrupt channel. If
57
less than 32 interrupt channels are implemented the remaining configuration bits are ignored.
58
 
59 64 zero_gravi
_XIRQ_TRIGGER_TYPE_ is used to define the general trigger type. This can be either _level-triggered_ (`0`) or
60 61 zero_gravi
_edge-triggered_ (`1`). _XIRQ_TRIGGER_POLARITY_ is used to configure the polarity of the trigger: a `0` defines
61 64 zero_gravi
low-level or falling-edge and a `1` defines high-level or rising-edge.
62 61 zero_gravi
 
63
.Example trigger configuration: channel 0 for rising-edge, IRQ channels 1 to 31 for high-level
64
[source, vhdl]
65
----
66
XIRQ_TRIGGER_TYPE     => x"00000001";
67
XIRQ_TRIGGER_POLARITY => x"ffffffff";
68
----
69
 
70 64 zero_gravi
.XIRQ register map (`struct NEORV32_XIRQ`)
71 61 zero_gravi
[cols="^4,<5,^2,^2,<14"]
72
[options="header",grid="all"]
73
|=======================
74
| Address | Name [C] | Bit(s) | R/W | Function
75 64 zero_gravi
| `0xffffff80` | `NEORV32_XIRQ.IER` | `31:0` | r/w | Interrupt enable register (one bit per channel, LSB-aligned)
76
| `0xffffff84` | `NEORV32_XIRQ.IPR` | `31:0` | r/w | Interrupt pending register (one bit per channel, LSB-aligned); writing 0 to a bit clears according pending interrupt
77
| `0xffffff88` | `NEORV32_XIRQ.SCR` |  `4:0` | r/w | Channel id (0..31) of firing IRQ (prioritized!); writing _any_ value will acknowledge the current interrupt
78
| `0xffffff8c` | -                  | `31:0` | r/- | _reserved_, read as zero
79 61 zero_gravi
|=======================

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.