1 # nmigen: UnusedElaboratable=no
4 from nmigen
import Elaboratable
, Signal
, Module
5 from nmigen
.back
.pysim
import Simulator
, Fragment
7 from nmigen_soc
import csr
8 from nmigen_soc
.csr
.wishbone
import WishboneCSRBridge
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
)
18 def elaborate(self
, platform
):
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
)
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
)
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")
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,
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
)
53 yield dut
.wb_bus
.cyc
.eq(1)
54 yield dut
.wb_bus
.sel
.eq(0b1)
56 yield dut
.wb_bus
.we
.eq(1)
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)
63 yield dut
.wb_bus
.stb
.eq(0)
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)
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)
75 yield dut
.wb_bus
.stb
.eq(0)
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)
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)
87 yield dut
.wb_bus
.stb
.eq(0)
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)
94 yield dut
.wb_bus
.we
.eq(0)
96 yield dut
.wb_bus
.adr
.eq(0)
97 yield dut
.wb_bus
.stb
.eq(1)
100 yield dut
.wb_bus
.stb
.eq(0)
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)
107 yield dut
.wb_bus
.adr
.eq(1)
108 yield dut
.wb_bus
.stb
.eq(1)
111 yield dut
.wb_bus
.stb
.eq(0)
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)
118 yield reg_2
.data
.eq(0x33333)
120 yield dut
.wb_bus
.adr
.eq(2)
121 yield dut
.wb_bus
.stb
.eq(1)
124 yield dut
.wb_bus
.stb
.eq(0)
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)
132 m
.submodules
+= mux
, reg_1
, reg_2
, dut
133 with
Simulator(m
, vcd_file
=open("test.vcd", "w")) as sim
:
135 sim
.add_sync_process(sim_test())
139 mux
= csr
.Multiplexer(addr_width
=10, data_width
=8)
140 reg
= MockRegister(32)
142 dut
= WishboneCSRBridge(mux
.bus
, data_width
=32)
145 yield dut
.wb_bus
.cyc
.eq(1)
146 yield dut
.wb_bus
.adr
.eq(0)
148 yield dut
.wb_bus
.we
.eq(1)
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)
158 yield dut
.wb_bus
.stb
.eq(0)
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)
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)
174 yield dut
.wb_bus
.stb
.eq(0)
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)
181 yield dut
.wb_bus
.we
.eq(0)
183 yield dut
.wb_bus
.sel
.eq(0b1111)
184 yield dut
.wb_bus
.stb
.eq(1)
190 yield dut
.wb_bus
.stb
.eq(0)
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)
197 yield reg
.data
.eq(0xaaaaaaaa)
200 yield dut
.wb_bus
.sel
.eq(0b0110)
201 yield dut
.wb_bus
.stb
.eq(1)
207 yield dut
.wb_bus
.stb
.eq(0)
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)
215 m
.submodules
+= mux
, reg
, dut
216 with
Simulator(m
, vcd_file
=open("test.vcd", "w")) as sim
:
218 sim
.add_sync_process(sim_test())