periph.intc: add GenericInterruptController
[lambdasoc.git] / lambdasoc / test / test_periph_intc.py
1 #nmigen: UnusedElaboratable=no
2
3 import unittest
4
5 from nmigen import *
6 from nmigen.back.pysim import *
7
8 from ..periph import IRQLine
9 from ..periph.intc import *
10
11
12 class InterruptControllerTestCase(unittest.TestCase):
13 def test_add_irq_wrong_line(self):
14 intc = InterruptController()
15 with self.assertRaisesRegex(TypeError,
16 r"IRQ line must be an instance of IRQLine, not 'foo'"):
17 intc.add_irq("foo", 0)
18
19 def test_add_irq_wrong_index(self):
20 intc = InterruptController()
21 with self.assertRaisesRegex(ValueError,
22 r"IRQ index must be a non-negative integer, not 'bar'"):
23 intc.add_irq(IRQLine(name="foo"), "bar")
24 with self.assertRaisesRegex(ValueError,
25 r"IRQ index must be a non-negative integer, not -1"):
26 intc.add_irq(IRQLine(name="foo"), -1)
27
28 def test_add_irq_line_twice(self):
29 intc = InterruptController()
30 line = IRQLine()
31 with self.assertRaisesRegex(ValueError,
32 r"IRQ line \(sig line\) has already been mapped to IRQ index 0"):
33 intc.add_irq(line, 0)
34 intc.add_irq(line, 1)
35
36 def test_add_irq_index_twice(self):
37 intc = InterruptController()
38 line_0 = IRQLine()
39 line_1 = IRQLine()
40 with self.assertRaisesRegex(ValueError,
41 r"IRQ index 0 has already been mapped to IRQ line \(sig line_0\)"):
42 intc.add_irq(line_0, 0)
43 intc.add_irq(line_1, 0)
44
45 def test_iter_irqs(self):
46 intc = InterruptController()
47 line_0 = IRQLine()
48 line_1 = IRQLine()
49 intc.add_irq(line_0, 0)
50 intc.add_irq(line_1, 1)
51 self.assertEqual(list(intc.iter_irqs()), [
52 (0, line_0),
53 (1, line_1),
54 ])
55
56 def test_find_index(self):
57 intc = InterruptController()
58 line_0 = IRQLine()
59 line_1 = IRQLine()
60 intc.add_irq(line_0, 0)
61 intc.add_irq(line_1, 1)
62 self.assertEqual(intc.find_index(line_0), 0)
63 self.assertEqual(intc.find_index(line_1), 1)
64
65 def test_find_index_absent(self):
66 intc = InterruptController()
67 line = IRQLine()
68 with self.assertRaises(KeyError):
69 intc.find_index(line)
70
71
72 class GenericInterruptControllerTestCase(unittest.TestCase):
73 def test_wrong_width(self):
74 with self.assertRaisesRegex(ValueError,
75 r"Width must be a strictly positive integer, not 'foo'"):
76 intc = GenericInterruptController(width="foo")
77 with self.assertRaisesRegex(ValueError,
78 r"Width must be a strictly positive integer, not 0"):
79 intc = GenericInterruptController(width=0)
80
81 def test_add_irq_wrong_index(self):
82 intc = GenericInterruptController(width=8)
83 line = IRQLine()
84 with self.assertRaisesRegex(ValueError,
85 r"IRQ index must be an integer ranging from 0 to 7, not 8"):
86 intc.add_irq(line, 8)
87
88 def test_passthrough(self):
89 dut = GenericInterruptController(width=8)
90 line_0 = IRQLine()
91 line_1 = IRQLine()
92 dut.add_irq(line_0, 0)
93 dut.add_irq(line_1, 1)
94
95 def process():
96 self.assertEqual((yield dut.ip), 0b00)
97
98 yield line_0.eq(1)
99 yield Delay(1e-6)
100 self.assertEqual((yield dut.ip), 0b01)
101
102 yield line_1.eq(1)
103 yield Delay(1e-6)
104 self.assertEqual((yield dut.ip), 0b11)
105
106 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
107 sim.add_process(process)
108 sim.run()