resolve internal (nmigen_soc) imports
[nmigen-soc.git] / nmigen_soc / test / test_csr_wishbone.py
1 # nmigen: UnusedElaboratable=no
2
3 import unittest
4 from nmigen import Elaboratable, Signal, Module
5 from nmigen.back.pysim import Simulator, Fragment
6
7 from nmigen_soc import csr
8 from nmigen_soc.csr.wishbone import WishboneCSRBridge
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,
42 data_width=7))
43
44 def test_narrow(self):
45 mux = csr.Multiplexer(addr_width=10, data_width=8)
46 reg_1 = MockRegister(8)
47 mux.add(reg_1.element)
48 reg_2 = MockRegister(16)
49 mux.add(reg_2.element)
50 dut = WishboneCSRBridge(mux.bus)
51
52 def sim_test():
53 yield dut.wb_bus.cyc.eq(1)
54 yield dut.wb_bus.sel.eq(0b1)
55
56 yield dut.wb_bus.we.eq(1)
57
58 yield dut.wb_bus.adr.eq(0)
59 yield dut.wb_bus.stb.eq(1)
60 yield dut.wb_bus.dat_w.eq(0x55)
61 yield
62 yield
63 yield dut.wb_bus.stb.eq(0)
64 yield
65 self.assertEqual((yield dut.wb_bus.ack), 1)
66 self.assertEqual((yield reg_1.r_count), 0)
67 self.assertEqual((yield reg_1.w_count), 1)
68 self.assertEqual((yield reg_1.data), 0x55)
69
70 yield dut.wb_bus.adr.eq(1)
71 yield dut.wb_bus.stb.eq(1)
72 yield dut.wb_bus.dat_w.eq(0xaa)
73 yield
74 yield
75 yield dut.wb_bus.stb.eq(0)
76 yield
77 self.assertEqual((yield dut.wb_bus.ack), 1)
78 self.assertEqual((yield reg_2.r_count), 0)
79 self.assertEqual((yield reg_2.w_count), 0)
80 self.assertEqual((yield reg_2.data), 0)
81
82 yield dut.wb_bus.adr.eq(2)
83 yield dut.wb_bus.stb.eq(1)
84 yield dut.wb_bus.dat_w.eq(0xbb)
85 yield
86 yield
87 yield dut.wb_bus.stb.eq(0)
88 yield
89 self.assertEqual((yield dut.wb_bus.ack), 1)
90 self.assertEqual((yield reg_2.r_count), 0)
91 self.assertEqual((yield reg_2.w_count), 1)
92 self.assertEqual((yield reg_2.data), 0xbbaa)
93
94 yield dut.wb_bus.we.eq(0)
95
96 yield dut.wb_bus.adr.eq(0)
97 yield dut.wb_bus.stb.eq(1)
98 yield
99 yield
100 yield dut.wb_bus.stb.eq(0)
101 yield
102 self.assertEqual((yield dut.wb_bus.ack), 1)
103 self.assertEqual((yield dut.wb_bus.dat_r), 0x55)
104 self.assertEqual((yield reg_1.r_count), 1)
105 self.assertEqual((yield reg_1.w_count), 1)
106
107 yield dut.wb_bus.adr.eq(1)
108 yield dut.wb_bus.stb.eq(1)
109 yield
110 yield
111 yield dut.wb_bus.stb.eq(0)
112 yield
113 self.assertEqual((yield dut.wb_bus.ack), 1)
114 self.assertEqual((yield dut.wb_bus.dat_r), 0xaa)
115 self.assertEqual((yield reg_2.r_count), 1)
116 self.assertEqual((yield reg_2.w_count), 1)
117
118 yield reg_2.data.eq(0x33333)
119
120 yield dut.wb_bus.adr.eq(2)
121 yield dut.wb_bus.stb.eq(1)
122 yield
123 yield
124 yield dut.wb_bus.stb.eq(0)
125 yield
126 self.assertEqual((yield dut.wb_bus.ack), 1)
127 self.assertEqual((yield dut.wb_bus.dat_r), 0xbb)
128 self.assertEqual((yield reg_2.r_count), 1)
129 self.assertEqual((yield reg_2.w_count), 1)
130
131 m = Module()
132 m.submodules += mux, reg_1, reg_2, dut
133 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
134 sim.add_clock(1e-6)
135 sim.add_sync_process(sim_test())
136 sim.run()
137
138 def test_wide(self):
139 mux = csr.Multiplexer(addr_width=10, data_width=8)
140 reg = MockRegister(32)
141 mux.add(reg.element)
142 dut = WishboneCSRBridge(mux.bus, data_width=32)
143
144 def sim_test():
145 yield dut.wb_bus.cyc.eq(1)
146 yield dut.wb_bus.adr.eq(0)
147
148 yield dut.wb_bus.we.eq(1)
149
150 yield dut.wb_bus.dat_w.eq(0x44332211)
151 yield dut.wb_bus.sel.eq(0b1111)
152 yield dut.wb_bus.stb.eq(1)
153 yield
154 yield
155 yield
156 yield
157 yield
158 yield dut.wb_bus.stb.eq(0)
159 yield
160 self.assertEqual((yield dut.wb_bus.ack), 1)
161 self.assertEqual((yield reg.r_count), 0)
162 self.assertEqual((yield reg.w_count), 1)
163 self.assertEqual((yield reg.data), 0x44332211)
164
165 # partial write
166 yield dut.wb_bus.dat_w.eq(0xaabbccdd)
167 yield dut.wb_bus.sel.eq(0b0110)
168 yield dut.wb_bus.stb.eq(1)
169 yield
170 yield
171 yield
172 yield
173 yield
174 yield dut.wb_bus.stb.eq(0)
175 yield
176 self.assertEqual((yield dut.wb_bus.ack), 1)
177 self.assertEqual((yield reg.r_count), 0)
178 self.assertEqual((yield reg.w_count), 1)
179 self.assertEqual((yield reg.data), 0x44332211)
180
181 yield dut.wb_bus.we.eq(0)
182
183 yield dut.wb_bus.sel.eq(0b1111)
184 yield dut.wb_bus.stb.eq(1)
185 yield
186 yield
187 yield
188 yield
189 yield
190 yield dut.wb_bus.stb.eq(0)
191 yield
192 self.assertEqual((yield dut.wb_bus.ack), 1)
193 self.assertEqual((yield dut.wb_bus.dat_r), 0x44332211)
194 self.assertEqual((yield reg.r_count), 1)
195 self.assertEqual((yield reg.w_count), 1)
196
197 yield reg.data.eq(0xaaaaaaaa)
198
199 # partial read
200 yield dut.wb_bus.sel.eq(0b0110)
201 yield dut.wb_bus.stb.eq(1)
202 yield
203 yield
204 yield
205 yield
206 yield
207 yield dut.wb_bus.stb.eq(0)
208 yield
209 self.assertEqual((yield dut.wb_bus.ack), 1)
210 self.assertEqual((yield dut.wb_bus.dat_r), 0x00332200)
211 self.assertEqual((yield reg.r_count), 1)
212 self.assertEqual((yield reg.w_count), 1)
213
214 m = Module()
215 m.submodules += mux, reg, dut
216 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
217 sim.add_clock(1e-6)
218 sim.add_sync_process(sim_test())
219 sim.run()