self._signal_slots = SignalDict() # Signal -> int/slot
self._slot_signals = list() # int/slot -> Signal
- self._domains = dict() # str/domain -> ClockDomain
- self._domain_triggers = list() # int/slot -> str/domain
+ self._domains = list() # [ClockDomain]
+ self._domain_triggers = list() # int/slot -> ClockDomain
self._signals = SignalSet() # {Signal}
self._comb_signals = bitarray() # {Signal}
self._sync_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._timestamp = 0.
half_period = period / 2
if phase is None:
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():
yield Passive()
yield Delay(phase)
comment="Generated by nMigen")
root_fragment = self._fragment.prepare()
- self._domains = root_fragment.domains
hierarchy = {}
+ domains = set()
def add_fragment(fragment, scope=()):
hierarchy[fragment] = scope
+ domains.update(fragment.domains.values())
for index, (subfragment, name) in enumerate(fragment.subfragments):
if name is None:
add_fragment(subfragment, (*scope, "U{}".format(index)))
else:
add_fragment(subfragment, (*scope, name))
add_fragment(root_fragment, scope=("top",))
+ self._domains = list(domains)
def add_signal(signal):
if signal not in self._signals:
for signal in fragment.iter_signals():
add_signal(signal)
- for domain, cd in fragment.domains.items():
- add_domain_signal(cd.clk, domain)
- if cd.rst is not None:
- add_domain_signal(cd.rst, domain)
+ for domain_name, domain in fragment.domains.items():
+ add_domain_signal(domain.clk, domain)
+ if domain.rst is not None:
+ add_domain_signal(domain.rst, domain)
for fragment, fragment_scope in hierarchy.items():
for signal in fragment.iter_signals():
except KeyError:
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.setall(False)
for signal in signals:
signals_bits[self._signal_slots[signal]] = True
- if domain is None:
+ if domain_name is None:
self._comb_signals |= signals_bits
else:
self._sync_signals |= signals_bits
- self._domain_signals[domain] |= signals_bits
+ self._domain_signals[fragment.domains[domain_name]] |= signals_bits
statements = []
- for domain, signals in fragment.drivers.items():
+ for domain_name, signals in fragment.drivers.items():
reset_stmts = []
hold_stmts = []
for signal in signals:
reset_stmts.append(signal.eq(signal.reset))
hold_stmts .append(signal.eq(signal))
- if domain is None:
+ if domain_name is None:
statements += reset_stmts
else:
- if self._domains[domain].async_reset:
- statements.append(Switch(self._domains[domain].rst,
+ if fragment.domains[domain_name].async_reset:
+ statements.append(Switch(fragment.domains[domain_name].rst,
{0: hold_stmts, 1: reset_stmts}))
else:
statements += hold_stmts
for signal in compiler.sensitivity:
add_funclet(signal, funclet)
- for domain, cd in fragment.domains.items():
- add_funclet(cd.clk, funclet)
- if cd.rst is not None:
- add_funclet(cd.rst, funclet)
+ for domain in fragment.domains.values():
+ add_funclet(domain.clk, funclet)
+ if domain.rst is not None:
+ add_funclet(domain.rst, funclet)
self._user_signals = bitarray(len(self._signals))
self._user_signals.setall(True)
def _commit_sync_signals(self, domains):
"""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:
# Advance the timeline a bit (purely for observational purposes) and commit all of them
# at the same timestamp.
domain = curr_domains.pop()
# Wake up any simulator processes that wait for a domain tick.
- for process, wait_domain in list(self._wait_tick.items()):
- if domain == wait_domain:
+ for process, wait_domain_name in list(self._wait_tick.items()):
+ if domain.name == wait_domain_name:
del self._wait_tick[process]
self._suspended.remove(process)
suffix = ""
gtkw_save.trace(self._vcd_names[signal_slot] + suffix, **kwargs)
- for domain, cd in self._domains.items():
- with gtkw_save.group("d.{}".format(domain)):
- if cd.rst is not None:
- add_trace(cd.rst)
- add_trace(cd.clk)
+ for domain in self._domains:
+ with gtkw_save.group("d.{}".format(domain.name)):
+ if domain.rst is not None:
+ add_trace(domain.rst)
+ add_trace(domain.clk)
for signal in self._traces:
add_trace(signal)