Closed as not planned
Description
DomainRenamers don't seem to change the domain that Past
looks at. Below is a minimal example that demonstrates the problem and the correct behavior.
The Toggle
module flips its internal toggle every clock cycle, then uses Past
to output it delayed by one cycle. Both toggles are DomainRenamed to the "fast" domain. Toggle t1
uses Past(domain=None)
and generates an incorrect output because Past
samples the toggle from the sync
domain; the DomainRenamer didn't change it to "fast". Toggle t2
, on the other hand, uses Past(domain="fast")
to ensure the sample is taken from the correct clock domain and so generates the correct output.
from nmigen import *
from nmigen.asserts import Past
from nmigen.back.pysim import Simulator, Delay
class Toggle(Elaboratable):
def __init__(self, domain):
self.domain = domain
self.delayed = Signal()
def elaborate(self, platform):
m = Module()
toggle = Signal()
m.d.sync += toggle.eq(~toggle)
m.d.sync += self.delayed.eq(Past(toggle, domain=self.domain))
return m
m = Module()
m.submodules.t1 = t1 = DomainRenamer("fast")(Toggle(None))
m.submodules.t2 = t2 = DomainRenamer("fast")(Toggle("fast"))
sim = Simulator(m)
sim.add_clock(1e-6, domain="sync")
sim.add_clock((1/3)*1e-6, domain="fast")
with sim.write_vcd("test.vcd", "test.gtkw", traces=[t1.delayed, t2.delayed]):
sim.run_until(10e-6, run_passive=True)
GTKWave output is shown below. The top trace is the output of t1
and the bottom is the output of t2
.