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