wishbone: fix SRAM; improve tests for Decoder & Arbiter
[nmigen-soc.git] / nmigen_soc / test / test_wishbone_bus.py
1 # nmigen: UnusedElaboratable=no
2
3 import unittest
4 from nmigen import *
5 from nmigen.hdl.rec import *
6 from nmigen.back.pysim import *
7
8 from ..wishbone import *
9
10
11 class InterfaceTestCase(unittest.TestCase):
12 def test_simple(self):
13 iface = Interface(addr_width=32, data_width=8)
14 self.assertEqual(iface.addr_width, 32)
15 self.assertEqual(iface.data_width, 8)
16 self.assertEqual(iface.granularity, 8)
17 self.assertEqual(iface.memory_map.addr_width, 32)
18 self.assertEqual(iface.memory_map.data_width, 8)
19 self.assertEqual(iface.layout, Layout.cast([
20 ("adr", 32, DIR_FANOUT),
21 ("dat_w", 8, DIR_FANOUT),
22 ("dat_r", 8, DIR_FANIN),
23 ("sel", 1, DIR_FANOUT),
24 ("cyc", 1, DIR_FANOUT),
25 ("stb", 1, DIR_FANOUT),
26 ("we", 1, DIR_FANOUT),
27 ("ack", 1, DIR_FANIN),
28 ]))
29
30 def test_granularity(self):
31 iface = Interface(addr_width=30, data_width=32, granularity=8)
32 self.assertEqual(iface.addr_width, 30)
33 self.assertEqual(iface.data_width, 32)
34 self.assertEqual(iface.granularity, 8)
35 self.assertEqual(iface.memory_map.addr_width, 32)
36 self.assertEqual(iface.memory_map.data_width, 8)
37 self.assertEqual(iface.layout, Layout.cast([
38 ("adr", 30, DIR_FANOUT),
39 ("dat_w", 32, DIR_FANOUT),
40 ("dat_r", 32, DIR_FANIN),
41 ("sel", 4, DIR_FANOUT),
42 ("cyc", 1, DIR_FANOUT),
43 ("stb", 1, DIR_FANOUT),
44 ("we", 1, DIR_FANOUT),
45 ("ack", 1, DIR_FANIN),
46 ]))
47
48 def test_features(self):
49 iface = Interface(addr_width=32, data_width=32,
50 features={"rty", "err", "stall", "lock", "cti", "bte"})
51 self.assertEqual(iface.layout, Layout.cast([
52 ("adr", 32, DIR_FANOUT),
53 ("dat_w", 32, DIR_FANOUT),
54 ("dat_r", 32, DIR_FANIN),
55 ("sel", 1, DIR_FANOUT),
56 ("cyc", 1, DIR_FANOUT),
57 ("stb", 1, DIR_FANOUT),
58 ("we", 1, DIR_FANOUT),
59 ("ack", 1, DIR_FANIN),
60 ("err", 1, DIR_FANIN),
61 ("rty", 1, DIR_FANIN),
62 ("stall", 1, DIR_FANIN),
63 ("lock", 1, DIR_FANOUT),
64 ("cti", CycleType, DIR_FANOUT),
65 ("bte", BurstTypeExt, DIR_FANOUT),
66 ]))
67
68 def test_wrong_addr_width(self):
69 with self.assertRaisesRegex(ValueError,
70 r"Address width must be a non-negative integer, not -1"):
71 Interface(addr_width=-1, data_width=8)
72
73 def test_wrong_data_width(self):
74 with self.assertRaisesRegex(ValueError,
75 r"Data width must be one of 8, 16, 32, 64, not 7"):
76 Interface(addr_width=0, data_width=7)
77
78 def test_wrong_granularity(self):
79 with self.assertRaisesRegex(ValueError,
80 r"Granularity must be one of 8, 16, 32, 64, not 7"):
81 Interface(addr_width=0, data_width=32, granularity=7)
82
83 def test_wrong_granularity_wide(self):
84 with self.assertRaisesRegex(ValueError,
85 r"Granularity 32 may not be greater than data width 8"):
86 Interface(addr_width=0, data_width=8, granularity=32)
87
88 def test_wrong_features(self):
89 with self.assertRaisesRegex(ValueError,
90 r"Optional signal\(s\) 'foo' are not supported"):
91 Interface(addr_width=0, data_width=8, features={"foo"})
92
93
94 class DecoderTestCase(unittest.TestCase):
95 def setUp(self):
96 self.dut = Decoder(addr_width=31, data_width=32, granularity=16)
97
98 def test_add_align_to(self):
99 sub_1 = Interface(addr_width=15, data_width=32, granularity=16)
100 sub_2 = Interface(addr_width=15, data_width=32, granularity=16)
101 self.assertEqual(self.dut.add(sub_1), (0x00000000, 0x00010000, 1))
102 self.assertEqual(self.dut.align_to(18), 0x000040000)
103 self.assertEqual(self.dut.add(sub_2), (0x00040000, 0x00050000, 1))
104
105 def test_add_wrong(self):
106 with self.assertRaisesRegex(TypeError,
107 r"Subordinate bus must be an instance of wishbone\.Interface, not 'foo'"):
108 self.dut.add("foo")
109
110 def test_add_wrong_granularity(self):
111 with self.assertRaisesRegex(ValueError,
112 r"Subordinate bus has granularity 32, which is greater than "
113 r"the decoder granularity 16"):
114 self.dut.add(Interface(addr_width=15, data_width=32, granularity=32))
115
116 def test_add_wrong_width_dense(self):
117 with self.assertRaisesRegex(ValueError,
118 r"Subordinate bus has data width 16, which is not the same as decoder "
119 r"data width 32 \(required for dense address translation\)"):
120 self.dut.add(Interface(addr_width=15, data_width=16, granularity=16))
121
122 def test_add_wrong_granularity_sparse(self):
123 with self.assertRaisesRegex(ValueError,
124 r"Subordinate bus has data width 64, which is not the same as subordinate "
125 r"bus granularity 16 \(required for sparse address translation\)"):
126 self.dut.add(Interface(addr_width=15, data_width=64, granularity=16), sparse=True)
127
128 def test_add_wrong_optional_output(self):
129 with self.assertRaisesRegex(ValueError,
130 r"Subordinate bus has optional output 'err', but the decoder does "
131 r"not have a corresponding input"):
132 self.dut.add(Interface(addr_width=15, data_width=32, granularity=16, features={"err"}))
133
134
135 class DecoderSimulationTestCase(unittest.TestCase):
136 def test_simple(self):
137 dut = Decoder(addr_width=30, data_width=32, granularity=8,
138 features={"err", "rty", "stall", "lock", "cti", "bte"})
139 sub_1 = Interface(addr_width=14, data_width=32, granularity=8)
140 self.assertEqual(dut.add(sub_1, addr=0x10000),
141 (0x10000, 0x20000, 1))
142 sub_2 = Interface(addr_width=14, data_width=32, granularity=8,
143 features={"err", "rty", "stall", "lock", "cti", "bte"})
144 self.assertEqual(dut.add(sub_2),
145 (0x20000, 0x30000, 1))
146
147 def sim_test():
148 yield dut.bus.adr.eq(0x10400 >> 2)
149 yield dut.bus.cyc.eq(1)
150 yield dut.bus.stb.eq(1)
151 yield dut.bus.sel.eq(0b11)
152 yield dut.bus.dat_w.eq(0x12345678)
153 yield dut.bus.lock.eq(1)
154 yield dut.bus.cti.eq(CycleType.INCR_BURST)
155 yield dut.bus.bte.eq(BurstTypeExt.WRAP_4)
156 yield sub_1.ack.eq(1)
157 yield sub_1.dat_r.eq(0xabcdef01)
158 yield sub_2.dat_r.eq(0x5678abcd)
159 yield Delay(1e-6)
160 self.assertEqual((yield sub_1.adr), 0x400 >> 2)
161 self.assertEqual((yield sub_1.cyc), 1)
162 self.assertEqual((yield sub_2.cyc), 0)
163 self.assertEqual((yield sub_1.stb), 1)
164 self.assertEqual((yield sub_1.sel), 0b11)
165 self.assertEqual((yield sub_1.dat_w), 0x12345678)
166 self.assertEqual((yield dut.bus.ack), 1)
167 self.assertEqual((yield dut.bus.err), 0)
168 self.assertEqual((yield dut.bus.rty), 0)
169 self.assertEqual((yield dut.bus.dat_r), 0xabcdef01)
170
171 yield dut.bus.adr.eq(0x20400 >> 2)
172 yield dut.bus.sel.eq(0b1001)
173 yield dut.bus.we.eq(1)
174 yield sub_1.dat_r.eq(0)
175 yield sub_1.ack.eq(0)
176 yield sub_2.err.eq(1)
177 yield sub_2.rty.eq(1)
178 yield sub_2.stall.eq(1)
179 yield Delay(1e-6)
180 self.assertEqual((yield sub_2.adr), 0x400 >> 2)
181 self.assertEqual((yield sub_1.cyc), 0)
182 self.assertEqual((yield sub_2.cyc), 1)
183 self.assertEqual((yield sub_1.stb), 1)
184 self.assertEqual((yield sub_1.sel), 0b1001)
185 self.assertEqual((yield sub_1.dat_w), 0x12345678)
186 self.assertEqual((yield sub_2.stb), 1)
187 self.assertEqual((yield sub_2.sel), 0b1001)
188 self.assertEqual((yield sub_2.dat_w), 0x12345678)
189 self.assertEqual((yield sub_2.lock), 1)
190 self.assertEqual((yield sub_2.cti), CycleType.INCR_BURST.value)
191 self.assertEqual((yield sub_2.bte), BurstTypeExt.WRAP_4.value)
192 self.assertEqual((yield dut.bus.ack), 0)
193 self.assertEqual((yield dut.bus.err), 1)
194 self.assertEqual((yield dut.bus.rty), 1)
195 self.assertEqual((yield dut.bus.stall), 1)
196 self.assertEqual((yield dut.bus.dat_r), 0x5678abcd)
197
198 yield dut.bus.adr.eq(0x10400 >> 2)
199 yield dut.bus.sel.eq(0)
200 yield dut.bus.cyc.eq(0)
201 yield dut.bus.stb.eq(0)
202 yield dut.bus.dat_w.eq(0x87654321)
203 yield dut.bus.we.eq(0)
204 yield Delay(1e-6)
205 self.assertEqual((yield sub_1.adr), 0x400 >> 2)
206 self.assertEqual((yield sub_1.cyc), 0)
207 self.assertEqual((yield sub_2.cyc), 0)
208 self.assertEqual((yield sub_1.stb), 0)
209 self.assertEqual((yield sub_1.sel), 0)
210 self.assertEqual((yield sub_1.dat_w), 0x87654321)
211 self.assertEqual((yield sub_2.stb), 0)
212 self.assertEqual((yield sub_2.sel), 0)
213 self.assertEqual((yield sub_2.dat_w), 0x87654321)
214 self.assertEqual((yield dut.bus.ack), 0)
215 self.assertEqual((yield dut.bus.dat_r), 0)
216
217 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
218 sim.add_process(sim_test())
219 sim.run()
220
221 def test_addr_translate(self):
222 class AddressLoopback(Elaboratable):
223 def __init__(self, **kwargs):
224 self.bus = Interface(**kwargs)
225
226 def elaborate(self, platform):
227 m = Module()
228
229 for index, sel_bit in enumerate(self.bus.sel):
230 with m.If(sel_bit):
231 segment = self.bus.dat_r.word_select(index, self.bus.granularity)
232 m.d.comb += segment.eq(self.bus.adr + index)
233
234 return m
235
236 dut = Decoder(addr_width=20, data_width=32, granularity=16)
237 loop_1 = AddressLoopback(addr_width=7, data_width=32, granularity=16)
238 self.assertEqual(dut.add(loop_1.bus, addr=0x10000),
239 (0x10000, 0x10100, 1))
240 loop_2 = AddressLoopback(addr_width=6, data_width=32, granularity=8)
241 self.assertEqual(dut.add(loop_2.bus, addr=0x20000),
242 (0x20000, 0x20080, 2))
243 loop_3 = AddressLoopback(addr_width=8, data_width=16, granularity=16)
244 self.assertEqual(dut.add(loop_3.bus, addr=0x30000, sparse=True),
245 (0x30000, 0x30100, 1))
246 loop_4 = AddressLoopback(addr_width=8, data_width=8, granularity=8)
247 self.assertEqual(dut.add(loop_4.bus, addr=0x40000, sparse=True),
248 (0x40000, 0x40100, 1))
249
250 for sig in ["adr", "dat_r", "sel"]:
251 getattr(dut.bus, sig).name = "dec__" + sig
252 getattr(loop_1.bus, sig).name = "sub1__" + sig
253 getattr(loop_2.bus, sig).name = "sub2__" + sig
254 getattr(loop_3.bus, sig).name = "sub3__" + sig
255 getattr(loop_4.bus, sig).name = "sub4__" + sig
256
257 def sim_test():
258 yield dut.bus.cyc.eq(1)
259
260 yield dut.bus.adr.eq(0x10010 >> 1)
261
262 yield dut.bus.sel.eq(0b11)
263 yield Delay(1e-6)
264 self.assertEqual((yield dut.bus.dat_r), 0x00090008)
265
266 yield dut.bus.sel.eq(0b01)
267 yield Delay(1e-6)
268 self.assertEqual((yield dut.bus.dat_r), 0x00000008)
269
270 yield dut.bus.sel.eq(0b10)
271 yield Delay(1e-6)
272 self.assertEqual((yield dut.bus.dat_r), 0x00090000)
273
274 yield dut.bus.adr.eq(0x20010 >> 1)
275
276 yield dut.bus.sel.eq(0b11)
277 yield Delay(1e-6)
278 self.assertEqual((yield dut.bus.dat_r), 0x13121110)
279
280 yield dut.bus.sel.eq(0b01)
281 yield Delay(1e-6)
282 self.assertEqual((yield dut.bus.dat_r), 0x00001110)
283
284 yield dut.bus.sel.eq(0b10)
285 yield Delay(1e-6)
286 self.assertEqual((yield dut.bus.dat_r), 0x13120000)
287
288 yield dut.bus.adr.eq(0x30010 >> 1)
289
290 yield dut.bus.sel.eq(0b11)
291 yield Delay(1e-6)
292 self.assertEqual((yield dut.bus.dat_r), 0x0008)
293
294 yield dut.bus.sel.eq(0b01)
295 yield Delay(1e-6)
296 self.assertEqual((yield dut.bus.dat_r), 0x0008)
297
298 yield dut.bus.sel.eq(0b10)
299 yield Delay(1e-6)
300 self.assertEqual((yield dut.bus.dat_r), 0x0000)
301
302 yield dut.bus.adr.eq(0x30012 >> 1)
303
304 yield dut.bus.sel.eq(0b11)
305 yield Delay(1e-6)
306 self.assertEqual((yield dut.bus.dat_r), 0x0009)
307
308 yield dut.bus.adr.eq(0x40010 >> 1)
309
310 yield dut.bus.sel.eq(0b11)
311 yield Delay(1e-6)
312 self.assertEqual((yield dut.bus.dat_r), 0x08)
313
314 yield dut.bus.sel.eq(0b01)
315 yield Delay(1e-6)
316 self.assertEqual((yield dut.bus.dat_r), 0x08)
317
318 yield dut.bus.sel.eq(0b10)
319 yield Delay(1e-6)
320 self.assertEqual((yield dut.bus.dat_r), 0x00)
321
322 yield dut.bus.adr.eq(0x40012 >> 1)
323
324 yield dut.bus.sel.eq(0b11)
325 yield Delay(1e-6)
326 self.assertEqual((yield dut.bus.dat_r), 0x09)
327
328 m = Module()
329 m.submodules += dut, loop_1, loop_2, loop_3, loop_4
330 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
331 sim.add_process(sim_test())
332 sim.run()
333
334
335 class ArbiterTestCase(unittest.TestCase):
336 def setUp(self):
337 self.dut = Arbiter(addr_width=31, data_width=32, granularity=16)
338
339 def test_add_wrong(self):
340 with self.assertRaisesRegex(TypeError,
341 r"Initiator bus must be an instance of wishbone\.Interface, not 'foo'"):
342 self.dut.add("foo")
343
344 def test_add_wrong_addr_width(self):
345 with self.assertRaisesRegex(ValueError,
346 r"Initiator bus has address width 15, which is not the same as arbiter "
347 r"address width 31"):
348 self.dut.add(Interface(addr_width=15, data_width=32, granularity=16))
349
350 def test_add_wrong_granularity(self):
351 with self.assertRaisesRegex(ValueError,
352 r"Initiator bus has granularity 8, which is lesser than "
353 r"the arbiter granularity 16"):
354 self.dut.add(Interface(addr_width=31, data_width=32, granularity=8))
355
356 def test_add_wrong_data_width(self):
357 with self.assertRaisesRegex(ValueError,
358 r"Initiator bus has data width 16, which is not the same as arbiter "
359 r"data width 32"):
360 self.dut.add(Interface(addr_width=31, data_width=16, granularity=16))
361
362 def test_add_wrong_optional_output(self):
363 with self.assertRaisesRegex(ValueError,
364 r"Initiator bus has optional output 'lock', but the arbiter does "
365 r"not have a corresponding input"):
366 self.dut.add(Interface(addr_width=31, data_width=32, granularity=16,
367 features={"lock"}))
368
369
370 class ArbiterSimulationTestCase(unittest.TestCase):
371 def test_simple(self):
372 dut = Arbiter(addr_width=30, data_width=32, granularity=8,
373 features={"err", "rty", "stall", "lock", "cti", "bte"})
374 itor_1 = Interface(addr_width=30, data_width=32, granularity=8)
375 dut.add(itor_1)
376 itor_2 = Interface(addr_width=30, data_width=32, granularity=16,
377 features={"err", "rty", "stall", "lock", "cti", "bte"})
378 dut.add(itor_2)
379
380 def sim_test():
381 yield itor_1.adr.eq(0x7ffffffc >> 2)
382 yield itor_1.cyc.eq(1)
383 yield itor_1.stb.eq(1)
384 yield itor_1.sel.eq(0b1111)
385 yield itor_1.we.eq(1)
386 yield itor_1.dat_w.eq(0x12345678)
387 yield dut.bus.dat_r.eq(0xabcdef01)
388 yield dut.bus.ack.eq(1)
389 yield Delay(1e-7)
390 self.assertEqual((yield dut.bus.adr), 0x7ffffffc >> 2)
391 self.assertEqual((yield dut.bus.cyc), 1)
392 self.assertEqual((yield dut.bus.stb), 1)
393 self.assertEqual((yield dut.bus.sel), 0b1111)
394 self.assertEqual((yield dut.bus.we), 1)
395 self.assertEqual((yield dut.bus.dat_w), 0x12345678)
396 self.assertEqual((yield dut.bus.lock), 1)
397 self.assertEqual((yield dut.bus.cti), CycleType.CLASSIC.value)
398 self.assertEqual((yield dut.bus.bte), BurstTypeExt.LINEAR.value)
399 self.assertEqual((yield itor_1.dat_r), 0xabcdef01)
400 self.assertEqual((yield itor_1.ack), 1)
401
402 yield itor_1.cyc.eq(0)
403 yield itor_2.adr.eq(0xe0000000 >> 2)
404 yield itor_2.cyc.eq(1)
405 yield itor_2.stb.eq(1)
406 yield itor_2.sel.eq(0b10)
407 yield itor_2.we.eq(0)
408 yield itor_2.dat_w.eq(0x43218765)
409 yield itor_2.lock.eq(0)
410 yield itor_2.cti.eq(CycleType.INCR_BURST)
411 yield itor_2.bte.eq(BurstTypeExt.WRAP_4)
412 yield Tick()
413
414 yield dut.bus.err.eq(1)
415 yield dut.bus.rty.eq(1)
416 yield dut.bus.stall.eq(0)
417 yield Delay(1e-7)
418 self.assertEqual((yield dut.bus.adr), 0xe0000000 >> 2)
419 self.assertEqual((yield dut.bus.cyc), 1)
420 self.assertEqual((yield dut.bus.stb), 1)
421 self.assertEqual((yield dut.bus.sel), 0b1100)
422 self.assertEqual((yield dut.bus.we), 0)
423 self.assertEqual((yield dut.bus.dat_w), 0x43218765)
424 self.assertEqual((yield dut.bus.lock), 0)
425 self.assertEqual((yield dut.bus.cti), CycleType.INCR_BURST.value)
426 self.assertEqual((yield dut.bus.bte), BurstTypeExt.WRAP_4.value)
427 self.assertEqual((yield itor_2.dat_r), 0xabcdef01)
428 self.assertEqual((yield itor_2.ack), 1)
429 self.assertEqual((yield itor_2.err), 1)
430 self.assertEqual((yield itor_2.rty), 1)
431 self.assertEqual((yield itor_2.stall), 0)
432
433 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
434 sim.add_clock(1e-6)
435 sim.add_sync_process(sim_test())
436 sim.run()
437
438 def test_lock(self):
439 dut = Arbiter(addr_width=30, data_width=32, features={"lock"})
440 itor_1 = Interface(addr_width=30, data_width=32, features={"lock"})
441 dut.add(itor_1)
442 itor_2 = Interface(addr_width=30, data_width=32, features={"lock"})
443 dut.add(itor_2)
444
445 def sim_test():
446 yield itor_1.cyc.eq(1)
447 yield itor_1.lock.eq(1)
448 yield itor_2.cyc.eq(1)
449 yield dut.bus.ack.eq(1)
450 yield Delay(1e-7)
451 self.assertEqual((yield itor_1.ack), 1)
452 self.assertEqual((yield itor_2.ack), 0)
453
454 yield Tick()
455 yield Delay(1e-7)
456 self.assertEqual((yield itor_1.ack), 1)
457 self.assertEqual((yield itor_2.ack), 0)
458
459 yield itor_1.lock.eq(0)
460 yield Tick()
461 yield Delay(1e-7)
462 self.assertEqual((yield itor_1.ack), 0)
463 self.assertEqual((yield itor_2.ack), 1)
464
465 yield itor_2.cyc.eq(0)
466 yield Tick()
467 yield Delay(1e-7)
468 self.assertEqual((yield itor_1.ack), 1)
469 self.assertEqual((yield itor_2.ack), 0)
470
471 yield itor_1.stb.eq(1)
472 yield Tick()
473 yield Delay(1e-7)
474 self.assertEqual((yield itor_1.ack), 1)
475 self.assertEqual((yield itor_2.ack), 0)
476
477 yield itor_1.stb.eq(0)
478 yield itor_2.cyc.eq(1)
479 yield Tick()
480 yield Delay(1e-7)
481 self.assertEqual((yield itor_1.ack), 0)
482 self.assertEqual((yield itor_2.ack), 1)
483
484 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
485 sim.add_clock(1e-6)
486 sim.add_sync_process(sim_test())
487 sim.run()
488
489 def test_stall(self):
490 dut = Arbiter(addr_width=30, data_width=32, features={"stall"})
491 itor_1 = Interface(addr_width=30, data_width=32, features={"stall"})
492 dut.add(itor_1)
493 itor_2 = Interface(addr_width=30, data_width=32, features={"stall"})
494 dut.add(itor_2)
495
496 def sim_test():
497 yield itor_1.cyc.eq(1)
498 yield itor_2.cyc.eq(1)
499 yield dut.bus.stall.eq(0)
500 yield Delay(1e-6)
501 self.assertEqual((yield itor_1.stall), 0)
502 self.assertEqual((yield itor_2.stall), 1)
503
504 yield dut.bus.stall.eq(1)
505 yield Delay(1e-6)
506 self.assertEqual((yield itor_1.stall), 1)
507 self.assertEqual((yield itor_2.stall), 1)
508
509 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
510 sim.add_process(sim_test())
511 sim.run()
512
513 def test_stall_compat(self):
514 dut = Arbiter(addr_width=30, data_width=32)
515 itor_1 = Interface(addr_width=30, data_width=32, features={"stall"})
516 dut.add(itor_1)
517 itor_2 = Interface(addr_width=30, data_width=32, features={"stall"})
518 dut.add(itor_2)
519
520 def sim_test():
521 yield itor_1.cyc.eq(1)
522 yield itor_2.cyc.eq(1)
523 yield Delay(1e-6)
524 self.assertEqual((yield itor_1.stall), 1)
525 self.assertEqual((yield itor_2.stall), 1)
526
527 yield dut.bus.ack.eq(1)
528 yield Delay(1e-6)
529 self.assertEqual((yield itor_1.stall), 0)
530 self.assertEqual((yield itor_2.stall), 1)
531
532 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
533 sim.add_process(sim_test())
534 sim.run()
535
536 def test_roundrobin(self):
537 dut = Arbiter(addr_width=30, data_width=32)
538 itor_1 = Interface(addr_width=30, data_width=32)
539 dut.add(itor_1)
540 itor_2 = Interface(addr_width=30, data_width=32)
541 dut.add(itor_2)
542 itor_3 = Interface(addr_width=30, data_width=32)
543 dut.add(itor_3)
544
545 def sim_test():
546 yield itor_1.cyc.eq(1)
547 yield itor_2.cyc.eq(0)
548 yield itor_3.cyc.eq(1)
549 yield dut.bus.ack.eq(1)
550 yield Delay(1e-7)
551 self.assertEqual((yield itor_1.ack), 1)
552 self.assertEqual((yield itor_2.ack), 0)
553 self.assertEqual((yield itor_3.ack), 0)
554
555 yield itor_1.cyc.eq(0)
556 yield itor_2.cyc.eq(0)
557 yield itor_3.cyc.eq(1)
558 yield Tick()
559 yield Delay(1e-7)
560 self.assertEqual((yield itor_1.ack), 0)
561 self.assertEqual((yield itor_2.ack), 0)
562 self.assertEqual((yield itor_3.ack), 1)
563
564 yield itor_1.cyc.eq(1)
565 yield itor_2.cyc.eq(1)
566 yield itor_3.cyc.eq(0)
567 yield Tick()
568 yield Delay(1e-7)
569 self.assertEqual((yield itor_1.ack), 1)
570 self.assertEqual((yield itor_2.ack), 0)
571 self.assertEqual((yield itor_3.ack), 0)
572
573 yield itor_1.cyc.eq(0)
574 yield itor_2.cyc.eq(1)
575 yield itor_3.cyc.eq(1)
576 yield Tick()
577 yield Delay(1e-7)
578 self.assertEqual((yield itor_1.ack), 0)
579 self.assertEqual((yield itor_2.ack), 1)
580 self.assertEqual((yield itor_3.ack), 0)
581
582 yield itor_1.cyc.eq(1)
583 yield itor_2.cyc.eq(0)
584 yield itor_3.cyc.eq(1)
585 yield Tick()
586 yield Delay(1e-7)
587 self.assertEqual((yield itor_1.ack), 0)
588 self.assertEqual((yield itor_2.ack), 0)
589 self.assertEqual((yield itor_3.ack), 1)
590
591 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
592 sim.add_clock(1e-6)
593 sim.add_sync_process(sim_test())
594 sim.run()
595
596
597 class InterconnectSharedSimulationTestCase(unittest.TestCase):
598 def setUp(self):
599 self.shared = Interface(addr_width=30,
600 data_width=32,
601 granularity=8,
602 features={"err","cti","bte"},
603 name="shared")
604 self.master01 = Interface(addr_width=30,
605 data_width=32,
606 granularity=8,
607 features={"err","cti","bte"},
608 name="master01")
609 self.master02 = Record([
610 ("adr", 30, DIR_FANOUT),
611 ("dat_w", 32, DIR_FANOUT),
612 ("dat_r", 32, DIR_FANIN),
613 ("sel", 4, DIR_FANOUT),
614 ("cyc", 1, DIR_FANOUT),
615 ("stb", 1, DIR_FANOUT),
616 ("ack", 1, DIR_FANIN),
617 ("we", 1, DIR_FANOUT),
618 ("cti", 3, DIR_FANOUT),
619 ("bte", 2, DIR_FANOUT),
620 ("err", 1, DIR_FANIN)
621 ])
622 self.sub01 = Interface(addr_width=11,
623 data_width=32,
624 granularity=8,
625 features={"err","cti","bte"},
626 name="sub01")
627 self.sub02 = Interface(addr_width=21,
628 data_width=32,
629 granularity=8,
630 features={"err","cti","bte"},
631 name="sub02")
632 self.dut = InterconnectShared(
633 addr_width=30, data_width=32, granularity=8,
634 features={"err","cti","bte"},
635 itors=[
636 self.master01,
637 self.master02
638 ],
639 targets=[
640 (self.sub01, 0),
641 (self.sub02, (2**21) << 2)
642 ]
643 )
644
645 def test_basic(self):
646 def sim_test():
647 yield self.master01.adr.eq(0)
648 yield self.master02.adr.eq(2**21)
649 yield self.master01.we.eq(0)
650 yield self.master02.we.eq(0)
651 #
652 for _ in range(5):
653 yield self.master01.cyc.eq(1)
654 yield self.master02.cyc.eq(1)
655 yield
656 sub01_cyc = (yield self.sub01.cyc)
657 sub02_cyc = (yield self.sub02.cyc)
658 if sub01_cyc == 1:
659 yield self.master01.stb.eq(1)
660 yield
661 yield self.sub01.ack.eq(1)
662 yield self.master01.stb.eq(0)
663 yield
664 yield self.sub01.ack.eq(0)
665 yield self.master01.cyc.eq(0)
666 elif sub02_cyc == 1:
667 yield self.master02.stb.eq(1)
668 yield
669 yield self.sub02.ack.eq(1)
670 yield self.master02.stb.eq(0)
671 yield
672 yield self.sub02.ack.eq(0)
673 yield self.master02.cyc.eq(0)
674 yield
675
676 with Simulator(self.dut, vcd_file=open("test.vcd", "w")) as sim:
677 sim.add_clock(1e-6)
678 sim.add_sync_process(sim_test())
679 sim.run()