back.pysim: index domains by identity, not by name.
Changed in preparation for introducing local clock domains.
This commit is contained in:
parent
69d36dc139
commit
9bdadbff09
|
@ -381,14 +381,14 @@ class Simulator:
|
||||||
self._signal_slots = SignalDict() # Signal -> int/slot
|
self._signal_slots = SignalDict() # Signal -> int/slot
|
||||||
self._slot_signals = list() # int/slot -> Signal
|
self._slot_signals = list() # int/slot -> Signal
|
||||||
|
|
||||||
self._domains = dict() # str/domain -> ClockDomain
|
self._domains = list() # [ClockDomain]
|
||||||
self._domain_triggers = list() # int/slot -> str/domain
|
self._domain_triggers = list() # int/slot -> ClockDomain
|
||||||
|
|
||||||
self._signals = SignalSet() # {Signal}
|
self._signals = SignalSet() # {Signal}
|
||||||
self._comb_signals = bitarray() # {Signal}
|
self._comb_signals = bitarray() # {Signal}
|
||||||
self._sync_signals = bitarray() # {Signal}
|
self._sync_signals = bitarray() # {Signal}
|
||||||
self._user_signals = bitarray() # {Signal}
|
self._user_signals = bitarray() # {Signal}
|
||||||
self._domain_signals = dict() # str/domain -> {Signal}
|
self._domain_signals = dict() # ClockDomain -> {Signal}
|
||||||
|
|
||||||
self._started = False
|
self._started = False
|
||||||
self._timestamp = 0.
|
self._timestamp = 0.
|
||||||
|
@ -463,7 +463,9 @@ class Simulator:
|
||||||
half_period = period / 2
|
half_period = period / 2
|
||||||
if phase is None:
|
if phase is None:
|
||||||
phase = half_period
|
phase = half_period
|
||||||
clk = self._domains[domain].clk
|
for domain_obj in self._domains:
|
||||||
|
if not domain_obj.local and domain_obj.name == domain:
|
||||||
|
clk = domain_obj.clk
|
||||||
def clk_process():
|
def clk_process():
|
||||||
yield Passive()
|
yield Passive()
|
||||||
yield Delay(phase)
|
yield Delay(phase)
|
||||||
|
@ -481,17 +483,19 @@ class Simulator:
|
||||||
comment="Generated by nMigen")
|
comment="Generated by nMigen")
|
||||||
|
|
||||||
root_fragment = self._fragment.prepare()
|
root_fragment = self._fragment.prepare()
|
||||||
self._domains = root_fragment.domains
|
|
||||||
|
|
||||||
hierarchy = {}
|
hierarchy = {}
|
||||||
|
domains = set()
|
||||||
def add_fragment(fragment, scope=()):
|
def add_fragment(fragment, scope=()):
|
||||||
hierarchy[fragment] = scope
|
hierarchy[fragment] = scope
|
||||||
|
domains.update(fragment.domains.values())
|
||||||
for index, (subfragment, name) in enumerate(fragment.subfragments):
|
for index, (subfragment, name) in enumerate(fragment.subfragments):
|
||||||
if name is None:
|
if name is None:
|
||||||
add_fragment(subfragment, (*scope, "U{}".format(index)))
|
add_fragment(subfragment, (*scope, "U{}".format(index)))
|
||||||
else:
|
else:
|
||||||
add_fragment(subfragment, (*scope, name))
|
add_fragment(subfragment, (*scope, name))
|
||||||
add_fragment(root_fragment, scope=("top",))
|
add_fragment(root_fragment, scope=("top",))
|
||||||
|
self._domains = list(domains)
|
||||||
|
|
||||||
def add_signal(signal):
|
def add_signal(signal):
|
||||||
if signal not in self._signals:
|
if signal not in self._signals:
|
||||||
|
@ -526,10 +530,10 @@ class Simulator:
|
||||||
for signal in fragment.iter_signals():
|
for signal in fragment.iter_signals():
|
||||||
add_signal(signal)
|
add_signal(signal)
|
||||||
|
|
||||||
for domain, cd in fragment.domains.items():
|
for domain_name, domain in fragment.domains.items():
|
||||||
add_domain_signal(cd.clk, domain)
|
add_domain_signal(domain.clk, domain)
|
||||||
if cd.rst is not None:
|
if domain.rst is not None:
|
||||||
add_domain_signal(cd.rst, domain)
|
add_domain_signal(domain.rst, domain)
|
||||||
|
|
||||||
for fragment, fragment_scope in hierarchy.items():
|
for fragment, fragment_scope in hierarchy.items():
|
||||||
for signal in fragment.iter_signals():
|
for signal in fragment.iter_signals():
|
||||||
|
@ -571,31 +575,31 @@ class Simulator:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
suffix = (suffix or 0) + 1
|
suffix = (suffix or 0) + 1
|
||||||
|
|
||||||
for domain, signals in fragment.drivers.items():
|
for domain_name, signals in fragment.drivers.items():
|
||||||
signals_bits = bitarray(len(self._signals))
|
signals_bits = bitarray(len(self._signals))
|
||||||
signals_bits.setall(False)
|
signals_bits.setall(False)
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
signals_bits[self._signal_slots[signal]] = True
|
signals_bits[self._signal_slots[signal]] = True
|
||||||
|
|
||||||
if domain is None:
|
if domain_name is None:
|
||||||
self._comb_signals |= signals_bits
|
self._comb_signals |= signals_bits
|
||||||
else:
|
else:
|
||||||
self._sync_signals |= signals_bits
|
self._sync_signals |= signals_bits
|
||||||
self._domain_signals[domain] |= signals_bits
|
self._domain_signals[fragment.domains[domain_name]] |= signals_bits
|
||||||
|
|
||||||
statements = []
|
statements = []
|
||||||
for domain, signals in fragment.drivers.items():
|
for domain_name, signals in fragment.drivers.items():
|
||||||
reset_stmts = []
|
reset_stmts = []
|
||||||
hold_stmts = []
|
hold_stmts = []
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
reset_stmts.append(signal.eq(signal.reset))
|
reset_stmts.append(signal.eq(signal.reset))
|
||||||
hold_stmts .append(signal.eq(signal))
|
hold_stmts .append(signal.eq(signal))
|
||||||
|
|
||||||
if domain is None:
|
if domain_name is None:
|
||||||
statements += reset_stmts
|
statements += reset_stmts
|
||||||
else:
|
else:
|
||||||
if self._domains[domain].async_reset:
|
if fragment.domains[domain_name].async_reset:
|
||||||
statements.append(Switch(self._domains[domain].rst,
|
statements.append(Switch(fragment.domains[domain_name].rst,
|
||||||
{0: hold_stmts, 1: reset_stmts}))
|
{0: hold_stmts, 1: reset_stmts}))
|
||||||
else:
|
else:
|
||||||
statements += hold_stmts
|
statements += hold_stmts
|
||||||
|
@ -610,10 +614,10 @@ class Simulator:
|
||||||
|
|
||||||
for signal in compiler.sensitivity:
|
for signal in compiler.sensitivity:
|
||||||
add_funclet(signal, funclet)
|
add_funclet(signal, funclet)
|
||||||
for domain, cd in fragment.domains.items():
|
for domain in fragment.domains.values():
|
||||||
add_funclet(cd.clk, funclet)
|
add_funclet(domain.clk, funclet)
|
||||||
if cd.rst is not None:
|
if domain.rst is not None:
|
||||||
add_funclet(cd.rst, funclet)
|
add_funclet(domain.rst, funclet)
|
||||||
|
|
||||||
self._user_signals = bitarray(len(self._signals))
|
self._user_signals = bitarray(len(self._signals))
|
||||||
self._user_signals.setall(True)
|
self._user_signals.setall(True)
|
||||||
|
@ -670,7 +674,7 @@ class Simulator:
|
||||||
|
|
||||||
def _commit_sync_signals(self, domains):
|
def _commit_sync_signals(self, domains):
|
||||||
"""Perform the sync part of IR processes (aka RTLIL posedge)."""
|
"""Perform the sync part of IR processes (aka RTLIL posedge)."""
|
||||||
# At entry, `domains` contains a list of every simultaneously triggered sync update.
|
# At entry, `domains` contains a set of every simultaneously triggered sync update.
|
||||||
while domains:
|
while domains:
|
||||||
# Advance the timeline a bit (purely for observational purposes) and commit all of them
|
# Advance the timeline a bit (purely for observational purposes) and commit all of them
|
||||||
# at the same timestamp.
|
# at the same timestamp.
|
||||||
|
@ -681,8 +685,8 @@ class Simulator:
|
||||||
domain = curr_domains.pop()
|
domain = curr_domains.pop()
|
||||||
|
|
||||||
# Wake up any simulator processes that wait for a domain tick.
|
# Wake up any simulator processes that wait for a domain tick.
|
||||||
for process, wait_domain in list(self._wait_tick.items()):
|
for process, wait_domain_name in list(self._wait_tick.items()):
|
||||||
if domain == wait_domain:
|
if domain.name == wait_domain_name:
|
||||||
del self._wait_tick[process]
|
del self._wait_tick[process]
|
||||||
self._suspended.remove(process)
|
self._suspended.remove(process)
|
||||||
|
|
||||||
|
@ -860,11 +864,11 @@ class Simulator:
|
||||||
suffix = ""
|
suffix = ""
|
||||||
gtkw_save.trace(self._vcd_names[signal_slot] + suffix, **kwargs)
|
gtkw_save.trace(self._vcd_names[signal_slot] + suffix, **kwargs)
|
||||||
|
|
||||||
for domain, cd in self._domains.items():
|
for domain in self._domains:
|
||||||
with gtkw_save.group("d.{}".format(domain)):
|
with gtkw_save.group("d.{}".format(domain.name)):
|
||||||
if cd.rst is not None:
|
if domain.rst is not None:
|
||||||
add_trace(cd.rst)
|
add_trace(domain.rst)
|
||||||
add_trace(cd.clk)
|
add_trace(domain.clk)
|
||||||
|
|
||||||
for signal in self._traces:
|
for signal in self._traces:
|
||||||
add_trace(signal)
|
add_trace(signal)
|
||||||
|
|
Loading…
Reference in a new issue