3 from nmigen
.hdl
.rec
import Layout
4 from nmigen
.back
.pysim
import *
6 from ..csr
.bus
import *
9 class ElementTestCase(unittest
.TestCase
):
10 def test_layout_1_ro(self
):
11 elem
= Element(1, "r")
12 self
.assertEqual(elem
.width
, 1)
13 self
.assertEqual(elem
.access
, "r")
14 self
.assertEqual(elem
.layout
, Layout
.cast([
19 def test_layout_8_rw(self
):
20 elem
= Element(8, access
="rw")
21 self
.assertEqual(elem
.width
, 8)
22 self
.assertEqual(elem
.access
, "rw")
23 self
.assertEqual(elem
.layout
, Layout
.cast([
30 def test_layout_10_wo(self
):
31 elem
= Element(10, "w")
32 self
.assertEqual(elem
.width
, 10)
33 self
.assertEqual(elem
.access
, "w")
34 self
.assertEqual(elem
.layout
, Layout
.cast([
39 def test_layout_0_rw(self
): # degenerate but legal case
40 elem
= Element(0, access
="rw")
41 self
.assertEqual(elem
.width
, 0)
42 self
.assertEqual(elem
.access
, "rw")
43 self
.assertEqual(elem
.layout
, Layout
.cast([
50 def test_width_wrong(self
):
51 with self
.assertRaisesRegex(ValueError,
52 r
"Width must be a non-negative integer, not -1"):
55 def test_access_wrong(self
):
56 with self
.assertRaisesRegex(ValueError,
57 r
"Access mode must be one of \"r
\", \"w
\", or \"rw
\", not 'wo'"):
61 class InterfaceTestCase(unittest.TestCase):
62 def test_layout(self):
63 iface = Interface(addr_width=12, data_width=8)
64 self.assertEqual(iface.addr_width, 12)
65 self.assertEqual(iface.data_width, 8)
66 self.assertEqual(iface.layout, Layout.cast([
74 def test_addr_width_wrong(self):
75 with self.assertRaisesRegex(ValueError,
76 r"Address width must be a positive integer
, not -1"):
77 Interface(addr_width=-1, data_width=8)
79 def test_data_width_wrong(self):
80 with self.assertRaisesRegex(ValueError,
81 r"Data width must be a positive integer
, not -1"):
82 Interface(addr_width=16, data_width=-1)
85 class DecoderTestCase(unittest.TestCase):
87 self.dut = Decoder(addr_width=16, data_width=8)
89 def test_alignment_wrong(self):
90 with self.assertRaisesRegex(ValueError,
91 r"Alignment must be a non
-negative integer
, not -1"):
92 Decoder(addr_width=16, data_width=8, alignment=-1)
95 self.assertEqual(self.dut.alignment, 0)
97 def test_add_4b(self):
98 self.assertEqual(self.dut.add(Element(4, "rw
")),
101 def test_add_8b(self):
102 self.assertEqual(self.dut.add(Element(8, "rw
")),
105 def test_add_12b(self):
106 self.assertEqual(self.dut.add(Element(12, "rw
")),
109 def test_add_16b(self):
110 self.assertEqual(self.dut.add(Element(16, "rw
")),
113 def test_add_two(self):
114 self.assertEqual(self.dut.add(Element(16, "rw
")),
116 self.assertEqual(self.dut.add(Element(8, "rw
")),
119 def test_add_wrong(self):
120 with self.assertRaisesRegex(ValueError,
121 r"Width must be a non
-negative integer
, not -1"):
124 def test_align_to(self):
125 self.assertEqual(self.dut.add(Element(8, "rw
")),
127 self.assertEqual(self.dut.align_to(2), 4)
128 self.assertEqual(self.dut.add(Element(8, "rw
")),
134 elem_4_r = Element(4, "r
")
135 self.dut.add(elem_4_r)
136 elem_8_w = Element(8, "w
")
137 self.dut.add(elem_8_w)
138 elem_16_rw = Element(16, "rw
")
139 self.dut.add(elem_16_rw)
142 yield elem_4_r.r_data.eq(0xa)
143 yield elem_16_rw.r_data.eq(0x5aa5)
146 yield bus.r_stb.eq(1)
148 yield bus.r_stb.eq(0)
149 self.assertEqual((yield elem_4_r.r_stb), 1)
150 self.assertEqual((yield elem_16_rw.r_stb), 0)
152 self.assertEqual((yield bus.r_data), 0xa)
155 yield bus.r_stb.eq(1)
157 yield bus.r_stb.eq(0)
158 self.assertEqual((yield elem_4_r.r_stb), 0)
159 self.assertEqual((yield elem_16_rw.r_stb), 1)
161 yield bus.addr.eq(3) # pipeline a read
162 self.assertEqual((yield bus.r_data), 0xa5)
164 yield bus.r_stb.eq(1)
166 yield bus.r_stb.eq(0)
167 self.assertEqual((yield elem_4_r.r_stb), 0)
168 self.assertEqual((yield elem_16_rw.r_stb), 0)
170 self.assertEqual((yield bus.r_data), 0x5a)
173 yield bus.w_data.eq(0x3d)
174 yield bus.w_stb.eq(1)
176 yield bus.w_stb.eq(0)
178 self.assertEqual((yield elem_8_w.w_stb), 1)
179 self.assertEqual((yield elem_8_w.w_data), 0x3d)
180 self.assertEqual((yield elem_16_rw.w_stb), 0)
183 yield bus.w_data.eq(0x55)
184 yield bus.w_stb.eq(1)
186 self.assertEqual((yield elem_8_w.w_stb), 0)
187 self.assertEqual((yield elem_16_rw.w_stb), 0)
188 yield bus.addr.eq(3) # pipeline a write
189 yield bus.w_data.eq(0xaa)
191 self.assertEqual((yield elem_8_w.w_stb), 0)
192 self.assertEqual((yield elem_16_rw.w_stb), 0)
193 yield bus.w_stb.eq(0)
195 self.assertEqual((yield elem_8_w.w_stb), 0)
196 self.assertEqual((yield elem_16_rw.w_stb), 1)
197 self.assertEqual((yield elem_16_rw.w_data), 0xaa55)
199 with Simulator(self.dut, vcd_file=open("test
.vcd
", "w
")) as sim:
201 sim.add_sync_process(sim_test())
205 class DecoderAlignedTestCase(unittest.TestCase):
207 self.dut = Decoder(addr_width=16, data_width=8, alignment=2)
209 def test_attrs(self):
210 self.assertEqual(self.dut.alignment, 2)
212 def test_add_two(self):
213 self.assertEqual(self.dut.add(Element(8, "rw
")),
215 self.assertEqual(self.dut.add(Element(16, "rw
")),
218 def test_over_align_to(self):
219 self.assertEqual(self.dut.add(Element(8, "rw
")),
221 self.assertEqual(self.dut.align_to(3), 8)
222 self.assertEqual(self.dut.add(Element(8, "rw
")),
225 def test_under_align_to(self):
226 self.assertEqual(self.dut.add(Element(8, "rw
")),
228 self.assertEqual(self.dut.align_to(1), 4)
229 self.assertEqual(self.dut.add(Element(8, "rw
")),
235 elem_20_rw = Element(20, "rw
")
236 self.dut.add(elem_20_rw)
239 yield bus.w_stb.eq(1)
241 yield bus.w_data.eq(0x55)
243 self.assertEqual((yield elem_20_rw.w_stb), 0)
245 yield bus.w_data.eq(0xaa)
247 self.assertEqual((yield elem_20_rw.w_stb), 0)
249 yield bus.w_data.eq(0x33)
251 self.assertEqual((yield elem_20_rw.w_stb), 0)
253 yield bus.w_data.eq(0xdd)
255 self.assertEqual((yield elem_20_rw.w_stb), 0)
256 yield bus.w_stb.eq(0)
258 self.assertEqual((yield elem_20_rw.w_stb), 1)
259 self.assertEqual((yield elem_20_rw.w_data), 0x3aa55)
261 with Simulator(self.dut, vcd_file=open("test
.vcd
", "w
")) as sim:
263 sim.add_sync_process(sim_test())