2 from contextlib
import contextmanager
5 from .._utils
import flatten
, union
6 from ..hdl
.ast
import *
8 from ..hdl
.mem
import *
9 from ..hdl
.rec
import *
10 from ..hdl
.dsl
import *
11 from ..hdl
.ir
import *
12 from ..back
.pysim
import *
15 class SimulatorUnitTestCase(FHDLTestCase
):
16 def assertStatement(self
, stmt
, inputs
, output
, reset
=0):
17 inputs
= [Value
.cast(i
) for i
in inputs
]
18 output
= Value
.cast(output
)
20 isigs
= [Signal(i
.shape(), name
=n
) for i
, n
in zip(inputs
, "abcd")]
21 osig
= Signal(output
.shape(), name
="y", reset
=reset
)
23 stmt
= stmt(osig
, *isigs
)
25 frag
.add_statements(stmt
)
26 for signal
in flatten(s
._lhs
_signals
() for s
in Statement
.cast(stmt
)):
27 frag
.add_driver(signal
)
31 for isig
, input in zip(isigs
, inputs
):
34 self
.assertEqual((yield osig
), output
.value
)
35 sim
.add_process(process
)
36 with sim
.write_vcd("test.vcd", "test.gtkw", traces
=[*isigs
, osig
]):
39 def test_invert(self
):
40 stmt
= lambda y
, a
: y
.eq(~a
)
41 self
.assertStatement(stmt
, [C(0b0000, 4)], C(0b1111, 4))
42 self
.assertStatement(stmt
, [C(0b1010, 4)], C(0b0101, 4))
43 self
.assertStatement(stmt
, [C(0, 4)], C(-1, 4))
46 stmt
= lambda y
, a
: y
.eq(-a
)
47 self
.assertStatement(stmt
, [C(0b0000, 4)], C(0b0000, 4))
48 self
.assertStatement(stmt
, [C(0b0001, 4)], C(0b1111, 4))
49 self
.assertStatement(stmt
, [C(0b1010, 4)], C(0b0110, 4))
50 self
.assertStatement(stmt
, [C(1, 4)], C(-1, 4))
51 self
.assertStatement(stmt
, [C(5, 4)], C(-5, 4))
54 stmt
= lambda y
, a
: y
.eq(a
.bool())
55 self
.assertStatement(stmt
, [C(0, 4)], C(0))
56 self
.assertStatement(stmt
, [C(1, 4)], C(1))
57 self
.assertStatement(stmt
, [C(2, 4)], C(1))
60 stmt
= lambda y
, a
: y
.eq(a
.any())
61 self
.assertStatement(stmt
, [C(0b00, 2)], C(0))
62 self
.assertStatement(stmt
, [C(0b01, 2)], C(1))
63 self
.assertStatement(stmt
, [C(0b10, 2)], C(1))
64 self
.assertStatement(stmt
, [C(0b11, 2)], C(1))
67 stmt
= lambda y
, a
: y
.eq(a
.all())
68 self
.assertStatement(stmt
, [C(0b00, 2)], C(0))
69 self
.assertStatement(stmt
, [C(0b01, 2)], C(0))
70 self
.assertStatement(stmt
, [C(0b10, 2)], C(0))
71 self
.assertStatement(stmt
, [C(0b11, 2)], C(1))
73 def test_xor_unary(self
):
74 stmt
= lambda y
, a
: y
.eq(a
.xor())
75 self
.assertStatement(stmt
, [C(0b00, 2)], C(0))
76 self
.assertStatement(stmt
, [C(0b01, 2)], C(1))
77 self
.assertStatement(stmt
, [C(0b10, 2)], C(1))
78 self
.assertStatement(stmt
, [C(0b11, 2)], C(0))
81 stmt
= lambda y
, a
, b
: y
.eq(a
+ b
)
82 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1, 4))
83 self
.assertStatement(stmt
, [C(-5, 4), C(-5, 4)], C(-10, 5))
86 stmt
= lambda y
, a
, b
: y
.eq(a
- b
)
87 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(1, 4))
88 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(-1, 4))
89 self
.assertStatement(stmt
, [C(0, 4), C(10, 4)], C(-10, 5))
92 stmt
= lambda y
, a
, b
: y
.eq(a
* b
)
93 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(2, 8))
94 self
.assertStatement(stmt
, [C(2, 4), C(2, 4)], C(4, 8))
95 self
.assertStatement(stmt
, [C(7, 4), C(7, 4)], C(49, 8))
97 def test_floordiv(self
):
98 stmt
= lambda y
, a
, b
: y
.eq(a
// b
)
99 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(2, 8))
100 self
.assertStatement(stmt
, [C(2, 4), C(2, 4)], C(1, 8))
101 self
.assertStatement(stmt
, [C(7, 4), C(2, 4)], C(3, 8))
104 stmt
= lambda y
, a
, b
: y
.eq(a
& b
)
105 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
108 stmt
= lambda y
, a
, b
: y
.eq(a | b
)
109 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
111 def test_xor_binary(self
):
112 stmt
= lambda y
, a
, b
: y
.eq(a ^ b
)
113 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b0110, 4))
116 stmt
= lambda y
, a
, b
: y
.eq(a
<< b
)
117 self
.assertStatement(stmt
, [C(0b1001, 4), C(0)], C(0b1001, 5))
118 self
.assertStatement(stmt
, [C(0b1001, 4), C(3)], C(0b1001000, 7))
119 self
.assertStatement(stmt
, [C(0b1001, 4), C(-2)], C(0b10, 7))
122 stmt
= lambda y
, a
, b
: y
.eq(a
>> b
)
123 self
.assertStatement(stmt
, [C(0b1001, 4), C(0)], C(0b1001, 4))
124 self
.assertStatement(stmt
, [C(0b1001, 4), C(2)], C(0b10, 4))
125 self
.assertStatement(stmt
, [C(0b1001, 4), C(-2)], C(0b100100, 5))
128 stmt
= lambda y
, a
, b
: y
.eq(a
== b
)
129 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
130 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
131 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
134 stmt
= lambda y
, a
, b
: y
.eq(a
!= b
)
135 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
136 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
137 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
140 stmt
= lambda y
, a
, b
: y
.eq(a
< b
)
141 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
142 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
143 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
146 stmt
= lambda y
, a
, b
: y
.eq(a
>= b
)
147 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
148 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
149 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
152 stmt
= lambda y
, a
, b
: y
.eq(a
> b
)
153 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
154 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
155 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
158 stmt
= lambda y
, a
, b
: y
.eq(a
<= b
)
159 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
160 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
161 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
164 stmt
= lambda y
, a
, b
, c
: y
.eq(Mux(c
, a
, b
))
165 self
.assertStatement(stmt
, [C(2, 4), C(3, 4), C(0)], C(3, 4))
166 self
.assertStatement(stmt
, [C(2, 4), C(3, 4), C(1)], C(2, 4))
168 def test_slice(self
):
169 stmt1
= lambda y
, a
: y
.eq(a
[2])
170 self
.assertStatement(stmt1
, [C(0b10110100, 8)], C(0b1, 1))
171 stmt2
= lambda y
, a
: y
.eq(a
[2:4])
172 self
.assertStatement(stmt2
, [C(0b10110100, 8)], C(0b01, 2))
174 def test_slice_lhs(self
):
175 stmt1
= lambda y
, a
: y
[2].eq(a
)
176 self
.assertStatement(stmt1
, [C(0b0, 1)], C(0b11111011, 8), reset
=0b11111111)
177 stmt2
= lambda y
, a
: y
[2:4].eq(a
)
178 self
.assertStatement(stmt2
, [C(0b01, 2)], C(0b11110111, 8), reset
=0b11111011)
180 def test_bit_select(self
):
181 stmt
= lambda y
, a
, b
: y
.eq(a
.bit_select(b
, 3))
182 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
183 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b101, 3))
184 self
.assertStatement(stmt
, [C(0b10110100, 8), C(3)], C(0b110, 3))
186 def test_bit_select_lhs(self
):
187 stmt
= lambda y
, a
, b
: y
.bit_select(a
, 3).eq(b
)
188 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
189 self
.assertStatement(stmt
, [C(2), C(0b101, 3)], C(0b11110111, 8), reset
=0b11111111)
190 self
.assertStatement(stmt
, [C(3), C(0b110, 3)], C(0b11110111, 8), reset
=0b11111111)
192 def test_word_select(self
):
193 stmt
= lambda y
, a
, b
: y
.eq(a
.word_select(b
, 3))
194 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
195 self
.assertStatement(stmt
, [C(0b10110100, 8), C(1)], C(0b110, 3))
196 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b010, 3))
198 def test_word_select_lhs(self
):
199 stmt
= lambda y
, a
, b
: y
.word_select(a
, 3).eq(b
)
200 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
201 self
.assertStatement(stmt
, [C(1), C(0b101, 3)], C(0b11101111, 8), reset
=0b11111111)
202 self
.assertStatement(stmt
, [C(2), C(0b110, 3)], C(0b10111111, 8), reset
=0b11111111)
205 stmt
= lambda y
, *xs
: y
.eq(Cat(*xs
))
206 self
.assertStatement(stmt
, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
208 def test_cat_lhs(self
):
212 stmt
= lambda y
, a
: [Cat(l
, m
, n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
213 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
215 def test_nested_cat_lhs(self
):
219 stmt
= lambda y
, a
: [Cat(Cat(l
, Cat(m
)), n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
220 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
222 def test_record(self
):
227 stmt
= lambda y
, a
: [rec
.eq(a
), y
.eq(rec
)]
228 self
.assertStatement(stmt
, [C(0b101, 3)], C(0b101, 3))
231 stmt
= lambda y
, a
: y
.eq(Repl(a
, 3))
232 self
.assertStatement(stmt
, [C(0b10, 2)], C(0b101010, 6))
234 def test_array(self
):
235 array
= Array([1, 4, 10])
236 stmt
= lambda y
, a
: y
.eq(array
[a
])
237 self
.assertStatement(stmt
, [C(0)], C(1))
238 self
.assertStatement(stmt
, [C(1)], C(4))
239 self
.assertStatement(stmt
, [C(2)], C(10))
241 def test_array_oob(self
):
242 array
= Array([1, 4, 10])
243 stmt
= lambda y
, a
: y
.eq(array
[a
])
244 self
.assertStatement(stmt
, [C(3)], C(10))
245 self
.assertStatement(stmt
, [C(4)], C(10))
247 def test_array_lhs(self
):
248 l
= Signal(3, reset
=1)
249 m
= Signal(3, reset
=4)
250 n
= Signal(3, reset
=7)
251 array
= Array([l
, m
, n
])
252 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
253 self
.assertStatement(stmt
, [C(0), C(0b000)], C(0b111100000))
254 self
.assertStatement(stmt
, [C(1), C(0b010)], C(0b111010001))
255 self
.assertStatement(stmt
, [C(2), C(0b100)], C(0b100100001))
257 def test_array_lhs_oob(self
):
261 array
= Array([l
, m
, n
])
262 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
263 self
.assertStatement(stmt
, [C(3), C(0b001)], C(0b001000000))
264 self
.assertStatement(stmt
, [C(4), C(0b010)], C(0b010000000))
266 def test_array_index(self
):
267 array
= Array(Array(x
* y
for y
in range(10)) for x
in range(10))
268 stmt
= lambda y
, a
, b
: y
.eq(array
[a
][b
])
271 self
.assertStatement(stmt
, [C(x
), C(y
)], C(x
* y
))
273 def test_array_attr(self
):
274 from collections
import namedtuple
275 pair
= namedtuple("pair", ("p", "n"))
277 array
= Array(pair(x
, -x
) for x
in range(10))
278 stmt
= lambda y
, a
: y
.eq(array
[a
].p
+ array
[a
].n
)
280 self
.assertStatement(stmt
, [C(i
)], C(0))
283 class SimulatorIntegrationTestCase(FHDLTestCase
):
285 def assertSimulation(self
, module
, deadline
=None):
286 sim
= Simulator(module
)
288 with sim
.write_vcd("test.vcd", "test.gtkw"):
292 sim
.run_until(deadline
)
294 def setUp_counter(self
):
295 self
.count
= Signal(3, reset
=4)
296 self
.sync
= ClockDomain()
299 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
300 self
.m
.domains
+= self
.sync
302 def test_counter_process(self
):
304 with self
.assertSimulation(self
.m
) as sim
:
306 self
.assertEqual((yield self
.count
), 4)
308 self
.assertEqual((yield self
.count
), 4)
309 yield self
.sync
.clk
.eq(1)
310 self
.assertEqual((yield self
.count
), 4)
312 self
.assertEqual((yield self
.count
), 5)
314 self
.assertEqual((yield self
.count
), 5)
315 yield self
.sync
.clk
.eq(0)
316 self
.assertEqual((yield self
.count
), 5)
318 self
.assertEqual((yield self
.count
), 5)
321 yield self
.sync
.clk
.eq(1)
323 yield self
.sync
.clk
.eq(0)
324 self
.assertEqual((yield self
.count
), 0)
325 sim
.add_process(process
)
327 def test_counter_clock_and_sync_process(self
):
329 with self
.assertSimulation(self
.m
) as sim
:
330 sim
.add_clock(1e-6, domain
="sync")
332 self
.assertEqual((yield self
.count
), 4)
333 self
.assertEqual((yield self
.sync
.clk
), 1)
335 self
.assertEqual((yield self
.count
), 5)
336 self
.assertEqual((yield self
.sync
.clk
), 1)
339 self
.assertEqual((yield self
.count
), 0)
340 sim
.add_sync_process(process
)
342 def test_reset(self
):
344 sim
= Simulator(self
.m
)
349 self
.assertEqual((yield self
.count
), 4)
351 self
.assertEqual((yield self
.count
), 5)
353 self
.assertEqual((yield self
.count
), 6)
356 sim
.add_sync_process(process
)
360 self
.assertEqual(times
, 2)
368 self
.sync
= ClockDomain(reset_less
=True)
371 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
372 with self
.m
.Switch(self
.s
):
374 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
376 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
378 self
.m
.d
.sync
+= self
.o
.eq(0)
379 self
.m
.domains
+= self
.sync
383 with self
.assertSimulation(self
.m
) as sim
:
389 self
.assertEqual((yield self
.x
), 4)
391 self
.assertEqual((yield self
.o
), 6)
395 self
.assertEqual((yield self
.o
), 4)
399 self
.assertEqual((yield self
.o
), 0)
400 sim
.add_sync_process(process
)
402 def setUp_multiclock(self
):
403 self
.sys
= ClockDomain()
404 self
.pix
= ClockDomain()
407 self
.m
.domains
+= self
.sys
, self
.pix
409 def test_multiclock(self
):
410 self
.setUp_multiclock()
411 with self
.assertSimulation(self
.m
) as sim
:
412 sim
.add_clock(1e-6, domain
="sys")
413 sim
.add_clock(0.3e-6, domain
="pix")
424 sim
.add_sync_process(sys_process
, domain
="sys")
425 sim
.add_sync_process(pix_process
, domain
="pix")
427 def setUp_lhs_rhs(self
):
432 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
434 def test_complex_lhs_rhs(self
):
436 with self
.assertSimulation(self
.m
) as sim
:
438 yield self
.i
.eq(0b10101010)
439 yield self
.i
[:4].eq(-1)
441 self
.assertEqual((yield self
.i
[:4]), 0b1111)
442 self
.assertEqual((yield self
.i
), 0b10101111)
443 sim
.add_process(process
)
445 def test_run_until(self
):
449 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
455 sim
.add_process(process
)
457 def test_add_process_wrong(self
):
458 with self
.assertSimulation(Module()) as sim
:
459 with self
.assertRaises(TypeError,
460 msg
="Cannot add a process 1 because it is not a generator function"):
463 def test_add_process_wrong_generator(self
):
464 with self
.assertSimulation(Module()) as sim
:
465 with self
.assertWarns(DeprecationWarning,
466 msg
="instead of generators, use generator functions as processes; "
467 "this allows the simulator to be repeatedly reset"):
470 sim
.add_process(process())
472 def test_add_clock_wrong_twice(self
):
476 with self
.assertSimulation(m
) as sim
:
478 with self
.assertRaises(ValueError,
479 msg
="Domain 'sync' already has a clock driving it"):
482 def test_add_clock_wrong_missing(self
):
484 with self
.assertSimulation(m
) as sim
:
485 with self
.assertRaises(ValueError,
486 msg
="Domain 'sync' is not present in simulation"):
489 def test_add_clock_if_exists(self
):
491 with self
.assertSimulation(m
) as sim
:
492 sim
.add_clock(1, if_exists
=True)
494 def test_command_wrong(self
):
496 with self
.assertSimulation(Module()) as sim
:
499 with self
.assertRaisesRegex(TypeError,
500 regex
=r
"Received unsupported command 1 from process .+?"):
504 sim
.add_process(process
)
505 self
.assertTrue(survived
)
507 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
509 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
510 self
.m
.submodules
.rdport
= self
.rdport
= \
511 self
.memory
.read_port(domain
="sync" if rd_synchronous
else "comb",
512 transparent
=rd_transparent
)
513 self
.m
.submodules
.wrport
= self
.wrport
= \
514 self
.memory
.write_port(granularity
=wr_granularity
)
516 def test_memory_init(self
):
518 with self
.assertSimulation(self
.m
) as sim
:
520 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
521 yield self
.rdport
.addr
.eq(1)
524 self
.assertEqual((yield self
.rdport
.data
), 0x55)
525 yield self
.rdport
.addr
.eq(2)
528 self
.assertEqual((yield self
.rdport
.data
), 0x00)
530 sim
.add_sync_process(process
)
532 def test_memory_write(self
):
534 with self
.assertSimulation(self
.m
) as sim
:
536 yield self
.wrport
.addr
.eq(4)
537 yield self
.wrport
.data
.eq(0x33)
538 yield self
.wrport
.en
.eq(1)
540 yield self
.wrport
.en
.eq(0)
541 yield self
.rdport
.addr
.eq(4)
543 self
.assertEqual((yield self
.rdport
.data
), 0x33)
545 sim
.add_sync_process(process
)
547 def test_memory_write_granularity(self
):
548 self
.setUp_memory(wr_granularity
=4)
549 with self
.assertSimulation(self
.m
) as sim
:
551 yield self
.wrport
.data
.eq(0x50)
552 yield self
.wrport
.en
.eq(0b00)
554 yield self
.wrport
.en
.eq(0)
556 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
557 yield self
.wrport
.en
.eq(0b10)
559 yield self
.wrport
.en
.eq(0)
561 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
562 yield self
.wrport
.data
.eq(0x33)
563 yield self
.wrport
.en
.eq(0b01)
565 yield self
.wrport
.en
.eq(0)
567 self
.assertEqual((yield self
.rdport
.data
), 0x53)
569 sim
.add_sync_process(process
)
571 def test_memory_read_before_write(self
):
572 self
.setUp_memory(rd_transparent
=False)
573 with self
.assertSimulation(self
.m
) as sim
:
575 yield self
.wrport
.data
.eq(0x33)
576 yield self
.wrport
.en
.eq(1)
578 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
580 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
582 self
.assertEqual((yield self
.rdport
.data
), 0x33)
584 sim
.add_sync_process(process
)
586 def test_memory_write_through(self
):
587 self
.setUp_memory(rd_transparent
=True)
588 with self
.assertSimulation(self
.m
) as sim
:
590 yield self
.wrport
.data
.eq(0x33)
591 yield self
.wrport
.en
.eq(1)
593 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
595 self
.assertEqual((yield self
.rdport
.data
), 0x33)
597 yield self
.rdport
.addr
.eq(1)
599 self
.assertEqual((yield self
.rdport
.data
), 0x33)
601 sim
.add_sync_process(process
)
603 def test_memory_async_read_write(self
):
604 self
.setUp_memory(rd_synchronous
=False)
605 with self
.assertSimulation(self
.m
) as sim
:
607 yield self
.rdport
.addr
.eq(0)
609 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
610 yield self
.rdport
.addr
.eq(1)
612 self
.assertEqual((yield self
.rdport
.data
), 0x55)
613 yield self
.rdport
.addr
.eq(0)
614 yield self
.wrport
.addr
.eq(0)
615 yield self
.wrport
.data
.eq(0x33)
616 yield self
.wrport
.en
.eq(1)
618 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
620 self
.assertEqual((yield self
.rdport
.data
), 0x33)
622 sim
.add_process(process
)
624 def test_memory_read_only(self
):
626 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
627 self
.m
.submodules
.rdport
= self
.rdport
= self
.memory
.read_port()
628 with self
.assertSimulation(self
.m
) as sim
:
630 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
631 yield self
.rdport
.addr
.eq(1)
634 self
.assertEqual((yield self
.rdport
.data
), 0x55)
636 sim
.add_sync_process(process
)
638 def test_sample_helpers(self
):
645 p0
, r0
, f0
, s0
= mk(Past(s
, 0)), mk(Rose(s
)), mk(Fell(s
)), mk(Stable(s
))
646 p1
, r1
, f1
, s1
= mk(Past(s
)), mk(Rose(s
, 1)), mk(Fell(s
, 1)), mk(Stable(s
, 1))
647 p2
, r2
, f2
, s2
= mk(Past(s
, 2)), mk(Rose(s
, 2)), mk(Fell(s
, 2)), mk(Stable(s
, 2))
648 p3
, r3
, f3
, s3
= mk(Past(s
, 3)), mk(Rose(s
, 3)), mk(Fell(s
, 3)), mk(Stable(s
, 3))
649 with self
.assertSimulation(m
) as sim
:
661 self
.assertEqual((yield p0
), 0b01)
662 self
.assertEqual((yield p1
), 0b10)
663 self
.assertEqual((yield p2
), 0b10)
664 self
.assertEqual((yield p3
), 0b00)
666 self
.assertEqual((yield s0
), 0b0)
667 self
.assertEqual((yield s1
), 0b1)
668 self
.assertEqual((yield s2
), 0b0)
669 self
.assertEqual((yield s3
), 0b1)
671 self
.assertEqual((yield r0
), 0b01)
672 self
.assertEqual((yield r1
), 0b00)
673 self
.assertEqual((yield r2
), 0b10)
674 self
.assertEqual((yield r3
), 0b00)
676 self
.assertEqual((yield f0
), 0b10)
677 self
.assertEqual((yield f1
), 0b00)
678 self
.assertEqual((yield f2
), 0b00)
679 self
.assertEqual((yield f3
), 0b00)
681 sim
.add_sync_process(process_gen
)
682 sim
.add_sync_process(process_check
)
684 def test_vcd_wrong_nonzero_time(self
):
691 with self
.assertRaisesRegex(ValueError,
692 regex
=r
"^Cannot start writing waveforms after advancing simulation time$"):
693 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
696 def test_vcd_wrong_twice(self
):
702 with self
.assertRaisesRegex(ValueError,
703 regex
=r
"^Already writing waveforms to .+$"):
704 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
705 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):