nmigen
nmigen copied to clipboard
Make it possible for generators to simulate combinatorial logic
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.