back.pysim: synchronize waveform writing with cxxrtl.
[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 def test_shift_left(self):
305 stmt1 = lambda y, a: y.eq(a.shift_left(1))
306 self.assertStatement(stmt1, [C(0b10100010, 8)], C( 0b101000100, 9))
307 stmt2 = lambda y, a: y.eq(a.shift_left(4))
308 self.assertStatement(stmt2, [C(0b10100010, 8)], C(0b101000100000, 12))
309
310 def test_shift_right(self):
311 stmt1 = lambda y, a: y.eq(a.shift_right(1))
312 self.assertStatement(stmt1, [C(0b10100010, 8)], C(0b1010001, 7))
313 stmt2 = lambda y, a: y.eq(a.shift_right(4))
314 self.assertStatement(stmt2, [C(0b10100010, 8)], C( 0b1010, 4))
315
316 def test_rotate_left(self):
317 stmt = lambda y, a: y.eq(a.rotate_left(1))
318 self.assertStatement(stmt, [C(0b1)], C(0b1))
319 self.assertStatement(stmt, [C(0b1001000)], C(0b0010001))
320 stmt = lambda y, a: y.eq(a.rotate_left(5))
321 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
322 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
323 stmt = lambda y, a: y.eq(a.rotate_left(7))
324 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
325 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
326 stmt = lambda y, a: y.eq(a.rotate_left(9))
327 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
328 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
329 stmt = lambda y, a: y.eq(a.rotate_left(-1))
330 self.assertStatement(stmt, [C(0b1)], C(0b1))
331 self.assertStatement(stmt, [C(0b1001000)], C(0b0100100))
332 stmt = lambda y, a: y.eq(a.rotate_left(-5))
333 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
334 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
335 stmt = lambda y, a: y.eq(a.rotate_left(-7))
336 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
337 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
338 stmt = lambda y, a: y.eq(a.rotate_left(-9))
339 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
340 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
341
342 def test_rotate_right(self):
343 stmt = lambda y, a: y.eq(a.rotate_right(1))
344 self.assertStatement(stmt, [C(0b1)], C(0b1))
345 self.assertStatement(stmt, [C(0b1001000)], C(0b0100100))
346 stmt = lambda y, a: y.eq(a.rotate_right(5))
347 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
348 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
349 stmt = lambda y, a: y.eq(a.rotate_right(7))
350 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
351 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
352 stmt = lambda y, a: y.eq(a.rotate_right(9))
353 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
354 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
355 stmt = lambda y, a: y.eq(a.rotate_right(-1))
356 self.assertStatement(stmt, [C(0b1)], C(0b1))
357 self.assertStatement(stmt, [C(0b1001000)], C(0b0010001))
358 stmt = lambda y, a: y.eq(a.rotate_right(-5))
359 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
360 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
361 stmt = lambda y, a: y.eq(a.rotate_right(-7))
362 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
363 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
364 stmt = lambda y, a: y.eq(a.rotate_right(-9))
365 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
366 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
367
368 class SimulatorIntegrationTestCase(FHDLTestCase):
369 @contextmanager
370 def assertSimulation(self, module, deadline=None):
371 sim = Simulator(module)
372 yield sim
373 with sim.write_vcd("test.vcd", "test.gtkw"):
374 if deadline is None:
375 sim.run()
376 else:
377 sim.run_until(deadline)
378
379 def setUp_counter(self):
380 self.count = Signal(3, reset=4)
381 self.sync = ClockDomain()
382
383 self.m = Module()
384 self.m.d.sync += self.count.eq(self.count + 1)
385 self.m.domains += self.sync
386
387 def test_counter_process(self):
388 self.setUp_counter()
389 with self.assertSimulation(self.m) as sim:
390 def process():
391 self.assertEqual((yield self.count), 4)
392 yield Delay(1e-6)
393 self.assertEqual((yield self.count), 4)
394 yield self.sync.clk.eq(1)
395 self.assertEqual((yield self.count), 4)
396 yield Settle()
397 self.assertEqual((yield self.count), 5)
398 yield Delay(1e-6)
399 self.assertEqual((yield self.count), 5)
400 yield self.sync.clk.eq(0)
401 self.assertEqual((yield self.count), 5)
402 yield Settle()
403 self.assertEqual((yield self.count), 5)
404 for _ in range(3):
405 yield Delay(1e-6)
406 yield self.sync.clk.eq(1)
407 yield Delay(1e-6)
408 yield self.sync.clk.eq(0)
409 self.assertEqual((yield self.count), 0)
410 sim.add_process(process)
411
412 def test_counter_clock_and_sync_process(self):
413 self.setUp_counter()
414 with self.assertSimulation(self.m) as sim:
415 sim.add_clock(1e-6, domain="sync")
416 def process():
417 self.assertEqual((yield self.count), 4)
418 self.assertEqual((yield self.sync.clk), 1)
419 yield
420 self.assertEqual((yield self.count), 5)
421 self.assertEqual((yield self.sync.clk), 1)
422 for _ in range(3):
423 yield
424 self.assertEqual((yield self.count), 0)
425 sim.add_sync_process(process)
426
427 def test_reset(self):
428 self.setUp_counter()
429 sim = Simulator(self.m)
430 sim.add_clock(1e-6)
431 times = 0
432 def process():
433 nonlocal times
434 self.assertEqual((yield self.count), 4)
435 yield
436 self.assertEqual((yield self.count), 5)
437 yield
438 self.assertEqual((yield self.count), 6)
439 yield
440 times += 1
441 sim.add_sync_process(process)
442 sim.run()
443 sim.reset()
444 sim.run()
445 self.assertEqual(times, 2)
446
447 def setUp_alu(self):
448 self.a = Signal(8)
449 self.b = Signal(8)
450 self.o = Signal(8)
451 self.x = Signal(8)
452 self.s = Signal(2)
453 self.sync = ClockDomain(reset_less=True)
454
455 self.m = Module()
456 self.m.d.comb += self.x.eq(self.a ^ self.b)
457 with self.m.Switch(self.s):
458 with self.m.Case(0):
459 self.m.d.sync += self.o.eq(self.a + self.b)
460 with self.m.Case(1):
461 self.m.d.sync += self.o.eq(self.a - self.b)
462 with self.m.Case():
463 self.m.d.sync += self.o.eq(0)
464 self.m.domains += self.sync
465
466 def test_alu(self):
467 self.setUp_alu()
468 with self.assertSimulation(self.m) as sim:
469 sim.add_clock(1e-6)
470 def process():
471 yield self.a.eq(5)
472 yield self.b.eq(1)
473 yield
474 self.assertEqual((yield self.x), 4)
475 yield
476 self.assertEqual((yield self.o), 6)
477 yield self.s.eq(1)
478 yield
479 yield
480 self.assertEqual((yield self.o), 4)
481 yield self.s.eq(2)
482 yield
483 yield
484 self.assertEqual((yield self.o), 0)
485 sim.add_sync_process(process)
486
487 def setUp_multiclock(self):
488 self.sys = ClockDomain()
489 self.pix = ClockDomain()
490
491 self.m = Module()
492 self.m.domains += self.sys, self.pix
493
494 def test_multiclock(self):
495 self.setUp_multiclock()
496 with self.assertSimulation(self.m) as sim:
497 sim.add_clock(1e-6, domain="sys")
498 sim.add_clock(0.3e-6, domain="pix")
499
500 def sys_process():
501 yield Passive()
502 yield
503 yield
504 self.fail()
505 def pix_process():
506 yield
507 yield
508 yield
509 sim.add_sync_process(sys_process, domain="sys")
510 sim.add_sync_process(pix_process, domain="pix")
511
512 def setUp_lhs_rhs(self):
513 self.i = Signal(8)
514 self.o = Signal(8)
515
516 self.m = Module()
517 self.m.d.comb += self.o.eq(self.i)
518
519 def test_complex_lhs_rhs(self):
520 self.setUp_lhs_rhs()
521 with self.assertSimulation(self.m) as sim:
522 def process():
523 yield self.i.eq(0b10101010)
524 yield self.i[:4].eq(-1)
525 yield Settle()
526 self.assertEqual((yield self.i[:4]), 0b1111)
527 self.assertEqual((yield self.i), 0b10101111)
528 sim.add_process(process)
529
530 def test_run_until(self):
531 m = Module()
532 s = Signal()
533 m.d.sync += s.eq(0)
534 with self.assertSimulation(m, deadline=100e-6) as sim:
535 sim.add_clock(1e-6)
536 def process():
537 for _ in range(101):
538 yield Delay(1e-6)
539 self.fail()
540 sim.add_process(process)
541
542 def test_add_process_wrong(self):
543 with self.assertSimulation(Module()) as sim:
544 with self.assertRaises(TypeError,
545 msg="Cannot add a process 1 because it is not a generator function"):
546 sim.add_process(1)
547
548 def test_add_process_wrong_generator(self):
549 with self.assertSimulation(Module()) as sim:
550 with self.assertRaisesRegex(TypeError,
551 r"^Cannot add a process <.+?> because it is not a generator function$"):
552 def process():
553 yield Delay()
554 sim.add_process(process())
555
556 def test_add_clock_wrong_twice(self):
557 m = Module()
558 s = Signal()
559 m.d.sync += s.eq(0)
560 with self.assertSimulation(m) as sim:
561 sim.add_clock(1)
562 with self.assertRaises(ValueError,
563 msg="Domain 'sync' already has a clock driving it"):
564 sim.add_clock(1)
565
566 def test_add_clock_wrong_missing(self):
567 m = Module()
568 with self.assertSimulation(m) as sim:
569 with self.assertRaises(ValueError,
570 msg="Domain 'sync' is not present in simulation"):
571 sim.add_clock(1)
572
573 def test_add_clock_if_exists(self):
574 m = Module()
575 with self.assertSimulation(m) as sim:
576 sim.add_clock(1, if_exists=True)
577
578 def test_command_wrong(self):
579 survived = False
580 with self.assertSimulation(Module()) as sim:
581 def process():
582 nonlocal survived
583 with self.assertRaisesRegex(TypeError,
584 r"Received unsupported command 1 from process .+?"):
585 yield 1
586 yield Settle()
587 survived = True
588 sim.add_process(process)
589 self.assertTrue(survived)
590
591 def setUp_memory(self, rd_synchronous=True, rd_transparent=True, wr_granularity=None):
592 self.m = Module()
593 self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
594 self.m.submodules.rdport = self.rdport = \
595 self.memory.read_port(domain="sync" if rd_synchronous else "comb",
596 transparent=rd_transparent)
597 self.m.submodules.wrport = self.wrport = \
598 self.memory.write_port(granularity=wr_granularity)
599
600 def test_memory_init(self):
601 self.setUp_memory()
602 with self.assertSimulation(self.m) as sim:
603 def process():
604 self.assertEqual((yield self.rdport.data), 0xaa)
605 yield self.rdport.addr.eq(1)
606 yield
607 yield
608 self.assertEqual((yield self.rdport.data), 0x55)
609 yield self.rdport.addr.eq(2)
610 yield
611 yield
612 self.assertEqual((yield self.rdport.data), 0x00)
613 sim.add_clock(1e-6)
614 sim.add_sync_process(process)
615
616 def test_memory_write(self):
617 self.setUp_memory()
618 with self.assertSimulation(self.m) as sim:
619 def process():
620 yield self.wrport.addr.eq(4)
621 yield self.wrport.data.eq(0x33)
622 yield self.wrport.en.eq(1)
623 yield
624 yield self.wrport.en.eq(0)
625 yield self.rdport.addr.eq(4)
626 yield
627 self.assertEqual((yield self.rdport.data), 0x33)
628 sim.add_clock(1e-6)
629 sim.add_sync_process(process)
630
631 def test_memory_write_granularity(self):
632 self.setUp_memory(wr_granularity=4)
633 with self.assertSimulation(self.m) as sim:
634 def process():
635 yield self.wrport.data.eq(0x50)
636 yield self.wrport.en.eq(0b00)
637 yield
638 yield self.wrport.en.eq(0)
639 yield
640 self.assertEqual((yield self.rdport.data), 0xaa)
641 yield self.wrport.en.eq(0b10)
642 yield
643 yield self.wrport.en.eq(0)
644 yield
645 self.assertEqual((yield self.rdport.data), 0x5a)
646 yield self.wrport.data.eq(0x33)
647 yield self.wrport.en.eq(0b01)
648 yield
649 yield self.wrport.en.eq(0)
650 yield
651 self.assertEqual((yield self.rdport.data), 0x53)
652 sim.add_clock(1e-6)
653 sim.add_sync_process(process)
654
655 def test_memory_read_before_write(self):
656 self.setUp_memory(rd_transparent=False)
657 with self.assertSimulation(self.m) as sim:
658 def process():
659 yield self.wrport.data.eq(0x33)
660 yield self.wrport.en.eq(1)
661 yield
662 self.assertEqual((yield self.rdport.data), 0xaa)
663 yield
664 self.assertEqual((yield self.rdport.data), 0xaa)
665 yield Settle()
666 self.assertEqual((yield self.rdport.data), 0x33)
667 sim.add_clock(1e-6)
668 sim.add_sync_process(process)
669
670 def test_memory_write_through(self):
671 self.setUp_memory(rd_transparent=True)
672 with self.assertSimulation(self.m) as sim:
673 def process():
674 yield self.wrport.data.eq(0x33)
675 yield self.wrport.en.eq(1)
676 yield
677 self.assertEqual((yield self.rdport.data), 0xaa)
678 yield Settle()
679 self.assertEqual((yield self.rdport.data), 0x33)
680 yield
681 yield self.rdport.addr.eq(1)
682 yield Settle()
683 self.assertEqual((yield self.rdport.data), 0x33)
684 sim.add_clock(1e-6)
685 sim.add_sync_process(process)
686
687 def test_memory_async_read_write(self):
688 self.setUp_memory(rd_synchronous=False)
689 with self.assertSimulation(self.m) as sim:
690 def process():
691 yield self.rdport.addr.eq(0)
692 yield Settle()
693 self.assertEqual((yield self.rdport.data), 0xaa)
694 yield self.rdport.addr.eq(1)
695 yield Settle()
696 self.assertEqual((yield self.rdport.data), 0x55)
697 yield self.rdport.addr.eq(0)
698 yield self.wrport.addr.eq(0)
699 yield self.wrport.data.eq(0x33)
700 yield self.wrport.en.eq(1)
701 yield Tick("sync")
702 self.assertEqual((yield self.rdport.data), 0xaa)
703 yield Settle()
704 self.assertEqual((yield self.rdport.data), 0x33)
705 sim.add_clock(1e-6)
706 sim.add_process(process)
707
708 def test_memory_read_only(self):
709 self.m = Module()
710 self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
711 self.m.submodules.rdport = self.rdport = self.memory.read_port()
712 with self.assertSimulation(self.m) as sim:
713 def process():
714 self.assertEqual((yield self.rdport.data), 0xaa)
715 yield self.rdport.addr.eq(1)
716 yield
717 yield
718 self.assertEqual((yield self.rdport.data), 0x55)
719 sim.add_clock(1e-6)
720 sim.add_sync_process(process)
721
722 def test_sample_helpers(self):
723 m = Module()
724 s = Signal(2)
725 def mk(x):
726 y = Signal.like(x)
727 m.d.comb += y.eq(x)
728 return y
729 p0, r0, f0, s0 = mk(Past(s, 0)), mk(Rose(s)), mk(Fell(s)), mk(Stable(s))
730 p1, r1, f1, s1 = mk(Past(s)), mk(Rose(s, 1)), mk(Fell(s, 1)), mk(Stable(s, 1))
731 p2, r2, f2, s2 = mk(Past(s, 2)), mk(Rose(s, 2)), mk(Fell(s, 2)), mk(Stable(s, 2))
732 p3, r3, f3, s3 = mk(Past(s, 3)), mk(Rose(s, 3)), mk(Fell(s, 3)), mk(Stable(s, 3))
733 with self.assertSimulation(m) as sim:
734 def process_gen():
735 yield s.eq(0b10)
736 yield
737 yield
738 yield s.eq(0b01)
739 yield
740 def process_check():
741 yield
742 yield
743 yield
744
745 self.assertEqual((yield p0), 0b01)
746 self.assertEqual((yield p1), 0b10)
747 self.assertEqual((yield p2), 0b10)
748 self.assertEqual((yield p3), 0b00)
749
750 self.assertEqual((yield s0), 0b0)
751 self.assertEqual((yield s1), 0b1)
752 self.assertEqual((yield s2), 0b0)
753 self.assertEqual((yield s3), 0b1)
754
755 self.assertEqual((yield r0), 0b01)
756 self.assertEqual((yield r1), 0b00)
757 self.assertEqual((yield r2), 0b10)
758 self.assertEqual((yield r3), 0b00)
759
760 self.assertEqual((yield f0), 0b10)
761 self.assertEqual((yield f1), 0b00)
762 self.assertEqual((yield f2), 0b00)
763 self.assertEqual((yield f3), 0b00)
764 sim.add_clock(1e-6)
765 sim.add_sync_process(process_gen)
766 sim.add_sync_process(process_check)
767
768 def test_vcd_wrong_nonzero_time(self):
769 s = Signal()
770 m = Module()
771 m.d.sync += s.eq(s)
772 sim = Simulator(m)
773 sim.add_clock(1e-6)
774 sim.run_until(1e-5)
775 with self.assertRaisesRegex(ValueError,
776 r"^Cannot start writing waveforms after advancing simulation time$"):
777 with sim.write_vcd(open(os.path.devnull, "wt")):
778 pass
779
780
781 class SimulatorRegressionTestCase(FHDLTestCase):
782 def test_bug_325(self):
783 dut = Module()
784 dut.d.comb += Signal().eq(Cat())
785 Simulator(dut).run()
786
787 def test_bug_325_bis(self):
788 dut = Module()
789 dut.d.comb += Signal().eq(Repl(Const(1), 0))
790 Simulator(dut).run()