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

Subversion Repositories neorv32

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

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 70 zero_gravi
| Top entity port:         | `xirq_i` | IRQ input (32-bit, fixed)
12 61 zero_gravi
| 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 70 zero_gravi
input signal vector represents one interrupt channel. If less than 32 channels are configure, only the LSB-aligned channels
26
are used while the remaining bits are left unconnected. An interrupt channel is enabled by setting the according bit in the
27 64 zero_gravi
interrupt enable register `IER`.
28 61 zero_gravi
 
29
If the configured trigger (see below) of an enabled channel fires, the request is stored into an internal buffer.
30 64 zero_gravi
This buffer is available via the interrupt pending register `IPR`. A `1` in this register indicates that the
31
corresponding interrupt channel has fired but has not yet been serviced (so it is pending). An interrupt channel can
32
become pending if the according `IER` bit is set. Pending IRQs can be cleared by writing `0` to the according `IPR`
33
bit. As soon as there is a least one pending interrupt in the buffer, an interrupt request is send to the CPU.
34 61 zero_gravi
 
35 64 zero_gravi
[NOTE]
36
A disabled interrupt channel can still be pending if it has been triggered before clearing the according `IER` bit.
37
 
38 65 zero_gravi
The CPU can determine active external interrupt request either by checking the bits in the `IPR` register, which show all
39 64 zero_gravi
pending interrupt channels, or by reading the interrupt source register `SCR`.
40 61 zero_gravi
This register provides a 5-bit wide ID (0..31) that shows the interrupt request with _highest priority_.
41
Interrupt channel `xirq_i(0)` has highest priority and `xirq_i(_XIRQ_NUM_CH_-1)` has lowest priority.
42
This priority assignment is fixed and cannot be altered by software.
43 64 zero_gravi
The CPU can use the ID from `SCR` to service IRQ according to their priority. To acknowledge the according
44
interrupt the CPU can write `1 << SCR` to `IPR`.
45 61 zero_gravi
 
46 73 zero_gravi
In order to clear a pending FIRQ interrupt from the external interrupt controller again, the according <<_mip>> CSR bit has
47
to be cleared. Additionally, the XIRQ interrupt has to be acknowledged by writing _any_
48 65 zero_gravi
value to the interrupt source register `SRC`.
49 64 zero_gravi
 
50
[NOTE]
51
An interrupt handler should clear the interrupt pending bit that caused the interrupt first before
52
acknowledging the interrupt by writing the `SCR` register.
53
 
54 61 zero_gravi
**IRQ Trigger Configuration**
55
 
56
The controller does not provide a configuration option to define the IRQ triggers _during runtime_. Instead, two
57
generics are provided to configure the trigger of each interrupt channel before synthesis: the _XIRQ_TRIGGER_TYPE_
58
and _XIRQ_TRIGGER_POLARITY_ generic. Both generics are 32 bit wide representing one bit per interrupt channel. If
59
less than 32 interrupt channels are implemented the remaining configuration bits are ignored.
60
 
61 64 zero_gravi
_XIRQ_TRIGGER_TYPE_ is used to define the general trigger type. This can be either _level-triggered_ (`0`) or
62 61 zero_gravi
_edge-triggered_ (`1`). _XIRQ_TRIGGER_POLARITY_ is used to configure the polarity of the trigger: a `0` defines
63 64 zero_gravi
low-level or falling-edge and a `1` defines high-level or rising-edge.
64 61 zero_gravi
 
65
.Example trigger configuration: channel 0 for rising-edge, IRQ channels 1 to 31 for high-level
66
[source, vhdl]
67
----
68
XIRQ_TRIGGER_TYPE     => x"00000001";
69
XIRQ_TRIGGER_POLARITY => x"ffffffff";
70
----
71
 
72 64 zero_gravi
.XIRQ register map (`struct NEORV32_XIRQ`)
73 61 zero_gravi
[cols="^4,<5,^2,^2,<14"]
74
[options="header",grid="all"]
75
|=======================
76
| Address | Name [C] | Bit(s) | R/W | Function
77 64 zero_gravi
| `0xffffff80` | `NEORV32_XIRQ.IER` | `31:0` | r/w | Interrupt enable register (one bit per channel, LSB-aligned)
78
| `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
79
| `0xffffff88` | `NEORV32_XIRQ.SCR` |  `4:0` | r/w | Channel id (0..31) of firing IRQ (prioritized!); writing _any_ value will acknowledge the current interrupt
80
| `0xffffff8c` | -                  | `31:0` | r/- | _reserved_, read as zero
81 61 zero_gravi
|=======================

powered by: WebSVN 2.1.0

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