3 from nmigen
.hdl
.rec
import Layout
4 from nmigen
.back
.pysim
import *
6 from ..csr
.bus
import *
9 class CSRElementTestCase(unittest
.TestCase
):
11 elem
= CSRElement(1, "r")
12 self
.assertEqual(elem
.width
, 1)
13 self
.assertEqual(elem
.access
, "r")
14 self
.assertEqual(elem
.layout
, Layout
.cast([
20 elem
= CSRElement(8, access
="rw")
21 self
.assertEqual(elem
.width
, 8)
22 self
.assertEqual(elem
.access
, "rw")
23 self
.assertEqual(elem
.layout
, Layout
.cast([
31 elem
= CSRElement(10, "w")
32 self
.assertEqual(elem
.width
, 10)
33 self
.assertEqual(elem
.access
, "w")
34 self
.assertEqual(elem
.layout
, Layout
.cast([
39 def test_0_rw(self
): # degenerate but legal case
40 elem
= CSRElement(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 CSRMultiplexerTestCase(unittest.TestCase):
63 self.dut = CSRMultiplexer(addr_width=16, data_width=8)
65 def test_addr_width_wrong(self):
66 with self.assertRaisesRegex(ValueError,
67 r"Address width must be a positive integer
, not -1"):
68 CSRMultiplexer(addr_width=-1, data_width=8)
70 def test_data_width_wrong(self):
71 with self.assertRaisesRegex(ValueError,
72 r"Data width must be a positive integer
, not -1"):
73 CSRMultiplexer(addr_width=16, data_width=-1)
75 def test_alignment_wrong(self):
76 with self.assertRaisesRegex(ValueError,
77 r"Alignment must be a non
-negative integer
, not -1"):
78 CSRMultiplexer(addr_width=16, data_width=8, alignment=-1)
81 self.assertEqual(self.dut.addr_width, 16)
82 self.assertEqual(self.dut.data_width, 8)
83 self.assertEqual(self.dut.alignment, 0)
85 def test_add_4b(self):
86 self.assertEqual(self.dut.add(CSRElement(4, "rw
")),
89 def test_add_8b(self):
90 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
93 def test_add_12b(self):
94 self.assertEqual(self.dut.add(CSRElement(12, "rw
")),
97 def test_add_16b(self):
98 self.assertEqual(self.dut.add(CSRElement(16, "rw
")),
101 def test_add_two(self):
102 self.assertEqual(self.dut.add(CSRElement(16, "rw
")),
104 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
107 def test_add_wrong(self):
108 with self.assertRaisesRegex(ValueError,
109 r"Width must be a non
-negative integer
, not -1"):
112 def test_align_to(self):
113 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
115 self.assertEqual(self.dut.align_to(2), 4)
116 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
120 elem_4_r = CSRElement(4, "r
")
121 self.dut.add(elem_4_r)
122 elem_8_w = CSRElement(8, "w
")
123 self.dut.add(elem_8_w)
124 elem_16_rw = CSRElement(16, "rw
")
125 self.dut.add(elem_16_rw)
128 yield elem_4_r.r_data.eq(0xa)
129 yield elem_16_rw.r_data.eq(0x5aa5)
131 yield self.dut.addr.eq(0)
132 yield self.dut.r_stb.eq(1)
134 yield self.dut.r_stb.eq(0)
135 self.assertEqual((yield elem_4_r.r_stb), 1)
136 self.assertEqual((yield elem_16_rw.r_stb), 0)
138 self.assertEqual((yield self.dut.r_data), 0xa)
140 yield self.dut.addr.eq(2)
141 yield self.dut.r_stb.eq(1)
143 yield self.dut.r_stb.eq(0)
144 self.assertEqual((yield elem_4_r.r_stb), 0)
145 self.assertEqual((yield elem_16_rw.r_stb), 1)
147 yield self.dut.addr.eq(3) # pipeline a read
148 self.assertEqual((yield self.dut.r_data), 0xa5)
150 yield self.dut.r_stb.eq(1)
152 yield self.dut.r_stb.eq(0)
153 self.assertEqual((yield elem_4_r.r_stb), 0)
154 self.assertEqual((yield elem_16_rw.r_stb), 0)
156 self.assertEqual((yield self.dut.r_data), 0x5a)
158 yield self.dut.addr.eq(1)
159 yield self.dut.w_data.eq(0x3d)
160 yield self.dut.w_stb.eq(1)
162 yield self.dut.w_stb.eq(0)
164 self.assertEqual((yield elem_8_w.w_stb), 1)
165 self.assertEqual((yield elem_8_w.w_data), 0x3d)
166 self.assertEqual((yield elem_16_rw.w_stb), 0)
168 yield self.dut.addr.eq(2)
169 yield self.dut.w_data.eq(0x55)
170 yield self.dut.w_stb.eq(1)
172 self.assertEqual((yield elem_8_w.w_stb), 0)
173 self.assertEqual((yield elem_16_rw.w_stb), 0)
174 yield self.dut.addr.eq(3) # pipeline a write
175 yield self.dut.w_data.eq(0xaa)
177 self.assertEqual((yield elem_8_w.w_stb), 0)
178 self.assertEqual((yield elem_16_rw.w_stb), 0)
179 yield self.dut.w_stb.eq(0)
181 self.assertEqual((yield elem_8_w.w_stb), 0)
182 self.assertEqual((yield elem_16_rw.w_stb), 1)
183 self.assertEqual((yield elem_16_rw.w_data), 0xaa55)
185 with Simulator(self.dut, vcd_file=open("test
.vcd
", "w
")) as sim:
187 sim.add_sync_process(sim_test())
191 class CSRAlignedMultiplexerTestCase(unittest.TestCase):
193 self.dut = CSRMultiplexer(addr_width=16, data_width=8, alignment=2)
195 def test_attrs(self):
196 self.assertEqual(self.dut.alignment, 2)
198 def test_add_two(self):
199 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
201 self.assertEqual(self.dut.add(CSRElement(16, "rw
")),
204 def test_over_align_to(self):
205 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
207 self.assertEqual(self.dut.align_to(3), 8)
208 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
211 def test_under_align_to(self):
212 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
214 self.assertEqual(self.dut.align_to(1), 4)
215 self.assertEqual(self.dut.add(CSRElement(8, "rw
")),
219 elem_20_rw = CSRElement(20, "rw
")
220 self.dut.add(elem_20_rw)
223 yield self.dut.w_stb.eq(1)
224 yield self.dut.addr.eq(0)
225 yield self.dut.w_data.eq(0x55)
227 self.assertEqual((yield elem_20_rw.w_stb), 0)
228 yield self.dut.addr.eq(1)
229 yield self.dut.w_data.eq(0xaa)
231 self.assertEqual((yield elem_20_rw.w_stb), 0)
232 yield self.dut.addr.eq(2)
233 yield self.dut.w_data.eq(0x33)
235 self.assertEqual((yield elem_20_rw.w_stb), 0)
236 yield self.dut.addr.eq(3)
237 yield self.dut.w_data.eq(0xdd)
239 self.assertEqual((yield elem_20_rw.w_stb), 0)
240 yield self.dut.w_stb.eq(0)
242 self.assertEqual((yield elem_20_rw.w_stb), 1)
243 self.assertEqual((yield elem_20_rw.w_data), 0x3aa55)
245 with Simulator(self.dut, vcd_file=open("test
.vcd
", "w
")) as sim:
247 sim.add_sync_process(sim_test())