from migen.fhdl.std import * from migen.genlib.roundrobin import * from migen.genlib.record import * class Arbiter(Module): def __init__(self, sources, sink): if len(sources) == 0: pass elif len(sources) == 1: self.grant = Signal() self.comb += Record.connect(sources.pop(), sink) else: self.submodules.rr = RoundRobin(len(sources)) self.grant = self.rr.grant cases = {} for i, source in enumerate(sources): sop = Signal() eop = Signal() ongoing = Signal() self.comb += [ sop.eq(source.stb & source.sop), eop.eq(source.stb & source.eop & source.ack), ] self.sync += ongoing.eq((sop | ongoing) & ~eop) self.comb += self.rr.request[i].eq((sop | ongoing) & ~eop) cases[i] = [Record.connect(source, sink)] self.comb += Case(self.grant, cases)