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
.back
.pysim
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))
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))
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))
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))
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))
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))
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))
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))
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))
122 stmt
= lambda y
, a
, b
: y
.eq(a
& b
)
123 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
126 stmt
= lambda y
, a
, b
: y
.eq(a | b
)
127 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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)))
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))
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)
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))
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)
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))
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)
228 stmt
= lambda y
, *xs
: y
.eq(Cat(*xs
))
229 self
.assertStatement(stmt
, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
231 def test_cat_lhs(self
):
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))
238 def test_nested_cat_lhs(self
):
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))
245 def test_record(self
):
250 stmt
= lambda y
, a
: [rec
.eq(a
), y
.eq(rec
)]
251 self
.assertStatement(stmt
, [C(0b101, 3)], C(0b101, 3))
254 stmt
= lambda y
, a
: y
.eq(Repl(a
, 3))
255 self
.assertStatement(stmt
, [C(0b10, 2)], C(0b101010, 6))
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))
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))
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))
280 def test_array_lhs_oob(self
):
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))
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
])
294 self
.assertStatement(stmt
, [C(x
), C(y
)], C(x
* y
))
296 def test_array_attr(self
):
297 from collections
import namedtuple
298 pair
= namedtuple("pair", ("p", "n"))
300 array
= Array(pair(x
, -x
) for x
in range(10))
301 stmt
= lambda y
, a
: y
.eq(array
[a
].p
+ array
[a
].n
)
303 self
.assertStatement(stmt
, [C(i
)], C(0))
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))
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))
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))
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))
370 class SimulatorIntegrationTestCase(FHDLTestCase
):
372 def assertSimulation(self
, module
, deadline
=None):
373 sim
= Simulator(module
)
375 with sim
.write_vcd("test.vcd", "test.gtkw"):
379 sim
.run_until(deadline
)
381 def setUp_counter(self
):
382 self
.count
= Signal(3, reset
=4)
383 self
.sync
= ClockDomain()
386 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
387 self
.m
.domains
+= self
.sync
389 def test_counter_process(self
):
391 with self
.assertSimulation(self
.m
) as sim
:
393 self
.assertEqual((yield self
.count
), 4)
395 self
.assertEqual((yield self
.count
), 4)
396 yield self
.sync
.clk
.eq(1)
397 self
.assertEqual((yield self
.count
), 4)
399 self
.assertEqual((yield self
.count
), 5)
401 self
.assertEqual((yield self
.count
), 5)
402 yield self
.sync
.clk
.eq(0)
403 self
.assertEqual((yield self
.count
), 5)
405 self
.assertEqual((yield self
.count
), 5)
408 yield self
.sync
.clk
.eq(1)
410 yield self
.sync
.clk
.eq(0)
411 self
.assertEqual((yield self
.count
), 0)
412 sim
.add_process(process
)
414 def test_counter_clock_and_sync_process(self
):
416 with self
.assertSimulation(self
.m
) as sim
:
417 sim
.add_clock(1e-6, domain
="sync")
419 self
.assertEqual((yield self
.count
), 4)
420 self
.assertEqual((yield self
.sync
.clk
), 1)
422 self
.assertEqual((yield self
.count
), 5)
423 self
.assertEqual((yield self
.sync
.clk
), 1)
426 self
.assertEqual((yield self
.count
), 0)
427 sim
.add_sync_process(process
)
429 def test_reset(self
):
431 sim
= Simulator(self
.m
)
436 self
.assertEqual((yield self
.count
), 4)
438 self
.assertEqual((yield self
.count
), 5)
440 self
.assertEqual((yield self
.count
), 6)
443 sim
.add_sync_process(process
)
447 self
.assertEqual(times
, 2)
455 self
.sync
= ClockDomain(reset_less
=True)
458 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
459 with self
.m
.Switch(self
.s
):
461 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
463 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
465 self
.m
.d
.sync
+= self
.o
.eq(0)
466 self
.m
.domains
+= self
.sync
470 with self
.assertSimulation(self
.m
) as sim
:
476 self
.assertEqual((yield self
.x
), 4)
478 self
.assertEqual((yield self
.o
), 6)
482 self
.assertEqual((yield self
.o
), 4)
486 self
.assertEqual((yield self
.o
), 0)
487 sim
.add_sync_process(process
)
489 def setUp_multiclock(self
):
490 self
.sys
= ClockDomain()
491 self
.pix
= ClockDomain()
494 self
.m
.domains
+= self
.sys
, self
.pix
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")
511 sim
.add_sync_process(sys_process
, domain
="sys")
512 sim
.add_sync_process(pix_process
, domain
="pix")
514 def setUp_lhs_rhs(self
):
519 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
521 def test_complex_lhs_rhs(self
):
523 with self
.assertSimulation(self
.m
) as sim
:
525 yield self
.i
.eq(0b10101010)
526 yield self
.i
[:4].eq(-1)
528 self
.assertEqual((yield self
.i
[:4]), 0b1111)
529 self
.assertEqual((yield self
.i
), 0b10101111)
530 sim
.add_process(process
)
532 def test_run_until(self
):
536 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
542 sim
.add_process(process
)
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$"):
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$"):
556 sim
.add_process(process())
558 def test_add_clock_wrong_twice(self
):
562 with self
.assertSimulation(m
) as sim
:
564 with self
.assertRaisesRegex(ValueError,
565 r
"^Domain 'sync' already has a clock driving it$"):
568 def test_add_clock_wrong_missing(self
):
570 with self
.assertSimulation(m
) as sim
:
571 with self
.assertRaisesRegex(ValueError,
572 r
"^Domain 'sync' is not present in simulation$"):
575 def test_add_clock_if_exists(self
):
577 with self
.assertSimulation(m
) as sim
:
578 sim
.add_clock(1, if_exists
=True)
580 def test_command_wrong(self
):
582 with self
.assertSimulation(Module()) as sim
:
585 with self
.assertRaisesRegex(TypeError,
586 r
"Received unsupported command 1 from process .+?"):
590 sim
.add_process(process
)
591 self
.assertTrue(survived
)
593 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
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
)
602 def test_memory_init(self
):
604 with self
.assertSimulation(self
.m
) as sim
:
606 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
607 yield self
.rdport
.addr
.eq(1)
610 self
.assertEqual((yield self
.rdport
.data
), 0x55)
611 yield self
.rdport
.addr
.eq(2)
614 self
.assertEqual((yield self
.rdport
.data
), 0x00)
616 sim
.add_sync_process(process
)
618 def test_memory_write(self
):
620 with self
.assertSimulation(self
.m
) as sim
:
622 yield self
.wrport
.addr
.eq(4)
623 yield self
.wrport
.data
.eq(0x33)
624 yield self
.wrport
.en
.eq(1)
626 yield self
.wrport
.en
.eq(0)
627 yield self
.rdport
.addr
.eq(4)
629 self
.assertEqual((yield self
.rdport
.data
), 0x33)
631 sim
.add_sync_process(process
)
633 def test_memory_write_granularity(self
):
634 self
.setUp_memory(wr_granularity
=4)
635 with self
.assertSimulation(self
.m
) as sim
:
637 yield self
.wrport
.data
.eq(0x50)
638 yield self
.wrport
.en
.eq(0b00)
640 yield self
.wrport
.en
.eq(0)
642 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
643 yield self
.wrport
.en
.eq(0b10)
645 yield self
.wrport
.en
.eq(0)
647 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
648 yield self
.wrport
.data
.eq(0x33)
649 yield self
.wrport
.en
.eq(0b01)
651 yield self
.wrport
.en
.eq(0)
653 self
.assertEqual((yield self
.rdport
.data
), 0x53)
655 sim
.add_sync_process(process
)
657 def test_memory_read_before_write(self
):
658 self
.setUp_memory(rd_transparent
=False)
659 with self
.assertSimulation(self
.m
) as sim
:
661 yield self
.wrport
.data
.eq(0x33)
662 yield self
.wrport
.en
.eq(1)
664 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
666 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
668 self
.assertEqual((yield self
.rdport
.data
), 0x33)
670 sim
.add_sync_process(process
)
672 def test_memory_write_through(self
):
673 self
.setUp_memory(rd_transparent
=True)
674 with self
.assertSimulation(self
.m
) as sim
:
676 yield self
.wrport
.data
.eq(0x33)
677 yield self
.wrport
.en
.eq(1)
679 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
681 self
.assertEqual((yield self
.rdport
.data
), 0x33)
683 yield self
.rdport
.addr
.eq(1)
685 self
.assertEqual((yield self
.rdport
.data
), 0x33)
687 sim
.add_sync_process(process
)
689 def test_memory_async_read_write(self
):
690 self
.setUp_memory(rd_synchronous
=False)
691 with self
.assertSimulation(self
.m
) as sim
:
693 yield self
.rdport
.addr
.eq(0)
695 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
696 yield self
.rdport
.addr
.eq(1)
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)
704 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
706 self
.assertEqual((yield self
.rdport
.data
), 0x33)
708 sim
.add_process(process
)
710 def test_memory_read_only(self
):
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
:
716 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
717 yield self
.rdport
.addr
.eq(1)
720 self
.assertEqual((yield self
.rdport
.data
), 0x55)
722 sim
.add_sync_process(process
)
724 def test_sample_helpers(self
):
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
:
747 self
.assertEqual((yield p0
), 0b01)
748 self
.assertEqual((yield p1
), 0b10)
749 self
.assertEqual((yield p2
), 0b10)
750 self
.assertEqual((yield p3
), 0b00)
752 self
.assertEqual((yield s0
), 0b0)
753 self
.assertEqual((yield s1
), 0b1)
754 self
.assertEqual((yield s2
), 0b0)
755 self
.assertEqual((yield s3
), 0b1)
757 self
.assertEqual((yield r0
), 0b01)
758 self
.assertEqual((yield r1
), 0b00)
759 self
.assertEqual((yield r2
), 0b10)
760 self
.assertEqual((yield r3
), 0b00)
762 self
.assertEqual((yield f0
), 0b10)
763 self
.assertEqual((yield f1
), 0b00)
764 self
.assertEqual((yield f2
), 0b00)
765 self
.assertEqual((yield f3
), 0b00)
767 sim
.add_sync_process(process_gen
)
768 sim
.add_sync_process(process_check
)
770 def test_vcd_wrong_nonzero_time(self
):
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")):
783 class SimulatorRegressionTestCase(FHDLTestCase
):
784 def test_bug_325(self
):
786 dut
.d
.comb
+= Signal().eq(Cat())
789 def test_bug_325_bis(self
):
791 dut
.d
.comb
+= Signal().eq(Repl(Const(1), 0))
794 def test_bug_473(self
):
795 sim
= Simulator(Module())
797 self
.assertEqual((yield -(Const(0b11, 2).as_signed())), 1)
798 sim
.add_process(process
)