import functools import inspect from collections.abc import Iterable from ...hdl.cd import ClockDomain from ...back.pysim import * __all__ = ["run_simulation", "passive"] def run_simulation(fragment_or_module, generators, clocks={"sync": 10}, vcd_name=None, special_overrides={}): assert not special_overrides if hasattr(fragment_or_module, "get_fragment"): fragment = fragment_or_module.get_fragment() else: fragment = fragment_or_module if not isinstance(generators, dict): generators = {"sync": generators} fragment.domains += ClockDomain("sync") sim = Simulator(fragment) for domain, period in clocks.items(): sim.add_clock(period / 1e9, domain=domain) for domain, processes in generators.items(): def wrap(process): def wrapper(): yield from process return wrapper if isinstance(processes, Iterable) and not inspect.isgenerator(processes): for process in processes: sim.add_sync_process(wrap(process), domain=domain) else: sim.add_sync_process(wrap(processes), domain=domain) if vcd_name is not None: with sim.write_vcd(vcd_name): sim.run() else: sim.run() def passive(generator): @functools.wraps(generator) def wrapper(*args, **kwargs): yield Passive() yield from generator(*args, **kwargs) return wrapper