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(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
118 stmt
= lambda y
, a
, b
: y
.eq(a | b
)
119 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
121 def test_xor_binary(self
):
122 stmt
= lambda y
, a
, b
: y
.eq(a ^ b
)
123 self
.assertStatement(stmt
, [C(0b1100, 4), C(0b1010, 4)], C(0b0110, 4))
126 stmt
= lambda y
, a
, b
: y
.eq(a
<< b
)
127 self
.assertStatement(stmt
, [C(0b1001, 4), C(0)], C(0b1001, 5))
128 self
.assertStatement(stmt
, [C(0b1001, 4), C(3)], C(0b1001000, 7))
131 stmt
= lambda y
, a
, b
: y
.eq(a
>> b
)
132 self
.assertStatement(stmt
, [C(0b1001, 4), C(0)], C(0b1001, 4))
133 self
.assertStatement(stmt
, [C(0b1001, 4), C(2)], C(0b10, 4))
136 stmt
= lambda y
, a
, b
: y
.eq(a
== b
)
137 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
138 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
139 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
142 stmt
= lambda y
, a
, b
: y
.eq(a
!= b
)
143 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
144 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
145 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
148 stmt
= lambda y
, a
, b
: y
.eq(a
< b
)
149 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
150 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
151 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
154 stmt
= lambda y
, a
, b
: y
.eq(a
>= b
)
155 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
156 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
157 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
160 stmt
= lambda y
, a
, b
: y
.eq(a
> b
)
161 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(0))
162 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(0))
163 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(1))
166 stmt
= lambda y
, a
, b
: y
.eq(a
<= b
)
167 self
.assertStatement(stmt
, [C(0, 4), C(0, 4)], C(1))
168 self
.assertStatement(stmt
, [C(0, 4), C(1, 4)], C(1))
169 self
.assertStatement(stmt
, [C(1, 4), C(0, 4)], C(0))
172 stmt
= lambda y
, a
, b
, c
: y
.eq(Mux(c
, a
, b
))
173 self
.assertStatement(stmt
, [C(2, 4), C(3, 4), C(0)], C(3, 4))
174 self
.assertStatement(stmt
, [C(2, 4), C(3, 4), C(1)], C(2, 4))
176 def test_slice(self
):
177 stmt1
= lambda y
, a
: y
.eq(a
[2])
178 self
.assertStatement(stmt1
, [C(0b10110100, 8)], C(0b1, 1))
179 stmt2
= lambda y
, a
: y
.eq(a
[2:4])
180 self
.assertStatement(stmt2
, [C(0b10110100, 8)], C(0b01, 2))
182 def test_slice_lhs(self
):
183 stmt1
= lambda y
, a
: y
[2].eq(a
)
184 self
.assertStatement(stmt1
, [C(0b0, 1)], C(0b11111011, 8), reset
=0b11111111)
185 stmt2
= lambda y
, a
: y
[2:4].eq(a
)
186 self
.assertStatement(stmt2
, [C(0b01, 2)], C(0b11110111, 8), reset
=0b11111011)
188 def test_bit_select(self
):
189 stmt
= lambda y
, a
, b
: y
.eq(a
.bit_select(b
, 3))
190 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
191 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b101, 3))
192 self
.assertStatement(stmt
, [C(0b10110100, 8), C(3)], C(0b110, 3))
194 def test_bit_select_lhs(self
):
195 stmt
= lambda y
, a
, b
: y
.bit_select(a
, 3).eq(b
)
196 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
197 self
.assertStatement(stmt
, [C(2), C(0b101, 3)], C(0b11110111, 8), reset
=0b11111111)
198 self
.assertStatement(stmt
, [C(3), C(0b110, 3)], C(0b11110111, 8), reset
=0b11111111)
200 def test_word_select(self
):
201 stmt
= lambda y
, a
, b
: y
.eq(a
.word_select(b
, 3))
202 self
.assertStatement(stmt
, [C(0b10110100, 8), C(0)], C(0b100, 3))
203 self
.assertStatement(stmt
, [C(0b10110100, 8), C(1)], C(0b110, 3))
204 self
.assertStatement(stmt
, [C(0b10110100, 8), C(2)], C(0b010, 3))
206 def test_word_select_lhs(self
):
207 stmt
= lambda y
, a
, b
: y
.word_select(a
, 3).eq(b
)
208 self
.assertStatement(stmt
, [C(0), C(0b100, 3)], C(0b11111100, 8), reset
=0b11111111)
209 self
.assertStatement(stmt
, [C(1), C(0b101, 3)], C(0b11101111, 8), reset
=0b11111111)
210 self
.assertStatement(stmt
, [C(2), C(0b110, 3)], C(0b10111111, 8), reset
=0b11111111)
213 stmt
= lambda y
, *xs
: y
.eq(Cat(*xs
))
214 self
.assertStatement(stmt
, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
216 def test_cat_lhs(self
):
220 stmt
= lambda y
, a
: [Cat(l
, m
, n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
221 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
223 def test_nested_cat_lhs(self
):
227 stmt
= lambda y
, a
: [Cat(Cat(l
, Cat(m
)), n
).eq(a
), y
.eq(Cat(n
, m
, l
))]
228 self
.assertStatement(stmt
, [C(0b100101110, 9)], C(0b110101100, 9))
230 def test_record(self
):
235 stmt
= lambda y
, a
: [rec
.eq(a
), y
.eq(rec
)]
236 self
.assertStatement(stmt
, [C(0b101, 3)], C(0b101, 3))
239 stmt
= lambda y
, a
: y
.eq(Repl(a
, 3))
240 self
.assertStatement(stmt
, [C(0b10, 2)], C(0b101010, 6))
242 def test_array(self
):
243 array
= Array([1, 4, 10])
244 stmt
= lambda y
, a
: y
.eq(array
[a
])
245 self
.assertStatement(stmt
, [C(0)], C(1))
246 self
.assertStatement(stmt
, [C(1)], C(4))
247 self
.assertStatement(stmt
, [C(2)], C(10))
249 def test_array_oob(self
):
250 array
= Array([1, 4, 10])
251 stmt
= lambda y
, a
: y
.eq(array
[a
])
252 self
.assertStatement(stmt
, [C(3)], C(10))
253 self
.assertStatement(stmt
, [C(4)], C(10))
255 def test_array_lhs(self
):
256 l
= Signal(3, reset
=1)
257 m
= Signal(3, reset
=4)
258 n
= Signal(3, reset
=7)
259 array
= Array([l
, m
, n
])
260 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
261 self
.assertStatement(stmt
, [C(0), C(0b000)], C(0b111100000))
262 self
.assertStatement(stmt
, [C(1), C(0b010)], C(0b111010001))
263 self
.assertStatement(stmt
, [C(2), C(0b100)], C(0b100100001))
265 def test_array_lhs_oob(self
):
269 array
= Array([l
, m
, n
])
270 stmt
= lambda y
, a
, b
: [array
[a
].eq(b
), y
.eq(Cat(*array
))]
271 self
.assertStatement(stmt
, [C(3), C(0b001)], C(0b001000000))
272 self
.assertStatement(stmt
, [C(4), C(0b010)], C(0b010000000))
274 def test_array_index(self
):
275 array
= Array(Array(x
* y
for y
in range(10)) for x
in range(10))
276 stmt
= lambda y
, a
, b
: y
.eq(array
[a
][b
])
279 self
.assertStatement(stmt
, [C(x
), C(y
)], C(x
* y
))
281 def test_array_attr(self
):
282 from collections
import namedtuple
283 pair
= namedtuple("pair", ("p", "n"))
285 array
= Array(pair(x
, -x
) for x
in range(10))
286 stmt
= lambda y
, a
: y
.eq(array
[a
].p
+ array
[a
].n
)
288 self
.assertStatement(stmt
, [C(i
)], C(0))
291 class SimulatorIntegrationTestCase(FHDLTestCase
):
293 def assertSimulation(self
, module
, deadline
=None):
294 sim
= Simulator(module
)
296 with sim
.write_vcd("test.vcd", "test.gtkw"):
300 sim
.run_until(deadline
)
302 def setUp_counter(self
):
303 self
.count
= Signal(3, reset
=4)
304 self
.sync
= ClockDomain()
307 self
.m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
308 self
.m
.domains
+= self
.sync
310 def test_counter_process(self
):
312 with self
.assertSimulation(self
.m
) as sim
:
314 self
.assertEqual((yield self
.count
), 4)
316 self
.assertEqual((yield self
.count
), 4)
317 yield self
.sync
.clk
.eq(1)
318 self
.assertEqual((yield self
.count
), 4)
320 self
.assertEqual((yield self
.count
), 5)
322 self
.assertEqual((yield self
.count
), 5)
323 yield self
.sync
.clk
.eq(0)
324 self
.assertEqual((yield self
.count
), 5)
326 self
.assertEqual((yield self
.count
), 5)
329 yield self
.sync
.clk
.eq(1)
331 yield self
.sync
.clk
.eq(0)
332 self
.assertEqual((yield self
.count
), 0)
333 sim
.add_process(process
)
335 def test_counter_clock_and_sync_process(self
):
337 with self
.assertSimulation(self
.m
) as sim
:
338 sim
.add_clock(1e-6, domain
="sync")
340 self
.assertEqual((yield self
.count
), 4)
341 self
.assertEqual((yield self
.sync
.clk
), 1)
343 self
.assertEqual((yield self
.count
), 5)
344 self
.assertEqual((yield self
.sync
.clk
), 1)
347 self
.assertEqual((yield self
.count
), 0)
348 sim
.add_sync_process(process
)
350 def test_reset(self
):
352 sim
= Simulator(self
.m
)
357 self
.assertEqual((yield self
.count
), 4)
359 self
.assertEqual((yield self
.count
), 5)
361 self
.assertEqual((yield self
.count
), 6)
364 sim
.add_sync_process(process
)
368 self
.assertEqual(times
, 2)
376 self
.sync
= ClockDomain(reset_less
=True)
379 self
.m
.d
.comb
+= self
.x
.eq(self
.a ^ self
.b
)
380 with self
.m
.Switch(self
.s
):
382 self
.m
.d
.sync
+= self
.o
.eq(self
.a
+ self
.b
)
384 self
.m
.d
.sync
+= self
.o
.eq(self
.a
- self
.b
)
386 self
.m
.d
.sync
+= self
.o
.eq(0)
387 self
.m
.domains
+= self
.sync
391 with self
.assertSimulation(self
.m
) as sim
:
397 self
.assertEqual((yield self
.x
), 4)
399 self
.assertEqual((yield self
.o
), 6)
403 self
.assertEqual((yield self
.o
), 4)
407 self
.assertEqual((yield self
.o
), 0)
408 sim
.add_sync_process(process
)
410 def setUp_multiclock(self
):
411 self
.sys
= ClockDomain()
412 self
.pix
= ClockDomain()
415 self
.m
.domains
+= self
.sys
, self
.pix
417 def test_multiclock(self
):
418 self
.setUp_multiclock()
419 with self
.assertSimulation(self
.m
) as sim
:
420 sim
.add_clock(1e-6, domain
="sys")
421 sim
.add_clock(0.3e-6, domain
="pix")
432 sim
.add_sync_process(sys_process
, domain
="sys")
433 sim
.add_sync_process(pix_process
, domain
="pix")
435 def setUp_lhs_rhs(self
):
440 self
.m
.d
.comb
+= self
.o
.eq(self
.i
)
442 def test_complex_lhs_rhs(self
):
444 with self
.assertSimulation(self
.m
) as sim
:
446 yield self
.i
.eq(0b10101010)
447 yield self
.i
[:4].eq(-1)
449 self
.assertEqual((yield self
.i
[:4]), 0b1111)
450 self
.assertEqual((yield self
.i
), 0b10101111)
451 sim
.add_process(process
)
453 def test_run_until(self
):
457 with self
.assertSimulation(m
, deadline
=100e-6) as sim
:
463 sim
.add_process(process
)
465 def test_add_process_wrong(self
):
466 with self
.assertSimulation(Module()) as sim
:
467 with self
.assertRaises(TypeError,
468 msg
="Cannot add a process 1 because it is not a generator function"):
471 def test_add_process_wrong_generator(self
):
472 with self
.assertSimulation(Module()) as sim
:
473 with self
.assertWarns(DeprecationWarning,
474 msg
="instead of generators, use generator functions as processes; "
475 "this allows the simulator to be repeatedly reset"):
478 sim
.add_process(process())
480 def test_add_clock_wrong_twice(self
):
484 with self
.assertSimulation(m
) as sim
:
486 with self
.assertRaises(ValueError,
487 msg
="Domain 'sync' already has a clock driving it"):
490 def test_add_clock_wrong_missing(self
):
492 with self
.assertSimulation(m
) as sim
:
493 with self
.assertRaises(ValueError,
494 msg
="Domain 'sync' is not present in simulation"):
497 def test_add_clock_if_exists(self
):
499 with self
.assertSimulation(m
) as sim
:
500 sim
.add_clock(1, if_exists
=True)
502 def test_command_wrong(self
):
504 with self
.assertSimulation(Module()) as sim
:
507 with self
.assertRaisesRegex(TypeError,
508 regex
=r
"Received unsupported command 1 from process .+?"):
512 sim
.add_process(process
)
513 self
.assertTrue(survived
)
515 def setUp_memory(self
, rd_synchronous
=True, rd_transparent
=True, wr_granularity
=None):
517 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
518 self
.m
.submodules
.rdport
= self
.rdport
= \
519 self
.memory
.read_port(domain
="sync" if rd_synchronous
else "comb",
520 transparent
=rd_transparent
)
521 self
.m
.submodules
.wrport
= self
.wrport
= \
522 self
.memory
.write_port(granularity
=wr_granularity
)
524 def test_memory_init(self
):
526 with self
.assertSimulation(self
.m
) as sim
:
528 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
529 yield self
.rdport
.addr
.eq(1)
532 self
.assertEqual((yield self
.rdport
.data
), 0x55)
533 yield self
.rdport
.addr
.eq(2)
536 self
.assertEqual((yield self
.rdport
.data
), 0x00)
538 sim
.add_sync_process(process
)
540 def test_memory_write(self
):
542 with self
.assertSimulation(self
.m
) as sim
:
544 yield self
.wrport
.addr
.eq(4)
545 yield self
.wrport
.data
.eq(0x33)
546 yield self
.wrport
.en
.eq(1)
548 yield self
.wrport
.en
.eq(0)
549 yield self
.rdport
.addr
.eq(4)
551 self
.assertEqual((yield self
.rdport
.data
), 0x33)
553 sim
.add_sync_process(process
)
555 def test_memory_write_granularity(self
):
556 self
.setUp_memory(wr_granularity
=4)
557 with self
.assertSimulation(self
.m
) as sim
:
559 yield self
.wrport
.data
.eq(0x50)
560 yield self
.wrport
.en
.eq(0b00)
562 yield self
.wrport
.en
.eq(0)
564 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
565 yield self
.wrport
.en
.eq(0b10)
567 yield self
.wrport
.en
.eq(0)
569 self
.assertEqual((yield self
.rdport
.data
), 0x5a)
570 yield self
.wrport
.data
.eq(0x33)
571 yield self
.wrport
.en
.eq(0b01)
573 yield self
.wrport
.en
.eq(0)
575 self
.assertEqual((yield self
.rdport
.data
), 0x53)
577 sim
.add_sync_process(process
)
579 def test_memory_read_before_write(self
):
580 self
.setUp_memory(rd_transparent
=False)
581 with self
.assertSimulation(self
.m
) as sim
:
583 yield self
.wrport
.data
.eq(0x33)
584 yield self
.wrport
.en
.eq(1)
586 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
588 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
590 self
.assertEqual((yield self
.rdport
.data
), 0x33)
592 sim
.add_sync_process(process
)
594 def test_memory_write_through(self
):
595 self
.setUp_memory(rd_transparent
=True)
596 with self
.assertSimulation(self
.m
) as sim
:
598 yield self
.wrport
.data
.eq(0x33)
599 yield self
.wrport
.en
.eq(1)
601 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
603 self
.assertEqual((yield self
.rdport
.data
), 0x33)
605 yield self
.rdport
.addr
.eq(1)
607 self
.assertEqual((yield self
.rdport
.data
), 0x33)
609 sim
.add_sync_process(process
)
611 def test_memory_async_read_write(self
):
612 self
.setUp_memory(rd_synchronous
=False)
613 with self
.assertSimulation(self
.m
) as sim
:
615 yield self
.rdport
.addr
.eq(0)
617 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
618 yield self
.rdport
.addr
.eq(1)
620 self
.assertEqual((yield self
.rdport
.data
), 0x55)
621 yield self
.rdport
.addr
.eq(0)
622 yield self
.wrport
.addr
.eq(0)
623 yield self
.wrport
.data
.eq(0x33)
624 yield self
.wrport
.en
.eq(1)
626 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
628 self
.assertEqual((yield self
.rdport
.data
), 0x33)
630 sim
.add_process(process
)
632 def test_memory_read_only(self
):
634 self
.memory
= Memory(width
=8, depth
=4, init
=[0xaa, 0x55])
635 self
.m
.submodules
.rdport
= self
.rdport
= self
.memory
.read_port()
636 with self
.assertSimulation(self
.m
) as sim
:
638 self
.assertEqual((yield self
.rdport
.data
), 0xaa)
639 yield self
.rdport
.addr
.eq(1)
642 self
.assertEqual((yield self
.rdport
.data
), 0x55)
644 sim
.add_sync_process(process
)
646 def test_sample_helpers(self
):
653 p0
, r0
, f0
, s0
= mk(Past(s
, 0)), mk(Rose(s
)), mk(Fell(s
)), mk(Stable(s
))
654 p1
, r1
, f1
, s1
= mk(Past(s
)), mk(Rose(s
, 1)), mk(Fell(s
, 1)), mk(Stable(s
, 1))
655 p2
, r2
, f2
, s2
= mk(Past(s
, 2)), mk(Rose(s
, 2)), mk(Fell(s
, 2)), mk(Stable(s
, 2))
656 p3
, r3
, f3
, s3
= mk(Past(s
, 3)), mk(Rose(s
, 3)), mk(Fell(s
, 3)), mk(Stable(s
, 3))
657 with self
.assertSimulation(m
) as sim
:
669 self
.assertEqual((yield p0
), 0b01)
670 self
.assertEqual((yield p1
), 0b10)
671 self
.assertEqual((yield p2
), 0b10)
672 self
.assertEqual((yield p3
), 0b00)
674 self
.assertEqual((yield s0
), 0b0)
675 self
.assertEqual((yield s1
), 0b1)
676 self
.assertEqual((yield s2
), 0b0)
677 self
.assertEqual((yield s3
), 0b1)
679 self
.assertEqual((yield r0
), 0b01)
680 self
.assertEqual((yield r1
), 0b00)
681 self
.assertEqual((yield r2
), 0b10)
682 self
.assertEqual((yield r3
), 0b00)
684 self
.assertEqual((yield f0
), 0b10)
685 self
.assertEqual((yield f1
), 0b00)
686 self
.assertEqual((yield f2
), 0b00)
687 self
.assertEqual((yield f3
), 0b00)
689 sim
.add_sync_process(process_gen
)
690 sim
.add_sync_process(process_check
)
692 def test_vcd_wrong_nonzero_time(self
):
699 with self
.assertRaisesRegex(ValueError,
700 regex
=r
"^Cannot start writing waveforms after advancing simulation time$"):
701 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
704 def test_vcd_wrong_twice(self
):
710 with self
.assertRaisesRegex(ValueError,
711 regex
=r
"^Already writing waveforms to .+$"):
712 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
713 with sim
.write_vcd(open(os
.path
.devnull
, "wt")):
717 class SimulatorRegressionTestCase(FHDLTestCase
):
718 def test_bug_325(self
):
720 dut
.d
.comb
+= Signal().eq(Cat())
723 def test_bug_325_bis(self
):
725 dut
.d
.comb
+= Signal().eq(Repl(Const(1), 0))