3afc57df26a8adc9ee2b697d3ade4a7a27e9fa73
[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 dut.add(sub_1, addr=0x10000)
141 sub_2 = Interface(addr_width=14, data_width=32, granularity=8,
142 features={"err", "rty", "stall", "lock", "cti", "bte"})
143 dut.add(sub_2)
144
145 def sim_test():
146 yield dut.bus.adr.eq(0x10400 >> 2)
147 yield dut.bus.cyc.eq(1)
148 yield dut.bus.stb.eq(1)
149 yield dut.bus.sel.eq(0b11)
150 yield dut.bus.dat_w.eq(0x12345678)
151 yield dut.bus.lock.eq(1)
152 yield dut.bus.cti.eq(CycleType.INCR_BURST)
153 yield dut.bus.bte.eq(BurstTypeExt.WRAP_4)
154 yield sub_1.ack.eq(1)
155 yield sub_1.dat_r.eq(0xabcdef01)
156 yield sub_2.dat_r.eq(0x5678abcd)
157 yield Delay(1e-6)
158 self.assertEqual((yield sub_1.adr), 0x400 >> 2)
159 self.assertEqual((yield sub_1.cyc), 1)
160 self.assertEqual((yield sub_2.cyc), 0)
161 self.assertEqual((yield sub_1.stb), 1)
162 self.assertEqual((yield sub_1.sel), 0b11)
163 self.assertEqual((yield sub_1.dat_w), 0x12345678)
164 self.assertEqual((yield dut.bus.ack), 1)
165 self.assertEqual((yield dut.bus.err), 0)
166 self.assertEqual((yield dut.bus.rty), 0)
167 self.assertEqual((yield dut.bus.dat_r), 0xabcdef01)
168
169 yield dut.bus.adr.eq(0x20400 >> 2)
170 yield sub_1.ack.eq(0)
171 yield sub_2.err.eq(1)
172 yield sub_2.rty.eq(1)
173 yield sub_2.stall.eq(1)
174 yield Delay(1e-6)
175 self.assertEqual((yield sub_2.adr), 0x400 >> 2)
176 self.assertEqual((yield sub_1.cyc), 0)
177 self.assertEqual((yield sub_2.cyc), 1)
178 self.assertEqual((yield sub_1.stb), 1)
179 self.assertEqual((yield sub_1.sel), 0b11)
180 self.assertEqual((yield sub_1.dat_w), 0x12345678)
181 self.assertEqual((yield sub_2.lock), 1)
182 self.assertEqual((yield sub_2.cti), CycleType.INCR_BURST.value)
183 self.assertEqual((yield sub_2.bte), BurstTypeExt.WRAP_4.value)
184 self.assertEqual((yield dut.bus.ack), 0)
185 self.assertEqual((yield dut.bus.err), 1)
186 self.assertEqual((yield dut.bus.rty), 1)
187 self.assertEqual((yield dut.bus.stall), 1)
188 self.assertEqual((yield dut.bus.dat_r), 0x5678abcd)
189
190 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
191 sim.add_process(sim_test())
192 sim.run()
193
194 def test_addr_translate(self):
195 class AddressLoopback(Elaboratable):
196 def __init__(self, **kwargs):
197 self.bus = Interface(**kwargs)
198
199 def elaborate(self, platform):
200 m = Module()
201
202 for index, sel_bit in enumerate(self.bus.sel):
203 with m.If(sel_bit):
204 segment = self.bus.dat_r.word_select(index, self.bus.granularity)
205 m.d.comb += segment.eq(self.bus.adr + index)
206
207 return m
208
209 dut = Decoder(addr_width=20, data_width=32, granularity=16)
210 loop_1 = AddressLoopback(addr_width=7, data_width=32, granularity=16)
211 self.assertEqual(dut.add(loop_1.bus, addr=0x10000),
212 (0x10000, 0x10100, 1))
213 loop_2 = AddressLoopback(addr_width=6, data_width=32, granularity=8)
214 self.assertEqual(dut.add(loop_2.bus, addr=0x20000),
215 (0x20000, 0x20080, 2))
216 loop_3 = AddressLoopback(addr_width=8, data_width=16, granularity=16)
217 self.assertEqual(dut.add(loop_3.bus, addr=0x30000, sparse=True),
218 (0x30000, 0x30100, 1))
219 loop_4 = AddressLoopback(addr_width=8, data_width=8, granularity=8)
220 self.assertEqual(dut.add(loop_4.bus, addr=0x40000, sparse=True),
221 (0x40000, 0x40100, 1))
222
223 def sim_test():
224 yield dut.bus.cyc.eq(1)
225
226 yield dut.bus.adr.eq(0x10010 >> 1)
227
228 yield dut.bus.sel.eq(0b11)
229 yield Delay(1e-6)
230 self.assertEqual((yield dut.bus.dat_r), 0x00090008)
231
232 yield dut.bus.sel.eq(0b01)
233 yield Delay(1e-6)
234 self.assertEqual((yield dut.bus.dat_r), 0x00000008)
235
236 yield dut.bus.sel.eq(0b10)
237 yield Delay(1e-6)
238 self.assertEqual((yield dut.bus.dat_r), 0x00090000)
239
240 yield dut.bus.adr.eq(0x20010 >> 1)
241
242 yield dut.bus.sel.eq(0b11)
243 yield Delay(1e-6)
244 self.assertEqual((yield dut.bus.dat_r), 0x13121110)
245
246 yield dut.bus.sel.eq(0b01)
247 yield Delay(1e-6)
248 self.assertEqual((yield dut.bus.dat_r), 0x00001110)
249
250 yield dut.bus.sel.eq(0b10)
251 yield Delay(1e-6)
252 self.assertEqual((yield dut.bus.dat_r), 0x13120000)
253
254 yield dut.bus.adr.eq(0x30010 >> 1)
255
256 yield dut.bus.sel.eq(0b11)
257 yield Delay(1e-6)
258 self.assertEqual((yield dut.bus.dat_r), 0x0008)
259
260 yield dut.bus.sel.eq(0b01)
261 yield Delay(1e-6)
262 self.assertEqual((yield dut.bus.dat_r), 0x0008)
263
264 yield dut.bus.sel.eq(0b10)
265 yield Delay(1e-6)
266 self.assertEqual((yield dut.bus.dat_r), 0x0000)
267
268 yield dut.bus.adr.eq(0x30012 >> 1)
269
270 yield dut.bus.sel.eq(0b11)
271 yield Delay(1e-6)
272 self.assertEqual((yield dut.bus.dat_r), 0x0009)
273
274 yield dut.bus.adr.eq(0x40010 >> 1)
275
276 yield dut.bus.sel.eq(0b11)
277 yield Delay(1e-6)
278 self.assertEqual((yield dut.bus.dat_r), 0x08)
279
280 yield dut.bus.sel.eq(0b01)
281 yield Delay(1e-6)
282 self.assertEqual((yield dut.bus.dat_r), 0x08)
283
284 yield dut.bus.sel.eq(0b10)
285 yield Delay(1e-6)
286 self.assertEqual((yield dut.bus.dat_r), 0x00)
287
288 yield dut.bus.adr.eq(0x40012 >> 1)
289
290 yield dut.bus.sel.eq(0b11)
291 yield Delay(1e-6)
292 self.assertEqual((yield dut.bus.dat_r), 0x09)
293
294 m = Module()
295 m.submodules += dut, loop_1, loop_2, loop_3, loop_4
296 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
297 sim.add_process(sim_test())
298 sim.run()
299
300
301 class ArbiterTestCase(unittest.TestCase):
302 def setUp(self):
303 self.dut = Arbiter(addr_width=31, data_width=32, granularity=16)
304
305 def test_add_wrong(self):
306 with self.assertRaisesRegex(TypeError,
307 r"Initiator bus must be an instance of wishbone\.Interface, not 'foo'"):
308 self.dut.add("foo")
309
310 def test_add_wrong_addr_width(self):
311 with self.assertRaisesRegex(ValueError,
312 r"Initiator bus has address width 15, which is not the same as arbiter "
313 r"address width 31"):
314 self.dut.add(Interface(addr_width=15, data_width=32, granularity=16))
315
316 def test_add_wrong_granularity(self):
317 with self.assertRaisesRegex(ValueError,
318 r"Initiator bus has granularity 8, which is lesser than "
319 r"the arbiter granularity 16"):
320 self.dut.add(Interface(addr_width=31, data_width=32, granularity=8))
321
322 def test_add_wrong_data_width(self):
323 with self.assertRaisesRegex(ValueError,
324 r"Initiator bus has data width 16, which is not the same as arbiter "
325 r"data width 32"):
326 self.dut.add(Interface(addr_width=31, data_width=16, granularity=16))
327
328 def test_add_wrong_optional_output(self):
329 with self.assertRaisesRegex(ValueError,
330 r"Initiator bus has optional output 'lock', but the arbiter does "
331 r"not have a corresponding input"):
332 self.dut.add(Interface(addr_width=31, data_width=32, granularity=16,
333 features={"lock"}))
334
335
336 class ArbiterSimulationTestCase(unittest.TestCase):
337 def test_simple(self):
338 dut = Arbiter(addr_width=30, data_width=32, granularity=8,
339 features={"err", "rty", "stall", "lock", "cti", "bte"})
340 itor_1 = Interface(addr_width=30, data_width=32, granularity=8)
341 dut.add(itor_1)
342 itor_2 = Interface(addr_width=30, data_width=32, granularity=16,
343 features={"err", "rty", "stall", "lock", "cti", "bte"})
344 dut.add(itor_2)
345
346 def sim_test():
347 yield itor_1.adr.eq(0x7ffffffc >> 2)
348 yield itor_1.cyc.eq(1)
349 yield itor_1.stb.eq(1)
350 yield itor_1.sel.eq(0b1111)
351 yield itor_1.we.eq(1)
352 yield itor_1.dat_w.eq(0x12345678)
353 yield dut.bus.dat_r.eq(0xabcdef01)
354 yield dut.bus.ack.eq(1)
355 yield Delay(1e-7)
356 self.assertEqual((yield dut.bus.adr), 0x7ffffffc >> 2)
357 self.assertEqual((yield dut.bus.cyc), 1)
358 self.assertEqual((yield dut.bus.stb), 1)
359 self.assertEqual((yield dut.bus.sel), 0b1111)
360 self.assertEqual((yield dut.bus.we), 1)
361 self.assertEqual((yield dut.bus.dat_w), 0x12345678)
362 self.assertEqual((yield dut.bus.lock), 1)
363 self.assertEqual((yield dut.bus.cti), CycleType.CLASSIC.value)
364 self.assertEqual((yield dut.bus.bte), BurstTypeExt.LINEAR.value)
365 self.assertEqual((yield itor_1.dat_r), 0xabcdef01)
366 self.assertEqual((yield itor_1.ack), 1)
367
368 yield itor_1.cyc.eq(0)
369 yield itor_2.adr.eq(0xe0000000 >> 2)
370 yield itor_2.cyc.eq(1)
371 yield itor_2.stb.eq(1)
372 yield itor_2.sel.eq(0b10)
373 yield itor_2.we.eq(1)
374 yield itor_2.dat_w.eq(0x43218765)
375 yield itor_2.lock.eq(0)
376 yield itor_2.cti.eq(CycleType.INCR_BURST)
377 yield itor_2.bte.eq(BurstTypeExt.WRAP_4)
378 yield Tick()
379
380 yield dut.bus.err.eq(1)
381 yield dut.bus.rty.eq(1)
382 yield dut.bus.stall.eq(0)
383 yield Delay(1e-7)
384 self.assertEqual((yield dut.bus.adr), 0xe0000000 >> 2)
385 self.assertEqual((yield dut.bus.cyc), 1)
386 self.assertEqual((yield dut.bus.stb), 1)
387 self.assertEqual((yield dut.bus.sel), 0b1100)
388 self.assertEqual((yield dut.bus.we), 1)
389 self.assertEqual((yield dut.bus.dat_w), 0x43218765)
390 self.assertEqual((yield dut.bus.lock), 0)
391 self.assertEqual((yield dut.bus.cti), CycleType.INCR_BURST.value)
392 self.assertEqual((yield dut.bus.bte), BurstTypeExt.WRAP_4.value)
393 self.assertEqual((yield itor_2.dat_r), 0xabcdef01)
394 self.assertEqual((yield itor_2.ack), 1)
395 self.assertEqual((yield itor_2.err), 1)
396 self.assertEqual((yield itor_2.rty), 1)
397 self.assertEqual((yield itor_2.stall), 0)
398
399 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
400 sim.add_clock(1e-6)
401 sim.add_sync_process(sim_test())
402 sim.run()
403
404 def test_lock(self):
405 dut = Arbiter(addr_width=30, data_width=32, features={"lock"})
406 itor_1 = Interface(addr_width=30, data_width=32, features={"lock"})
407 dut.add(itor_1)
408 itor_2 = Interface(addr_width=30, data_width=32, features={"lock"})
409 dut.add(itor_2)
410
411 def sim_test():
412 yield itor_1.cyc.eq(1)
413 yield itor_1.lock.eq(1)
414 yield itor_2.cyc.eq(1)
415 yield dut.bus.ack.eq(1)
416 yield Delay(1e-7)
417 self.assertEqual((yield itor_1.ack), 1)
418 self.assertEqual((yield itor_2.ack), 0)
419
420 yield Tick()
421 yield Delay(1e-7)
422 self.assertEqual((yield itor_1.ack), 1)
423 self.assertEqual((yield itor_2.ack), 0)
424
425 yield itor_1.lock.eq(0)
426 yield Tick()
427 yield Delay(1e-7)
428 self.assertEqual((yield itor_1.ack), 0)
429 self.assertEqual((yield itor_2.ack), 1)
430
431 yield itor_2.cyc.eq(0)
432 yield Tick()
433 yield Delay(1e-7)
434 self.assertEqual((yield itor_1.ack), 1)
435 self.assertEqual((yield itor_2.ack), 0)
436
437 yield itor_1.stb.eq(1)
438 yield Tick()
439 yield Delay(1e-7)
440 self.assertEqual((yield itor_1.ack), 1)
441 self.assertEqual((yield itor_2.ack), 0)
442
443 yield itor_1.stb.eq(0)
444 yield itor_2.cyc.eq(1)
445 yield Tick()
446 yield Delay(1e-7)
447 self.assertEqual((yield itor_1.ack), 0)
448 self.assertEqual((yield itor_2.ack), 1)
449
450 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
451 sim.add_clock(1e-6)
452 sim.add_sync_process(sim_test())
453 sim.run()
454
455 def test_stall(self):
456 dut = Arbiter(addr_width=30, data_width=32, features={"stall"})
457 itor_1 = Interface(addr_width=30, data_width=32, features={"stall"})
458 dut.add(itor_1)
459 itor_2 = Interface(addr_width=30, data_width=32, features={"stall"})
460 dut.add(itor_2)
461
462 def sim_test():
463 yield itor_1.cyc.eq(1)
464 yield itor_2.cyc.eq(1)
465 yield dut.bus.stall.eq(0)
466 yield Delay(1e-6)
467 self.assertEqual((yield itor_1.stall), 0)
468 self.assertEqual((yield itor_2.stall), 1)
469
470 yield dut.bus.stall.eq(1)
471 yield Delay(1e-6)
472 self.assertEqual((yield itor_1.stall), 1)
473 self.assertEqual((yield itor_2.stall), 1)
474
475 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
476 sim.add_process(sim_test())
477 sim.run()
478
479 def test_stall_compat(self):
480 dut = Arbiter(addr_width=30, data_width=32)
481 itor_1 = Interface(addr_width=30, data_width=32, features={"stall"})
482 dut.add(itor_1)
483 itor_2 = Interface(addr_width=30, data_width=32, features={"stall"})
484 dut.add(itor_2)
485
486 def sim_test():
487 yield itor_1.cyc.eq(1)
488 yield itor_2.cyc.eq(1)
489 yield Delay(1e-6)
490 self.assertEqual((yield itor_1.stall), 1)
491 self.assertEqual((yield itor_2.stall), 1)
492
493 yield dut.bus.ack.eq(1)
494 yield Delay(1e-6)
495 self.assertEqual((yield itor_1.stall), 0)
496 self.assertEqual((yield itor_2.stall), 1)
497
498 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
499 sim.add_process(sim_test())
500 sim.run()
501
502 def test_roundrobin(self):
503 dut = Arbiter(addr_width=30, data_width=32)
504 itor_1 = Interface(addr_width=30, data_width=32)
505 dut.add(itor_1)
506 itor_2 = Interface(addr_width=30, data_width=32)
507 dut.add(itor_2)
508 itor_3 = Interface(addr_width=30, data_width=32)
509 dut.add(itor_3)
510
511 def sim_test():
512 yield itor_1.cyc.eq(1)
513 yield itor_2.cyc.eq(0)
514 yield itor_3.cyc.eq(1)
515 yield dut.bus.ack.eq(1)
516 yield Delay(1e-7)
517 self.assertEqual((yield itor_1.ack), 1)
518 self.assertEqual((yield itor_2.ack), 0)
519 self.assertEqual((yield itor_3.ack), 0)
520
521 yield itor_1.cyc.eq(0)
522 yield itor_2.cyc.eq(0)
523 yield itor_3.cyc.eq(1)
524 yield Tick()
525 yield Delay(1e-7)
526 self.assertEqual((yield itor_1.ack), 0)
527 self.assertEqual((yield itor_2.ack), 0)
528 self.assertEqual((yield itor_3.ack), 1)
529
530 yield itor_1.cyc.eq(1)
531 yield itor_2.cyc.eq(1)
532 yield itor_3.cyc.eq(0)
533 yield Tick()
534 yield Delay(1e-7)
535 self.assertEqual((yield itor_1.ack), 1)
536 self.assertEqual((yield itor_2.ack), 0)
537 self.assertEqual((yield itor_3.ack), 0)
538
539 yield itor_1.cyc.eq(0)
540 yield itor_2.cyc.eq(1)
541 yield itor_3.cyc.eq(1)
542 yield Tick()
543 yield Delay(1e-7)
544 self.assertEqual((yield itor_1.ack), 0)
545 self.assertEqual((yield itor_2.ack), 1)
546 self.assertEqual((yield itor_3.ack), 0)
547
548 yield itor_1.cyc.eq(1)
549 yield itor_2.cyc.eq(0)
550 yield itor_3.cyc.eq(1)
551 yield Tick()
552 yield Delay(1e-7)
553 self.assertEqual((yield itor_1.ack), 0)
554 self.assertEqual((yield itor_2.ack), 0)
555 self.assertEqual((yield itor_3.ack), 1)
556
557 with Simulator(dut, vcd_file=open("test.vcd", "w")) as sim:
558 sim.add_clock(1e-6)
559 sim.add_sync_process(sim_test())
560 sim.run()
561
562
563 class InterconnectSharedSimulationTestCase(unittest.TestCase):
564 def setUp(self):
565 self.shared = Interface(addr_width=30,
566 data_width=32,
567 granularity=8,
568 features={"err","cti","bte"},
569 name="shared")
570 self.master01 = Interface(addr_width=30,
571 data_width=32,
572 granularity=8,
573 features={"err","cti","bte"},
574 name="master01")
575 self.master02 = Record([
576 ("adr", 30, DIR_FANOUT),
577 ("dat_w", 32, DIR_FANOUT),
578 ("dat_r", 32, DIR_FANIN),
579 ("sel", 4, DIR_FANOUT),
580 ("cyc", 1, DIR_FANOUT),
581 ("stb", 1, DIR_FANOUT),
582 ("ack", 1, DIR_FANIN),
583 ("we", 1, DIR_FANOUT),
584 ("cti", 3, DIR_FANOUT),
585 ("bte", 2, DIR_FANOUT),
586 ("err", 1, DIR_FANIN)
587 ])
588 self.ram = SRAM(Memory(width=32, depth=2048, init=[]),
589 granularity=8, features={"err","cti","bte"})
590 self.sub01 = Interface(addr_width=21,
591 data_width=32,
592 granularity=8,
593 features={"err","cti","bte"},
594 name="sub01")
595 self.dut = InterconnectShared(
596 addr_width=30, data_width=32, granularity=8,
597 features={"err","cti","bte"},
598 itors=[
599 self.master01,
600 self.master02
601 ],
602 targets=[
603 (self.ram.bus, 0),
604 (self.sub01, (2**21) << 2)
605 ]
606 )
607
608 def test_basic(self):
609 def sim_test():
610 yield self.master01.adr.eq(0)
611 yield self.master02.adr.eq(2**21)
612 yield self.master01.we.eq(0)
613 yield self.master02.we.eq(0)
614 #
615 for _ in range(5):
616 yield self.master01.cyc.eq(1)
617 yield self.master02.cyc.eq(1)
618 yield
619 ram_cyc = (yield self.ram.bus.cyc)
620 sub01_cyc = (yield self.sub01.cyc)
621 if ram_cyc == 1:
622 yield self.master01.stb.eq(1)
623 yield
624 yield self.ram.bus.ack.eq(1)
625 yield self.master01.stb.eq(0)
626 yield
627 yield self.ram.bus.ack.eq(0)
628 yield self.master01.cyc.eq(0)
629 elif sub01_cyc == 1:
630 yield self.master02.stb.eq(1)
631 yield
632 yield self.sub01.ack.eq(1)
633 yield self.master02.stb.eq(0)
634 yield
635 yield self.sub01.ack.eq(0)
636 yield self.master02.cyc.eq(0)
637 yield
638
639 m = Module()
640 m.submodules += self.dut, self.ram
641 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
642 sim.add_clock(1e-6)
643 sim.add_sync_process(sim_test())
644 sim.run()