back.pysim: redesign the simulator.
[nmigen.git] / nmigen / test / test_sim.py
1 import os
2 from contextlib import contextmanager
3
4 from .utils import *
5 from .._utils import flatten, union
6 from ..hdl.ast import *
7 from ..hdl.cd 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 *
13
14
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)
19
20 isigs = [Signal(i.shape(), name=n) for i, n in zip(inputs, "abcd")]
21 osig = Signal(output.shape(), name="y", reset=reset)
22
23 stmt = stmt(osig, *isigs)
24 frag = Fragment()
25 frag.add_statements(stmt)
26 for signal in flatten(s._lhs_signals() for s in Statement.cast(stmt)):
27 frag.add_driver(signal)
28
29 sim = Simulator(frag)
30 def process():
31 for isig, input in zip(isigs, inputs):
32 yield isig.eq(input)
33 yield Settle()
34 self.assertEqual((yield osig), output.value)
35 sim.add_process(process)
36 with sim.write_vcd("test.vcd", "test.gtkw", traces=[*isigs, osig]):
37 sim.run()
38
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))
44
45 def test_neg(self):
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))
52
53 def test_bool(self):
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))
58
59 def test_any(self):
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))
65
66 def test_all(self):
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))
72
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))
79
80 def test_add(self):
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))
84
85 def test_sub(self):
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))
90
91 def test_mul(self):
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))
96
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))
102
103 def test_and(self):
104 stmt = lambda y, a, b: y.eq(a & b)
105 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
106
107 def test_or(self):
108 stmt = lambda y, a, b: y.eq(a | b)
109 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
110
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))
114
115 def test_shl(self):
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))
120
121 def test_shr(self):
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))
126
127 def test_eq(self):
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))
132
133 def test_ne(self):
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))
138
139 def test_lt(self):
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))
144
145 def test_ge(self):
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))
150
151 def test_gt(self):
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))
156
157 def test_le(self):
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))
162
163 def test_mux(self):
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))
167
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))
173
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)
179
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))
185
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)
191
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))
197
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)
203
204 def test_cat(self):
205 stmt = lambda y, *xs: y.eq(Cat(*xs))
206 self.assertStatement(stmt, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
207
208 def test_cat_lhs(self):
209 l = Signal(3)
210 m = Signal(3)
211 n = Signal(3)
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))
214
215 def test_nested_cat_lhs(self):
216 l = Signal(3)
217 m = Signal(3)
218 n = Signal(3)
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))
221
222 def test_record(self):
223 rec = Record([
224 ("l", 1),
225 ("m", 2),
226 ])
227 stmt = lambda y, a: [rec.eq(a), y.eq(rec)]
228 self.assertStatement(stmt, [C(0b101, 3)], C(0b101, 3))
229
230 def test_repl(self):
231 stmt = lambda y, a: y.eq(Repl(a, 3))
232 self.assertStatement(stmt, [C(0b10, 2)], C(0b101010, 6))
233
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))
240
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))
246
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))
256
257 def test_array_lhs_oob(self):
258 l = Signal(3)
259 m = Signal(3)
260 n = Signal(3)
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))
265
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])
269 for x in range(10):
270 for y in range(10):
271 self.assertStatement(stmt, [C(x), C(y)], C(x * y))
272
273 def test_array_attr(self):
274 from collections import namedtuple
275 pair = namedtuple("pair", ("p", "n"))
276
277 array = Array(pair(x, -x) for x in range(10))
278 stmt = lambda y, a: y.eq(array[a].p + array[a].n)
279 for i in range(10):
280 self.assertStatement(stmt, [C(i)], C(0))
281
282
283 class SimulatorIntegrationTestCase(FHDLTestCase):
284 @contextmanager
285 def assertSimulation(self, module, deadline=None):
286 sim = Simulator(module)
287 yield sim
288 with sim.write_vcd("test.vcd", "test.gtkw"):
289 if deadline is None:
290 sim.run()
291 else:
292 sim.run_until(deadline)
293
294 def setUp_counter(self):
295 self.count = Signal(3, reset=4)
296 self.sync = ClockDomain()
297
298 self.m = Module()
299 self.m.d.sync += self.count.eq(self.count + 1)
300 self.m.domains += self.sync
301
302 def test_counter_process(self):
303 self.setUp_counter()
304 with self.assertSimulation(self.m) as sim:
305 def process():
306 self.assertEqual((yield self.count), 4)
307 yield Delay(1e-6)
308 self.assertEqual((yield self.count), 4)
309 yield self.sync.clk.eq(1)
310 self.assertEqual((yield self.count), 4)
311 yield Settle()
312 self.assertEqual((yield self.count), 5)
313 yield Delay(1e-6)
314 self.assertEqual((yield self.count), 5)
315 yield self.sync.clk.eq(0)
316 self.assertEqual((yield self.count), 5)
317 yield Settle()
318 self.assertEqual((yield self.count), 5)
319 for _ in range(3):
320 yield Delay(1e-6)
321 yield self.sync.clk.eq(1)
322 yield Delay(1e-6)
323 yield self.sync.clk.eq(0)
324 self.assertEqual((yield self.count), 0)
325 sim.add_process(process)
326
327 def test_counter_clock_and_sync_process(self):
328 self.setUp_counter()
329 with self.assertSimulation(self.m) as sim:
330 sim.add_clock(1e-6, domain="sync")
331 def process():
332 self.assertEqual((yield self.count), 4)
333 self.assertEqual((yield self.sync.clk), 1)
334 yield
335 self.assertEqual((yield self.count), 5)
336 self.assertEqual((yield self.sync.clk), 1)
337 for _ in range(3):
338 yield
339 self.assertEqual((yield self.count), 0)
340 sim.add_sync_process(process)
341
342 def test_reset(self):
343 self.setUp_counter()
344 sim = Simulator(self.m)
345 sim.add_clock(1e-6)
346 times = 0
347 def process():
348 nonlocal times
349 self.assertEqual((yield self.count), 4)
350 yield
351 self.assertEqual((yield self.count), 5)
352 yield
353 self.assertEqual((yield self.count), 6)
354 yield
355 times += 1
356 sim.add_sync_process(process)
357 sim.run()
358 sim.reset()
359 sim.run()
360 self.assertEqual(times, 2)
361
362 def setUp_alu(self):
363 self.a = Signal(8)
364 self.b = Signal(8)
365 self.o = Signal(8)
366 self.x = Signal(8)
367 self.s = Signal(2)
368 self.sync = ClockDomain(reset_less=True)
369
370 self.m = Module()
371 self.m.d.comb += self.x.eq(self.a ^ self.b)
372 with self.m.Switch(self.s):
373 with self.m.Case(0):
374 self.m.d.sync += self.o.eq(self.a + self.b)
375 with self.m.Case(1):
376 self.m.d.sync += self.o.eq(self.a - self.b)
377 with self.m.Case():
378 self.m.d.sync += self.o.eq(0)
379 self.m.domains += self.sync
380
381 def test_alu(self):
382 self.setUp_alu()
383 with self.assertSimulation(self.m) as sim:
384 sim.add_clock(1e-6)
385 def process():
386 yield self.a.eq(5)
387 yield self.b.eq(1)
388 yield
389 self.assertEqual((yield self.x), 4)
390 yield
391 self.assertEqual((yield self.o), 6)
392 yield self.s.eq(1)
393 yield
394 yield
395 self.assertEqual((yield self.o), 4)
396 yield self.s.eq(2)
397 yield
398 yield
399 self.assertEqual((yield self.o), 0)
400 sim.add_sync_process(process)
401
402 def setUp_multiclock(self):
403 self.sys = ClockDomain()
404 self.pix = ClockDomain()
405
406 self.m = Module()
407 self.m.domains += self.sys, self.pix
408
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")
414
415 def sys_process():
416 yield Passive()
417 yield
418 yield
419 self.fail()
420 def pix_process():
421 yield
422 yield
423 yield
424 sim.add_sync_process(sys_process, domain="sys")
425 sim.add_sync_process(pix_process, domain="pix")
426
427 def setUp_lhs_rhs(self):
428 self.i = Signal(8)
429 self.o = Signal(8)
430
431 self.m = Module()
432 self.m.d.comb += self.o.eq(self.i)
433
434 def test_complex_lhs_rhs(self):
435 self.setUp_lhs_rhs()
436 with self.assertSimulation(self.m) as sim:
437 def process():
438 yield self.i.eq(0b10101010)
439 yield self.i[:4].eq(-1)
440 yield Settle()
441 self.assertEqual((yield self.i[:4]), 0b1111)
442 self.assertEqual((yield self.i), 0b10101111)
443 sim.add_process(process)
444
445 def test_run_until(self):
446 m = Module()
447 s = Signal()
448 m.d.sync += s.eq(0)
449 with self.assertSimulation(m, deadline=100e-6) as sim:
450 sim.add_clock(1e-6)
451 def process():
452 for _ in range(101):
453 yield Delay(1e-6)
454 self.fail()
455 sim.add_process(process)
456
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"):
461 sim.add_process(1)
462
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"):
468 def process():
469 yield Delay()
470 sim.add_process(process())
471
472 def test_add_clock_wrong_twice(self):
473 m = Module()
474 s = Signal()
475 m.d.sync += s.eq(0)
476 with self.assertSimulation(m) as sim:
477 sim.add_clock(1)
478 with self.assertRaises(ValueError,
479 msg="Domain 'sync' already has a clock driving it"):
480 sim.add_clock(1)
481
482 def test_add_clock_wrong_missing(self):
483 m = Module()
484 with self.assertSimulation(m) as sim:
485 with self.assertRaises(ValueError,
486 msg="Domain 'sync' is not present in simulation"):
487 sim.add_clock(1)
488
489 def test_add_clock_if_exists(self):
490 m = Module()
491 with self.assertSimulation(m) as sim:
492 sim.add_clock(1, if_exists=True)
493
494 def test_command_wrong(self):
495 survived = False
496 with self.assertSimulation(Module()) as sim:
497 def process():
498 nonlocal survived
499 with self.assertRaisesRegex(TypeError,
500 regex=r"Received unsupported command 1 from process .+?"):
501 yield 1
502 yield Settle()
503 survived = True
504 sim.add_process(process)
505 self.assertTrue(survived)
506
507 def setUp_memory(self, rd_synchronous=True, rd_transparent=True, wr_granularity=None):
508 self.m = Module()
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)
515
516 def test_memory_init(self):
517 self.setUp_memory()
518 with self.assertSimulation(self.m) as sim:
519 def process():
520 self.assertEqual((yield self.rdport.data), 0xaa)
521 yield self.rdport.addr.eq(1)
522 yield
523 yield
524 self.assertEqual((yield self.rdport.data), 0x55)
525 yield self.rdport.addr.eq(2)
526 yield
527 yield
528 self.assertEqual((yield self.rdport.data), 0x00)
529 sim.add_clock(1e-6)
530 sim.add_sync_process(process)
531
532 def test_memory_write(self):
533 self.setUp_memory()
534 with self.assertSimulation(self.m) as sim:
535 def process():
536 yield self.wrport.addr.eq(4)
537 yield self.wrport.data.eq(0x33)
538 yield self.wrport.en.eq(1)
539 yield
540 yield self.wrport.en.eq(0)
541 yield self.rdport.addr.eq(4)
542 yield
543 self.assertEqual((yield self.rdport.data), 0x33)
544 sim.add_clock(1e-6)
545 sim.add_sync_process(process)
546
547 def test_memory_write_granularity(self):
548 self.setUp_memory(wr_granularity=4)
549 with self.assertSimulation(self.m) as sim:
550 def process():
551 yield self.wrport.data.eq(0x50)
552 yield self.wrport.en.eq(0b00)
553 yield
554 yield self.wrport.en.eq(0)
555 yield
556 self.assertEqual((yield self.rdport.data), 0xaa)
557 yield self.wrport.en.eq(0b10)
558 yield
559 yield self.wrport.en.eq(0)
560 yield
561 self.assertEqual((yield self.rdport.data), 0x5a)
562 yield self.wrport.data.eq(0x33)
563 yield self.wrport.en.eq(0b01)
564 yield
565 yield self.wrport.en.eq(0)
566 yield
567 self.assertEqual((yield self.rdport.data), 0x53)
568 sim.add_clock(1e-6)
569 sim.add_sync_process(process)
570
571 def test_memory_read_before_write(self):
572 self.setUp_memory(rd_transparent=False)
573 with self.assertSimulation(self.m) as sim:
574 def process():
575 yield self.wrport.data.eq(0x33)
576 yield self.wrport.en.eq(1)
577 yield
578 self.assertEqual((yield self.rdport.data), 0xaa)
579 yield
580 self.assertEqual((yield self.rdport.data), 0xaa)
581 yield Settle()
582 self.assertEqual((yield self.rdport.data), 0x33)
583 sim.add_clock(1e-6)
584 sim.add_sync_process(process)
585
586 def test_memory_write_through(self):
587 self.setUp_memory(rd_transparent=True)
588 with self.assertSimulation(self.m) as sim:
589 def process():
590 yield self.wrport.data.eq(0x33)
591 yield self.wrport.en.eq(1)
592 yield
593 self.assertEqual((yield self.rdport.data), 0xaa)
594 yield Settle()
595 self.assertEqual((yield self.rdport.data), 0x33)
596 yield
597 yield self.rdport.addr.eq(1)
598 yield Settle()
599 self.assertEqual((yield self.rdport.data), 0x33)
600 sim.add_clock(1e-6)
601 sim.add_sync_process(process)
602
603 def test_memory_async_read_write(self):
604 self.setUp_memory(rd_synchronous=False)
605 with self.assertSimulation(self.m) as sim:
606 def process():
607 yield self.rdport.addr.eq(0)
608 yield Settle()
609 self.assertEqual((yield self.rdport.data), 0xaa)
610 yield self.rdport.addr.eq(1)
611 yield Settle()
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)
617 yield Tick("sync")
618 self.assertEqual((yield self.rdport.data), 0xaa)
619 yield Settle()
620 self.assertEqual((yield self.rdport.data), 0x33)
621 sim.add_clock(1e-6)
622 sim.add_process(process)
623
624 def test_memory_read_only(self):
625 self.m = Module()
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:
629 def process():
630 self.assertEqual((yield self.rdport.data), 0xaa)
631 yield self.rdport.addr.eq(1)
632 yield
633 yield
634 self.assertEqual((yield self.rdport.data), 0x55)
635 sim.add_clock(1e-6)
636 sim.add_sync_process(process)
637
638 def test_sample_helpers(self):
639 m = Module()
640 s = Signal(2)
641 def mk(x):
642 y = Signal.like(x)
643 m.d.comb += y.eq(x)
644 return y
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:
650 def process_gen():
651 yield s.eq(0b10)
652 yield
653 yield
654 yield s.eq(0b01)
655 yield
656 def process_check():
657 yield
658 yield
659 yield
660
661 self.assertEqual((yield p0), 0b01)
662 self.assertEqual((yield p1), 0b10)
663 self.assertEqual((yield p2), 0b10)
664 self.assertEqual((yield p3), 0b00)
665
666 self.assertEqual((yield s0), 0b0)
667 self.assertEqual((yield s1), 0b1)
668 self.assertEqual((yield s2), 0b0)
669 self.assertEqual((yield s3), 0b1)
670
671 self.assertEqual((yield r0), 0b01)
672 self.assertEqual((yield r1), 0b00)
673 self.assertEqual((yield r2), 0b10)
674 self.assertEqual((yield r3), 0b00)
675
676 self.assertEqual((yield f0), 0b10)
677 self.assertEqual((yield f1), 0b00)
678 self.assertEqual((yield f2), 0b00)
679 self.assertEqual((yield f3), 0b00)
680 sim.add_clock(1e-6)
681 sim.add_sync_process(process_gen)
682 sim.add_sync_process(process_check)
683
684 def test_vcd_wrong_nonzero_time(self):
685 s = Signal()
686 m = Module()
687 m.d.sync += s.eq(s)
688 sim = Simulator(m)
689 sim.add_clock(1e-6)
690 sim.run_until(1e-5)
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")):
694 pass
695
696 def test_vcd_wrong_twice(self):
697 s = Signal()
698 m = Module()
699 m.d.sync += s.eq(s)
700 sim = Simulator(m)
701 sim.add_clock(1e-6)
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")):
706 pass