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 nmigen_soc
.wishbone
import (Interface
, CycleType
, Decoder
,
10 Arbiter
, BurstTypeExt
)
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
),
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
),
50 def test_features(self
):
51 iface
= Interface(addr_width
=32, data_width
=32,
52 features
={"rty", "err", "stall", "lock",
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
),
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)
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)
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)
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)
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"})
97 class DecoderTestCase(unittest
.TestCase
):
99 self
.dut
= Decoder(addr_width
=31, data_width
=32, granularity
=16)
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))
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'"):
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,
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 "
125 r
"data width 32 \(required for dense address translation\)"):
126 self
.dut
.add(Interface(addr_width
=15, data_width
=16,
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)
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"}))
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",
156 self
.assertEqual(dut
.add(sub_2
),
157 (0x20000, 0x30000, 1))
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)
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)
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)
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)
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)
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)
229 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
230 sim
.add_process(sim_test())
233 def test_addr_translate(self
):
234 class AddressLoopback(Elaboratable
):
235 def __init__(self
, **kwargs
):
236 self
.bus
= Interface(**kwargs
)
238 def elaborate(self
, platform
):
241 for index
, sel_bit
in enumerate(self
.bus
.sel
):
243 segment
= self
.bus
.dat_r
.word_select(index
,
244 self
.bus
.granularity
)
245 m
.d
.comb
+= segment
.eq(self
.bus
.adr
+ index
)
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))
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
271 yield dut
.bus
.cyc
.eq(1)
273 yield dut
.bus
.adr
.eq(0x10010 >> 1)
275 yield dut
.bus
.sel
.eq(0b11)
277 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00090008)
279 yield dut
.bus
.sel
.eq(0b01)
281 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00000008)
283 yield dut
.bus
.sel
.eq(0b10)
285 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00090000)
287 yield dut
.bus
.adr
.eq(0x20010 >> 1)
289 yield dut
.bus
.sel
.eq(0b11)
291 self
.assertEqual((yield dut
.bus
.dat_r
), 0x13121110)
293 yield dut
.bus
.sel
.eq(0b01)
295 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00001110)
297 yield dut
.bus
.sel
.eq(0b10)
299 self
.assertEqual((yield dut
.bus
.dat_r
), 0x13120000)
301 yield dut
.bus
.adr
.eq(0x30010 >> 1)
303 yield dut
.bus
.sel
.eq(0b11)
305 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0008)
307 yield dut
.bus
.sel
.eq(0b01)
309 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0008)
311 yield dut
.bus
.sel
.eq(0b10)
313 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0000)
315 yield dut
.bus
.adr
.eq(0x30012 >> 1)
317 yield dut
.bus
.sel
.eq(0b11)
319 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0009)
321 yield dut
.bus
.adr
.eq(0x40010 >> 1)
323 yield dut
.bus
.sel
.eq(0b11)
325 self
.assertEqual((yield dut
.bus
.dat_r
), 0x08)
327 yield dut
.bus
.sel
.eq(0b01)
329 self
.assertEqual((yield dut
.bus
.dat_r
), 0x08)
331 yield dut
.bus
.sel
.eq(0b10)
333 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00)
335 yield dut
.bus
.adr
.eq(0x40012 >> 1)
337 yield dut
.bus
.sel
.eq(0b11)
339 self
.assertEqual((yield dut
.bus
.dat_r
), 0x09)
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())
348 class ArbiterTestCase(unittest
.TestCase
):
350 self
.dut
= Arbiter(addr_width
=31, data_width
=32, granularity
=16)
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'"):
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,
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,
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 "
378 self
.dut
.add(Interface(addr_width
=31, data_width
=16,
381 def test_add_wrong_optional_output(self
):
382 with self
.assertRaisesRegex(ValueError,
383 r
"Initiator bus has optional output 'lock', but "
385 r
"not have a corresponding input"):
386 self
.dut
.add(Interface(addr_width
=31, data_width
=32, granularity
=16,
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)
396 itor_2
= Interface(addr_width
=30, data_width
=32, granularity
=16,
397 features
={"err", "rty", "stall", "lock",
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)
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)
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
)
435 yield dut
.bus
.err
.eq(1)
436 yield dut
.bus
.rty
.eq(1)
437 yield dut
.bus
.stall
.eq(0)
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)
454 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
456 sim
.add_sync_process(sim_test())
460 dut
= Arbiter(addr_width
=30, data_width
=32, features
={"lock"})
461 itor_1
= Interface(addr_width
=30, data_width
=32, features
={"lock"})
463 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"lock"})
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)
472 self
.assertEqual((yield itor_1
.ack
), 1)
473 self
.assertEqual((yield itor_2
.ack
), 0)
477 self
.assertEqual((yield itor_1
.ack
), 1)
478 self
.assertEqual((yield itor_2
.ack
), 0)
480 yield itor_1
.lock
.eq(0)
483 self
.assertEqual((yield itor_1
.ack
), 0)
484 self
.assertEqual((yield itor_2
.ack
), 1)
486 yield itor_2
.cyc
.eq(0)
489 self
.assertEqual((yield itor_1
.ack
), 1)
490 self
.assertEqual((yield itor_2
.ack
), 0)
492 yield itor_1
.stb
.eq(1)
495 self
.assertEqual((yield itor_1
.ack
), 1)
496 self
.assertEqual((yield itor_2
.ack
), 0)
498 yield itor_1
.stb
.eq(0)
499 yield itor_2
.cyc
.eq(1)
502 self
.assertEqual((yield itor_1
.ack
), 0)
503 self
.assertEqual((yield itor_2
.ack
), 1)
505 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
507 sim
.add_sync_process(sim_test())
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"})
514 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"stall"})
518 yield itor_1
.cyc
.eq(1)
519 yield itor_2
.cyc
.eq(1)
520 yield dut
.bus
.stall
.eq(0)
522 self
.assertEqual((yield itor_1
.stall
), 0)
523 self
.assertEqual((yield itor_2
.stall
), 1)
525 yield dut
.bus
.stall
.eq(1)
527 self
.assertEqual((yield itor_1
.stall
), 1)
528 self
.assertEqual((yield itor_2
.stall
), 1)
530 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
531 sim
.add_process(sim_test())
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"})
538 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"stall"})
542 yield itor_1
.cyc
.eq(1)
543 yield itor_2
.cyc
.eq(1)
545 self
.assertEqual((yield itor_1
.stall
), 1)
546 self
.assertEqual((yield itor_2
.stall
), 1)
548 yield dut
.bus
.ack
.eq(1)
550 self
.assertEqual((yield itor_1
.stall
), 0)
551 self
.assertEqual((yield itor_2
.stall
), 1)
553 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
554 sim
.add_process(sim_test())
557 def test_roundrobin(self
):
558 dut
= Arbiter(addr_width
=30, data_width
=32)
559 itor_1
= Interface(addr_width
=30, data_width
=32)
561 itor_2
= Interface(addr_width
=30, data_width
=32)
563 itor_3
= Interface(addr_width
=30, data_width
=32)
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)
572 self
.assertEqual((yield itor_1
.ack
), 1)
573 self
.assertEqual((yield itor_2
.ack
), 0)
574 self
.assertEqual((yield itor_3
.ack
), 0)
576 yield itor_1
.cyc
.eq(0)
577 yield itor_2
.cyc
.eq(0)
578 yield itor_3
.cyc
.eq(1)
581 self
.assertEqual((yield itor_1
.ack
), 0)
582 self
.assertEqual((yield itor_2
.ack
), 0)
583 self
.assertEqual((yield itor_3
.ack
), 1)
585 yield itor_1
.cyc
.eq(1)
586 yield itor_2
.cyc
.eq(1)
587 yield itor_3
.cyc
.eq(0)
590 self
.assertEqual((yield itor_1
.ack
), 1)
591 self
.assertEqual((yield itor_2
.ack
), 0)
592 self
.assertEqual((yield itor_3
.ack
), 0)
594 yield itor_1
.cyc
.eq(0)
595 yield itor_2
.cyc
.eq(1)
596 yield itor_3
.cyc
.eq(1)
599 self
.assertEqual((yield itor_1
.ack
), 0)
600 self
.assertEqual((yield itor_2
.ack
), 1)
601 self
.assertEqual((yield itor_3
.ack
), 0)
603 yield itor_1
.cyc
.eq(1)
604 yield itor_2
.cyc
.eq(0)
605 yield itor_3
.cyc
.eq(1)
608 self
.assertEqual((yield itor_1
.ack
), 0)
609 self
.assertEqual((yield itor_2
.ack
), 0)
610 self
.assertEqual((yield itor_3
.ack
), 1)
612 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
614 sim
.add_sync_process(sim_test())
618 class InterconnectSharedSimulationTestCase(unittest
.TestCase
):
620 self
.shared
= Interface(addr_width
=30,
623 features
={"err", "cti", "bte"},
625 self
.master01
= Interface(addr_width
=30,
628 features
={"err", "cti", "bte"},
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
)
643 self
.sub01
= Interface(addr_width
=11,
646 features
={"err", "cti", "bte"},
648 self
.sub02
= Interface(addr_width
=21,
651 features
={"err", "cti", "bte"},
653 self
.dut
= InterconnectShared(
654 addr_width
=30, data_width
=32, granularity
=8,
655 features
={"err", "cti", "bte"},
662 (self
.sub02
, (2**21) << 2)
666 def test_basic(self
):
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)
674 yield self
.master01
.cyc
.eq(1)
675 yield self
.master02
.cyc
.eq(1)
677 sub01_cyc
= (yield self
.sub01
.cyc
)
678 sub02_cyc
= (yield self
.sub02
.cyc
)
680 yield self
.master01
.stb
.eq(1)
682 yield self
.sub01
.ack
.eq(1)
683 yield self
.master01
.stb
.eq(0)
685 yield self
.sub01
.ack
.eq(0)
686 yield self
.master01
.cyc
.eq(0)
688 yield self
.master02
.stb
.eq(1)
690 yield self
.sub02
.ack
.eq(1)
691 yield self
.master02
.stb
.eq(0)
693 yield self
.sub02
.ack
.eq(0)
694 yield self
.master02
.cyc
.eq(0)
697 with
Simulator(self
.dut
, vcd_file
=open("test.vcd", "w")) as sim
:
699 sim
.add_sync_process(sim_test())