Skip to content

asserts.Past doesn't work correctly with DomainRenamer #372

Closed as not planned
@tpwrules

Description

@tpwrules

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.
image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions