back.pysim: more general clean-up.
This commit is contained in:
parent
1b7f8c7950
commit
dd00b5e2d6
|
@ -20,6 +20,7 @@ frag = ctr.get_fragment(platform=None)
|
|||
# print(rtlil.convert(frag, ports=[ctr.o]))
|
||||
print(verilog.convert(frag, ports=[ctr.o]))
|
||||
|
||||
sim = pysim.Simulator(frag, vcd_file=open("clkdiv.vcd", "w"))
|
||||
sim.add_clock("sync", 1e-6)
|
||||
with sim: sim.run_until(100e-6, run_passive=True)
|
||||
with pysim.Simulator(frag,
|
||||
vcd_file=open("clkdiv.vcd", "w")) as sim:
|
||||
sim.add_clock(1e-6)
|
||||
sim.run_until(100e-6, run_passive=True)
|
||||
|
|
|
@ -21,17 +21,17 @@ frag = ctr.get_fragment(platform=None)
|
|||
# print(rtlil.convert(frag, ports=[ctr.o, ctr.ce]))
|
||||
print(verilog.convert(frag, ports=[ctr.o, ctr.ce]))
|
||||
|
||||
sim = pysim.Simulator(frag,
|
||||
vcd_file=open("ctrl.vcd", "w"),
|
||||
gtkw_file=open("ctrl.gtkw", "w"),
|
||||
gtkw_signals=[ctr.ce, ctr.v, ctr.o])
|
||||
sim.add_clock("sync", 1e-6)
|
||||
def ce_proc():
|
||||
yield; yield; yield
|
||||
yield ctr.ce.eq(1)
|
||||
yield; yield; yield
|
||||
yield ctr.ce.eq(0)
|
||||
yield; yield; yield
|
||||
yield ctr.ce.eq(1)
|
||||
sim.add_sync_process(ce_proc())
|
||||
with sim: sim.run_until(100e-6, run_passive=True)
|
||||
with pysim.Simulator(frag,
|
||||
vcd_file=open("ctrl.vcd", "w"),
|
||||
gtkw_file=open("ctrl.gtkw", "w"),
|
||||
gtkw_signals=[ctr.ce, ctr.v, ctr.o]) as sim:
|
||||
sim.add_clock(1e-6)
|
||||
def ce_proc():
|
||||
yield; yield; yield
|
||||
yield ctr.ce.eq(1)
|
||||
yield; yield; yield
|
||||
yield ctr.ce.eq(0)
|
||||
yield; yield; yield
|
||||
yield ctr.ce.eq(1)
|
||||
sim.add_sync_process(ce_proc())
|
||||
sim.run_until(100e-6, run_passive=True)
|
||||
|
|
|
@ -190,7 +190,7 @@ class _StatementCompiler(StatementTransformer):
|
|||
|
||||
class Simulator:
|
||||
def __init__(self, fragment, vcd_file=None, gtkw_file=None, gtkw_signals=()):
|
||||
self._fragments = {} # fragment -> hierarchy
|
||||
self._fragment = fragment
|
||||
|
||||
self._domains = {} # str/domain -> ClockDomain
|
||||
self._domain_triggers = ValueDict() # Signal -> str/domain
|
||||
|
@ -223,25 +223,10 @@ class Simulator:
|
|||
self._gtkw_file = gtkw_file
|
||||
self._gtkw_signals = gtkw_signals
|
||||
|
||||
fragment = fragment.prepare()
|
||||
|
||||
def add_fragment(fragment, hierarchy=("top",)):
|
||||
self._fragments[fragment] = hierarchy
|
||||
for subfragment, name in fragment.subfragments:
|
||||
add_fragment(subfragment, (*hierarchy, name))
|
||||
add_fragment(fragment)
|
||||
|
||||
self._domains = fragment.domains
|
||||
for domain, cd in self._domains.items():
|
||||
self._domain_triggers[cd.clk] = domain
|
||||
if cd.rst is not None:
|
||||
self._domain_triggers[cd.rst] = domain
|
||||
self._domain_signals[domain] = ValueSet()
|
||||
|
||||
def add_process(self, process):
|
||||
self._processes.add(process)
|
||||
|
||||
def add_clock(self, domain, period):
|
||||
def add_clock(self, period, domain="sync"):
|
||||
if self._fastest_clock == self._epsilon or period < self._fastest_clock:
|
||||
self._fastest_clock = period
|
||||
|
||||
|
@ -272,7 +257,23 @@ class Simulator:
|
|||
self._vcd_writer = VCDWriter(self._vcd_file, timescale="100 ps",
|
||||
comment="Generated by nMigen")
|
||||
|
||||
for fragment in self._fragments:
|
||||
root_fragment = self._fragment.prepare()
|
||||
|
||||
self._domains = root_fragment.domains
|
||||
for domain, cd in self._domains.items():
|
||||
self._domain_triggers[cd.clk] = domain
|
||||
if cd.rst is not None:
|
||||
self._domain_triggers[cd.rst] = domain
|
||||
self._domain_signals[domain] = ValueSet()
|
||||
|
||||
fragment_names = {}
|
||||
def add_fragment(fragment, hierarchy=("top",)):
|
||||
fragment_names[fragment] = hierarchy
|
||||
for subfragment, name in fragment.subfragments:
|
||||
add_fragment(subfragment, (*hierarchy, name))
|
||||
add_fragment(root_fragment)
|
||||
|
||||
for fragment, fragment_name in fragment_names.items():
|
||||
for signal in fragment.iter_signals():
|
||||
self._signals.add(signal)
|
||||
|
||||
|
@ -307,11 +308,10 @@ class Simulator:
|
|||
else:
|
||||
var_name_suffix = "{}${}".format(var_name, suffix)
|
||||
self._vcd_signals[signal].add(self._vcd_writer.register_var(
|
||||
scope=".".join(self._fragments[fragment]), name=var_name_suffix,
|
||||
scope=".".join(fragment_name), name=var_name_suffix,
|
||||
var_type=var_type, size=var_size, init=var_init))
|
||||
if signal not in self._vcd_names:
|
||||
self._vcd_names[signal] = \
|
||||
".".join(self._fragments[fragment] + (var_name_suffix,))
|
||||
self._vcd_names[signal] = ".".join(fragment_name + (var_name_suffix,))
|
||||
break
|
||||
except KeyError:
|
||||
suffix = (suffix or 0) + 1
|
||||
|
@ -344,6 +344,8 @@ class Simulator:
|
|||
|
||||
self._user_signals = self._signals - self._comb_signals - self._sync_signals
|
||||
|
||||
return self
|
||||
|
||||
def _update_dirty_signals(self):
|
||||
"""Perform the statement part of IR processes (aka RTLIL case)."""
|
||||
# First, for all dirty signals, use sensitivity lists to determine the set of fragments
|
||||
|
@ -502,6 +504,10 @@ class Simulator:
|
|||
# No processes, or all processes are passive. Nothing to do!
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
while self.step():
|
||||
pass
|
||||
|
||||
def run_until(self, deadline, run_passive=False):
|
||||
while self._timestamp < deadline:
|
||||
if not self.step(run_passive):
|
||||
|
|
Loading…
Reference in a new issue