1 # nmigen: UnusedElaboratable=no
5 from nmigen
.hdl
.rec
import *
6 from nmigen
.back
.pysim
import *
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", "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
),
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)
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)
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)
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)
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"})
94 class DecoderTestCase(unittest
.TestCase
):
96 self
.dut
= Decoder(addr_width
=31, data_width
=32, granularity
=16)
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))
105 def test_add_wrong(self
):
106 with self
.assertRaisesRegex(TypeError,
107 r
"Subordinate bus must be an instance of wishbone\.Interface, not 'foo'"):
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))
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))
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)
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"}))
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"})
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)
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)
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)
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)
190 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
191 sim
.add_process(sim_test())
194 def test_addr_translate(self
):
195 class AddressLoopback(Elaboratable
):
196 def __init__(self
, **kwargs
):
197 self
.bus
= Interface(**kwargs
)
199 def elaborate(self
, platform
):
202 for index
, sel_bit
in enumerate(self
.bus
.sel
):
204 segment
= self
.bus
.dat_r
.word_select(index
, self
.bus
.granularity
)
205 m
.d
.comb
+= segment
.eq(self
.bus
.adr
+ index
)
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))
224 yield dut
.bus
.cyc
.eq(1)
226 yield dut
.bus
.adr
.eq(0x10010 >> 1)
228 yield dut
.bus
.sel
.eq(0b11)
230 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00090008)
232 yield dut
.bus
.sel
.eq(0b01)
234 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00000008)
236 yield dut
.bus
.sel
.eq(0b10)
238 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00090000)
240 yield dut
.bus
.adr
.eq(0x20010 >> 1)
242 yield dut
.bus
.sel
.eq(0b11)
244 self
.assertEqual((yield dut
.bus
.dat_r
), 0x13121110)
246 yield dut
.bus
.sel
.eq(0b01)
248 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00001110)
250 yield dut
.bus
.sel
.eq(0b10)
252 self
.assertEqual((yield dut
.bus
.dat_r
), 0x13120000)
254 yield dut
.bus
.adr
.eq(0x30010 >> 1)
256 yield dut
.bus
.sel
.eq(0b11)
258 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0008)
260 yield dut
.bus
.sel
.eq(0b01)
262 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0008)
264 yield dut
.bus
.sel
.eq(0b10)
266 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0000)
268 yield dut
.bus
.adr
.eq(0x30012 >> 1)
270 yield dut
.bus
.sel
.eq(0b11)
272 self
.assertEqual((yield dut
.bus
.dat_r
), 0x0009)
274 yield dut
.bus
.adr
.eq(0x40010 >> 1)
276 yield dut
.bus
.sel
.eq(0b11)
278 self
.assertEqual((yield dut
.bus
.dat_r
), 0x08)
280 yield dut
.bus
.sel
.eq(0b01)
282 self
.assertEqual((yield dut
.bus
.dat_r
), 0x08)
284 yield dut
.bus
.sel
.eq(0b10)
286 self
.assertEqual((yield dut
.bus
.dat_r
), 0x00)
288 yield dut
.bus
.adr
.eq(0x40012 >> 1)
290 yield dut
.bus
.sel
.eq(0b11)
292 self
.assertEqual((yield dut
.bus
.dat_r
), 0x09)
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())
301 class ArbiterTestCase(unittest
.TestCase
):
303 self
.dut
= Arbiter(addr_width
=31, data_width
=32, granularity
=16)
305 def test_add_wrong(self
):
306 with self
.assertRaisesRegex(TypeError,
307 r
"Initiator bus must be an instance of wishbone\.Interface, not 'foo'"):
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))
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))
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 "
326 self
.dut
.add(Interface(addr_width
=31, data_width
=16, granularity
=16))
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,
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)
342 itor_2
= Interface(addr_width
=30, data_width
=32, granularity
=16,
343 features
={"err", "rty", "stall", "lock", "cti", "bte"})
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)
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)
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
)
380 yield dut
.bus
.err
.eq(1)
381 yield dut
.bus
.rty
.eq(1)
382 yield dut
.bus
.stall
.eq(0)
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)
399 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
401 sim
.add_sync_process(sim_test())
405 dut
= Arbiter(addr_width
=30, data_width
=32, features
={"lock"})
406 itor_1
= Interface(addr_width
=30, data_width
=32, features
={"lock"})
408 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"lock"})
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)
417 self
.assertEqual((yield itor_1
.ack
), 1)
418 self
.assertEqual((yield itor_2
.ack
), 0)
422 self
.assertEqual((yield itor_1
.ack
), 1)
423 self
.assertEqual((yield itor_2
.ack
), 0)
425 yield itor_1
.lock
.eq(0)
428 self
.assertEqual((yield itor_1
.ack
), 0)
429 self
.assertEqual((yield itor_2
.ack
), 1)
431 yield itor_2
.cyc
.eq(0)
434 self
.assertEqual((yield itor_1
.ack
), 1)
435 self
.assertEqual((yield itor_2
.ack
), 0)
437 yield itor_1
.stb
.eq(1)
440 self
.assertEqual((yield itor_1
.ack
), 1)
441 self
.assertEqual((yield itor_2
.ack
), 0)
443 yield itor_1
.stb
.eq(0)
444 yield itor_2
.cyc
.eq(1)
447 self
.assertEqual((yield itor_1
.ack
), 0)
448 self
.assertEqual((yield itor_2
.ack
), 1)
450 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
452 sim
.add_sync_process(sim_test())
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"})
459 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"stall"})
463 yield itor_1
.cyc
.eq(1)
464 yield itor_2
.cyc
.eq(1)
465 yield dut
.bus
.stall
.eq(0)
467 self
.assertEqual((yield itor_1
.stall
), 0)
468 self
.assertEqual((yield itor_2
.stall
), 1)
470 yield dut
.bus
.stall
.eq(1)
472 self
.assertEqual((yield itor_1
.stall
), 1)
473 self
.assertEqual((yield itor_2
.stall
), 1)
475 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
476 sim
.add_process(sim_test())
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"})
483 itor_2
= Interface(addr_width
=30, data_width
=32, features
={"stall"})
487 yield itor_1
.cyc
.eq(1)
488 yield itor_2
.cyc
.eq(1)
490 self
.assertEqual((yield itor_1
.stall
), 1)
491 self
.assertEqual((yield itor_2
.stall
), 1)
493 yield dut
.bus
.ack
.eq(1)
495 self
.assertEqual((yield itor_1
.stall
), 0)
496 self
.assertEqual((yield itor_2
.stall
), 1)
498 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
499 sim
.add_process(sim_test())
502 def test_roundrobin(self
):
503 dut
= Arbiter(addr_width
=30, data_width
=32)
504 itor_1
= Interface(addr_width
=30, data_width
=32)
506 itor_2
= Interface(addr_width
=30, data_width
=32)
508 itor_3
= Interface(addr_width
=30, data_width
=32)
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)
517 self
.assertEqual((yield itor_1
.ack
), 1)
518 self
.assertEqual((yield itor_2
.ack
), 0)
519 self
.assertEqual((yield itor_3
.ack
), 0)
521 yield itor_1
.cyc
.eq(0)
522 yield itor_2
.cyc
.eq(0)
523 yield itor_3
.cyc
.eq(1)
526 self
.assertEqual((yield itor_1
.ack
), 0)
527 self
.assertEqual((yield itor_2
.ack
), 0)
528 self
.assertEqual((yield itor_3
.ack
), 1)
530 yield itor_1
.cyc
.eq(1)
531 yield itor_2
.cyc
.eq(1)
532 yield itor_3
.cyc
.eq(0)
535 self
.assertEqual((yield itor_1
.ack
), 1)
536 self
.assertEqual((yield itor_2
.ack
), 0)
537 self
.assertEqual((yield itor_3
.ack
), 0)
539 yield itor_1
.cyc
.eq(0)
540 yield itor_2
.cyc
.eq(1)
541 yield itor_3
.cyc
.eq(1)
544 self
.assertEqual((yield itor_1
.ack
), 0)
545 self
.assertEqual((yield itor_2
.ack
), 1)
546 self
.assertEqual((yield itor_3
.ack
), 0)
548 yield itor_1
.cyc
.eq(1)
549 yield itor_2
.cyc
.eq(0)
550 yield itor_3
.cyc
.eq(1)
553 self
.assertEqual((yield itor_1
.ack
), 0)
554 self
.assertEqual((yield itor_2
.ack
), 0)
555 self
.assertEqual((yield itor_3
.ack
), 1)
557 with
Simulator(dut
, vcd_file
=open("test.vcd", "w")) as sim
:
559 sim
.add_sync_process(sim_test())
563 class InterconnectSharedSimulationTestCase(unittest
.TestCase
):
565 self
.shared
= Interface(addr_width
=30,
568 features
={"err","cti","bte"},
570 self
.master01
= Interface(addr_width
=30,
573 features
={"err","cti","bte"},
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
)
588 self
.ram
= SRAM(Memory(width
=32, depth
=2048, init
=[]),
589 granularity
=8, features
={"err","cti","bte"})
590 self
.sub01
= Interface(addr_width
=21,
593 features
={"err","cti","bte"},
595 self
.dut
= InterconnectShared(
596 addr_width
=30, data_width
=32, granularity
=8,
597 features
={"err","cti","bte"},
604 (self
.sub01
, (2**21) << 2)
608 def test_basic(self
):
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)
616 yield self
.master01
.cyc
.eq(1)
617 yield self
.master02
.cyc
.eq(1)
619 ram_cyc
= (yield self
.ram
.bus
.cyc
)
620 sub01_cyc
= (yield self
.sub01
.cyc
)
622 yield self
.master01
.stb
.eq(1)
624 yield self
.ram
.bus
.ack
.eq(1)
625 yield self
.master01
.stb
.eq(0)
627 yield self
.ram
.bus
.ack
.eq(0)
628 yield self
.master01
.cyc
.eq(0)
630 yield self
.master02
.stb
.eq(1)
632 yield self
.sub01
.ack
.eq(1)
633 yield self
.master02
.stb
.eq(0)
635 yield self
.sub01
.ack
.eq(0)
636 yield self
.master02
.cyc
.eq(0)
640 m
.submodules
+= self
.dut
, self
.ram
641 with
Simulator(m
, vcd_file
=open("test.vcd", "w")) as sim
:
643 sim
.add_sync_process(sim_test())