d2d255f5e94853f1d5ba06154267746b60da2d3c
[nmigen.git] / tests / test_sim.py
1 import os
2 from contextlib import contextmanager
3
4 from nmigen._utils import flatten, union
5 from nmigen.hdl.ast import *
6 from nmigen.hdl.cd import *
7 from nmigen.hdl.mem import *
8 from nmigen.hdl.rec import *
9 from nmigen.hdl.dsl import *
10 from nmigen.hdl.ir import *
11 from nmigen.sim import *
12
13 from .utils import *
14
15
16 class SimulatorUnitTestCase(FHDLTestCase):
17 def assertStatement(self, stmt, inputs, output, reset=0):
18 inputs = [Value.cast(i) for i in inputs]
19 output = Value.cast(output)
20
21 isigs = [Signal(i.shape(), name=n) for i, n in zip(inputs, "abcd")]
22 osig = Signal(output.shape(), name="y", reset=reset)
23
24 stmt = stmt(osig, *isigs)
25 frag = Fragment()
26 frag.add_statements(stmt)
27 for signal in flatten(s._lhs_signals() for s in Statement.cast(stmt)):
28 frag.add_driver(signal)
29
30 sim = Simulator(frag)
31 def process():
32 for isig, input in zip(isigs, inputs):
33 yield isig.eq(input)
34 yield Settle()
35 self.assertEqual((yield osig), output.value)
36 sim.add_process(process)
37 with sim.write_vcd("test.vcd", "test.gtkw", traces=[*isigs, osig]):
38 sim.run()
39
40 def test_invert(self):
41 stmt = lambda y, a: y.eq(~a)
42 self.assertStatement(stmt, [C(0b0000, 4)], C(0b1111, 4))
43 self.assertStatement(stmt, [C(0b1010, 4)], C(0b0101, 4))
44 self.assertStatement(stmt, [C(0, 4)], C(-1, 4))
45
46 def test_neg(self):
47 stmt = lambda y, a: y.eq(-a)
48 self.assertStatement(stmt, [C(0b0000, 4)], C(0b0000, 4))
49 self.assertStatement(stmt, [C(0b0001, 4)], C(0b1111, 4))
50 self.assertStatement(stmt, [C(0b1010, 4)], C(0b0110, 4))
51 self.assertStatement(stmt, [C(1, 4)], C(-1, 4))
52 self.assertStatement(stmt, [C(5, 4)], C(-5, 4))
53
54 def test_bool(self):
55 stmt = lambda y, a: y.eq(a.bool())
56 self.assertStatement(stmt, [C(0, 4)], C(0))
57 self.assertStatement(stmt, [C(1, 4)], C(1))
58 self.assertStatement(stmt, [C(2, 4)], C(1))
59
60 def test_as_unsigned(self):
61 stmt = lambda y, a, b: y.eq(a.as_unsigned() == b)
62 self.assertStatement(stmt, [C(0b01, signed(2)), C(0b0001, unsigned(4))], C(1))
63 self.assertStatement(stmt, [C(0b11, signed(2)), C(0b0011, unsigned(4))], C(1))
64
65 def test_as_signed(self):
66 stmt = lambda y, a, b: y.eq(a.as_signed() == b)
67 self.assertStatement(stmt, [C(0b01, unsigned(2)), C(0b0001, signed(4))], C(1))
68 self.assertStatement(stmt, [C(0b11, unsigned(2)), C(0b1111, signed(4))], C(1))
69
70 def test_as_signed_issue_502(self):
71 stmt = lambda y, a: y.eq(a.as_signed())
72 self.assertStatement(stmt, [C(0b01, unsigned(2))], C(0b0001, signed(4)))
73 self.assertStatement(stmt, [C(0b11, unsigned(2))], C(0b1111, signed(4)))
74
75 def test_any(self):
76 stmt = lambda y, a: y.eq(a.any())
77 self.assertStatement(stmt, [C(0b00, 2)], C(0))
78 self.assertStatement(stmt, [C(0b01, 2)], C(1))
79 self.assertStatement(stmt, [C(0b10, 2)], C(1))
80 self.assertStatement(stmt, [C(0b11, 2)], C(1))
81
82 def test_all(self):
83 stmt = lambda y, a: y.eq(a.all())
84 self.assertStatement(stmt, [C(0b00, 2)], C(0))
85 self.assertStatement(stmt, [C(0b01, 2)], C(0))
86 self.assertStatement(stmt, [C(0b10, 2)], C(0))
87 self.assertStatement(stmt, [C(0b11, 2)], C(1))
88
89 def test_xor_unary(self):
90 stmt = lambda y, a: y.eq(a.xor())
91 self.assertStatement(stmt, [C(0b00, 2)], C(0))
92 self.assertStatement(stmt, [C(0b01, 2)], C(1))
93 self.assertStatement(stmt, [C(0b10, 2)], C(1))
94 self.assertStatement(stmt, [C(0b11, 2)], C(0))
95
96 def test_add(self):
97 stmt = lambda y, a, b: y.eq(a + b)
98 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1, 4))
99 self.assertStatement(stmt, [C(-5, 4), C(-5, 4)], C(-10, 5))
100
101 def test_sub(self):
102 stmt = lambda y, a, b: y.eq(a - b)
103 self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(1, 4))
104 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(-1, 4))
105 self.assertStatement(stmt, [C(0, 4), C(10, 4)], C(-10, 5))
106
107 def test_mul(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(4, 8))
111 self.assertStatement(stmt, [C(7, 4), C(7, 4)], C(49, 8))
112
113 def test_floordiv(self):
114 stmt = lambda y, a, b: y.eq(a // b)
115 self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(2, 8))
116 self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(1, 8))
117 self.assertStatement(stmt, [C(7, 4), C(2, 4)], C(3, 8))
118
119 def test_mod(self):
120 stmt = lambda y, a, b: y.eq(a % b)
121 self.assertStatement(stmt, [C(2, 4), C(0, 4)], C(0, 8))
122 self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(0, 8))
123 self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(0, 8))
124 self.assertStatement(stmt, [C(7, 4), C(2, 4)], C(1, 8))
125
126 def test_and(self):
127 stmt = lambda y, a, b: y.eq(a & b)
128 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
129
130 def test_or(self):
131 stmt = lambda y, a, b: y.eq(a | b)
132 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
133
134 def test_xor_binary(self):
135 stmt = lambda y, a, b: y.eq(a ^ b)
136 self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b0110, 4))
137
138 def test_shl(self):
139 stmt = lambda y, a, b: y.eq(a << b)
140 self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 5))
141 self.assertStatement(stmt, [C(0b1001, 4), C(3)], C(0b1001000, 7))
142
143 def test_shr(self):
144 stmt = lambda y, a, b: y.eq(a >> b)
145 self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 4))
146 self.assertStatement(stmt, [C(0b1001, 4), C(2)], C(0b10, 4))
147
148 def test_eq(self):
149 stmt = lambda y, a, b: y.eq(a == b)
150 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
151 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
152 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
153
154 def test_ne(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(1))
159
160 def test_lt(self):
161 stmt = lambda y, a, b: y.eq(a < b)
162 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
163 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
164 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
165
166 def test_ge(self):
167 stmt = lambda y, a, b: y.eq(a >= b)
168 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
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_gt(self):
173 stmt = lambda y, a, b: y.eq(a > b)
174 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
175 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
176 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
177
178 def test_le(self):
179 stmt = lambda y, a, b: y.eq(a <= b)
180 self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
181 self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
182 self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
183
184 def test_mux(self):
185 stmt = lambda y, a, b, c: y.eq(Mux(c, a, b))
186 self.assertStatement(stmt, [C(2, 4), C(3, 4), C(0)], C(3, 4))
187 self.assertStatement(stmt, [C(2, 4), C(3, 4), C(1)], C(2, 4))
188
189 def test_abs(self):
190 stmt = lambda y, a: y.eq(abs(a))
191 self.assertStatement(stmt, [C(3, unsigned(8))], C(3, unsigned(8)))
192 self.assertStatement(stmt, [C(-3, unsigned(8))], C(-3, unsigned(8)))
193 self.assertStatement(stmt, [C(3, signed(8))], C(3, signed(8)))
194 self.assertStatement(stmt, [C(-3, signed(8))], C(3, signed(8)))
195
196 def test_slice(self):
197 stmt1 = lambda y, a: y.eq(a[2])
198 self.assertStatement(stmt1, [C(0b10110100, 8)], C(0b1, 1))
199 stmt2 = lambda y, a: y.eq(a[2:4])
200 self.assertStatement(stmt2, [C(0b10110100, 8)], C(0b01, 2))
201
202 def test_slice_lhs(self):
203 stmt1 = lambda y, a: y[2].eq(a)
204 self.assertStatement(stmt1, [C(0b0, 1)], C(0b11111011, 8), reset=0b11111111)
205 stmt2 = lambda y, a: y[2:4].eq(a)
206 self.assertStatement(stmt2, [C(0b01, 2)], C(0b11110111, 8), reset=0b11111011)
207
208 def test_bit_select(self):
209 stmt = lambda y, a, b: y.eq(a.bit_select(b, 3))
210 self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
211 self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b101, 3))
212 self.assertStatement(stmt, [C(0b10110100, 8), C(3)], C(0b110, 3))
213
214 def test_bit_select_lhs(self):
215 stmt = lambda y, a, b: y.bit_select(a, 3).eq(b)
216 self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
217 self.assertStatement(stmt, [C(2), C(0b101, 3)], C(0b11110111, 8), reset=0b11111111)
218 self.assertStatement(stmt, [C(3), C(0b110, 3)], C(0b11110111, 8), reset=0b11111111)
219
220 def test_word_select(self):
221 stmt = lambda y, a, b: y.eq(a.word_select(b, 3))
222 self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
223 self.assertStatement(stmt, [C(0b10110100, 8), C(1)], C(0b110, 3))
224 self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b010, 3))
225
226 def test_word_select_lhs(self):
227 stmt = lambda y, a, b: y.word_select(a, 3).eq(b)
228 self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
229 self.assertStatement(stmt, [C(1), C(0b101, 3)], C(0b11101111, 8), reset=0b11111111)
230 self.assertStatement(stmt, [C(2), C(0b110, 3)], C(0b10111111, 8), reset=0b11111111)
231
232 def test_cat(self):
233 stmt = lambda y, *xs: y.eq(Cat(*xs))
234 self.assertStatement(stmt, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
235
236 def test_cat_lhs(self):
237 l = Signal(3)
238 m = Signal(3)
239 n = Signal(3)
240 stmt = lambda y, a: [Cat(l, m, n).eq(a), y.eq(Cat(n, m, l))]
241 self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
242
243 def test_nested_cat_lhs(self):
244 l = Signal(3)
245 m = Signal(3)
246 n = Signal(3)
247 stmt = lambda y, a: [Cat(Cat(l, Cat(m)), n).eq(a), y.eq(Cat(n, m, l))]
248 self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
249
250 def test_record(self):
251 rec = Record([
252 ("l", 1),
253 ("m", 2),
254 ])
255 stmt = lambda y, a: [rec.eq(a), y.eq(rec)]
256 self.assertStatement(stmt, [C(0b101, 3)], C(0b101, 3))
257
258 def test_repl(self):
259 stmt = lambda y, a: y.eq(Repl(a, 3))
260 self.assertStatement(stmt, [C(0b10, 2)], C(0b101010, 6))
261
262 def test_array(self):
263 array = Array([1, 4, 10])
264 stmt = lambda y, a: y.eq(array[a])
265 self.assertStatement(stmt, [C(0)], C(1))
266 self.assertStatement(stmt, [C(1)], C(4))
267 self.assertStatement(stmt, [C(2)], C(10))
268
269 def test_array_oob(self):
270 array = Array([1, 4, 10])
271 stmt = lambda y, a: y.eq(array[a])
272 self.assertStatement(stmt, [C(3)], C(10))
273 self.assertStatement(stmt, [C(4)], C(10))
274
275 def test_array_lhs(self):
276 l = Signal(3, reset=1)
277 m = Signal(3, reset=4)
278 n = Signal(3, reset=7)
279 array = Array([l, m, n])
280 stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
281 self.assertStatement(stmt, [C(0), C(0b000)], C(0b111100000))
282 self.assertStatement(stmt, [C(1), C(0b010)], C(0b111010001))
283 self.assertStatement(stmt, [C(2), C(0b100)], C(0b100100001))
284
285 def test_array_lhs_oob(self):
286 l = Signal(3)
287 m = Signal(3)
288 n = Signal(3)
289 array = Array([l, m, n])
290 stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
291 self.assertStatement(stmt, [C(3), C(0b001)], C(0b001000000))
292 self.assertStatement(stmt, [C(4), C(0b010)], C(0b010000000))
293
294 def test_array_index(self):
295 array = Array(Array(x * y for y in range(10)) for x in range(10))
296 stmt = lambda y, a, b: y.eq(array[a][b])
297 for x in range(10):
298 for y in range(10):
299 self.assertStatement(stmt, [C(x), C(y)], C(x * y))
300
301 def test_array_attr(self):
302 from collections import namedtuple
303 pair = namedtuple("pair", ("p", "n"))
304
305 array = Array(pair(x, -x) for x in range(10))
306 stmt = lambda y, a: y.eq(array[a].p + array[a].n)
307 for i in range(10):
308 self.assertStatement(stmt, [C(i)], C(0))
309
310 def test_shift_left(self):
311 stmt1 = lambda y, a: y.eq(a.shift_left(1))
312 self.assertStatement(stmt1, [C(0b10100010, 8)], C( 0b101000100, 9))
313 stmt2 = lambda y, a: y.eq(a.shift_left(4))
314 self.assertStatement(stmt2, [C(0b10100010, 8)], C(0b101000100000, 12))
315
316 def test_shift_right(self):
317 stmt1 = lambda y, a: y.eq(a.shift_right(1))
318 self.assertStatement(stmt1, [C(0b10100010, 8)], C(0b1010001, 7))
319 stmt2 = lambda y, a: y.eq(a.shift_right(4))
320 self.assertStatement(stmt2, [C(0b10100010, 8)], C( 0b1010, 4))
321
322 def test_rotate_left(self):
323 stmt = lambda y, a: y.eq(a.rotate_left(1))
324 self.assertStatement(stmt, [C(0b1)], C(0b1))
325 self.assertStatement(stmt, [C(0b1001000)], C(0b0010001))
326 stmt = lambda y, a: y.eq(a.rotate_left(5))
327 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
328 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
329 stmt = lambda y, a: y.eq(a.rotate_left(7))
330 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
331 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
332 stmt = lambda y, a: y.eq(a.rotate_left(9))
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(-1))
336 self.assertStatement(stmt, [C(0b1)], C(0b1))
337 self.assertStatement(stmt, [C(0b1001000)], C(0b0100100))
338 stmt = lambda y, a: y.eq(a.rotate_left(-5))
339 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
340 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
341 stmt = lambda y, a: y.eq(a.rotate_left(-7))
342 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
343 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
344 stmt = lambda y, a: y.eq(a.rotate_left(-9))
345 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
346 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
347
348 def test_rotate_right(self):
349 stmt = lambda y, a: y.eq(a.rotate_right(1))
350 self.assertStatement(stmt, [C(0b1)], C(0b1))
351 self.assertStatement(stmt, [C(0b1001000)], C(0b0100100))
352 stmt = lambda y, a: y.eq(a.rotate_right(5))
353 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
354 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
355 stmt = lambda y, a: y.eq(a.rotate_right(7))
356 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
357 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
358 stmt = lambda y, a: y.eq(a.rotate_right(9))
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(-1))
362 self.assertStatement(stmt, [C(0b1)], C(0b1))
363 self.assertStatement(stmt, [C(0b1001000)], C(0b0010001))
364 stmt = lambda y, a: y.eq(a.rotate_right(-5))
365 self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
366 self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
367 stmt = lambda y, a: y.eq(a.rotate_right(-7))
368 self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
369 self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
370 stmt = lambda y, a: y.eq(a.rotate_right(-9))
371 self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
372 self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
373
374
375 class SimulatorIntegrationTestCase(FHDLTestCase):
376 @contextmanager
377 def assertSimulation(self, module, deadline=None):
378 sim = Simulator(module)
379 yield sim
380 with sim.write_vcd("test.vcd", "test.gtkw"):
381 if deadline is None:
382 sim.run()
383 else:
384 sim.run_until(deadline)
385
386 def setUp_counter(self):
387 self.count = Signal(3, reset=4)
388 self.sync = ClockDomain()
389
390 self.m = Module()
391 self.m.d.sync += self.count.eq(self.count + 1)
392 self.m.domains += self.sync
393
394 def test_counter_process(self):
395 self.setUp_counter()
396 with self.assertSimulation(self.m) as sim:
397 def process():
398 self.assertEqual((yield self.count), 4)
399 yield Delay(1e-6)
400 self.assertEqual((yield self.count), 4)
401 yield self.sync.clk.eq(1)
402 self.assertEqual((yield self.count), 4)
403 yield Settle()
404 self.assertEqual((yield self.count), 5)
405 yield Delay(1e-6)
406 self.assertEqual((yield self.count), 5)
407 yield self.sync.clk.eq(0)
408 self.assertEqual((yield self.count), 5)
409 yield Settle()
410 self.assertEqual((yield self.count), 5)
411 for _ in range(3):
412 yield Delay(1e-6)
413 yield self.sync.clk.eq(1)
414 yield Delay(1e-6)
415 yield self.sync.clk.eq(0)
416 self.assertEqual((yield self.count), 0)
417 sim.add_process(process)
418
419 def test_counter_clock_and_sync_process(self):
420 self.setUp_counter()
421 with self.assertSimulation(self.m) as sim:
422 sim.add_clock(1e-6, domain="sync")
423 def process():
424 self.assertEqual((yield self.count), 4)
425 self.assertEqual((yield self.sync.clk), 1)
426 yield
427 self.assertEqual((yield self.count), 5)
428 self.assertEqual((yield self.sync.clk), 1)
429 for _ in range(3):
430 yield
431 self.assertEqual((yield self.count), 0)
432 sim.add_sync_process(process)
433
434 def test_reset(self):
435 self.setUp_counter()
436 sim = Simulator(self.m)
437 sim.add_clock(1e-6)
438 times = 0
439 def process():
440 nonlocal times
441 self.assertEqual((yield self.count), 4)
442 yield
443 self.assertEqual((yield self.count), 5)
444 yield
445 self.assertEqual((yield self.count), 6)
446 yield
447 times += 1
448 sim.add_sync_process(process)
449 sim.run()
450 sim.reset()
451 sim.run()
452 self.assertEqual(times, 2)
453
454 def setUp_alu(self):
455 self.a = Signal(8)
456 self.b = Signal(8)
457 self.o = Signal(8)
458 self.x = Signal(8)
459 self.s = Signal(2)
460 self.sync = ClockDomain(reset_less=True)
461
462 self.m = Module()
463 self.m.d.comb += self.x.eq(self.a ^ self.b)
464 with self.m.Switch(self.s):
465 with self.m.Case(0):
466 self.m.d.sync += self.o.eq(self.a + self.b)
467 with self.m.Case(1):
468 self.m.d.sync += self.o.eq(self.a - self.b)
469 with self.m.Case():
470 self.m.d.sync += self.o.eq(0)
471 self.m.domains += self.sync
472
473 def test_alu(self):
474 self.setUp_alu()
475 with self.assertSimulation(self.m) as sim:
476 sim.add_clock(1e-6)
477 def process():
478 yield self.a.eq(5)
479 yield self.b.eq(1)
480 yield
481 self.assertEqual((yield self.x), 4)
482 yield
483 self.assertEqual((yield self.o), 6)
484 yield self.s.eq(1)
485 yield
486 yield
487 self.assertEqual((yield self.o), 4)
488 yield self.s.eq(2)
489 yield
490 yield
491 self.assertEqual((yield self.o), 0)
492 sim.add_sync_process(process)
493
494 def setUp_multiclock(self):
495 self.sys = ClockDomain()
496 self.pix = ClockDomain()
497
498 self.m = Module()
499 self.m.domains += self.sys, self.pix
500
501 def test_multiclock(self):
502 self.setUp_multiclock()
503 with self.assertSimulation(self.m) as sim:
504 sim.add_clock(1e-6, domain="sys")
505 sim.add_clock(0.3e-6, domain="pix")
506
507 def sys_process():
508 yield Passive()
509 yield
510 yield
511 self.fail()
512 def pix_process():
513 yield
514 yield
515 yield
516 sim.add_sync_process(sys_process, domain="sys")
517 sim.add_sync_process(pix_process, domain="pix")
518
519 def setUp_lhs_rhs(self):
520 self.i = Signal(8)
521 self.o = Signal(8)
522
523 self.m = Module()
524 self.m.d.comb += self.o.eq(self.i)
525
526 def test_complex_lhs_rhs(self):
527 self.setUp_lhs_rhs()
528 with self.assertSimulation(self.m) as sim:
529 def process():
530 yield self.i.eq(0b10101010)
531 yield self.i[:4].eq(-1)
532 yield Settle()
533 self.assertEqual((yield self.i[:4]), 0b1111)
534 self.assertEqual((yield self.i), 0b10101111)
535 sim.add_process(process)
536
537 def test_run_until(self):
538 m = Module()
539 s = Signal()
540 m.d.sync += s.eq(0)
541 with self.assertSimulation(m, deadline=100e-6) as sim:
542 sim.add_clock(1e-6)
543 def process():
544 for _ in range(101):
545 yield Delay(1e-6)
546 self.fail()
547 sim.add_process(process)
548
549 def test_add_process_wrong(self):
550 with self.assertSimulation(Module()) as sim:
551 with self.assertRaisesRegex(TypeError,
552 r"^Cannot add a process 1 because it is not a generator function$"):
553 sim.add_process(1)
554
555 def test_add_process_wrong_generator(self):
556 with self.assertSimulation(Module()) as sim:
557 with self.assertRaisesRegex(TypeError,
558 r"^Cannot add a process <.+?> because it is not a generator function$"):
559 def process():
560 yield Delay()
561 sim.add_process(process())
562
563 def test_add_clock_wrong_twice(self):
564 m = Module()
565 s = Signal()
566 m.d.sync += s.eq(0)
567 with self.assertSimulation(m) as sim:
568 sim.add_clock(1)
569 with self.assertRaisesRegex(ValueError,
570 r"^Domain 'sync' already has a clock driving it$"):
571 sim.add_clock(1)
572
573 def test_add_clock_wrong_missing(self):
574 m = Module()
575 with self.assertSimulation(m) as sim:
576 with self.assertRaisesRegex(ValueError,
577 r"^Domain 'sync' is not present in simulation$"):
578 sim.add_clock(1)
579
580 def test_add_clock_if_exists(self):
581 m = Module()
582 with self.assertSimulation(m) as sim:
583 sim.add_clock(1, if_exists=True)
584
585 def test_command_wrong(self):
586 survived = False
587 with self.assertSimulation(Module()) as sim:
588 def process():
589 nonlocal survived
590 with self.assertRaisesRegex(TypeError,
591 r"Received unsupported command 1 from process .+?"):
592 yield 1
593 yield Settle()
594 survived = True
595 sim.add_process(process)
596 self.assertTrue(survived)
597
598 def setUp_memory(self, rd_synchronous=True, rd_transparent=True, wr_granularity=None):
599 self.m = Module()
600 self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
601 self.m.submodules.rdport = self.rdport = \
602 self.memory.read_port(domain="sync" if rd_synchronous else "comb",
603 transparent=rd_transparent)
604 self.m.submodules.wrport = self.wrport = \
605 self.memory.write_port(granularity=wr_granularity)
606
607 def test_memory_init(self):
608 self.setUp_memory()
609 with self.assertSimulation(self.m) as sim:
610 def process():
611 self.assertEqual((yield self.rdport.data), 0xaa)
612 yield self.rdport.addr.eq(1)
613 yield
614 yield
615 self.assertEqual((yield self.rdport.data), 0x55)
616 yield self.rdport.addr.eq(2)
617 yield
618 yield
619 self.assertEqual((yield self.rdport.data), 0x00)
620 sim.add_clock(1e-6)
621 sim.add_sync_process(process)
622
623 def test_memory_write(self):
624 self.setUp_memory()
625 with self.assertSimulation(self.m) as sim:
626 def process():
627 yield self.wrport.addr.eq(4)
628 yield self.wrport.data.eq(0x33)
629 yield self.wrport.en.eq(1)
630 yield
631 yield self.wrport.en.eq(0)
632 yield self.rdport.addr.eq(4)
633 yield
634 self.assertEqual((yield self.rdport.data), 0x33)
635 sim.add_clock(1e-6)
636 sim.add_sync_process(process)
637
638 def test_memory_write_granularity(self):
639 self.setUp_memory(wr_granularity=4)
640 with self.assertSimulation(self.m) as sim:
641 def process():
642 yield self.wrport.data.eq(0x50)
643 yield self.wrport.en.eq(0b00)
644 yield
645 yield self.wrport.en.eq(0)
646 yield
647 self.assertEqual((yield self.rdport.data), 0xaa)
648 yield self.wrport.en.eq(0b10)
649 yield
650 yield self.wrport.en.eq(0)
651 yield
652 self.assertEqual((yield self.rdport.data), 0x5a)
653 yield self.wrport.data.eq(0x33)
654 yield self.wrport.en.eq(0b01)
655 yield
656 yield self.wrport.en.eq(0)
657 yield
658 self.assertEqual((yield self.rdport.data), 0x53)
659 sim.add_clock(1e-6)
660 sim.add_sync_process(process)
661
662 def test_memory_read_before_write(self):
663 self.setUp_memory(rd_transparent=False)
664 with self.assertSimulation(self.m) as sim:
665 def process():
666 yield self.wrport.data.eq(0x33)
667 yield self.wrport.en.eq(1)
668 yield
669 self.assertEqual((yield self.rdport.data), 0xaa)
670 yield
671 self.assertEqual((yield self.rdport.data), 0xaa)
672 yield Settle()
673 self.assertEqual((yield self.rdport.data), 0x33)
674 sim.add_clock(1e-6)
675 sim.add_sync_process(process)
676
677 def test_memory_write_through(self):
678 self.setUp_memory(rd_transparent=True)
679 with self.assertSimulation(self.m) as sim:
680 def process():
681 yield self.wrport.data.eq(0x33)
682 yield self.wrport.en.eq(1)
683 yield
684 self.assertEqual((yield self.rdport.data), 0xaa)
685 yield Settle()
686 self.assertEqual((yield self.rdport.data), 0x33)
687 yield
688 yield self.rdport.addr.eq(1)
689 yield Settle()
690 self.assertEqual((yield self.rdport.data), 0x33)
691 sim.add_clock(1e-6)
692 sim.add_sync_process(process)
693
694 def test_memory_async_read_write(self):
695 self.setUp_memory(rd_synchronous=False)
696 with self.assertSimulation(self.m) as sim:
697 def process():
698 yield self.rdport.addr.eq(0)
699 yield Settle()
700 self.assertEqual((yield self.rdport.data), 0xaa)
701 yield self.rdport.addr.eq(1)
702 yield Settle()
703 self.assertEqual((yield self.rdport.data), 0x55)
704 yield self.rdport.addr.eq(0)
705 yield self.wrport.addr.eq(0)
706 yield self.wrport.data.eq(0x33)
707 yield self.wrport.en.eq(1)
708 yield Tick("sync")
709 self.assertEqual((yield self.rdport.data), 0xaa)
710 yield Settle()
711 self.assertEqual((yield self.rdport.data), 0x33)
712 sim.add_clock(1e-6)
713 sim.add_process(process)
714
715 def test_memory_read_only(self):
716 self.m = Module()
717 self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
718 self.m.submodules.rdport = self.rdport = self.memory.read_port()
719 with self.assertSimulation(self.m) as sim:
720 def process():
721 self.assertEqual((yield self.rdport.data), 0xaa)
722 yield self.rdport.addr.eq(1)
723 yield
724 yield
725 self.assertEqual((yield self.rdport.data), 0x55)
726 sim.add_clock(1e-6)
727 sim.add_sync_process(process)
728
729 def test_sample_helpers(self):
730 m = Module()
731 s = Signal(2)
732 def mk(x):
733 y = Signal.like(x)
734 m.d.comb += y.eq(x)
735 return y
736 p0, r0, f0, s0 = mk(Past(s, 0)), mk(Rose(s)), mk(Fell(s)), mk(Stable(s))
737 p1, r1, f1, s1 = mk(Past(s)), mk(Rose(s, 1)), mk(Fell(s, 1)), mk(Stable(s, 1))
738 p2, r2, f2, s2 = mk(Past(s, 2)), mk(Rose(s, 2)), mk(Fell(s, 2)), mk(Stable(s, 2))
739 p3, r3, f3, s3 = mk(Past(s, 3)), mk(Rose(s, 3)), mk(Fell(s, 3)), mk(Stable(s, 3))
740 with self.assertSimulation(m) as sim:
741 def process_gen():
742 yield s.eq(0b10)
743 yield
744 yield
745 yield s.eq(0b01)
746 yield
747 def process_check():
748 yield
749 yield
750 yield
751
752 self.assertEqual((yield p0), 0b01)
753 self.assertEqual((yield p1), 0b10)
754 self.assertEqual((yield p2), 0b10)
755 self.assertEqual((yield p3), 0b00)
756
757 self.assertEqual((yield s0), 0b0)
758 self.assertEqual((yield s1), 0b1)
759 self.assertEqual((yield s2), 0b0)
760 self.assertEqual((yield s3), 0b1)
761
762 self.assertEqual((yield r0), 0b01)
763 self.assertEqual((yield r1), 0b00)
764 self.assertEqual((yield r2), 0b10)
765 self.assertEqual((yield r3), 0b00)
766
767 self.assertEqual((yield f0), 0b10)
768 self.assertEqual((yield f1), 0b00)
769 self.assertEqual((yield f2), 0b00)
770 self.assertEqual((yield f3), 0b00)
771 sim.add_clock(1e-6)
772 sim.add_sync_process(process_gen)
773 sim.add_sync_process(process_check)
774
775 def test_vcd_wrong_nonzero_time(self):
776 s = Signal()
777 m = Module()
778 m.d.sync += s.eq(s)
779 sim = Simulator(m)
780 sim.add_clock(1e-6)
781 sim.run_until(1e-5)
782 with self.assertRaisesRegex(ValueError,
783 r"^Cannot start writing waveforms after advancing simulation time$"):
784 with sim.write_vcd(open(os.path.devnull, "wt")):
785 pass
786
787
788 class SimulatorRegressionTestCase(FHDLTestCase):
789 def test_bug_325(self):
790 dut = Module()
791 dut.d.comb += Signal().eq(Cat())
792 Simulator(dut).run()
793
794 def test_bug_325_bis(self):
795 dut = Module()
796 dut.d.comb += Signal().eq(Repl(Const(1), 0))
797 Simulator(dut).run()
798
799 def test_bug_473(self):
800 sim = Simulator(Module())
801 def process():
802 self.assertEqual((yield -(Const(0b11, 2).as_signed())), 1)
803 sim.add_process(process)
804 sim.run()