2 from contextlib
import contextmanager
5 from .._utils
import flatten
, union
6 from ..hdl
.ast
import *
8 from ..hdl
.mem
import *
9 from ..hdl
.rec
import *
10 from ..hdl
.dsl
import *
11 from ..hdl
.ir
import *
12 from ..back
.pysim
import *
15 class SimulatorUnitTestCase(FHDLTestCase
):
16 def assertStatement(self
, stmt
, inputs
, output
, reset
=0):
17 inputs
= [Value
.cast(i
) for i
in inputs
]
18 output
= Value
.cast(output
)
20 isigs
= [Signal(i
.shape(), name
=n
) for i
, n
in zip(inputs
, "abcd")]
21 osig
= Signal(output
.shape(), name
="y", reset
=reset
)
23 stmt
= stmt(osig
, *isigs
)
25 frag
.add_statements(stmt
)
26 for signal
in flatten(s
._lhs
_signals
() for s
in Statement
.cast(stmt
)):
27 frag
.add_driver(signal
)
31 for isig
, input in zip(isigs
, inputs
):
34 self
.assertEqual((yield osig
), output
.value
)
35 sim
.add_process(process
)
36 with sim
.write_vcd("test.vcd", "test.gtkw", traces
=[*isigs
, osig
]):
39 def test_invert(self
):
40 stmt
= lambda y
, a
: y
.eq(~a
)
41 self
.assertStatement(stmt
, [C(0b0000, 4)], C(0b1111, 4))
42 self
.assertStatement(stmt
, [C(0b1010, 4)], C(0b0101, 4))
43 self
.assertStatement(stmt
, [C(0, 4)], C(-1, 4))
46 stmt
= lambda y
, a
: y
.eq(-a
)
47 self
.assertStatement(stmt
, [C(0b0000, 4)], C(0b0000, 4))
48 self
.assertStatement(stmt
, [C(0b0001, 4)], C(0b1111, 4))
49 self
.assertStatement(stmt
, [C(0b1010, 4)], C(0b0110, 4))
50 self
.assertStatement(stmt
, [C(1, 4)], C(-1, 4))
51 self
.assertStatement(stmt
, [C(5, 4)], C(-5, 4))
54 stmt
= lambda y
, a
: y
.eq(a
.bool())
55 self
.assertStatement(stmt
, [C(0, 4)], C(0))
56 self
.assertStatement(stmt
, [C(1, 4)], C(1))
57 self
.assertStatement(stmt
, [C(2, 4)], C(1))
59 def test_as_unsigned(self
):
60 stmt
= lambda y
, a
, b
: y
.eq(a
.as_unsigned() == b
)
61 self
.assertStatement(stmt
, [C(0b01, signed(2)), C(0b0001, unsigned(4))], C(1))
62 self
.assertStatement(stmt
, [C(0b11, signed(2)), C(0b0011, unsigned(4))], C(1))
64 def test_as_signed(self
):
65 stmt
= lambda y
, a
, b
: y
.eq(a
.as_signed() == b
)
66 self
.assertStatement(stmt
, [C(0b01, unsigned(2)), C(0b0001, signed(4))], C(1))
67 self
.assertStatement(stmt
, [C(0b11, unsigned(2)), C(0b1111, signed(4))], C(1))
70 stmt
= lambda y
, a
: y
.eq(a
.any())
71 self
.assertStatement(stmt
, [C(0b00, 2)], C(0))
72 self
.assertStatement(stmt
, [C(0b01, 2)], C(1))
73 self
.assertStatement(stmt
, [C(0b10, 2)], C(1))
74 self
.assertStatement(stmt
, [C(0b11, 2)], C(1))
77 stmt
= lambda y
, a
: y
.eq(a
.all())
78 self
.assertStatement(stmt
, [C(0b00, 2)], C(0))
79 self
.assertStatement(stmt
, [C(0b01, 2)], C(0))
80 self
.assertStatement(stmt
, [C(0b10, 2)], C(0))
81 self
.assertStatement(stmt
, [C(0b11, 2)], C(1))
83 def test_xor_unary(self
):
84 stmt
= lambda y
, a
: y
.eq(a
.xor())
85 self
.assertStatement(stmt
, [C(0b00, 2)], C(0))
86 self
.assertStatement(stmt
, [C(0b01, 2)], C(1))
87 self
.assertStatement(stmt
, [C(0b10, 2)], C(1))
88 self
.assertStatement(stmt
, [C(0b11, 2)], C(0))
91 stmt
= lambda y
, a
, b
: y
.eq(a
+ b
)
92 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1, 4))
93 self
.assertStatement(stmt
, [C(-5, 4), C(-5, 4)], C(-10, 5))
96 stmt
= lambda y
, a
, b
: y
.eq(a
- b
)
97 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(1, 4))
98 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(-1, 4))
99 self
.assertStatement(stmt
, [C(0, 4), C(10, 4)], C(-10, 5))
102 stmt
= lambda y
, a
, b
: y
.eq(a
* b
)
103 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(2, 8))
104 self
.assertStatement(stmt
, [C(2, 4), C(2, 4)], C(4, 8))
105 self
.assertStatement(stmt
, [C(7, 4), C(7, 4)], C(49, 8))
107 def test_floordiv(self
):
108 stmt
= lambda y
, a
, b
: y
.eq(a
// b
)
109 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(2, 8))
110 self
.assertStatement(stmt
, [C(2, 4), C(2, 4)], C(1, 8))
111 self
.assertStatement(stmt
, [C(7, 4), C(2, 4)], C(3, 8))
114 stmt
= lambda y
, a
, b
: y
.eq(a
% b
)
115 self
.assertStatement(stmt
, [C(2, 4), C(0, 4)], C(0, 8))
116 self
.assertStatement(stmt
, [C(2, 4), C(1, 4)], C(0, 8))
117 self
.assertStatement(stmt
, [C(2, 4), C(2, 4)], C(0, 8))
118 self
.assertStatement(stmt
, [C(7, 4), C(2, 4)], C(1, 8))
121 stmt
= lambda y
, a
, b
: y
.eq(a
& b
)
122 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
125 stmt
= lambda y
, a
, b
: y
.eq(a | b
)
126 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
128 def test_xor_binary(self
):
129 stmt
= lambda y
, a
, b
: y
.eq(a ^ b
)
130 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b0110, 4))
133 stmt
= lambda y
, a
, b
: y
.eq(a
<< b
)
134 self
.assertStatement(stmt
, [C(0b1001, 4), C(0)], C(0b1001, 5))
135 self
.assertStatement(stmt
, [C(0b1001, 4), C(3)], C(0b1001000, 7))
138 stmt
= lambda y
, a
, b
: y
.eq(a
>> b
)
139 self
.assertStatement(stmt
, [C(0b1001, 4), C(0)], C(0b1001, 4))
140 self
.assertStatement(stmt
, [C(0b1001, 4), C(2)], C(0b10, 4))
143 stmt
= lambda y
, a
, b
: y
.eq(a
== b
)
144 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
145 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
146 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
149 stmt
= lambda y
, a
, b
: y
.eq(a
!= b
)
150 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
151 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
152 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
155 stmt
= lambda y
, a
, b
: y
.eq(a
< b
)
156 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
157 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
158 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
161 stmt
= lambda y
, a
, b
: y
.eq(a
>= b
)
162 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
163 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
164 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
167 stmt
= lambda y
, a
, b
: y
.eq(a
> b
)
168 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
169 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
170 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
173 stmt
= lambda y
, a
, b
: y
.eq(a
<= b
)
174 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
175 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
176 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
179 stmt
= lambda y
, a
, b
, c
: y
.eq(Mux(c
, a
, b
))
180 self
.assertStatement(stmt
, [C(2, 4), C(3, 4), C(0)], C(3, 4))
181 self
.assertStatement(stmt
, [C(2, 4), C(3, 4), C(1)], C(2, 4))
184 stmt
= lambda y
, a
: y
.eq(abs(a
))
185 self
.assertStatement(stmt
, [C(3, unsigned(8))], C(3, unsigned(8)))
186 self
.assertStatement(stmt
, [C(-3, unsigned(8))], C(-3, unsigned(8)))
187 self
.assertStatement(stmt
, [C(3, signed(8))], C(3, signed(8)))
188 self
.assertStatement(stmt
, [C(-3, signed(8))], C(3, signed(8)))
190 def test_slice(self
):
191 stmt1
= lambda y
, a
: y
.eq(a
[2])
192 self
.assertStatement(stmt1
, [C(0b10110100, 8)], C(0b1, 1))
193 stmt2
= lambda y
, a
: y
.eq(a
[2:4])
194 self
.assertStatement(stmt2
, [C(0b10110100, 8)], C(0b01, 2))
196 def test_slice_lhs(self
):
197 stmt1
= lambda y
, a
: y
[2].eq(a
)
198 self
.assertStatement(stmt1
, [C(0b0, 1)], C(0b11111011, 8), reset
=0b11111111)
199 stmt2
= lambda y
, a
: y
[2:4].eq(a
)
200 self
.assertStatement(stmt2
, [C(0b01, 2)], C(0b11110111, 8), reset
=0b11111011)
202 def test_bit_select(self
):
203 stmt
= lambda y
, a
, b
: y
.eq(a
.bit_select(b
, 3))
204 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
205 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b101, 3))
206 self
.assertStatement(stmt
, [C(0b10110100, 8), C(3)], C(0b110, 3))
208 def test_bit_select_lhs(self
):
209 stmt
= lambda y
, a
, b
: y
.bit_select(a
, 3).eq(b
)
210 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
211 self
.assertStatement(stmt
, [C(2), C(0b101, 3)], C(0b11110111, 8), reset
=0b11111111)
212 self
.assertStatement(stmt
, [C(3), C(0b110, 3)], C(0b11110111, 8), reset
=0b11111111)
214 def test_word_select(self
):
215 stmt
= lambda y
, a
, b
: y
.eq(a
.word_select(b
, 3))
216 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
217 self
.assertStatement(stmt
, [C(0b10110100, 8), C(1)], C(0b110, 3))
218 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b010, 3))
220 def test_word_select_lhs(self
):
221 stmt
= lambda y
, a
, b
: y
.word_select(a
, 3).eq(b
)
222 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
223 self
.assertStatement(stmt
, [C(1), C(0b101, 3)], C(0b11101111, 8), reset
=0b11111111)
224 self
.assertStatement(stmt
, [C(2), C(0b110, 3)], C(0b10111111, 8), reset
=0b11111111)
227 stmt
= lambda y
, *xs
: y
.eq(Cat(*xs
))
228 self
.assertStatement(stmt
, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
230 def test_cat_lhs(self
):
234 stmt
= lambda y
, a
: [Cat(l
, m
, n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
235 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
237 def test_nested_cat_lhs(self
):
241 stmt
= lambda y
, a
: [Cat(Cat(l
, Cat(m
)), n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
242 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
244 def test_record(self
):
249 stmt
= lambda y
, a
: [rec
.eq(a
), y
.eq(rec
)]
250 self
.assertStatement(stmt
, [C(0b101, 3)], C(0b101, 3))
253 stmt
= lambda y
, a
: y
.eq(Repl(a
, 3))
254 self
.assertStatement(stmt
, [C(0b10, 2)], C(0b101010, 6))
256 def test_array(self
):
257 array
= Array([1, 4, 10])
258 stmt
= lambda y
, a
: y
.eq(array
[a
])
259 self
.assertStatement(stmt
, [C(0)], C(1))
260 self
.assertStatement(stmt
, [C(1)], C(4))
261 self
.assertStatement(stmt
, [C(2)], C(10))
263 def test_array_oob(self
):
264 array
= Array([1, 4, 10])
265 stmt
= lambda y
, a
: y
.eq(array
[a
])
266 self
.assertStatement(stmt
, [C(3)], C(10))
267 self
.assertStatement(stmt
, [C(4)], C(10))
269 def test_array_lhs(self
):
270 l
= Signal(3, reset
=1)
271 m
= Signal(3, reset
=4)
272 n
= Signal(3, reset
=7)
273 array
= Array([l
, m
, n
])
274 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
275 self
.assertStatement(stmt
, [C(0), C(0b000)], C(0b111100000))
276 self
.assertStatement(stmt
, [C(1), C(0b010)], C(0b111010001))
277 self
.assertStatement(stmt
, [C(2), C(0b100)], C(0b100100001))
279 def test_array_lhs_oob(self
):
283 array
= Array([l
, m
, n
])
284 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
285 self
.assertStatement(stmt
, [C(3), C(0b001)], C(0b001000000))
286 self
.assertStatement(stmt
, [C(4), C(0b010)], C(0b010000000))
288 def test_array_index(self
):
289 array
= Array(Array(x
* y
for y
in range(10)) for x
in range(10))
290 stmt
= lambda y
, a
, b
: y
.eq(array
[a
][b
])
293 self
.assertStatement(stmt
, [C(x
), C(y
)], C(x
* y
))
295 def test_array_attr(self
):
296 from collections
import namedtuple
297 pair
= namedtuple("pair", ("p", "n"))
299 array
= Array(pair(x
, -x
) for x
in range(10))
300 stmt
= lambda y
, a
: y
.eq(array
[a
].p
+ array
[a
].n
)
302 self
.assertStatement(stmt
, [C(i
)], C(0))
304 def test_shift_left(self
):
305 stmt1
= lambda y
, a
: y
.eq(a
.shift_left(1))
306 self
.assertStatement(stmt1
, [C(0b10100010, 8)], C( 0b101000100, 9))
307 stmt2
= lambda y
, a
: y
.eq(a
.shift_left(4))
308 self
.assertStatement(stmt2
, [C(0b10100010, 8)], C(0b101000100000, 12))
310 def test_shift_right(self
):
311 stmt1
= lambda y
, a
: y
.eq(a
.shift_right(1))
312 self
.assertStatement(stmt1
, [C(0b10100010, 8)], C(0b1010001, 7))
313 stmt2
= lambda y
, a
: y
.eq(a
.shift_right(4))
314 self
.assertStatement(stmt2
, [C(0b10100010, 8)], C( 0b1010, 4))
316 def test_rotate_left(self
):
317 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(1))
318 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
319 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0010001))
320 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(5))
321 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
322 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
323 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(7))
324 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
325 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
326 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(9))
327 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
328 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
329 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-1))
330 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
331 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0100100))
332 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-5))
333 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
334 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
335 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-7))
336 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
337 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
338 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-9))
339 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
340 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
342 def test_rotate_right(self
):
343 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(1))
344 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
345 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0100100))
346 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(5))
347 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
348 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
349 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(7))
350 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
351 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
352 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(9))
353 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
354 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
355 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-1))
356 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
357 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0010001))
358 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-5))
359 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
360 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
361 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-7))
362 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
363 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
364 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-9))
365 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
366 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
368 class SimulatorIntegrationTestCase(FHDLTestCase
):
370 def assertSimulation(self
, module
, deadline
=None):
371 sim
= Simulator(module
)
373 with sim
.write_vcd("test.vcd", "test.gtkw"):
377 sim
.run_until(deadline
)
379 def setUp_counter(self
):
380 self
.count
= Signal(3, reset
=4)
381 self
.sync
= ClockDomain()
384 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
385 self
.m
.domains
+= self
.sync
387 def test_counter_process(self
):
389 with self
.assertSimulation(self
.m
) as sim
:
391 self
.assertEqual((yield self
.count
), 4)
393 self
.assertEqual((yield self
.count
), 4)
394 yield self
.sync
.clk
.eq(1)
395 self
.assertEqual((yield self
.count
), 4)
397 self
.assertEqual((yield self
.count
), 5)
399 self
.assertEqual((yield self
.count
), 5)
400 yield self
.sync
.clk
.eq(0)
401 self
.assertEqual((yield self
.count
), 5)
403 self
.assertEqual((yield self
.count
), 5)
406 yield self
.sync
.clk
.eq(1)
408 yield self
.sync
.clk
.eq(0)
409 self
.assertEqual((yield self
.count
), 0)
410 sim
.add_process(process
)
412 def test_counter_clock_and_sync_process(self
):
414 with self
.assertSimulation(self
.m
) as sim
:
415 sim
.add_clock(1e-6, domain
="sync")
417 self
.assertEqual((yield self
.count
), 4)
418 self
.assertEqual((yield self
.sync
.clk
), 1)
420 self
.assertEqual((yield self
.count
), 5)
421 self
.assertEqual((yield self
.sync
.clk
), 1)
424 self
.assertEqual((yield self
.count
), 0)
425 sim
.add_sync_process(process
)
427 def test_reset(self
):
429 sim
= Simulator(self
.m
)
434 self
.assertEqual((yield self
.count
), 4)
436 self
.assertEqual((yield self
.count
), 5)
438 self
.assertEqual((yield self
.count
), 6)
441 sim
.add_sync_process(process
)
445 self
.assertEqual(times
, 2)
453 self
.sync
= ClockDomain(reset_less
=True)
456 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
457 with self
.m
.Switch(self
.s
):
459 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
461 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
463 self
.m
.d
.sync
+= self
.o
.eq(0)
464 self
.m
.domains
+= self
.sync
468 with self
.assertSimulation(self
.m
) as sim
:
474 self
.assertEqual((yield self
.x
), 4)
476 self
.assertEqual((yield self
.o
), 6)
480 self
.assertEqual((yield self
.o
), 4)
484 self
.assertEqual((yield self
.o
), 0)
485 sim
.add_sync_process(process
)
487 def setUp_multiclock(self
):
488 self
.sys
= ClockDomain()
489 self
.pix
= ClockDomain()
492 self
.m
.domains
+= self
.sys
, self
.pix
494 def test_multiclock(self
):
495 self
.setUp_multiclock()
496 with self
.assertSimulation(self
.m
) as sim
:
497 sim
.add_clock(1e-6, domain
="sys")
498 sim
.add_clock(0.3e-6, domain
="pix")
509 sim
.add_sync_process(sys_process
, domain
="sys")
510 sim
.add_sync_process(pix_process
, domain
="pix")
512 def setUp_lhs_rhs(self
):
517 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
519 def test_complex_lhs_rhs(self
):
521 with self
.assertSimulation(self
.m
) as sim
:
523 yield self
.i
.eq(0b10101010)
524 yield self
.i
[:4].eq(-1)
526 self
.assertEqual((yield self
.i
[:4]), 0b1111)
527 self
.assertEqual((yield self
.i
), 0b10101111)
528 sim
.add_process(process
)
530 def test_run_until(self
):
534 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
540 sim
.add_process(process
)
542 def test_add_process_wrong(self
):
543 with self
.assertSimulation(Module()) as sim
:
544 with self
.assertRaises(TypeError,
545 msg
="Cannot add a process 1 because it is not a generator function"):
548 def test_add_process_wrong_generator(self
):
549 with self
.assertSimulation(Module()) as sim
:
550 with self
.assertRaisesRegex(TypeError,
551 r
"^Cannot add a process <.+?> because it is not a generator function$"):
554 sim
.add_process(process())
556 def test_add_clock_wrong_twice(self
):
560 with self
.assertSimulation(m
) as sim
:
562 with self
.assertRaises(ValueError,
563 msg
="Domain 'sync' already has a clock driving it"):
566 def test_add_clock_wrong_missing(self
):
568 with self
.assertSimulation(m
) as sim
:
569 with self
.assertRaises(ValueError,
570 msg
="Domain 'sync' is not present in simulation"):
573 def test_add_clock_if_exists(self
):
575 with self
.assertSimulation(m
) as sim
:
576 sim
.add_clock(1, if_exists
=True)
578 def test_command_wrong(self
):
580 with self
.assertSimulation(Module()) as sim
:
583 with self
.assertRaisesRegex(TypeError,
584 r
"Received unsupported command 1 from process .+?"):
588 sim
.add_process(process
)
589 self
.assertTrue(survived
)
591 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
593 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
594 self
.m
.submodules
.rdport
= self
.rdport
= \
595 self
.memory
.read_port(domain
="sync" if rd_synchronous
else "comb",
596 transparent
=rd_transparent
)
597 self
.m
.submodules
.wrport
= self
.wrport
= \
598 self
.memory
.write_port(granularity
=wr_granularity
)
600 def test_memory_init(self
):
602 with self
.assertSimulation(self
.m
) as sim
:
604 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
605 yield self
.rdport
.addr
.eq(1)
608 self
.assertEqual((yield self
.rdport
.data
), 0x55)
609 yield self
.rdport
.addr
.eq(2)
612 self
.assertEqual((yield self
.rdport
.data
), 0x00)
614 sim
.add_sync_process(process
)
616 def test_memory_write(self
):
618 with self
.assertSimulation(self
.m
) as sim
:
620 yield self
.wrport
.addr
.eq(4)
621 yield self
.wrport
.data
.eq(0x33)
622 yield self
.wrport
.en
.eq(1)
624 yield self
.wrport
.en
.eq(0)
625 yield self
.rdport
.addr
.eq(4)
627 self
.assertEqual((yield self
.rdport
.data
), 0x33)
629 sim
.add_sync_process(process
)
631 def test_memory_write_granularity(self
):
632 self
.setUp_memory(wr_granularity
=4)
633 with self
.assertSimulation(self
.m
) as sim
:
635 yield self
.wrport
.data
.eq(0x50)
636 yield self
.wrport
.en
.eq(0b00)
638 yield self
.wrport
.en
.eq(0)
640 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
641 yield self
.wrport
.en
.eq(0b10)
643 yield self
.wrport
.en
.eq(0)
645 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
646 yield self
.wrport
.data
.eq(0x33)
647 yield self
.wrport
.en
.eq(0b01)
649 yield self
.wrport
.en
.eq(0)
651 self
.assertEqual((yield self
.rdport
.data
), 0x53)
653 sim
.add_sync_process(process
)
655 def test_memory_read_before_write(self
):
656 self
.setUp_memory(rd_transparent
=False)
657 with self
.assertSimulation(self
.m
) as sim
:
659 yield self
.wrport
.data
.eq(0x33)
660 yield self
.wrport
.en
.eq(1)
662 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
664 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
666 self
.assertEqual((yield self
.rdport
.data
), 0x33)
668 sim
.add_sync_process(process
)
670 def test_memory_write_through(self
):
671 self
.setUp_memory(rd_transparent
=True)
672 with self
.assertSimulation(self
.m
) as sim
:
674 yield self
.wrport
.data
.eq(0x33)
675 yield self
.wrport
.en
.eq(1)
677 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
679 self
.assertEqual((yield self
.rdport
.data
), 0x33)
681 yield self
.rdport
.addr
.eq(1)
683 self
.assertEqual((yield self
.rdport
.data
), 0x33)
685 sim
.add_sync_process(process
)
687 def test_memory_async_read_write(self
):
688 self
.setUp_memory(rd_synchronous
=False)
689 with self
.assertSimulation(self
.m
) as sim
:
691 yield self
.rdport
.addr
.eq(0)
693 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
694 yield self
.rdport
.addr
.eq(1)
696 self
.assertEqual((yield self
.rdport
.data
), 0x55)
697 yield self
.rdport
.addr
.eq(0)
698 yield self
.wrport
.addr
.eq(0)
699 yield self
.wrport
.data
.eq(0x33)
700 yield self
.wrport
.en
.eq(1)
702 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
704 self
.assertEqual((yield self
.rdport
.data
), 0x33)
706 sim
.add_process(process
)
708 def test_memory_read_only(self
):
710 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
711 self
.m
.submodules
.rdport
= self
.rdport
= self
.memory
.read_port()
712 with self
.assertSimulation(self
.m
) as sim
:
714 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
715 yield self
.rdport
.addr
.eq(1)
718 self
.assertEqual((yield self
.rdport
.data
), 0x55)
720 sim
.add_sync_process(process
)
722 def test_sample_helpers(self
):
729 p0
, r0
, f0
, s0
= mk(Past(s
, 0)), mk(Rose(s
)), mk(Fell(s
)), mk(Stable(s
))
730 p1
, r1
, f1
, s1
= mk(Past(s
)), mk(Rose(s
, 1)), mk(Fell(s
, 1)), mk(Stable(s
, 1))
731 p2
, r2
, f2
, s2
= mk(Past(s
, 2)), mk(Rose(s
, 2)), mk(Fell(s
, 2)), mk(Stable(s
, 2))
732 p3
, r3
, f3
, s3
= mk(Past(s
, 3)), mk(Rose(s
, 3)), mk(Fell(s
, 3)), mk(Stable(s
, 3))
733 with self
.assertSimulation(m
) as sim
:
745 self
.assertEqual((yield p0
), 0b01)
746 self
.assertEqual((yield p1
), 0b10)
747 self
.assertEqual((yield p2
), 0b10)
748 self
.assertEqual((yield p3
), 0b00)
750 self
.assertEqual((yield s0
), 0b0)
751 self
.assertEqual((yield s1
), 0b1)
752 self
.assertEqual((yield s2
), 0b0)
753 self
.assertEqual((yield s3
), 0b1)
755 self
.assertEqual((yield r0
), 0b01)
756 self
.assertEqual((yield r1
), 0b00)
757 self
.assertEqual((yield r2
), 0b10)
758 self
.assertEqual((yield r3
), 0b00)
760 self
.assertEqual((yield f0
), 0b10)
761 self
.assertEqual((yield f1
), 0b00)
762 self
.assertEqual((yield f2
), 0b00)
763 self
.assertEqual((yield f3
), 0b00)
765 sim
.add_sync_process(process_gen
)
766 sim
.add_sync_process(process_check
)
768 def test_vcd_wrong_nonzero_time(self
):
775 with self
.assertRaisesRegex(ValueError,
776 r
"^Cannot start writing waveforms after advancing simulation time$"):
777 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
781 class SimulatorRegressionTestCase(FHDLTestCase
):
782 def test_bug_325(self
):
784 dut
.d
.comb
+= Signal().eq(Cat())
787 def test_bug_325_bis(self
):
789 dut
.d
.comb
+= Signal().eq(Repl(Const(1), 0))