back.pysim: fix RHS codegen for Cat() and Repl(..., 0).
[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_as_unsigned(self):
60 stmt = lambda y, a, b: y.eq(a.as_unsigned() == b)
61 self.assertStatement(stmt, [C(0b01, signed(2)), C(0b0001, unsigned(4))], C(1))
62 self.assertStatement(stmt, [C(0b11, signed(2)), C(0b0011, unsigned(4))], C(1))
63
64 def test_as_signed(self):
65 stmt = lambda y, a, b: y.eq(a.as_signed() == b)
66 self.assertStatement(stmt, [C(0b01, unsigned(2)), C(0b0001, signed(4))], C(1))
67 self.assertStatement(stmt, [C(0b11, unsigned(2)), C(0b1111, signed(4))], C(1))
68
69 def test_any(self):
70 stmt = lambda y, a: y.eq(a.any())
71 self.assertStatement(stmt, [C(0b00, 2)], C(0))
72 self.assertStatement(stmt, [C(0b01, 2)], C(1))
73 self.assertStatement(stmt, [C(0b10, 2)], C(1))
74 self.assertStatement(stmt, [C(0b11, 2)], C(1))
75
76 def test_all(self):
77 stmt = lambda y, a: y.eq(a.all())
78 self.assertStatement(stmt, [C(0b00, 2)], C(0))
79 self.assertStatement(stmt, [C(0b01, 2)], C(0))
80 self.assertStatement(stmt, [C(0b10, 2)], C(0))
81 self.assertStatement(stmt, [C(0b11, 2)], C(1))
82
83 def test_xor_unary(self):
84 stmt = lambda y, a: y.eq(a.xor())
85 self.assertStatement(stmt, [C(0b00, 2)], C(0))
86 self.assertStatement(stmt, [C(0b01, 2)], C(1))
87 self.assertStatement(stmt, [C(0b10, 2)], C(1))
88 self.assertStatement(stmt, [C(0b11, 2)], C(0))
89
90 def test_add(self):
91 stmt = lambda y, a, b: y.eq(a + b)
92 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1, 4))
93 self.assertStatement(stmt, [C(-5, 4), C(-5, 4)], C(-10, 5))
94
95 def test_sub(self):
96 stmt = lambda y, a, b: y.eq(a - b)
97 self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(1, 4))
98 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(-1, 4))
99 self.assertStatement(stmt, [C(0, 4), C(10, 4)], C(-10, 5))
100
101 def test_mul(self):
102 stmt = lambda y, a, b: y.eq(a * b)
103 self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(2, 8))
104 self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(4, 8))
105 self.assertStatement(stmt, [C(7, 4), C(7, 4)], C(49, 8))
106
107 def test_floordiv(self):
108 stmt = lambda y, a, b: y.eq(a // b)
109 self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(2, 8))
110 self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(1, 8))
111 self.assertStatement(stmt, [C(7, 4), C(2, 4)], C(3, 8))
112
113 def test_and(self):
114 stmt = lambda y, a, b: y.eq(a & b)
115 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
116
117 def test_or(self):
118 stmt = lambda y, a, b: y.eq(a | b)
119 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
120
121 def test_xor_binary(self):
122 stmt = lambda y, a, b: y.eq(a ^ b)
123 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b0110, 4))
124
125 def test_shl(self):
126 stmt = lambda y, a, b: y.eq(a << b)
127 self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 5))
128 self.assertStatement(stmt, [C(0b1001, 4), C(3)], C(0b1001000, 7))
129
130 def test_shr(self):
131 stmt = lambda y, a, b: y.eq(a >> b)
132 self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 4))
133 self.assertStatement(stmt, [C(0b1001, 4), C(2)], C(0b10, 4))
134
135 def test_eq(self):
136 stmt = lambda y, a, b: y.eq(a == b)
137 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
138 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
139 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
140
141 def test_ne(self):
142 stmt = lambda y, a, b: y.eq(a != b)
143 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
144 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
145 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
146
147 def test_lt(self):
148 stmt = lambda y, a, b: y.eq(a < b)
149 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
150 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
151 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
152
153 def test_ge(self):
154 stmt = lambda y, a, b: y.eq(a >= b)
155 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
156 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
157 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
158
159 def test_gt(self):
160 stmt = lambda y, a, b: y.eq(a > b)
161 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
162 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
163 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
164
165 def test_le(self):
166 stmt = lambda y, a, b: y.eq(a <= b)
167 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
168 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
169 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
170
171 def test_mux(self):
172 stmt = lambda y, a, b, c: y.eq(Mux(c, a, b))
173 self.assertStatement(stmt, [C(2, 4), C(3, 4), C(0)], C(3, 4))
174 self.assertStatement(stmt, [C(2, 4), C(3, 4), C(1)], C(2, 4))
175
176 def test_slice(self):
177 stmt1 = lambda y, a: y.eq(a[2])
178 self.assertStatement(stmt1, [C(0b10110100, 8)], C(0b1, 1))
179 stmt2 = lambda y, a: y.eq(a[2:4])
180 self.assertStatement(stmt2, [C(0b10110100, 8)], C(0b01, 2))
181
182 def test_slice_lhs(self):
183 stmt1 = lambda y, a: y[2].eq(a)
184 self.assertStatement(stmt1, [C(0b0, 1)], C(0b11111011, 8), reset=0b11111111)
185 stmt2 = lambda y, a: y[2:4].eq(a)
186 self.assertStatement(stmt2, [C(0b01, 2)], C(0b11110111, 8), reset=0b11111011)
187
188 def test_bit_select(self):
189 stmt = lambda y, a, b: y.eq(a.bit_select(b, 3))
190 self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
191 self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b101, 3))
192 self.assertStatement(stmt, [C(0b10110100, 8), C(3)], C(0b110, 3))
193
194 def test_bit_select_lhs(self):
195 stmt = lambda y, a, b: y.bit_select(a, 3).eq(b)
196 self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
197 self.assertStatement(stmt, [C(2), C(0b101, 3)], C(0b11110111, 8), reset=0b11111111)
198 self.assertStatement(stmt, [C(3), C(0b110, 3)], C(0b11110111, 8), reset=0b11111111)
199
200 def test_word_select(self):
201 stmt = lambda y, a, b: y.eq(a.word_select(b, 3))
202 self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
203 self.assertStatement(stmt, [C(0b10110100, 8), C(1)], C(0b110, 3))
204 self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b010, 3))
205
206 def test_word_select_lhs(self):
207 stmt = lambda y, a, b: y.word_select(a, 3).eq(b)
208 self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
209 self.assertStatement(stmt, [C(1), C(0b101, 3)], C(0b11101111, 8), reset=0b11111111)
210 self.assertStatement(stmt, [C(2), C(0b110, 3)], C(0b10111111, 8), reset=0b11111111)
211
212 def test_cat(self):
213 stmt = lambda y, *xs: y.eq(Cat(*xs))
214 self.assertStatement(stmt, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
215
216 def test_cat_lhs(self):
217 l = Signal(3)
218 m = Signal(3)
219 n = Signal(3)
220 stmt = lambda y, a: [Cat(l, m, n).eq(a), y.eq(Cat(n, m, l))]
221 self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
222
223 def test_nested_cat_lhs(self):
224 l = Signal(3)
225 m = Signal(3)
226 n = Signal(3)
227 stmt = lambda y, a: [Cat(Cat(l, Cat(m)), n).eq(a), y.eq(Cat(n, m, l))]
228 self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
229
230 def test_record(self):
231 rec = Record([
232 ("l", 1),
233 ("m", 2),
234 ])
235 stmt = lambda y, a: [rec.eq(a), y.eq(rec)]
236 self.assertStatement(stmt, [C(0b101, 3)], C(0b101, 3))
237
238 def test_repl(self):
239 stmt = lambda y, a: y.eq(Repl(a, 3))
240 self.assertStatement(stmt, [C(0b10, 2)], C(0b101010, 6))
241
242 def test_array(self):
243 array = Array([1, 4, 10])
244 stmt = lambda y, a: y.eq(array[a])
245 self.assertStatement(stmt, [C(0)], C(1))
246 self.assertStatement(stmt, [C(1)], C(4))
247 self.assertStatement(stmt, [C(2)], C(10))
248
249 def test_array_oob(self):
250 array = Array([1, 4, 10])
251 stmt = lambda y, a: y.eq(array[a])
252 self.assertStatement(stmt, [C(3)], C(10))
253 self.assertStatement(stmt, [C(4)], C(10))
254
255 def test_array_lhs(self):
256 l = Signal(3, reset=1)
257 m = Signal(3, reset=4)
258 n = Signal(3, reset=7)
259 array = Array([l, m, n])
260 stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
261 self.assertStatement(stmt, [C(0), C(0b000)], C(0b111100000))
262 self.assertStatement(stmt, [C(1), C(0b010)], C(0b111010001))
263 self.assertStatement(stmt, [C(2), C(0b100)], C(0b100100001))
264
265 def test_array_lhs_oob(self):
266 l = Signal(3)
267 m = Signal(3)
268 n = Signal(3)
269 array = Array([l, m, n])
270 stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
271 self.assertStatement(stmt, [C(3), C(0b001)], C(0b001000000))
272 self.assertStatement(stmt, [C(4), C(0b010)], C(0b010000000))
273
274 def test_array_index(self):
275 array = Array(Array(x * y for y in range(10)) for x in range(10))
276 stmt = lambda y, a, b: y.eq(array[a][b])
277 for x in range(10):
278 for y in range(10):
279 self.assertStatement(stmt, [C(x), C(y)], C(x * y))
280
281 def test_array_attr(self):
282 from collections import namedtuple
283 pair = namedtuple("pair", ("p", "n"))
284
285 array = Array(pair(x, -x) for x in range(10))
286 stmt = lambda y, a: y.eq(array[a].p + array[a].n)
287 for i in range(10):
288 self.assertStatement(stmt, [C(i)], C(0))
289
290
291 class SimulatorIntegrationTestCase(FHDLTestCase):
292 @contextmanager
293 def assertSimulation(self, module, deadline=None):
294 sim = Simulator(module)
295 yield sim
296 with sim.write_vcd("test.vcd", "test.gtkw"):
297 if deadline is None:
298 sim.run()
299 else:
300 sim.run_until(deadline)
301
302 def setUp_counter(self):
303 self.count = Signal(3, reset=4)
304 self.sync = ClockDomain()
305
306 self.m = Module()
307 self.m.d.sync += self.count.eq(self.count + 1)
308 self.m.domains += self.sync
309
310 def test_counter_process(self):
311 self.setUp_counter()
312 with self.assertSimulation(self.m) as sim:
313 def process():
314 self.assertEqual((yield self.count), 4)
315 yield Delay(1e-6)
316 self.assertEqual((yield self.count), 4)
317 yield self.sync.clk.eq(1)
318 self.assertEqual((yield self.count), 4)
319 yield Settle()
320 self.assertEqual((yield self.count), 5)
321 yield Delay(1e-6)
322 self.assertEqual((yield self.count), 5)
323 yield self.sync.clk.eq(0)
324 self.assertEqual((yield self.count), 5)
325 yield Settle()
326 self.assertEqual((yield self.count), 5)
327 for _ in range(3):
328 yield Delay(1e-6)
329 yield self.sync.clk.eq(1)
330 yield Delay(1e-6)
331 yield self.sync.clk.eq(0)
332 self.assertEqual((yield self.count), 0)
333 sim.add_process(process)
334
335 def test_counter_clock_and_sync_process(self):
336 self.setUp_counter()
337 with self.assertSimulation(self.m) as sim:
338 sim.add_clock(1e-6, domain="sync")
339 def process():
340 self.assertEqual((yield self.count), 4)
341 self.assertEqual((yield self.sync.clk), 1)
342 yield
343 self.assertEqual((yield self.count), 5)
344 self.assertEqual((yield self.sync.clk), 1)
345 for _ in range(3):
346 yield
347 self.assertEqual((yield self.count), 0)
348 sim.add_sync_process(process)
349
350 def test_reset(self):
351 self.setUp_counter()
352 sim = Simulator(self.m)
353 sim.add_clock(1e-6)
354 times = 0
355 def process():
356 nonlocal times
357 self.assertEqual((yield self.count), 4)
358 yield
359 self.assertEqual((yield self.count), 5)
360 yield
361 self.assertEqual((yield self.count), 6)
362 yield
363 times += 1
364 sim.add_sync_process(process)
365 sim.run()
366 sim.reset()
367 sim.run()
368 self.assertEqual(times, 2)
369
370 def setUp_alu(self):
371 self.a = Signal(8)
372 self.b = Signal(8)
373 self.o = Signal(8)
374 self.x = Signal(8)
375 self.s = Signal(2)
376 self.sync = ClockDomain(reset_less=True)
377
378 self.m = Module()
379 self.m.d.comb += self.x.eq(self.a ^ self.b)
380 with self.m.Switch(self.s):
381 with self.m.Case(0):
382 self.m.d.sync += self.o.eq(self.a + self.b)
383 with self.m.Case(1):
384 self.m.d.sync += self.o.eq(self.a - self.b)
385 with self.m.Case():
386 self.m.d.sync += self.o.eq(0)
387 self.m.domains += self.sync
388
389 def test_alu(self):
390 self.setUp_alu()
391 with self.assertSimulation(self.m) as sim:
392 sim.add_clock(1e-6)
393 def process():
394 yield self.a.eq(5)
395 yield self.b.eq(1)
396 yield
397 self.assertEqual((yield self.x), 4)
398 yield
399 self.assertEqual((yield self.o), 6)
400 yield self.s.eq(1)
401 yield
402 yield
403 self.assertEqual((yield self.o), 4)
404 yield self.s.eq(2)
405 yield
406 yield
407 self.assertEqual((yield self.o), 0)
408 sim.add_sync_process(process)
409
410 def setUp_multiclock(self):
411 self.sys = ClockDomain()
412 self.pix = ClockDomain()
413
414 self.m = Module()
415 self.m.domains += self.sys, self.pix
416
417 def test_multiclock(self):
418 self.setUp_multiclock()
419 with self.assertSimulation(self.m) as sim:
420 sim.add_clock(1e-6, domain="sys")
421 sim.add_clock(0.3e-6, domain="pix")
422
423 def sys_process():
424 yield Passive()
425 yield
426 yield
427 self.fail()
428 def pix_process():
429 yield
430 yield
431 yield
432 sim.add_sync_process(sys_process, domain="sys")
433 sim.add_sync_process(pix_process, domain="pix")
434
435 def setUp_lhs_rhs(self):
436 self.i = Signal(8)
437 self.o = Signal(8)
438
439 self.m = Module()
440 self.m.d.comb += self.o.eq(self.i)
441
442 def test_complex_lhs_rhs(self):
443 self.setUp_lhs_rhs()
444 with self.assertSimulation(self.m) as sim:
445 def process():
446 yield self.i.eq(0b10101010)
447 yield self.i[:4].eq(-1)
448 yield Settle()
449 self.assertEqual((yield self.i[:4]), 0b1111)
450 self.assertEqual((yield self.i), 0b10101111)
451 sim.add_process(process)
452
453 def test_run_until(self):
454 m = Module()
455 s = Signal()
456 m.d.sync += s.eq(0)
457 with self.assertSimulation(m, deadline=100e-6) as sim:
458 sim.add_clock(1e-6)
459 def process():
460 for _ in range(101):
461 yield Delay(1e-6)
462 self.fail()
463 sim.add_process(process)
464
465 def test_add_process_wrong(self):
466 with self.assertSimulation(Module()) as sim:
467 with self.assertRaises(TypeError,
468 msg="Cannot add a process 1 because it is not a generator function"):
469 sim.add_process(1)
470
471 def test_add_process_wrong_generator(self):
472 with self.assertSimulation(Module()) as sim:
473 with self.assertWarns(DeprecationWarning,
474 msg="instead of generators, use generator functions as processes; "
475 "this allows the simulator to be repeatedly reset"):
476 def process():
477 yield Delay()
478 sim.add_process(process())
479
480 def test_add_clock_wrong_twice(self):
481 m = Module()
482 s = Signal()
483 m.d.sync += s.eq(0)
484 with self.assertSimulation(m) as sim:
485 sim.add_clock(1)
486 with self.assertRaises(ValueError,
487 msg="Domain 'sync' already has a clock driving it"):
488 sim.add_clock(1)
489
490 def test_add_clock_wrong_missing(self):
491 m = Module()
492 with self.assertSimulation(m) as sim:
493 with self.assertRaises(ValueError,
494 msg="Domain 'sync' is not present in simulation"):
495 sim.add_clock(1)
496
497 def test_add_clock_if_exists(self):
498 m = Module()
499 with self.assertSimulation(m) as sim:
500 sim.add_clock(1, if_exists=True)
501
502 def test_command_wrong(self):
503 survived = False
504 with self.assertSimulation(Module()) as sim:
505 def process():
506 nonlocal survived
507 with self.assertRaisesRegex(TypeError,
508 regex=r"Received unsupported command 1 from process .+?"):
509 yield 1
510 yield Settle()
511 survived = True
512 sim.add_process(process)
513 self.assertTrue(survived)
514
515 def setUp_memory(self, rd_synchronous=True, rd_transparent=True, wr_granularity=None):
516 self.m = Module()
517 self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
518 self.m.submodules.rdport = self.rdport = \
519 self.memory.read_port(domain="sync" if rd_synchronous else "comb",
520 transparent=rd_transparent)
521 self.m.submodules.wrport = self.wrport = \
522 self.memory.write_port(granularity=wr_granularity)
523
524 def test_memory_init(self):
525 self.setUp_memory()
526 with self.assertSimulation(self.m) as sim:
527 def process():
528 self.assertEqual((yield self.rdport.data), 0xaa)
529 yield self.rdport.addr.eq(1)
530 yield
531 yield
532 self.assertEqual((yield self.rdport.data), 0x55)
533 yield self.rdport.addr.eq(2)
534 yield
535 yield
536 self.assertEqual((yield self.rdport.data), 0x00)
537 sim.add_clock(1e-6)
538 sim.add_sync_process(process)
539
540 def test_memory_write(self):
541 self.setUp_memory()
542 with self.assertSimulation(self.m) as sim:
543 def process():
544 yield self.wrport.addr.eq(4)
545 yield self.wrport.data.eq(0x33)
546 yield self.wrport.en.eq(1)
547 yield
548 yield self.wrport.en.eq(0)
549 yield self.rdport.addr.eq(4)
550 yield
551 self.assertEqual((yield self.rdport.data), 0x33)
552 sim.add_clock(1e-6)
553 sim.add_sync_process(process)
554
555 def test_memory_write_granularity(self):
556 self.setUp_memory(wr_granularity=4)
557 with self.assertSimulation(self.m) as sim:
558 def process():
559 yield self.wrport.data.eq(0x50)
560 yield self.wrport.en.eq(0b00)
561 yield
562 yield self.wrport.en.eq(0)
563 yield
564 self.assertEqual((yield self.rdport.data), 0xaa)
565 yield self.wrport.en.eq(0b10)
566 yield
567 yield self.wrport.en.eq(0)
568 yield
569 self.assertEqual((yield self.rdport.data), 0x5a)
570 yield self.wrport.data.eq(0x33)
571 yield self.wrport.en.eq(0b01)
572 yield
573 yield self.wrport.en.eq(0)
574 yield
575 self.assertEqual((yield self.rdport.data), 0x53)
576 sim.add_clock(1e-6)
577 sim.add_sync_process(process)
578
579 def test_memory_read_before_write(self):
580 self.setUp_memory(rd_transparent=False)
581 with self.assertSimulation(self.m) as sim:
582 def process():
583 yield self.wrport.data.eq(0x33)
584 yield self.wrport.en.eq(1)
585 yield
586 self.assertEqual((yield self.rdport.data), 0xaa)
587 yield
588 self.assertEqual((yield self.rdport.data), 0xaa)
589 yield Settle()
590 self.assertEqual((yield self.rdport.data), 0x33)
591 sim.add_clock(1e-6)
592 sim.add_sync_process(process)
593
594 def test_memory_write_through(self):
595 self.setUp_memory(rd_transparent=True)
596 with self.assertSimulation(self.m) as sim:
597 def process():
598 yield self.wrport.data.eq(0x33)
599 yield self.wrport.en.eq(1)
600 yield
601 self.assertEqual((yield self.rdport.data), 0xaa)
602 yield Settle()
603 self.assertEqual((yield self.rdport.data), 0x33)
604 yield
605 yield self.rdport.addr.eq(1)
606 yield Settle()
607 self.assertEqual((yield self.rdport.data), 0x33)
608 sim.add_clock(1e-6)
609 sim.add_sync_process(process)
610
611 def test_memory_async_read_write(self):
612 self.setUp_memory(rd_synchronous=False)
613 with self.assertSimulation(self.m) as sim:
614 def process():
615 yield self.rdport.addr.eq(0)
616 yield Settle()
617 self.assertEqual((yield self.rdport.data), 0xaa)
618 yield self.rdport.addr.eq(1)
619 yield Settle()
620 self.assertEqual((yield self.rdport.data), 0x55)
621 yield self.rdport.addr.eq(0)
622 yield self.wrport.addr.eq(0)
623 yield self.wrport.data.eq(0x33)
624 yield self.wrport.en.eq(1)
625 yield Tick("sync")
626 self.assertEqual((yield self.rdport.data), 0xaa)
627 yield Settle()
628 self.assertEqual((yield self.rdport.data), 0x33)
629 sim.add_clock(1e-6)
630 sim.add_process(process)
631
632 def test_memory_read_only(self):
633 self.m = Module()
634 self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
635 self.m.submodules.rdport = self.rdport = self.memory.read_port()
636 with self.assertSimulation(self.m) as sim:
637 def process():
638 self.assertEqual((yield self.rdport.data), 0xaa)
639 yield self.rdport.addr.eq(1)
640 yield
641 yield
642 self.assertEqual((yield self.rdport.data), 0x55)
643 sim.add_clock(1e-6)
644 sim.add_sync_process(process)
645
646 def test_sample_helpers(self):
647 m = Module()
648 s = Signal(2)
649 def mk(x):
650 y = Signal.like(x)
651 m.d.comb += y.eq(x)
652 return y
653 p0, r0, f0, s0 = mk(Past(s, 0)), mk(Rose(s)), mk(Fell(s)), mk(Stable(s))
654 p1, r1, f1, s1 = mk(Past(s)), mk(Rose(s, 1)), mk(Fell(s, 1)), mk(Stable(s, 1))
655 p2, r2, f2, s2 = mk(Past(s, 2)), mk(Rose(s, 2)), mk(Fell(s, 2)), mk(Stable(s, 2))
656 p3, r3, f3, s3 = mk(Past(s, 3)), mk(Rose(s, 3)), mk(Fell(s, 3)), mk(Stable(s, 3))
657 with self.assertSimulation(m) as sim:
658 def process_gen():
659 yield s.eq(0b10)
660 yield
661 yield
662 yield s.eq(0b01)
663 yield
664 def process_check():
665 yield
666 yield
667 yield
668
669 self.assertEqual((yield p0), 0b01)
670 self.assertEqual((yield p1), 0b10)
671 self.assertEqual((yield p2), 0b10)
672 self.assertEqual((yield p3), 0b00)
673
674 self.assertEqual((yield s0), 0b0)
675 self.assertEqual((yield s1), 0b1)
676 self.assertEqual((yield s2), 0b0)
677 self.assertEqual((yield s3), 0b1)
678
679 self.assertEqual((yield r0), 0b01)
680 self.assertEqual((yield r1), 0b00)
681 self.assertEqual((yield r2), 0b10)
682 self.assertEqual((yield r3), 0b00)
683
684 self.assertEqual((yield f0), 0b10)
685 self.assertEqual((yield f1), 0b00)
686 self.assertEqual((yield f2), 0b00)
687 self.assertEqual((yield f3), 0b00)
688 sim.add_clock(1e-6)
689 sim.add_sync_process(process_gen)
690 sim.add_sync_process(process_check)
691
692 def test_vcd_wrong_nonzero_time(self):
693 s = Signal()
694 m = Module()
695 m.d.sync += s.eq(s)
696 sim = Simulator(m)
697 sim.add_clock(1e-6)
698 sim.run_until(1e-5)
699 with self.assertRaisesRegex(ValueError,
700 regex=r"^Cannot start writing waveforms after advancing simulation time$"):
701 with sim.write_vcd(open(os.path.devnull, "wt")):
702 pass
703
704 def test_vcd_wrong_twice(self):
705 s = Signal()
706 m = Module()
707 m.d.sync += s.eq(s)
708 sim = Simulator(m)
709 sim.add_clock(1e-6)
710 with self.assertRaisesRegex(ValueError,
711 regex=r"^Already writing waveforms to .+$"):
712 with sim.write_vcd(open(os.path.devnull, "wt")):
713 with sim.write_vcd(open(os.path.devnull, "wt")):
714 pass
715
716
717 class SimulatorRegressionTestCase(FHDLTestCase):
718 def test_bug_325(self):
719 dut = Module()
720 dut.d.comb += Signal().eq(Cat())
721 Simulator(dut).run()
722
723 def test_bug_325_bis(self):
724 dut = Module()
725 dut.d.comb += Signal().eq(Repl(Const(1), 0))
726 Simulator(dut).run()