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.

Too fast rlight

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 rlight module 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 rlight within 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
31302928272625242322212019181716
 
1514131211109876543210
  irq_enable
BitsTypeResetNameDescription
0rw0x0irq_enable0 = suppresses all outgoing interrupt requests


student_irq_ctrl.mask @ + 0x4
Mask register for enabling and disabling specific interrupts
Reset default = 0x0, mask 0xffffffff
31302928272625242322212019181716
irq_mask...
1514131211109876543210
...irq_mask
BitsTypeResetNameDescription
31:0rw0x0irq_maskmask(n) = 1 <=> irq(n) enabled


student_irq_ctrl.mask_set @ + 0x8
Shadowed Mask register for only enabling specific interrupts
Reset default = 0x0, mask 0xffffffff
31302928272625242322212019181716
irq_mask_set...
1514131211109876543210
...irq_mask_set
BitsTypeResetNameDescription
31:0wo0x0irq_mask_setmask(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
31302928272625242322212019181716
irq_mask_clr...
1514131211109876543210
...irq_mask_clr
BitsTypeResetNameDescription
31:0wo0x0irq_mask_clrmask(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
31302928272625242322212019181716
irq_status...
1514131211109876543210
...irq_status
BitsTypeResetNameDescription
31:0ro0x0irq_statusstatus(n) = 1 <=> irq(n) is asserted


student_irq_ctrl.irq_no @ + 0x14
Register that holds the number
Reset default = 0x0, mask 0xffffffff
31302928272625242322212019181716
irq_lowest...
1514131211109876543210
...irq_lowest
BitsTypeResetNameDescription
31:0ro0x0irq_lowestif 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
31302928272625242322212019181716
 
1514131211109876543210
  irq_test_enable
BitsTypeResetNameDescription
0rw0x0irq_test_enable0: 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
31302928272625242322212019181716
irq_test_mask...
1514131211109876543210
...irq_test_mask
BitsTypeResetNameDescription
31:0rw0x0irq_test_masksee 'Test IRQ Enable Register'


2.6 Updated interrupt controlled running light register interface

student_rlight.status @ + 0x0
Status
Reset default = 0x0, mask 0xff
31302928272625242322212019181716
 
1514131211109876543210
  pattern
BitsTypeResetNameDescription
7:0ro0x0patternBits of currently displayed LED pattern


student_rlight.mode @ + 0x4
LED animation mode
Reset default = 0x3, mask 0x3
31302928272625242322212019181716
 
1514131211109876543210
  val
BitsTypeResetNameDescription
1:0rw0x3val0 = 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
31302928272625242322212019181716
divisor...
1514131211109876543210
...divisor
BitsTypeResetNameDescription
31:0rw0x0divisorDivisor of the clock used for animation updates


student_rlight.pattern @ + 0xc
Current write address
Reset default = 0x0, mask 0xff
31302928272625242322212019181716
 
1514131211109876543210
  pattern
BitsTypeResetNameDescription
7:0rw0x0patternBits of initial LED pattern


student_rlight.masks @ + 0x10
Masks to trigger IRQ when the displayed pattern intersects them
Reset default = 0x0, mask 0xffff
31302928272625242322212019181716
 
1514131211109876543210
mask 1 mask 0
BitsTypeResetNameDescription
7:0rw0x0mask 0Mask that triggers interrupt 0
15:8rw0x0mask 1Mask that triggers interrupt 1


student_rlight.interrupt_status @ + 0x14
Indicates whether interrupts are active. Read to acknowledge interrupts
Reset default = 0x0, mask 0x3
31302928272625242322212019181716
 
1514131211109876543210
  interrupt 1 interrupt 0
BitsTypeResetNameDescription
0ro0x0interrupt 0IRQ triggered by mask 0
1ro0x0interrupt 1IRQ 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.

Wave View of rlight IRQ

{% include ‘appendix.md’ %}