1 # nmigen: UnusedElaboratable=no
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
8 from ..wishbone
import *
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
),
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
),
48 def test_features(self
):
49 iface
= Interface(addr_width
=32, data_width
=32,
50 features
={"rty", "err", "stall", "lock",
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
),
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)
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)
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)
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)
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"})
95 class DecoderTestCase(unittest
.TestCase
):
97 self
.dut
= Decoder(addr_width
=31, data_width
=32, granularity
=16)
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))
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'"):
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,
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 "
123 r
"data width 32 \(required for dense address translation\)"):
124 self
.dut
.add(Interface(addr_width
=15, data_width
=16,
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)
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"}))
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",
154 self
.assertEqual(dut
.add(sub_2
),
155 (0x20000, 0x30000, 1))
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)
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)
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)
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)
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)
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)
227 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
228 sim
.add_process(sim_test())
231 def test_addr_translate(self
):
232 class AddressLoopback(Elaboratable
):
233 def __init__(self
, **kwargs
):
234 self
.bus
= Interface(**kwargs
)
236 def elaborate(self
, platform
):
239 for index
, sel_bit
in enumerate(self
.bus
.sel
):
241 segment
= self
.bus
.dat_r
.word_select(index
,
242 self
.bus
.granularity
)
243 m
.d
.comb
+= segment
.eq(self
.bus
.adr
+ index
)
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))
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
269 yield dut
.bus
.cyc
.eq(1)
271 yield dut
.bus
.adr
.eq(0x10010 >> 1)
273 yield dut
.bus
.sel
.eq(0b11)
275 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00090008)
277 yield dut
.bus
.sel
.eq(0b01)
279 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00000008)
281 yield dut
.bus
.sel
.eq(0b10)
283 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00090000)
285 yield dut
.bus
.adr
.eq(0x20010 >> 1)
287 yield dut
.bus
.sel
.eq(0b11)
289 self
.assertEqual((yield dut
.bus
.dat_r
), 0x13121110)
291 yield dut
.bus
.sel
.eq(0b01)
293 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00001110)
295 yield dut
.bus
.sel
.eq(0b10)
297 self
.assertEqual((yield dut
.bus
.dat_r
), 0x13120000)
299 yield dut
.bus
.adr
.eq(0x30010 >> 1)
301 yield dut
.bus
.sel
.eq(0b11)
303 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0008)
305 yield dut
.bus
.sel
.eq(0b01)
307 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0008)
309 yield dut
.bus
.sel
.eq(0b10)
311 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0000)
313 yield dut
.bus
.adr
.eq(0x30012 >> 1)
315 yield dut
.bus
.sel
.eq(0b11)
317 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0009)
319 yield dut
.bus
.adr
.eq(0x40010 >> 1)
321 yield dut
.bus
.sel
.eq(0b11)
323 self
.assertEqual((yield dut
.bus
.dat_r
), 0x08)
325 yield dut
.bus
.sel
.eq(0b01)
327 self
.assertEqual((yield dut
.bus
.dat_r
), 0x08)
329 yield dut
.bus
.sel
.eq(0b10)
331 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00)
333 yield dut
.bus
.adr
.eq(0x40012 >> 1)
335 yield dut
.bus
.sel
.eq(0b11)
337 self
.assertEqual((yield dut
.bus
.dat_r
), 0x09)
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())
346 class ArbiterTestCase(unittest
.TestCase
):
348 self
.dut
= Arbiter(addr_width
=31, data_width
=32, granularity
=16)
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'"):
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,
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,
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 "
376 self
.dut
.add(Interface(addr_width
=31, data_width
=16,
379 def test_add_wrong_optional_output(self
):
380 with self
.assertRaisesRegex(ValueError,
381 r
"Initiator bus has optional output 'lock', but "
383 r
"not have a corresponding input"):
384 self
.dut
.add(Interface(addr_width
=31, data_width
=32, granularity
=16,
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)
394 itor_2
= Interface(addr_width
=30, data_width
=32, granularity
=16,
395 features
={"err", "rty", "stall", "lock",
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)
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)
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
)
433 yield dut
.bus
.err
.eq(1)
434 yield dut
.bus
.rty
.eq(1)
435 yield dut
.bus
.stall
.eq(0)
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)
452 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
454 sim
.add_sync_process(sim_test())
458 dut
= Arbiter(addr_width
=30, data_width
=32, features
={"lock"})
459 itor_1
= Interface(addr_width
=30, data_width
=32, features
={"lock"})
461 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"lock"})
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)
470 self
.assertEqual((yield itor_1
.ack
), 1)
471 self
.assertEqual((yield itor_2
.ack
), 0)
475 self
.assertEqual((yield itor_1
.ack
), 1)
476 self
.assertEqual((yield itor_2
.ack
), 0)
478 yield itor_1
.lock
.eq(0)
481 self
.assertEqual((yield itor_1
.ack
), 0)
482 self
.assertEqual((yield itor_2
.ack
), 1)
484 yield itor_2
.cyc
.eq(0)
487 self
.assertEqual((yield itor_1
.ack
), 1)
488 self
.assertEqual((yield itor_2
.ack
), 0)
490 yield itor_1
.stb
.eq(1)
493 self
.assertEqual((yield itor_1
.ack
), 1)
494 self
.assertEqual((yield itor_2
.ack
), 0)
496 yield itor_1
.stb
.eq(0)
497 yield itor_2
.cyc
.eq(1)
500 self
.assertEqual((yield itor_1
.ack
), 0)
501 self
.assertEqual((yield itor_2
.ack
), 1)
503 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
505 sim
.add_sync_process(sim_test())
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"})
512 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"stall"})
516 yield itor_1
.cyc
.eq(1)
517 yield itor_2
.cyc
.eq(1)
518 yield dut
.bus
.stall
.eq(0)
520 self
.assertEqual((yield itor_1
.stall
), 0)
521 self
.assertEqual((yield itor_2
.stall
), 1)
523 yield dut
.bus
.stall
.eq(1)
525 self
.assertEqual((yield itor_1
.stall
), 1)
526 self
.assertEqual((yield itor_2
.stall
), 1)
528 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
529 sim
.add_process(sim_test())
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"})
536 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"stall"})
540 yield itor_1
.cyc
.eq(1)
541 yield itor_2
.cyc
.eq(1)
543 self
.assertEqual((yield itor_1
.stall
), 1)
544 self
.assertEqual((yield itor_2
.stall
), 1)
546 yield dut
.bus
.ack
.eq(1)
548 self
.assertEqual((yield itor_1
.stall
), 0)
549 self
.assertEqual((yield itor_2
.stall
), 1)
551 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
552 sim
.add_process(sim_test())
555 def test_roundrobin(self
):
556 dut
= Arbiter(addr_width
=30, data_width
=32)
557 itor_1
= Interface(addr_width
=30, data_width
=32)
559 itor_2
= Interface(addr_width
=30, data_width
=32)
561 itor_3
= Interface(addr_width
=30, data_width
=32)
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)
570 self
.assertEqual((yield itor_1
.ack
), 1)
571 self
.assertEqual((yield itor_2
.ack
), 0)
572 self
.assertEqual((yield itor_3
.ack
), 0)
574 yield itor_1
.cyc
.eq(0)
575 yield itor_2
.cyc
.eq(0)
576 yield itor_3
.cyc
.eq(1)
579 self
.assertEqual((yield itor_1
.ack
), 0)
580 self
.assertEqual((yield itor_2
.ack
), 0)
581 self
.assertEqual((yield itor_3
.ack
), 1)
583 yield itor_1
.cyc
.eq(1)
584 yield itor_2
.cyc
.eq(1)
585 yield itor_3
.cyc
.eq(0)
588 self
.assertEqual((yield itor_1
.ack
), 1)
589 self
.assertEqual((yield itor_2
.ack
), 0)
590 self
.assertEqual((yield itor_3
.ack
), 0)
592 yield itor_1
.cyc
.eq(0)
593 yield itor_2
.cyc
.eq(1)
594 yield itor_3
.cyc
.eq(1)
597 self
.assertEqual((yield itor_1
.ack
), 0)
598 self
.assertEqual((yield itor_2
.ack
), 1)
599 self
.assertEqual((yield itor_3
.ack
), 0)
601 yield itor_1
.cyc
.eq(1)
602 yield itor_2
.cyc
.eq(0)
603 yield itor_3
.cyc
.eq(1)
606 self
.assertEqual((yield itor_1
.ack
), 0)
607 self
.assertEqual((yield itor_2
.ack
), 0)
608 self
.assertEqual((yield itor_3
.ack
), 1)
610 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
612 sim
.add_sync_process(sim_test())
616 class InterconnectSharedSimulationTestCase(unittest
.TestCase
):
618 self
.shared
= Interface(addr_width
=30,
621 features
={"err", "cti", "bte"},
623 self
.master01
= Interface(addr_width
=30,
626 features
={"err", "cti", "bte"},
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
)
641 self
.sub01
= Interface(addr_width
=11,
644 features
={"err", "cti", "bte"},
646 self
.sub02
= Interface(addr_width
=21,
649 features
={"err", "cti", "bte"},
651 self
.dut
= InterconnectShared(
652 addr_width
=30, data_width
=32, granularity
=8,
653 features
={"err", "cti", "bte"},
660 (self
.sub02
, (2**21) << 2)
664 def test_basic(self
):
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)
672 yield self
.master01
.cyc
.eq(1)
673 yield self
.master02
.cyc
.eq(1)
675 sub01_cyc
= (yield self
.sub01
.cyc
)
676 sub02_cyc
= (yield self
.sub02
.cyc
)
678 yield self
.master01
.stb
.eq(1)
680 yield self
.sub01
.ack
.eq(1)
681 yield self
.master01
.stb
.eq(0)
683 yield self
.sub01
.ack
.eq(0)
684 yield self
.master01
.cyc
.eq(0)
686 yield self
.master02
.stb
.eq(1)
688 yield self
.sub02
.ack
.eq(1)
689 yield self
.master02
.stb
.eq(0)
691 yield self
.sub02
.ack
.eq(0)
692 yield self
.master02
.cyc
.eq(0)
695 with
Simulator(self
.dut
, vcd_file
=open("test.vcd", "w")) as sim
:
697 sim
.add_sync_process(sim_test())