1. Interrupt line block (irq)
Wbgen2 provides an easy way to multiplex several interrupts from the
peripheral into a single Wishbone wb_irq_o
IRQ request line. Designer
can specify up to 32 interrupt sources per peripheral. Wbgen2 will:
- add the interrupt lines to the Wishbone slave core,
- instantiate an Embedded Interrupt Controller for configuration and
multiplexing of interrupts
1.1. Block-specific attributes
Attribute | Status | Description |
---|---|---|
trigger | mandatory | Trigger condition for the interrupt: can be choosen from: LEVEL_1 (high logic level), LEVEL_0 (low logic level), EDGE_RISING, EDGE_FALLING |
1.2. Embedded Interrupt Controller operation
Embedded interrupt controller is a simple, non-prioritised interrupt controller, very similar to ones used in ARM-based SoC peripherals. It's automatically configured and instantiated inside the generated slave core.
Figure 1.* Embedded Interrupt Controller inside a slave core.
When any of the currently enabled IRQ input lines goes active (either by
setting certain logic level, or by generating a positive/negative edge),
wb_irq_o
output is asserted high to indicate the occurence of the
interrupt to the system-wide interrupt controller, and remains active
until:
-
For edge-triggered interrupts: 1 is written to the bitfield
assigned to the interrupt in
EIC_ISR
register - For level-triggered interrupts: interrupt is cleared by the hardware which caused it (so it drives it's level-active IRQ line to idle level)
User can also perform the following operations:
- Enable/disable the interrupts by writing 1 to respective bitfields
of
EIC_IER
andEIC_IDR
registers. - Check pending interrupt status by reading
EIC_ISR
register: 1 means that certain interrupt is pending. - Check which interrupts are enabled by reading
EIC_IMR
register.
1.3. Interrupt naming convention
Interrupt port names are generated by concatenating following strings:
irq_
, IRQ block prefix and _i
. Therefore, interrupt with prefix
myint
will have an input line named irq_myint_i
.
2. Example
Following code demostrates how to use all possible interrupt triggers:
<code class="C">
irq {
name = "Rising edge IRQ";
description = "Rising-edge triggered IRQ line: interrupt is triggered when logic state on the input changes from 0 to 1";
prefix = "ipe";
trigger = EDGE_RISING;
};
irq {
name = "Falling edge IRQ";
description = "Falling-edge triggered IRQ line: interrupt is triggered when logic state on the input changes from 1 to 0";
prefix = "ine";
trigger = EDGE_FALLING;
};
irq {
name = "Level-0 IRQ";
description = "Hi-level triggered IRQ line: interrupt is active when state of the input is 0. \
Interrupt can be only cleared by changing the input state back to 1.";
prefix = "il0";
trigger = LEVEL_0;
};
irq {
name = "Level-1 IRQ";
description = "Lo-level triggered IRQ line: interrupt is active when state of the input is 1. \
Interrupt can be only cleared by changing the input state back to 0.";
prefix = "il1";
trigger = LEVEL_1;
};
</code>