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