test: fix broken tests.
[lambdasoc.git] / lambdasoc / test / test_periph_base.py
1 # nmigen: UnusedElaboratable=no
2
3 import unittest
4 from nmigen import *
5 from nmigen.back.pysim import *
6
7 from nmigen_soc.memory import MemoryMap
8
9 from .utils.wishbone import *
10 from ..periph.base import Peripheral, CSRBank, PeripheralBridge
11
12
13 def simulation_test(dut, process):
14 sim = Simulator(dut)
15 sim.add_clock(1e-6)
16 sim.add_sync_process(process)
17 with sim.write_vcd("test.vcd"):
18 sim.run()
19
20
21 class PeripheralTestCase(unittest.TestCase):
22 def test_name(self):
23 class Wrapper(Peripheral):
24 def __init__(self):
25 super().__init__()
26 periph_0 = Wrapper()
27 periph_1 = Peripheral(name="periph_1")
28 self.assertEqual(periph_0.name, "periph_0")
29 self.assertEqual(periph_1.name, "periph_1")
30
31 def test_periph_name_wrong(self):
32 with self.assertRaisesRegex(TypeError,
33 r"Name must be a string, not 2"):
34 periph = Peripheral(name=2)
35
36 def test_set_bus_wrong(self):
37 periph = Peripheral(src_loc_at=0)
38 with self.assertRaisesRegex(TypeError,
39 r"Bus interface must be an instance of wishbone.Interface, not 'foo'"):
40 periph.bus = "foo"
41
42 def test_get_bus_wrong(self):
43 periph = Peripheral(src_loc_at=0)
44 with self.assertRaisesRegex(NotImplementedError,
45 r"Peripheral <.*> does not have a bus interface"):
46 periph.bus
47
48 def test_set_irq_wrong(self):
49 periph = Peripheral(src_loc_at=0)
50 with self.assertRaisesRegex(TypeError,
51 r"IRQ line must be an instance of IRQLine, not 'foo'"):
52 periph.irq = "foo"
53
54 def test_get_irq_wrong(self):
55 periph = Peripheral(src_loc_at=0)
56 with self.assertRaisesRegex(NotImplementedError,
57 r"Peripheral <.*> does not have an IRQ line"):
58 periph.irq
59
60 def test_iter_csr_banks(self):
61 periph = Peripheral(src_loc_at=0)
62 bank_0 = periph.csr_bank()
63 bank_1 = periph.csr_bank(addr=0x4, alignment=2)
64 self.assertEqual(list(periph.iter_csr_banks()), [
65 (bank_0, None, None),
66 (bank_1, 0x4, 2),
67 ])
68
69 def test_iter_windows(self):
70 periph = Peripheral(src_loc_at=0)
71 win_0 = periph.window(addr_width=2, data_width=8)
72 win_1 = periph.window(addr_width=4, data_width=8, addr=0x4, sparse=True)
73 self.assertEqual(list(periph.iter_windows()), [
74 (win_0, None, None),
75 (win_1, 0x4, True),
76 ])
77
78 def test_iter_events(self):
79 periph = Peripheral(src_loc_at=0)
80 ev_0 = periph.event()
81 ev_1 = periph.event(mode="rise")
82 self.assertEqual((ev_0.name, ev_0.mode), ("ev_0", "level"))
83 self.assertEqual((ev_1.name, ev_1.mode), ("ev_1", "rise"))
84 self.assertEqual(list(periph.iter_events()), [
85 ev_0,
86 ev_1,
87 ])
88
89
90 class CSRBankTestCase(unittest.TestCase):
91 def test_bank_name(self):
92 bank = CSRBank(name="foo")
93 self.assertEqual(bank.name, "foo")
94
95 def test_bank_name_wrong(self):
96 with self.assertRaisesRegex(TypeError,
97 r"Name must be a string, not 2"):
98 bank = CSRBank(name=2)
99
100 def test_csr_name_wrong(self):
101 bank = CSRBank()
102 with self.assertRaisesRegex(TypeError,
103 r"Name must be a string, not 2"):
104 bank.csr(1, "r", name=2)
105
106 def test_iter_csr_regs(self):
107 bank = CSRBank()
108 csr_0 = bank.csr(1, "r")
109 csr_1 = bank.csr(8, "rw", addr=0x4, alignment=2)
110 self.assertEqual(list(bank.iter_csr_regs()), [
111 (csr_0, None, None),
112 (csr_1, 0x4, 2),
113 ])
114
115
116 class PeripheralBridgeTestCase(unittest.TestCase):
117 def test_periph_wrong(self):
118 with self.assertRaisesRegex(TypeError,
119 r"Peripheral must be an instance of Peripheral, not 'foo'"):
120 PeripheralBridge('foo', data_width=8, granularity=8, features=(), alignment=0)
121
122
123 class PeripheralSimulationTestCase(unittest.TestCase):
124 def test_csrs(self):
125 class DummyPeripheral(Peripheral, Elaboratable):
126 def __init__(self):
127 super().__init__()
128 bank = self.csr_bank(addr=0x100)
129 self._csr_0 = bank.csr(8, "r")
130 self._csr_1 = bank.csr(8, "r", addr=0x8, alignment=4)
131 self._csr_2 = bank.csr(8, "rw")
132
133 self.win_0 = self.window(addr_width=1, data_width=8, sparse=True, addr=0x000)
134 self.win_1 = self.window(addr_width=1, data_width=32, granularity=8, addr=0x200)
135 self.win_0.memory_map = MemoryMap(addr_width=1, data_width=8)
136 self.win_1.memory_map = MemoryMap(addr_width=3, data_width=8)
137
138 self._bridge = self.bridge(data_width=32, granularity=8, alignment=2)
139 self.bus = self._bridge.bus
140
141 def elaborate(self, platform):
142 m = Module()
143 m.submodules.bridge = self._bridge
144 m.d.comb += [
145 self._csr_0.r_data.eq(0xa),
146 self._csr_1.r_data.eq(0xb),
147 ]
148 with m.If(self._csr_2.w_stb):
149 m.d.sync += self._csr_2.r_data.eq(self._csr_2.w_data)
150 return m
151
152 dut = DummyPeripheral()
153
154 def process():
155 self.assertEqual((yield from wb_read(dut.bus, addr=0x100 >> 2, sel=0xf)), 0xa)
156 yield
157 self.assertEqual((yield from wb_read(dut.bus, addr=0x108 >> 2, sel=0xf)), 0xb)
158 yield
159 yield from wb_write(dut.bus, addr=0x118 >> 2, data=0xc, sel=0xf)
160 yield
161 self.assertEqual((yield from wb_read(dut.bus, addr=0x118 >> 2, sel=0xf)), 0xc)
162 yield
163
164 yield dut.bus.cyc.eq(1)
165 yield dut.bus.adr.eq(0x000 >> 2)
166 yield Delay(1e-7)
167 self.assertEqual((yield dut.win_0.cyc), 1)
168
169 yield dut.bus.adr.eq(0x200 >> 2)
170 yield Delay(1e-7)
171 self.assertEqual((yield dut.win_1.cyc), 1)
172
173 simulation_test(dut, process)
174
175 def test_events(self):
176 class DummyPeripheral(Peripheral, Elaboratable):
177 def __init__(self):
178 super().__init__()
179 self.ev_0 = self.event()
180 self.ev_1 = self.event(mode="rise")
181 self.ev_2 = self.event(mode="fall")
182 self._bridge = self.bridge(data_width=8)
183 self.bus = self._bridge.bus
184 self.irq = self._bridge.irq
185
186 def elaborate(self, platform):
187 m = Module()
188 m.submodules.bridge = self._bridge
189 return m
190
191 dut = DummyPeripheral()
192
193 ev_status_addr = 0x0
194 ev_pending_addr = 0x1
195 ev_enable_addr = 0x2
196
197 def process():
198 yield dut.ev_0.stb.eq(1)
199 yield dut.ev_1.stb.eq(0)
200 yield dut.ev_2.stb.eq(1)
201 yield
202 self.assertEqual((yield dut.irq), 0)
203 self.assertEqual((yield from wb_read(dut.bus, ev_status_addr, sel=0xf)), 0b101)
204 yield
205
206 yield from wb_write(dut.bus, ev_enable_addr, data=0b111, sel=0xf)
207 yield
208 self.assertEqual((yield dut.irq), 1)
209
210 yield from wb_write(dut.bus, ev_pending_addr, data=0b001, sel=0xf)
211 yield
212 self.assertEqual((yield from wb_read(dut.bus, ev_pending_addr, sel=0xf)), 0b001)
213 yield
214 self.assertEqual((yield dut.irq), 1)
215 yield dut.ev_0.stb.eq(0)
216 yield from wb_write(dut.bus, ev_pending_addr, data=0b001, sel=0xf)
217 yield
218 self.assertEqual((yield dut.irq), 0)
219
220 yield dut.ev_1.stb.eq(1)
221 yield
222 self.assertEqual((yield from wb_read(dut.bus, ev_pending_addr, sel=0xf)), 0b010)
223 yield
224 self.assertEqual((yield dut.irq), 1)
225 yield from wb_write(dut.bus, ev_pending_addr, data=0b010, sel=0xf)
226 yield
227 self.assertEqual((yield dut.irq), 0)
228
229 yield dut.ev_2.stb.eq(0)
230 yield
231 self.assertEqual((yield from wb_read(dut.bus, ev_pending_addr, sel=0xf)), 0b100)
232 yield
233 self.assertEqual((yield dut.irq), 1)
234 yield from wb_write(dut.bus, ev_pending_addr, data=0b100, sel=0xf)
235 yield
236 self.assertEqual((yield dut.irq), 0)
237
238 simulation_test(dut, process)