Ex. 5: Hierarchical buses and cascaded interrupts
Group:
{% include ‘group.md’ %}
1. Questions
1. of 2: How big (in kB) is the address range for each of the 16 TL-UL devices inside your student module ?
The student_device_peri is in the address range 0x10000000 to 0x10FFFFFF.
Therefore, 24 bits are available for addressing.
Splitting that into 16 equal parts, we have 4 bits of device number and 20 bits left for the device address.
This equates to 2^21 = 2048 KiB of address space per device.
It should be mentioned that in the default testbench configuration, this would be 4 bits and therefore 2^5 = 16 Bytes of address space per device.
2. of 2: Which address bits did your 1:N bus multiplexer decode ?
Of the full 32 bit address, the first 8 bits are the area our mux covers, the next 4 bits are the device address to be decoded, and the last 20 bits are for device internal addressing. The Mux therefore decodes the bits [23:20].
3. of 6: How many cycles pass after one of the outermost gray LEDs light up until the application writes to the mode register ?
During that time, 3560ns or 178 cycles pass.
4. of 6: Which problems occur in the specified implementation when the change frequency of the running light is too high ? How would a more robust (maybe even elegant?) solution would look like ? Of course the running light itself may be modified as well.
When the running light is set too fast, the interrupt routine is too slow to change the direction in time before the outermost LED is lit. The screenshot below shows that preparing for the actual interrupt routine (saving all registers to the stack) adds quite a big reaction delay. After that, the 4 register/TL transactions to the rlight to change the mode (shown at the second cursor) add an additional delay.

Possible solutions include:
Writing an optimised assembly irq function could increase the performance on the software side. Maybe even a custom IRQ handler that doesn’t require saving all registers.
Adding addional functionality to the
rlightmodule to support a ping pong animation within a given mask, would be the most performant and a more elegant solution.Lowering the amount of rergister/TL transactions required to change the direction of the
rlightwithin the irq handler would also improve the maximum speed.
Once one would get into the speeds that would cause irqs to be triggered during an execution of a previous irq, one would also need to think about ways to handle that. Even though the current irq implementation is a bit slower than the software polling method, both are well suited for a simple running light.
5. Adding IRQ support to the memcpy bus master. How would the IRQ signal be generated ? Which basic steps would the IRQ handler perform ?
The IRQ should be fired once the memcpy is completed, so the signal would be determinated by comparing the number of open writes to the memory area to 0. A handler might then provide a callback to the software for proceeding to work with the generated copy, such that the software does not need to run idly while awaiting the memcpy to complete.
2. Source texts
See appendix
2.2 IRQ-Ctrl register interface
student_irq_ctrl.en_all @ + 0x0 0 = suppresses all outgoing interrupt requests Reset default = 0x0, mask 0x1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 0 | rw | 0x0 | irq_enable | 0 = suppresses all outgoing interrupt requests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.mask @ + 0x4 Mask register for enabling and disabling specific interrupts Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | rw | 0x0 | irq_mask | mask(n) = 1 <=> irq(n) enabled | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.mask_set @ + 0x8 Shadowed Mask register for only enabling specific interrupts Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | wo | 0x0 | irq_mask_set | mask(n) = 1 <=> set bit n in 'Interrupt Mask Register' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.mask_clr @ + 0xc Shadowed Mask register for only disabling/clearing specific interrupts Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | wo | 0x0 | irq_mask_clr | mask(n) = 1 <=> clear bit n in 'Interrupt Mask Register' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.status @ + 0x10 Register that holds information about which interrupt is asserted Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | ro | 0x0 | irq_status | status(n) = 1 <=> irq(n) is asserted | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.irq_no @ + 0x14 Register that holds the number Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | ro | 0x0 | irq_lowest | if n < IRQ_MAX: lowest irq number that is asserted; if n == IRQ_MAX: no pending IRQ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.test @ + 0x18 Enable test register functionality Reset default = 0x0, mask 0x1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 0 | rw | 0x0 | irq_test_enable | 0: Regular operation; 1: all irq inputs are wired to the test_irq register | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_irq_ctrl.test_irq @ + 0x1c set IRQ input lines if in test mode Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | rw | 0x0 | irq_test_mask | see 'Test IRQ Enable Register' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2.6 Updated interrupt controlled running light register interface
student_rlight.status @ + 0x0 Status Reset default = 0x0, mask 0xff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 7:0 | ro | 0x0 | pattern | Bits of currently displayed LED pattern | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_rlight.mode @ + 0x4 LED animation mode Reset default = 0x3, mask 0x3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1:0 | rw | 0x3 | val | 0 = stop, 1 = right-to-left, 2 = left-to-right, 3 = ping-pong | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_rlight.speed @ + 0x8 Speed register for LED animation Reset default = 0x0, mask 0xffffffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31:0 | rw | 0x0 | divisor | Divisor of the clock used for animation updates | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_rlight.pattern @ + 0xc Current write address Reset default = 0x0, mask 0xff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 7:0 | rw | 0x0 | pattern | Bits of initial LED pattern | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_rlight.masks @ + 0x10 Masks to trigger IRQ when the displayed pattern intersects them Reset default = 0x0, mask 0xffff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 7:0 | rw | 0x0 | mask 0 | Mask that triggers interrupt 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 15:8 | rw | 0x0 | mask 1 | Mask that triggers interrupt 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
student_rlight.interrupt_status @ + 0x14 Indicates whether interrupts are active. Read to acknowledge interrupts Reset default = 0x0, mask 0x3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bits | Type | Reset | Name | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 0 | ro | 0x0 | interrupt 0 | IRQ triggered by mask 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | ro | 0x0 | interrupt 1 | IRQ triggered by mask 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3. Wave Views
In the following screenshot, the desired signals are displayed in yellow and the start/end trigger signals (led_o[6], mode.qe) are displayed in magenta. The cursors mark the relevant rising edges.

{% include ‘appendix.md’ %}