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