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