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
, Element
.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
, Element
.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
, Element
.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
=Element
.Access
.RW
)
41 self
.assertEqual(elem
.width
, 0)
42 self
.assertEqual(elem
.access
, Element
.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_add_4b(self):
90 self.assertEqual(self.dut.add(Element(4, "rw
")),
93 def test_add_8b(self):
94 self.assertEqual(self.dut.add(Element(8, "rw
")),
97 def test_add_12b(self):
98 self.assertEqual(self.dut.add(Element(12, "rw
")),
101 def test_add_16b(self):
102 self.assertEqual(self.dut.add(Element(16, "rw
")),
105 def test_add_two(self):
106 self.assertEqual(self.dut.add(Element(16, "rw
")),
108 self.assertEqual(self.dut.add(Element(8, "rw
")),
111 def test_add_wrong(self):
112 with self.assertRaisesRegex(ValueError,
113 r"Width must be a non
-negative integer
, not -1"):
116 def test_align_to(self):
117 self.assertEqual(self.dut.add(Element(8, "rw
")),
119 self.assertEqual(self.dut.align_to(2), 4)
120 self.assertEqual(self.dut.add(Element(8, "rw
")),
126 elem_4_r = Element(4, "r
")
127 self.dut.add(elem_4_r)
128 elem_8_w = Element(8, "w
")
129 self.dut.add(elem_8_w)
130 elem_16_rw = Element(16, "rw
")
131 self.dut.add(elem_16_rw)
134 yield elem_4_r.r_data.eq(0xa)
135 yield elem_16_rw.r_data.eq(0x5aa5)
138 yield bus.r_stb.eq(1)
140 yield bus.r_stb.eq(0)
141 self.assertEqual((yield elem_4_r.r_stb), 1)
142 self.assertEqual((yield elem_16_rw.r_stb), 0)
144 self.assertEqual((yield bus.r_data), 0xa)
147 yield bus.r_stb.eq(1)
149 yield bus.r_stb.eq(0)
150 self.assertEqual((yield elem_4_r.r_stb), 0)
151 self.assertEqual((yield elem_16_rw.r_stb), 1)
153 yield bus.addr.eq(3) # pipeline a read
154 self.assertEqual((yield bus.r_data), 0xa5)
156 yield bus.r_stb.eq(1)
158 yield bus.r_stb.eq(0)
159 self.assertEqual((yield elem_4_r.r_stb), 0)
160 self.assertEqual((yield elem_16_rw.r_stb), 0)
162 self.assertEqual((yield bus.r_data), 0x5a)
165 yield bus.w_data.eq(0x3d)
166 yield bus.w_stb.eq(1)
168 yield bus.w_stb.eq(0)
170 self.assertEqual((yield elem_8_w.w_stb), 1)
171 self.assertEqual((yield elem_8_w.w_data), 0x3d)
172 self.assertEqual((yield elem_16_rw.w_stb), 0)
175 yield bus.w_data.eq(0x55)
176 yield bus.w_stb.eq(1)
178 self.assertEqual((yield elem_8_w.w_stb), 0)
179 self.assertEqual((yield elem_16_rw.w_stb), 0)
180 yield bus.addr.eq(3) # pipeline a write
181 yield bus.w_data.eq(0xaa)
183 self.assertEqual((yield elem_8_w.w_stb), 0)
184 self.assertEqual((yield elem_16_rw.w_stb), 0)
185 yield bus.w_stb.eq(0)
187 self.assertEqual((yield elem_8_w.w_stb), 0)
188 self.assertEqual((yield elem_16_rw.w_stb), 1)
189 self.assertEqual((yield elem_16_rw.w_data), 0xaa55)
191 with Simulator(self.dut, vcd_file=open("test
.vcd
", "w
")) as sim:
193 sim.add_sync_process(sim_test())
197 class DecoderAlignedTestCase(unittest.TestCase):
199 self.dut = Decoder(addr_width=16, data_width=8, alignment=2)
201 def test_add_two(self):
202 self.assertEqual(self.dut.add(Element(8, "rw
")),
204 self.assertEqual(self.dut.add(Element(16, "rw
")),
207 def test_over_align_to(self):
208 self.assertEqual(self.dut.add(Element(8, "rw
")),
210 self.assertEqual(self.dut.align_to(3), 8)
211 self.assertEqual(self.dut.add(Element(8, "rw
")),
214 def test_under_align_to(self):
215 self.assertEqual(self.dut.add(Element(8, "rw
")),
217 self.assertEqual(self.dut.align_to(1), 4)
218 self.assertEqual(self.dut.add(Element(8, "rw
")),
224 elem_20_rw = Element(20, "rw
")
225 self.dut.add(elem_20_rw)
228 yield bus.w_stb.eq(1)
230 yield bus.w_data.eq(0x55)
232 self.assertEqual((yield elem_20_rw.w_stb), 0)
234 yield bus.w_data.eq(0xaa)
236 self.assertEqual((yield elem_20_rw.w_stb), 0)
238 yield bus.w_data.eq(0x33)
240 self.assertEqual((yield elem_20_rw.w_stb), 0)
242 yield bus.w_data.eq(0xdd)
244 self.assertEqual((yield elem_20_rw.w_stb), 0)
245 yield bus.w_stb.eq(0)
247 self.assertEqual((yield elem_20_rw.w_stb), 1)
248 self.assertEqual((yield elem_20_rw.w_data), 0x3aa55)
250 with Simulator(self.dut, vcd_file=open("test
.vcd
", "w
")) as sim:
252 sim.add_sync_process(sim_test())