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