d2d255f5e94853f1d5ba06154267746b60da2d3c
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))
190 stmt
= lambda y
, a
: y
.eq(abs(a
))
191 self
.assertStatement(stmt
, [C(3, unsigned(8))], C(3, unsigned(8)))
192 self
.assertStatement(stmt
, [C(-3, unsigned(8))], C(-3, unsigned(8)))
193 self
.assertStatement(stmt
, [C(3, signed(8))], C(3, signed(8)))
194 self
.assertStatement(stmt
, [C(-3, signed(8))], C(3, signed(8)))
196 def test_slice(self
):
197 stmt1
= lambda y
, a
: y
.eq(a
[2])
198 self
.assertStatement(stmt1
, [C(0b10110100, 8)], C(0b1, 1))
199 stmt2
= lambda y
, a
: y
.eq(a
[2:4])
200 self
.assertStatement(stmt2
, [C(0b10110100, 8)], C(0b01, 2))
202 def test_slice_lhs(self
):
203 stmt1
= lambda y
, a
: y
[2].eq(a
)
204 self
.assertStatement(stmt1
, [C(0b0, 1)], C(0b11111011, 8), reset
=0b11111111)
205 stmt2
= lambda y
, a
: y
[2:4].eq(a
)
206 self
.assertStatement(stmt2
, [C(0b01, 2)], C(0b11110111, 8), reset
=0b11111011)
208 def test_bit_select(self
):
209 stmt
= lambda y
, a
, b
: y
.eq(a
.bit_select(b
, 3))
210 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
211 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b101, 3))
212 self
.assertStatement(stmt
, [C(0b10110100, 8), C(3)], C(0b110, 3))
214 def test_bit_select_lhs(self
):
215 stmt
= lambda y
, a
, b
: y
.bit_select(a
, 3).eq(b
)
216 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
217 self
.assertStatement(stmt
, [C(2), C(0b101, 3)], C(0b11110111, 8), reset
=0b11111111)
218 self
.assertStatement(stmt
, [C(3), C(0b110, 3)], C(0b11110111, 8), reset
=0b11111111)
220 def test_word_select(self
):
221 stmt
= lambda y
, a
, b
: y
.eq(a
.word_select(b
, 3))
222 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
223 self
.assertStatement(stmt
, [C(0b10110100, 8), C(1)], C(0b110, 3))
224 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b010, 3))
226 def test_word_select_lhs(self
):
227 stmt
= lambda y
, a
, b
: y
.word_select(a
, 3).eq(b
)
228 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
229 self
.assertStatement(stmt
, [C(1), C(0b101, 3)], C(0b11101111, 8), reset
=0b11111111)
230 self
.assertStatement(stmt
, [C(2), C(0b110, 3)], C(0b10111111, 8), reset
=0b11111111)
233 stmt
= lambda y
, *xs
: y
.eq(Cat(*xs
))
234 self
.assertStatement(stmt
, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
236 def test_cat_lhs(self
):
240 stmt
= lambda y
, a
: [Cat(l
, m
, n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
241 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
243 def test_nested_cat_lhs(self
):
247 stmt
= lambda y
, a
: [Cat(Cat(l
, Cat(m
)), n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
248 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
250 def test_record(self
):
255 stmt
= lambda y
, a
: [rec
.eq(a
), y
.eq(rec
)]
256 self
.assertStatement(stmt
, [C(0b101, 3)], C(0b101, 3))
259 stmt
= lambda y
, a
: y
.eq(Repl(a
, 3))
260 self
.assertStatement(stmt
, [C(0b10, 2)], C(0b101010, 6))
262 def test_array(self
):
263 array
= Array([1, 4, 10])
264 stmt
= lambda y
, a
: y
.eq(array
[a
])
265 self
.assertStatement(stmt
, [C(0)], C(1))
266 self
.assertStatement(stmt
, [C(1)], C(4))
267 self
.assertStatement(stmt
, [C(2)], C(10))
269 def test_array_oob(self
):
270 array
= Array([1, 4, 10])
271 stmt
= lambda y
, a
: y
.eq(array
[a
])
272 self
.assertStatement(stmt
, [C(3)], C(10))
273 self
.assertStatement(stmt
, [C(4)], C(10))
275 def test_array_lhs(self
):
276 l
= Signal(3, reset
=1)
277 m
= Signal(3, reset
=4)
278 n
= Signal(3, reset
=7)
279 array
= Array([l
, m
, n
])
280 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
281 self
.assertStatement(stmt
, [C(0), C(0b000)], C(0b111100000))
282 self
.assertStatement(stmt
, [C(1), C(0b010)], C(0b111010001))
283 self
.assertStatement(stmt
, [C(2), C(0b100)], C(0b100100001))
285 def test_array_lhs_oob(self
):
289 array
= Array([l
, m
, n
])
290 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
291 self
.assertStatement(stmt
, [C(3), C(0b001)], C(0b001000000))
292 self
.assertStatement(stmt
, [C(4), C(0b010)], C(0b010000000))
294 def test_array_index(self
):
295 array
= Array(Array(x
* y
for y
in range(10)) for x
in range(10))
296 stmt
= lambda y
, a
, b
: y
.eq(array
[a
][b
])
299 self
.assertStatement(stmt
, [C(x
), C(y
)], C(x
* y
))
301 def test_array_attr(self
):
302 from collections
import namedtuple
303 pair
= namedtuple("pair", ("p", "n"))
305 array
= Array(pair(x
, -x
) for x
in range(10))
306 stmt
= lambda y
, a
: y
.eq(array
[a
].p
+ array
[a
].n
)
308 self
.assertStatement(stmt
, [C(i
)], C(0))
310 def test_shift_left(self
):
311 stmt1
= lambda y
, a
: y
.eq(a
.shift_left(1))
312 self
.assertStatement(stmt1
, [C(0b10100010, 8)], C( 0b101000100, 9))
313 stmt2
= lambda y
, a
: y
.eq(a
.shift_left(4))
314 self
.assertStatement(stmt2
, [C(0b10100010, 8)], C(0b101000100000, 12))
316 def test_shift_right(self
):
317 stmt1
= lambda y
, a
: y
.eq(a
.shift_right(1))
318 self
.assertStatement(stmt1
, [C(0b10100010, 8)], C(0b1010001, 7))
319 stmt2
= lambda y
, a
: y
.eq(a
.shift_right(4))
320 self
.assertStatement(stmt2
, [C(0b10100010, 8)], C( 0b1010, 4))
322 def test_rotate_left(self
):
323 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(1))
324 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
325 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0010001))
326 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(5))
327 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
328 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
329 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(7))
330 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
331 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
332 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(9))
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(-1))
336 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
337 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0100100))
338 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-5))
339 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
340 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
341 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-7))
342 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
343 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
344 stmt
= lambda y
, a
: y
.eq(a
.rotate_left(-9))
345 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
346 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
348 def test_rotate_right(self
):
349 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(1))
350 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
351 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0100100))
352 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(5))
353 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
354 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
355 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(7))
356 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
357 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
358 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(9))
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(-1))
362 self
.assertStatement(stmt
, [C(0b1)], C(0b1))
363 self
.assertStatement(stmt
, [C(0b1001000)], C(0b0010001))
364 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-5))
365 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0010000))
366 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0110000))
367 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-7))
368 self
.assertStatement(stmt
, [C(0b1000000)], C(0b1000000))
369 self
.assertStatement(stmt
, [C(0b1000001)], C(0b1000001))
370 stmt
= lambda y
, a
: y
.eq(a
.rotate_right(-9))
371 self
.assertStatement(stmt
, [C(0b1000000)], C(0b0000010))
372 self
.assertStatement(stmt
, [C(0b1000001)], C(0b0000110))
375 class SimulatorIntegrationTestCase(FHDLTestCase
):
377 def assertSimulation(self
, module
, deadline
=None):
378 sim
= Simulator(module
)
380 with sim
.write_vcd("test.vcd", "test.gtkw"):
384 sim
.run_until(deadline
)
386 def setUp_counter(self
):
387 self
.count
= Signal(3, reset
=4)
388 self
.sync
= ClockDomain()
391 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
392 self
.m
.domains
+= self
.sync
394 def test_counter_process(self
):
396 with self
.assertSimulation(self
.m
) as sim
:
398 self
.assertEqual((yield self
.count
), 4)
400 self
.assertEqual((yield self
.count
), 4)
401 yield self
.sync
.clk
.eq(1)
402 self
.assertEqual((yield self
.count
), 4)
404 self
.assertEqual((yield self
.count
), 5)
406 self
.assertEqual((yield self
.count
), 5)
407 yield self
.sync
.clk
.eq(0)
408 self
.assertEqual((yield self
.count
), 5)
410 self
.assertEqual((yield self
.count
), 5)
413 yield self
.sync
.clk
.eq(1)
415 yield self
.sync
.clk
.eq(0)
416 self
.assertEqual((yield self
.count
), 0)
417 sim
.add_process(process
)
419 def test_counter_clock_and_sync_process(self
):
421 with self
.assertSimulation(self
.m
) as sim
:
422 sim
.add_clock(1e-6, domain
="sync")
424 self
.assertEqual((yield self
.count
), 4)
425 self
.assertEqual((yield self
.sync
.clk
), 1)
427 self
.assertEqual((yield self
.count
), 5)
428 self
.assertEqual((yield self
.sync
.clk
), 1)
431 self
.assertEqual((yield self
.count
), 0)
432 sim
.add_sync_process(process
)
434 def test_reset(self
):
436 sim
= Simulator(self
.m
)
441 self
.assertEqual((yield self
.count
), 4)
443 self
.assertEqual((yield self
.count
), 5)
445 self
.assertEqual((yield self
.count
), 6)
448 sim
.add_sync_process(process
)
452 self
.assertEqual(times
, 2)
460 self
.sync
= ClockDomain(reset_less
=True)
463 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
464 with self
.m
.Switch(self
.s
):
466 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
468 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
470 self
.m
.d
.sync
+= self
.o
.eq(0)
471 self
.m
.domains
+= self
.sync
475 with self
.assertSimulation(self
.m
) as sim
:
481 self
.assertEqual((yield self
.x
), 4)
483 self
.assertEqual((yield self
.o
), 6)
487 self
.assertEqual((yield self
.o
), 4)
491 self
.assertEqual((yield self
.o
), 0)
492 sim
.add_sync_process(process
)
494 def setUp_multiclock(self
):
495 self
.sys
= ClockDomain()
496 self
.pix
= ClockDomain()
499 self
.m
.domains
+= self
.sys
, self
.pix
501 def test_multiclock(self
):
502 self
.setUp_multiclock()
503 with self
.assertSimulation(self
.m
) as sim
:
504 sim
.add_clock(1e-6, domain
="sys")
505 sim
.add_clock(0.3e-6, domain
="pix")
516 sim
.add_sync_process(sys_process
, domain
="sys")
517 sim
.add_sync_process(pix_process
, domain
="pix")
519 def setUp_lhs_rhs(self
):
524 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
526 def test_complex_lhs_rhs(self
):
528 with self
.assertSimulation(self
.m
) as sim
:
530 yield self
.i
.eq(0b10101010)
531 yield self
.i
[:4].eq(-1)
533 self
.assertEqual((yield self
.i
[:4]), 0b1111)
534 self
.assertEqual((yield self
.i
), 0b10101111)
535 sim
.add_process(process
)
537 def test_run_until(self
):
541 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
547 sim
.add_process(process
)
549 def test_add_process_wrong(self
):
550 with self
.assertSimulation(Module()) as sim
:
551 with self
.assertRaisesRegex(TypeError,
552 r
"^Cannot add a process 1 because it is not a generator function$"):
555 def test_add_process_wrong_generator(self
):
556 with self
.assertSimulation(Module()) as sim
:
557 with self
.assertRaisesRegex(TypeError,
558 r
"^Cannot add a process <.+?> because it is not a generator function$"):
561 sim
.add_process(process())
563 def test_add_clock_wrong_twice(self
):
567 with self
.assertSimulation(m
) as sim
:
569 with self
.assertRaisesRegex(ValueError,
570 r
"^Domain 'sync' already has a clock driving it$"):
573 def test_add_clock_wrong_missing(self
):
575 with self
.assertSimulation(m
) as sim
:
576 with self
.assertRaisesRegex(ValueError,
577 r
"^Domain 'sync' is not present in simulation$"):
580 def test_add_clock_if_exists(self
):
582 with self
.assertSimulation(m
) as sim
:
583 sim
.add_clock(1, if_exists
=True)
585 def test_command_wrong(self
):
587 with self
.assertSimulation(Module()) as sim
:
590 with self
.assertRaisesRegex(TypeError,
591 r
"Received unsupported command 1 from process .+?"):
595 sim
.add_process(process
)
596 self
.assertTrue(survived
)
598 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
600 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
601 self
.m
.submodules
.rdport
= self
.rdport
= \
602 self
.memory
.read_port(domain
="sync" if rd_synchronous
else "comb",
603 transparent
=rd_transparent
)
604 self
.m
.submodules
.wrport
= self
.wrport
= \
605 self
.memory
.write_port(granularity
=wr_granularity
)
607 def test_memory_init(self
):
609 with self
.assertSimulation(self
.m
) as sim
:
611 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
612 yield self
.rdport
.addr
.eq(1)
615 self
.assertEqual((yield self
.rdport
.data
), 0x55)
616 yield self
.rdport
.addr
.eq(2)
619 self
.assertEqual((yield self
.rdport
.data
), 0x00)
621 sim
.add_sync_process(process
)
623 def test_memory_write(self
):
625 with self
.assertSimulation(self
.m
) as sim
:
627 yield self
.wrport
.addr
.eq(4)
628 yield self
.wrport
.data
.eq(0x33)
629 yield self
.wrport
.en
.eq(1)
631 yield self
.wrport
.en
.eq(0)
632 yield self
.rdport
.addr
.eq(4)
634 self
.assertEqual((yield self
.rdport
.data
), 0x33)
636 sim
.add_sync_process(process
)
638 def test_memory_write_granularity(self
):
639 self
.setUp_memory(wr_granularity
=4)
640 with self
.assertSimulation(self
.m
) as sim
:
642 yield self
.wrport
.data
.eq(0x50)
643 yield self
.wrport
.en
.eq(0b00)
645 yield self
.wrport
.en
.eq(0)
647 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
648 yield self
.wrport
.en
.eq(0b10)
650 yield self
.wrport
.en
.eq(0)
652 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
653 yield self
.wrport
.data
.eq(0x33)
654 yield self
.wrport
.en
.eq(0b01)
656 yield self
.wrport
.en
.eq(0)
658 self
.assertEqual((yield self
.rdport
.data
), 0x53)
660 sim
.add_sync_process(process
)
662 def test_memory_read_before_write(self
):
663 self
.setUp_memory(rd_transparent
=False)
664 with self
.assertSimulation(self
.m
) as sim
:
666 yield self
.wrport
.data
.eq(0x33)
667 yield self
.wrport
.en
.eq(1)
669 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
671 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
673 self
.assertEqual((yield self
.rdport
.data
), 0x33)
675 sim
.add_sync_process(process
)
677 def test_memory_write_through(self
):
678 self
.setUp_memory(rd_transparent
=True)
679 with self
.assertSimulation(self
.m
) as sim
:
681 yield self
.wrport
.data
.eq(0x33)
682 yield self
.wrport
.en
.eq(1)
684 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
686 self
.assertEqual((yield self
.rdport
.data
), 0x33)
688 yield self
.rdport
.addr
.eq(1)
690 self
.assertEqual((yield self
.rdport
.data
), 0x33)
692 sim
.add_sync_process(process
)
694 def test_memory_async_read_write(self
):
695 self
.setUp_memory(rd_synchronous
=False)
696 with self
.assertSimulation(self
.m
) as sim
:
698 yield self
.rdport
.addr
.eq(0)
700 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
701 yield self
.rdport
.addr
.eq(1)
703 self
.assertEqual((yield self
.rdport
.data
), 0x55)
704 yield self
.rdport
.addr
.eq(0)
705 yield self
.wrport
.addr
.eq(0)
706 yield self
.wrport
.data
.eq(0x33)
707 yield self
.wrport
.en
.eq(1)
709 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
711 self
.assertEqual((yield self
.rdport
.data
), 0x33)
713 sim
.add_process(process
)
715 def test_memory_read_only(self
):
717 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
718 self
.m
.submodules
.rdport
= self
.rdport
= self
.memory
.read_port()
719 with self
.assertSimulation(self
.m
) as sim
:
721 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
722 yield self
.rdport
.addr
.eq(1)
725 self
.assertEqual((yield self
.rdport
.data
), 0x55)
727 sim
.add_sync_process(process
)
729 def test_sample_helpers(self
):
736 p0
, r0
, f0
, s0
= mk(Past(s
, 0)), mk(Rose(s
)), mk(Fell(s
)), mk(Stable(s
))
737 p1
, r1
, f1
, s1
= mk(Past(s
)), mk(Rose(s
, 1)), mk(Fell(s
, 1)), mk(Stable(s
, 1))
738 p2
, r2
, f2
, s2
= mk(Past(s
, 2)), mk(Rose(s
, 2)), mk(Fell(s
, 2)), mk(Stable(s
, 2))
739 p3
, r3
, f3
, s3
= mk(Past(s
, 3)), mk(Rose(s
, 3)), mk(Fell(s
, 3)), mk(Stable(s
, 3))
740 with self
.assertSimulation(m
) as sim
:
752 self
.assertEqual((yield p0
), 0b01)
753 self
.assertEqual((yield p1
), 0b10)
754 self
.assertEqual((yield p2
), 0b10)
755 self
.assertEqual((yield p3
), 0b00)
757 self
.assertEqual((yield s0
), 0b0)
758 self
.assertEqual((yield s1
), 0b1)
759 self
.assertEqual((yield s2
), 0b0)
760 self
.assertEqual((yield s3
), 0b1)
762 self
.assertEqual((yield r0
), 0b01)
763 self
.assertEqual((yield r1
), 0b00)
764 self
.assertEqual((yield r2
), 0b10)
765 self
.assertEqual((yield r3
), 0b00)
767 self
.assertEqual((yield f0
), 0b10)
768 self
.assertEqual((yield f1
), 0b00)
769 self
.assertEqual((yield f2
), 0b00)
770 self
.assertEqual((yield f3
), 0b00)
772 sim
.add_sync_process(process_gen
)
773 sim
.add_sync_process(process_check
)
775 def test_vcd_wrong_nonzero_time(self
):
782 with self
.assertRaisesRegex(ValueError,
783 r
"^Cannot start writing waveforms after advancing simulation time$"):
784 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
788 class SimulatorRegressionTestCase(FHDLTestCase
):
789 def test_bug_325(self
):
791 dut
.d
.comb
+= Signal().eq(Cat())
794 def test_bug_325_bis(self
):
796 dut
.d
.comb
+= Signal().eq(Repl(Const(1), 0))
799 def test_bug_473(self
):
800 sim
= Simulator(Module())
802 self
.assertEqual((yield -(Const(0b11, 2).as_signed())), 1)
803 sim
.add_process(process
)