2 from contextlib
import contextmanager
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 *
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
)
21 isigs
= [Signal(i
.shape(), name
=n
) for i
, n
in zip(inputs
, "abcd")]
22 osig
= Signal(output
.shape(), name
="y", reset
=reset
)
24 stmt
= stmt(osig
, *isigs
)
26 frag
.add_statements(stmt
)
27 for signal
in flatten(s
._lhs
_signals
() for s
in Statement
.cast(stmt
)):
28 frag
.add_driver(signal
)
32 for isig
, input in zip(isigs
, inputs
):
35 self
.assertEqual((yield osig
), output
.value
)
36 sim
.add_process(process
)
37 with sim
.write_vcd("test.vcd", "test.gtkw", traces
=[*isigs
, osig
]):
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))
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))
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))
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))
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))
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)))
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))
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))
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))
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))
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))
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))
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))
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))
127 stmt
= lambda y
, a
, b
: y
.eq(a
& b
)
128 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
131 stmt
= lambda y
, a
, b
: y
.eq(a | b
)
132 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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)))
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))
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)
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))
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)
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))
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)
238 stmt
= lambda y
, *xs
: y
.eq(Cat(*xs
))
239 self
.assertStatement(stmt
, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
241 def test_cat_lhs(self
):
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))
248 def test_nested_cat_lhs(self
):
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))
255 def test_record(self
):
260 stmt
= lambda y
, a
: [rec
.eq(a
), y
.eq(rec
)]
261 self
.assertStatement(stmt
, [C(0b101, 3)], C(0b101, 3))
264 stmt
= lambda y
, a
: y
.eq(Repl(a
, 3))
265 self
.assertStatement(stmt
, [C(0b10, 2)], C(0b101010, 6))
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))
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))
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))
290 def test_array_lhs_oob(self
):
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))
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
])
304 self
.assertStatement(stmt
, [C(x
), C(y
)], C(x
* y
))
306 def test_array_attr(self
):
307 from collections
import namedtuple
308 pair
= namedtuple("pair", ("p", "n"))
310 array
= Array(pair(x
, -x
) for x
in range(10))
311 stmt
= lambda y
, a
: y
.eq(array
[a
].p
+ array
[a
].n
)
313 self
.assertStatement(stmt
, [C(i
)], C(0))
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))
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))
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))
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))
380 class SimulatorIntegrationTestCase(FHDLTestCase
):
382 def assertSimulation(self
, module
, deadline
=None):
383 sim
= Simulator(module
)
385 with sim
.write_vcd("test.vcd", "test.gtkw"):
389 sim
.run_until(deadline
)
391 def setUp_counter(self
):
392 self
.count
= Signal(3, reset
=4)
393 self
.sync
= ClockDomain()
396 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
397 self
.m
.domains
+= self
.sync
399 def test_counter_process(self
):
401 with self
.assertSimulation(self
.m
) as sim
:
403 self
.assertEqual((yield self
.count
), 4)
405 self
.assertEqual((yield self
.count
), 4)
406 yield self
.sync
.clk
.eq(1)
407 self
.assertEqual((yield self
.count
), 4)
409 self
.assertEqual((yield self
.count
), 5)
411 self
.assertEqual((yield self
.count
), 5)
412 yield self
.sync
.clk
.eq(0)
413 self
.assertEqual((yield self
.count
), 5)
415 self
.assertEqual((yield self
.count
), 5)
418 yield self
.sync
.clk
.eq(1)
420 yield self
.sync
.clk
.eq(0)
421 self
.assertEqual((yield self
.count
), 0)
422 sim
.add_process(process
)
424 def test_counter_clock_and_sync_process(self
):
426 with self
.assertSimulation(self
.m
) as sim
:
427 sim
.add_clock(1e-6, domain
="sync")
429 self
.assertEqual((yield self
.count
), 4)
430 self
.assertEqual((yield self
.sync
.clk
), 1)
432 self
.assertEqual((yield self
.count
), 5)
433 self
.assertEqual((yield self
.sync
.clk
), 1)
436 self
.assertEqual((yield self
.count
), 0)
437 sim
.add_sync_process(process
)
439 def test_reset(self
):
441 sim
= Simulator(self
.m
)
446 self
.assertEqual((yield self
.count
), 4)
448 self
.assertEqual((yield self
.count
), 5)
450 self
.assertEqual((yield self
.count
), 6)
453 sim
.add_sync_process(process
)
457 self
.assertEqual(times
, 2)
465 self
.sync
= ClockDomain(reset_less
=True)
468 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
469 with self
.m
.Switch(self
.s
):
471 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
473 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
475 self
.m
.d
.sync
+= self
.o
.eq(0)
476 self
.m
.domains
+= self
.sync
480 with self
.assertSimulation(self
.m
) as sim
:
486 self
.assertEqual((yield self
.x
), 4)
488 self
.assertEqual((yield self
.o
), 6)
492 self
.assertEqual((yield self
.o
), 4)
496 self
.assertEqual((yield self
.o
), 0)
497 sim
.add_sync_process(process
)
499 def setUp_multiclock(self
):
500 self
.sys
= ClockDomain()
501 self
.pix
= ClockDomain()
504 self
.m
.domains
+= self
.sys
, self
.pix
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")
521 sim
.add_sync_process(sys_process
, domain
="sys")
522 sim
.add_sync_process(pix_process
, domain
="pix")
524 def setUp_lhs_rhs(self
):
529 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
531 def test_complex_lhs_rhs(self
):
533 with self
.assertSimulation(self
.m
) as sim
:
535 yield self
.i
.eq(0b10101010)
536 yield self
.i
[:4].eq(-1)
538 self
.assertEqual((yield self
.i
[:4]), 0b1111)
539 self
.assertEqual((yield self
.i
), 0b10101111)
540 sim
.add_process(process
)
542 def test_run_until(self
):
546 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
552 sim
.add_process(process
)
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$"):
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$"):
566 sim
.add_process(process())
568 def test_add_clock_wrong_twice(self
):
572 with self
.assertSimulation(m
) as sim
:
574 with self
.assertRaisesRegex(ValueError,
575 r
"^Domain 'sync' already has a clock driving it$"):
578 def test_add_clock_wrong_missing(self
):
580 with self
.assertSimulation(m
) as sim
:
581 with self
.assertRaisesRegex(ValueError,
582 r
"^Domain 'sync' is not present in simulation$"):
585 def test_add_clock_if_exists(self
):
587 with self
.assertSimulation(m
) as sim
:
588 sim
.add_clock(1, if_exists
=True)
590 def test_command_wrong(self
):
592 with self
.assertSimulation(Module()) as sim
:
595 with self
.assertRaisesRegex(TypeError,
596 r
"Received unsupported command 1 from process .+?"):
600 sim
.add_process(process
)
601 self
.assertTrue(survived
)
603 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
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
)
612 def test_memory_init(self
):
614 with self
.assertSimulation(self
.m
) as sim
:
616 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
617 yield self
.rdport
.addr
.eq(1)
620 self
.assertEqual((yield self
.rdport
.data
), 0x55)
621 yield self
.rdport
.addr
.eq(2)
624 self
.assertEqual((yield self
.rdport
.data
), 0x00)
626 sim
.add_sync_process(process
)
628 def test_memory_write(self
):
630 with self
.assertSimulation(self
.m
) as sim
:
632 yield self
.wrport
.addr
.eq(4)
633 yield self
.wrport
.data
.eq(0x33)
634 yield self
.wrport
.en
.eq(1)
636 yield self
.wrport
.en
.eq(0)
637 yield self
.rdport
.addr
.eq(4)
639 self
.assertEqual((yield self
.rdport
.data
), 0x33)
641 sim
.add_sync_process(process
)
643 def test_memory_write_granularity(self
):
644 self
.setUp_memory(wr_granularity
=4)
645 with self
.assertSimulation(self
.m
) as sim
:
647 yield self
.wrport
.data
.eq(0x50)
648 yield self
.wrport
.en
.eq(0b00)
650 yield self
.wrport
.en
.eq(0)
652 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
653 yield self
.wrport
.en
.eq(0b10)
655 yield self
.wrport
.en
.eq(0)
657 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
658 yield self
.wrport
.data
.eq(0x33)
659 yield self
.wrport
.en
.eq(0b01)
661 yield self
.wrport
.en
.eq(0)
663 self
.assertEqual((yield self
.rdport
.data
), 0x53)
665 sim
.add_sync_process(process
)
667 def test_memory_read_before_write(self
):
668 self
.setUp_memory(rd_transparent
=False)
669 with self
.assertSimulation(self
.m
) as sim
:
671 yield self
.wrport
.data
.eq(0x33)
672 yield self
.wrport
.en
.eq(1)
674 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
676 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
678 self
.assertEqual((yield self
.rdport
.data
), 0x33)
680 sim
.add_sync_process(process
)
682 def test_memory_write_through(self
):
683 self
.setUp_memory(rd_transparent
=True)
684 with self
.assertSimulation(self
.m
) as sim
:
686 yield self
.wrport
.data
.eq(0x33)
687 yield self
.wrport
.en
.eq(1)
689 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
691 self
.assertEqual((yield self
.rdport
.data
), 0x33)
693 yield self
.rdport
.addr
.eq(1)
695 self
.assertEqual((yield self
.rdport
.data
), 0x33)
697 sim
.add_sync_process(process
)
699 def test_memory_async_read_write(self
):
700 self
.setUp_memory(rd_synchronous
=False)
701 with self
.assertSimulation(self
.m
) as sim
:
703 yield self
.rdport
.addr
.eq(0)
705 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
706 yield self
.rdport
.addr
.eq(1)
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)
714 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
716 self
.assertEqual((yield self
.rdport
.data
), 0x33)
718 sim
.add_process(process
)
720 def test_memory_read_only(self
):
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
:
726 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
727 yield self
.rdport
.addr
.eq(1)
730 self
.assertEqual((yield self
.rdport
.data
), 0x55)
732 sim
.add_sync_process(process
)
734 def test_sample_helpers(self
):
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
:
757 self
.assertEqual((yield p0
), 0b01)
758 self
.assertEqual((yield p1
), 0b10)
759 self
.assertEqual((yield p2
), 0b10)
760 self
.assertEqual((yield p3
), 0b00)
762 self
.assertEqual((yield s0
), 0b0)
763 self
.assertEqual((yield s1
), 0b1)
764 self
.assertEqual((yield s2
), 0b0)
765 self
.assertEqual((yield s3
), 0b1)
767 self
.assertEqual((yield r0
), 0b01)
768 self
.assertEqual((yield r1
), 0b00)
769 self
.assertEqual((yield r2
), 0b10)
770 self
.assertEqual((yield r3
), 0b00)
772 self
.assertEqual((yield f0
), 0b10)
773 self
.assertEqual((yield f1
), 0b00)
774 self
.assertEqual((yield f2
), 0b00)
775 self
.assertEqual((yield f3
), 0b00)
777 sim
.add_sync_process(process_gen
)
778 sim
.add_sync_process(process_check
)
780 def test_vcd_wrong_nonzero_time(self
):
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")):
793 class SimulatorRegressionTestCase(FHDLTestCase
):
794 def test_bug_325(self
):
796 dut
.d
.comb
+= Signal().eq(Cat())
799 def test_bug_325_bis(self
):
801 dut
.d
.comb
+= Signal().eq(Repl(Const(1), 0))
804 def test_bug_473(self
):
805 sim
= Simulator(Module())
807 self
.assertEqual((yield -(Const(0b11, 2).as_signed())), 1)
808 sim
.add_process(process
)