csr.wishbone: add WishboneCSRBridge.
[nmigen-soc.git] / nmigen_soc / test / test_csr_wishbone.py
1 import unittest
2 from nmigen import *
3 from nmigen.back.pysim import *
4
5 from .. import csr
6 from ..csr.wishbone import *
7
8
9 class MockRegister(Elaboratable):
10 def __init__(self, width):
11 self.element = csr.Element(width, "rw")
12 self.r_count = Signal(8)
13 self.w_count = Signal(8)
14 self.data = Signal(width)
15
16 def elaborate(self, platform):
17 m = Module()
18
19 with m.If(self.element.r_stb):
20 m.d.sync += self.r_count.eq(self.r_count + 1)
21 m.d.comb += self.element.r_data.eq(self.data)
22
23 with m.If(self.element.w_stb):
24 m.d.sync += self.w_count.eq(self.w_count + 1)
25 m.d.sync += self.data.eq(self.element.w_data)
26
27 return m
28
29
30 class WishboneCSRBridgeTestCase(unittest.TestCase):
31 def test_wrong_csr_bus(self):
32 with self.assertRaisesRegex(ValueError,
33 r"CSR bus must be an instance of CSRInterface, not 'foo'"):
34 WishboneCSRBridge(csr_bus="foo")
35
36 def test_wrong_csr_bus_data_width(self):
37 with self.assertRaisesRegex(ValueError,
38 r"CSR bus data width must be one of 8, 16, 32, 64, not 7"):
39 WishboneCSRBridge(csr_bus=csr.Interface(addr_width=10, data_width=7))
40
41 def test_narrow(self):
42 mux = csr.Multiplexer(addr_width=10, data_width=8)
43 reg_1 = MockRegister(8)
44 mux.add(reg_1.element)
45 reg_2 = MockRegister(16)
46 mux.add(reg_2.element)
47 dut = WishboneCSRBridge(mux.bus)
48
49 def sim_test():
50 yield dut.wb_bus.cyc.eq(1)
51 yield dut.wb_bus.sel.eq(0b1)
52
53 yield dut.wb_bus.we.eq(1)
54
55 yield dut.wb_bus.adr.eq(0)
56 yield dut.wb_bus.stb.eq(1)
57 yield dut.wb_bus.dat_w.eq(0x55)
58 yield
59 yield
60 yield dut.wb_bus.stb.eq(0)
61 yield
62 self.assertEqual((yield dut.wb_bus.ack), 1)
63 self.assertEqual((yield reg_1.r_count), 0)
64 self.assertEqual((yield reg_1.w_count), 1)
65 self.assertEqual((yield reg_1.data), 0x55)
66
67 yield dut.wb_bus.adr.eq(1)
68 yield dut.wb_bus.stb.eq(1)
69 yield dut.wb_bus.dat_w.eq(0xaa)
70 yield
71 yield
72 yield dut.wb_bus.stb.eq(0)
73 yield
74 self.assertEqual((yield dut.wb_bus.ack), 1)
75 self.assertEqual((yield reg_2.r_count), 0)
76 self.assertEqual((yield reg_2.w_count), 0)
77 self.assertEqual((yield reg_2.data), 0)
78
79 yield dut.wb_bus.adr.eq(2)
80 yield dut.wb_bus.stb.eq(1)
81 yield dut.wb_bus.dat_w.eq(0xbb)
82 yield
83 yield
84 yield dut.wb_bus.stb.eq(0)
85 yield
86 self.assertEqual((yield dut.wb_bus.ack), 1)
87 self.assertEqual((yield reg_2.r_count), 0)
88 self.assertEqual((yield reg_2.w_count), 1)
89 self.assertEqual((yield reg_2.data), 0xbbaa)
90
91 yield dut.wb_bus.we.eq(0)
92
93 yield dut.wb_bus.adr.eq(0)
94 yield dut.wb_bus.stb.eq(1)
95 yield
96 yield
97 yield dut.wb_bus.stb.eq(0)
98 yield
99 self.assertEqual((yield dut.wb_bus.ack), 1)
100 self.assertEqual((yield dut.wb_bus.dat_r), 0x55)
101 self.assertEqual((yield reg_1.r_count), 1)
102 self.assertEqual((yield reg_1.w_count), 1)
103
104 yield dut.wb_bus.adr.eq(1)
105 yield dut.wb_bus.stb.eq(1)
106 yield
107 yield
108 yield dut.wb_bus.stb.eq(0)
109 yield
110 self.assertEqual((yield dut.wb_bus.ack), 1)
111 self.assertEqual((yield dut.wb_bus.dat_r), 0xaa)
112 self.assertEqual((yield reg_2.r_count), 1)
113 self.assertEqual((yield reg_2.w_count), 1)
114
115 yield reg_2.data.eq(0x33333)
116
117 yield dut.wb_bus.adr.eq(2)
118 yield dut.wb_bus.stb.eq(1)
119 yield
120 yield
121 yield dut.wb_bus.stb.eq(0)
122 yield
123 self.assertEqual((yield dut.wb_bus.ack), 1)
124 self.assertEqual((yield dut.wb_bus.dat_r), 0xbb)
125 self.assertEqual((yield reg_2.r_count), 1)
126 self.assertEqual((yield reg_2.w_count), 1)
127
128 m = Module()
129 m.submodules += mux, reg_1, reg_2, dut
130 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
131 sim.add_clock(1e-6)
132 sim.add_sync_process(sim_test())
133 sim.run()
134
135 def test_wide(self):
136 mux = csr.Multiplexer(addr_width=10, data_width=8)
137 reg = MockRegister(32)
138 mux.add(reg.element)
139 dut = WishboneCSRBridge(mux.bus, data_width=32)
140
141 def sim_test():
142 yield dut.wb_bus.cyc.eq(1)
143 yield dut.wb_bus.adr.eq(0)
144
145 yield dut.wb_bus.we.eq(1)
146
147 yield dut.wb_bus.dat_w.eq(0x44332211)
148 yield dut.wb_bus.sel.eq(0b1111)
149 yield dut.wb_bus.stb.eq(1)
150 yield
151 yield
152 yield
153 yield
154 yield
155 yield dut.wb_bus.stb.eq(0)
156 yield
157 self.assertEqual((yield dut.wb_bus.ack), 1)
158 self.assertEqual((yield reg.r_count), 0)
159 self.assertEqual((yield reg.w_count), 1)
160 self.assertEqual((yield reg.data), 0x44332211)
161
162 # partial write
163 yield dut.wb_bus.dat_w.eq(0xaabbccdd)
164 yield dut.wb_bus.sel.eq(0b0110)
165 yield dut.wb_bus.stb.eq(1)
166 yield
167 yield
168 yield
169 yield
170 yield
171 yield dut.wb_bus.stb.eq(0)
172 yield
173 self.assertEqual((yield dut.wb_bus.ack), 1)
174 self.assertEqual((yield reg.r_count), 0)
175 self.assertEqual((yield reg.w_count), 1)
176 self.assertEqual((yield reg.data), 0x44332211)
177
178 yield dut.wb_bus.we.eq(0)
179
180 yield dut.wb_bus.sel.eq(0b1111)
181 yield dut.wb_bus.stb.eq(1)
182 yield
183 yield
184 yield
185 yield
186 yield
187 yield dut.wb_bus.stb.eq(0)
188 yield
189 self.assertEqual((yield dut.wb_bus.ack), 1)
190 self.assertEqual((yield dut.wb_bus.dat_r), 0x44332211)
191 self.assertEqual((yield reg.r_count), 1)
192 self.assertEqual((yield reg.w_count), 1)
193
194 yield reg.data.eq(0xaaaaaaaa)
195
196 # partial read
197 yield dut.wb_bus.sel.eq(0b0110)
198 yield dut.wb_bus.stb.eq(1)
199 yield
200 yield
201 yield
202 yield
203 yield
204 yield dut.wb_bus.stb.eq(0)
205 yield
206 self.assertEqual((yield dut.wb_bus.ack), 1)
207 self.assertEqual((yield dut.wb_bus.dat_r), 0x00332200)
208 self.assertEqual((yield reg.r_count), 1)
209 self.assertEqual((yield reg.w_count), 1)
210
211 m = Module()
212 m.submodules += mux, reg, dut
213 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
214 sim.add_clock(1e-6)
215 sim.add_sync_process(sim_test())
216 sim.run()