1 # nmigen: UnusedElaboratable=no
5 from nmigen
.back
.pysim
import *
7 from ._wishbone
import *
8 from ..periph
.base
import Peripheral
, CSRBank
, PeripheralBridge
11 def simulation_test(dut
, process
):
14 sim
.add_sync_process(process
)
15 with sim
.write_vcd("test.vcd"):
19 class PeripheralTestCase(unittest
.TestCase
):
21 class Wrapper(Peripheral
):
25 periph_1
= Peripheral(name
="periph_1")
26 self
.assertEqual(periph_0
.name
, "periph_0")
27 self
.assertEqual(periph_1
.name
, "periph_1")
29 def test_periph_name_wrong(self
):
30 with self
.assertRaisesRegex(TypeError,
31 r
"Name must be a string, not 2"):
32 periph
= Peripheral(name
=2)
34 def test_set_bus_wrong(self
):
35 periph
= Peripheral(src_loc_at
=0)
36 with self
.assertRaisesRegex(TypeError,
37 r
"Bus interface must be an instance of wishbone.Interface, not 'foo'"):
40 def test_get_bus_wrong(self
):
41 periph
= Peripheral(src_loc_at
=0)
42 with self
.assertRaisesRegex(NotImplementedError,
43 r
"Peripheral <.*> does not have a bus interface"):
46 def test_set_irq_wrong(self
):
47 periph
= Peripheral(src_loc_at
=0)
48 with self
.assertRaisesRegex(TypeError,
49 r
"IRQ line must be an instance of IRQLine, not 'foo'"):
52 def test_get_irq_wrong(self
):
53 periph
= Peripheral(src_loc_at
=0)
54 with self
.assertRaisesRegex(NotImplementedError,
55 r
"Peripheral <.*> does not have an IRQ line"):
58 def test_iter_csr_banks(self
):
59 periph
= Peripheral(src_loc_at
=0)
60 bank_0
= periph
.csr_bank()
61 bank_1
= periph
.csr_bank(addr
=0x4, alignment
=2)
62 self
.assertEqual(list(periph
.iter_csr_banks()), [
67 def test_iter_windows(self
):
68 periph
= Peripheral(src_loc_at
=0)
69 win_0
= periph
.window(addr_width
=2, data_width
=8)
70 win_1
= periph
.window(addr_width
=4, data_width
=8, addr
=0x4, sparse
=True)
71 self
.assertEqual(list(periph
.iter_windows()), [
76 def test_iter_events(self
):
77 periph
= Peripheral(src_loc_at
=0)
79 ev_1
= periph
.event(mode
="rise")
80 self
.assertEqual((ev_0
.name
, ev_0
.mode
), ("ev_0", "level"))
81 self
.assertEqual((ev_1
.name
, ev_1
.mode
), ("ev_1", "rise"))
82 self
.assertEqual(list(periph
.iter_events()), [
88 class CSRBankTestCase(unittest
.TestCase
):
89 def test_csr_name(self
):
90 bank
= CSRBank(name_prefix
="foo")
91 bar
= bank
.csr(1, "r")
92 self
.assertEqual(bar
.name
, "foo_bar")
94 def test_csr_name_wrong(self
):
96 with self
.assertRaisesRegex(TypeError,
97 r
"Name must be a string, not 2"):
98 bank
.csr(1, "r", name
=2)
100 def test_iter_csr_regs(self
):
102 csr_0
= bank
.csr(1, "r")
103 csr_1
= bank
.csr(8, "rw", addr
=0x4, alignment
=2)
104 self
.assertEqual(list(bank
.iter_csr_regs()), [
110 class PeripheralBridgeTestCase(unittest
.TestCase
):
111 def test_periph_wrong(self
):
112 with self
.assertRaisesRegex(TypeError,
113 r
"Peripheral must be an instance of Peripheral, not 'foo'"):
114 PeripheralBridge('foo', data_width
=8, granularity
=8, features
=(), alignment
=0)
117 class PeripheralSimulationTestCase(unittest
.TestCase
):
119 class DummyPeripheral(Peripheral
, Elaboratable
):
122 bank
= self
.csr_bank(addr
=0x100)
123 self
._csr
_0 = bank
.csr(8, "r")
124 self
._csr
_1 = bank
.csr(8, "r", addr
=0x8, alignment
=4)
125 self
._csr
_2 = bank
.csr(8, "rw")
127 self
.win_0
= self
.window(addr_width
=1, data_width
=8, sparse
=True, addr
=0x000)
128 self
.win_1
= self
.window(addr_width
=1, data_width
=32, granularity
=8, addr
=0x200)
130 self
._bridge
= self
.bridge(data_width
=32, granularity
=8, alignment
=2)
131 self
.bus
= self
._bridge
.bus
133 def elaborate(self
, platform
):
135 m
.submodules
.bridge
= self
._bridge
137 self
._csr
_0.r_data
.eq(0xa),
138 self
._csr
_1.r_data
.eq(0xb),
140 with m
.If(self
._csr
_2.w_stb
):
141 m
.d
.sync
+= self
._csr
_2.r_data
.eq(self
._csr
_2.w_data
)
144 dut
= DummyPeripheral()
147 self
.assertEqual((yield from wb_read(dut
.bus
, addr
=0x100 >> 2, sel
=0xf)), 0xa)
149 self
.assertEqual((yield from wb_read(dut
.bus
, addr
=0x108 >> 2, sel
=0xf)), 0xb)
151 yield from wb_write(dut
.bus
, addr
=0x118 >> 2, data
=0xc, sel
=0xf)
153 self
.assertEqual((yield from wb_read(dut
.bus
, addr
=0x118 >> 2, sel
=0xf)), 0xc)
156 yield dut
.bus
.cyc
.eq(1)
157 yield dut
.bus
.adr
.eq(0x000 >> 2)
159 self
.assertEqual((yield dut
.win_0
.cyc
), 1)
161 yield dut
.bus
.adr
.eq(0x200 >> 2)
163 self
.assertEqual((yield dut
.win_1
.cyc
), 1)
165 simulation_test(dut
, process
)
167 def test_events(self
):
168 class DummyPeripheral(Peripheral
, Elaboratable
):
171 self
.ev_0
= self
.event()
172 self
.ev_1
= self
.event(mode
="rise")
173 self
.ev_2
= self
.event(mode
="fall")
174 self
._bridge
= self
.bridge(data_width
=8)
175 self
.bus
= self
._bridge
.bus
176 self
.irq
= self
._bridge
.irq
178 def elaborate(self
, platform
):
180 m
.submodules
.bridge
= self
._bridge
183 dut
= DummyPeripheral()
186 ev_pending_addr
= 0x1
190 yield dut
.ev_0
.stb
.eq(1)
191 yield dut
.ev_1
.stb
.eq(0)
192 yield dut
.ev_2
.stb
.eq(1)
194 self
.assertEqual((yield dut
.irq
), 0)
195 self
.assertEqual((yield from wb_read(dut
.bus
, ev_status_addr
, sel
=0xf)), 0b101)
198 yield from wb_write(dut
.bus
, ev_enable_addr
, data
=0b111, sel
=0xf)
200 self
.assertEqual((yield dut
.irq
), 1)
202 yield from wb_write(dut
.bus
, ev_pending_addr
, data
=0b001, sel
=0xf)
204 self
.assertEqual((yield from wb_read(dut
.bus
, ev_pending_addr
, sel
=0xf)), 0b001)
206 self
.assertEqual((yield dut
.irq
), 1)
207 yield dut
.ev_0
.stb
.eq(0)
208 yield from wb_write(dut
.bus
, ev_pending_addr
, data
=0b001, sel
=0xf)
210 self
.assertEqual((yield dut
.irq
), 0)
212 yield dut
.ev_1
.stb
.eq(1)
214 self
.assertEqual((yield from wb_read(dut
.bus
, ev_pending_addr
, sel
=0xf)), 0b010)
216 self
.assertEqual((yield dut
.irq
), 1)
217 yield from wb_write(dut
.bus
, ev_pending_addr
, data
=0b010, sel
=0xf)
219 self
.assertEqual((yield dut
.irq
), 0)
221 yield dut
.ev_2
.stb
.eq(0)
223 self
.assertEqual((yield from wb_read(dut
.bus
, ev_pending_addr
, sel
=0xf)), 0b100)
225 self
.assertEqual((yield dut
.irq
), 1)
226 yield from wb_write(dut
.bus
, ev_pending_addr
, data
=0b100, sel
=0xf)
228 self
.assertEqual((yield dut
.irq
), 0)
230 simulation_test(dut
, process
)