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