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))
305 class SimulatorIntegrationTestCase(FHDLTestCase
):
307 def assertSimulation(self
, module
, deadline
=None):
308 sim
= Simulator(module
)
310 with sim
.write_vcd("test.vcd", "test.gtkw"):
314 sim
.run_until(deadline
)
316 def setUp_counter(self
):
317 self
.count
= Signal(3, reset
=4)
318 self
.sync
= ClockDomain()
321 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
322 self
.m
.domains
+= self
.sync
324 def test_counter_process(self
):
326 with self
.assertSimulation(self
.m
) as sim
:
328 self
.assertEqual((yield self
.count
), 4)
330 self
.assertEqual((yield self
.count
), 4)
331 yield self
.sync
.clk
.eq(1)
332 self
.assertEqual((yield self
.count
), 4)
334 self
.assertEqual((yield self
.count
), 5)
336 self
.assertEqual((yield self
.count
), 5)
337 yield self
.sync
.clk
.eq(0)
338 self
.assertEqual((yield self
.count
), 5)
340 self
.assertEqual((yield self
.count
), 5)
343 yield self
.sync
.clk
.eq(1)
345 yield self
.sync
.clk
.eq(0)
346 self
.assertEqual((yield self
.count
), 0)
347 sim
.add_process(process
)
349 def test_counter_clock_and_sync_process(self
):
351 with self
.assertSimulation(self
.m
) as sim
:
352 sim
.add_clock(1e-6, domain
="sync")
354 self
.assertEqual((yield self
.count
), 4)
355 self
.assertEqual((yield self
.sync
.clk
), 1)
357 self
.assertEqual((yield self
.count
), 5)
358 self
.assertEqual((yield self
.sync
.clk
), 1)
361 self
.assertEqual((yield self
.count
), 0)
362 sim
.add_sync_process(process
)
364 def test_reset(self
):
366 sim
= Simulator(self
.m
)
371 self
.assertEqual((yield self
.count
), 4)
373 self
.assertEqual((yield self
.count
), 5)
375 self
.assertEqual((yield self
.count
), 6)
378 sim
.add_sync_process(process
)
382 self
.assertEqual(times
, 2)
390 self
.sync
= ClockDomain(reset_less
=True)
393 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
394 with self
.m
.Switch(self
.s
):
396 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
398 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
400 self
.m
.d
.sync
+= self
.o
.eq(0)
401 self
.m
.domains
+= self
.sync
405 with self
.assertSimulation(self
.m
) as sim
:
411 self
.assertEqual((yield self
.x
), 4)
413 self
.assertEqual((yield self
.o
), 6)
417 self
.assertEqual((yield self
.o
), 4)
421 self
.assertEqual((yield self
.o
), 0)
422 sim
.add_sync_process(process
)
424 def setUp_multiclock(self
):
425 self
.sys
= ClockDomain()
426 self
.pix
= ClockDomain()
429 self
.m
.domains
+= self
.sys
, self
.pix
431 def test_multiclock(self
):
432 self
.setUp_multiclock()
433 with self
.assertSimulation(self
.m
) as sim
:
434 sim
.add_clock(1e-6, domain
="sys")
435 sim
.add_clock(0.3e-6, domain
="pix")
446 sim
.add_sync_process(sys_process
, domain
="sys")
447 sim
.add_sync_process(pix_process
, domain
="pix")
449 def setUp_lhs_rhs(self
):
454 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
456 def test_complex_lhs_rhs(self
):
458 with self
.assertSimulation(self
.m
) as sim
:
460 yield self
.i
.eq(0b10101010)
461 yield self
.i
[:4].eq(-1)
463 self
.assertEqual((yield self
.i
[:4]), 0b1111)
464 self
.assertEqual((yield self
.i
), 0b10101111)
465 sim
.add_process(process
)
467 def test_run_until(self
):
471 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
477 sim
.add_process(process
)
479 def test_add_process_wrong(self
):
480 with self
.assertSimulation(Module()) as sim
:
481 with self
.assertRaises(TypeError,
482 msg
="Cannot add a process 1 because it is not a generator function"):
485 def test_add_process_wrong_generator(self
):
486 with self
.assertSimulation(Module()) as sim
:
487 with self
.assertWarns(DeprecationWarning,
488 msg
="instead of generators, use generator functions as processes; "
489 "this allows the simulator to be repeatedly reset"):
492 sim
.add_process(process())
494 def test_add_clock_wrong_twice(self
):
498 with self
.assertSimulation(m
) as sim
:
500 with self
.assertRaises(ValueError,
501 msg
="Domain 'sync' already has a clock driving it"):
504 def test_add_clock_wrong_missing(self
):
506 with self
.assertSimulation(m
) as sim
:
507 with self
.assertRaises(ValueError,
508 msg
="Domain 'sync' is not present in simulation"):
511 def test_add_clock_if_exists(self
):
513 with self
.assertSimulation(m
) as sim
:
514 sim
.add_clock(1, if_exists
=True)
516 def test_command_wrong(self
):
518 with self
.assertSimulation(Module()) as sim
:
521 with self
.assertRaisesRegex(TypeError,
522 regex
=r
"Received unsupported command 1 from process .+?"):
526 sim
.add_process(process
)
527 self
.assertTrue(survived
)
529 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
531 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
532 self
.m
.submodules
.rdport
= self
.rdport
= \
533 self
.memory
.read_port(domain
="sync" if rd_synchronous
else "comb",
534 transparent
=rd_transparent
)
535 self
.m
.submodules
.wrport
= self
.wrport
= \
536 self
.memory
.write_port(granularity
=wr_granularity
)
538 def test_memory_init(self
):
540 with self
.assertSimulation(self
.m
) as sim
:
542 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
543 yield self
.rdport
.addr
.eq(1)
546 self
.assertEqual((yield self
.rdport
.data
), 0x55)
547 yield self
.rdport
.addr
.eq(2)
550 self
.assertEqual((yield self
.rdport
.data
), 0x00)
552 sim
.add_sync_process(process
)
554 def test_memory_write(self
):
556 with self
.assertSimulation(self
.m
) as sim
:
558 yield self
.wrport
.addr
.eq(4)
559 yield self
.wrport
.data
.eq(0x33)
560 yield self
.wrport
.en
.eq(1)
562 yield self
.wrport
.en
.eq(0)
563 yield self
.rdport
.addr
.eq(4)
565 self
.assertEqual((yield self
.rdport
.data
), 0x33)
567 sim
.add_sync_process(process
)
569 def test_memory_write_granularity(self
):
570 self
.setUp_memory(wr_granularity
=4)
571 with self
.assertSimulation(self
.m
) as sim
:
573 yield self
.wrport
.data
.eq(0x50)
574 yield self
.wrport
.en
.eq(0b00)
576 yield self
.wrport
.en
.eq(0)
578 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
579 yield self
.wrport
.en
.eq(0b10)
581 yield self
.wrport
.en
.eq(0)
583 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
584 yield self
.wrport
.data
.eq(0x33)
585 yield self
.wrport
.en
.eq(0b01)
587 yield self
.wrport
.en
.eq(0)
589 self
.assertEqual((yield self
.rdport
.data
), 0x53)
591 sim
.add_sync_process(process
)
593 def test_memory_read_before_write(self
):
594 self
.setUp_memory(rd_transparent
=False)
595 with self
.assertSimulation(self
.m
) as sim
:
597 yield self
.wrport
.data
.eq(0x33)
598 yield self
.wrport
.en
.eq(1)
600 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
602 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
604 self
.assertEqual((yield self
.rdport
.data
), 0x33)
606 sim
.add_sync_process(process
)
608 def test_memory_write_through(self
):
609 self
.setUp_memory(rd_transparent
=True)
610 with self
.assertSimulation(self
.m
) as sim
:
612 yield self
.wrport
.data
.eq(0x33)
613 yield self
.wrport
.en
.eq(1)
615 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
617 self
.assertEqual((yield self
.rdport
.data
), 0x33)
619 yield self
.rdport
.addr
.eq(1)
621 self
.assertEqual((yield self
.rdport
.data
), 0x33)
623 sim
.add_sync_process(process
)
625 def test_memory_async_read_write(self
):
626 self
.setUp_memory(rd_synchronous
=False)
627 with self
.assertSimulation(self
.m
) as sim
:
629 yield self
.rdport
.addr
.eq(0)
631 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
632 yield self
.rdport
.addr
.eq(1)
634 self
.assertEqual((yield self
.rdport
.data
), 0x55)
635 yield self
.rdport
.addr
.eq(0)
636 yield self
.wrport
.addr
.eq(0)
637 yield self
.wrport
.data
.eq(0x33)
638 yield self
.wrport
.en
.eq(1)
640 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
642 self
.assertEqual((yield self
.rdport
.data
), 0x33)
644 sim
.add_process(process
)
646 def test_memory_read_only(self
):
648 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
649 self
.m
.submodules
.rdport
= self
.rdport
= self
.memory
.read_port()
650 with self
.assertSimulation(self
.m
) as sim
:
652 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
653 yield self
.rdport
.addr
.eq(1)
656 self
.assertEqual((yield self
.rdport
.data
), 0x55)
658 sim
.add_sync_process(process
)
660 def test_sample_helpers(self
):
667 p0
, r0
, f0
, s0
= mk(Past(s
, 0)), mk(Rose(s
)), mk(Fell(s
)), mk(Stable(s
))
668 p1
, r1
, f1
, s1
= mk(Past(s
)), mk(Rose(s
, 1)), mk(Fell(s
, 1)), mk(Stable(s
, 1))
669 p2
, r2
, f2
, s2
= mk(Past(s
, 2)), mk(Rose(s
, 2)), mk(Fell(s
, 2)), mk(Stable(s
, 2))
670 p3
, r3
, f3
, s3
= mk(Past(s
, 3)), mk(Rose(s
, 3)), mk(Fell(s
, 3)), mk(Stable(s
, 3))
671 with self
.assertSimulation(m
) as sim
:
683 self
.assertEqual((yield p0
), 0b01)
684 self
.assertEqual((yield p1
), 0b10)
685 self
.assertEqual((yield p2
), 0b10)
686 self
.assertEqual((yield p3
), 0b00)
688 self
.assertEqual((yield s0
), 0b0)
689 self
.assertEqual((yield s1
), 0b1)
690 self
.assertEqual((yield s2
), 0b0)
691 self
.assertEqual((yield s3
), 0b1)
693 self
.assertEqual((yield r0
), 0b01)
694 self
.assertEqual((yield r1
), 0b00)
695 self
.assertEqual((yield r2
), 0b10)
696 self
.assertEqual((yield r3
), 0b00)
698 self
.assertEqual((yield f0
), 0b10)
699 self
.assertEqual((yield f1
), 0b00)
700 self
.assertEqual((yield f2
), 0b00)
701 self
.assertEqual((yield f3
), 0b00)
703 sim
.add_sync_process(process_gen
)
704 sim
.add_sync_process(process_check
)
706 def test_vcd_wrong_nonzero_time(self
):
713 with self
.assertRaisesRegex(ValueError,
714 regex
=r
"^Cannot start writing waveforms after advancing simulation time$"):
715 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
718 def test_vcd_wrong_twice(self
):
724 with self
.assertRaisesRegex(ValueError,
725 regex
=r
"^Already writing waveforms to .+$"):
726 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
727 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
731 class SimulatorRegressionTestCase(FHDLTestCase
):
732 def test_bug_325(self
):
734 dut
.d
.comb
+= Signal().eq(Cat())
737 def test_bug_325_bis(self
):
739 dut
.d
.comb
+= Signal().eq(Repl(Const(1), 0))