nmigen icon indicating copy to clipboard operation
nmigen copied to clipboard

Make it possible for generators to simulate combinatorial logic

Open nakengelhardt opened this issue 5 years ago • 0 comments

Sometimes I want to use generators to build a simulation model of some module. In migen, this wasn't possible for modules that implement combinatorial logic.

Trying my hand at nmigen syntax, an example could be something like this:

class RoutingPolicy:
    def __init__(self, width, n):
        self.data = Signal(width)
        self.destination = Signal(max=n)

    # I haven't decided yet what I want this module to do, let's try some options
    def gen_destination(self):
        while True: # or something?
            data = (yield self.data)
            if (data == 23):
                yield self.destination.eq(0)
            else:
                yield self.destination.eq(self.data[:log2_int(n)])

class Router:
    def __init__(self, width, n):
        self.in_port = Signal(width)
        self.out_ports = Array(Signal(width) for _ in range(n))

        self.policy = RoutingPolicy(width, n)

    def get_fragment(self, platform):
        m = Module()
        m.submodules.policy = self.policy
        m.d.comb += [
            self.policy.data.eq(self.in_port),
            self.out_ports[self.policy.destination].eq(self.in_port)
        ]
        return m.lower(platform)

m = Router(8, 2)
run_simulation(m, m.policy.gen_destination())

There probably needs to be something to tell what constitutes one iteration of the generator, with while True it would just run indefinitely. while (yield input_values_changed()): ? Also the whole thing would need to be @passive or so since there's no predefined end point. Another question is whether it's possible, or even makes sense, to mix combinatorial assignments and synchronous assignments in one generator.

nakengelhardt avatar Dec 18 '18 05:12 nakengelhardt