sim: split into base, core, and engines.
[nmigen.git] / nmigen / compat / sim / __init__.py
1 import functools
2 import inspect
3 from collections.abc import Iterable
4 from ...hdl.cd import ClockDomain
5 from ...hdl.ir import Fragment
6 from ...sim import *
7
8
9 __all__ = ["run_simulation", "passive"]
10
11
12 def run_simulation(fragment_or_module, generators, clocks={"sync": 10}, vcd_name=None,
13 special_overrides={}):
14 assert not special_overrides
15
16 if hasattr(fragment_or_module, "get_fragment"):
17 fragment = fragment_or_module.get_fragment()
18 else:
19 fragment = fragment_or_module
20
21 fragment = Fragment.get(fragment, platform=None)
22
23 if not isinstance(generators, dict):
24 generators = {"sync": generators}
25 if "sync" not in fragment.domains:
26 fragment.add_domains(ClockDomain("sync"))
27
28 sim = Simulator(fragment)
29 for domain, period in clocks.items():
30 sim.add_clock(period / 1e9, domain=domain)
31 for domain, processes in generators.items():
32 def wrap(process):
33 def wrapper():
34 yield from process
35 return wrapper
36 if isinstance(processes, Iterable) and not inspect.isgenerator(processes):
37 for process in processes:
38 sim.add_sync_process(wrap(process), domain=domain)
39 else:
40 sim.add_sync_process(wrap(processes), domain=domain)
41
42 if vcd_name is not None:
43 with sim.write_vcd(vcd_name):
44 sim.run()
45 else:
46 sim.run()
47
48
49 def passive(generator):
50 @functools.wraps(generator)
51 def wrapper(*args, **kwargs):
52 yield Passive()
53 yield from generator(*args, **kwargs)
54 return wrapper