from operator import itemgetter from migen.fhdl.std import * from migen.fhdl import visit as fhdl class AbstractLoad: def __init__(self, target, source): self.target = target self.source = source def lower(self): if not self.target.finalized: raise FinalizeError return self.target.sel.eq(self.target.source_encoding[id(self.source)]) class LowerAbstractLoad(fhdl.NodeTransformer): def visit_unknown(self, node): if isinstance(node, AbstractLoad): return node.lower() else: return node class ImplRegister(Module): def __init__(self, name, bits_sign): self.name = name self.storage = Signal(bits_sign, name=self.name) self.source_encoding = {} self.id_to_source = {} def load(self, source): if id(source) not in self.source_encoding: self.source_encoding[id(source)] = len(self.source_encoding) + 1 self.id_to_source[id(source)] = source return AbstractLoad(self, source) def do_finalize(self): self.sel = Signal(max=len(self.source_encoding)+1, name="pl_regsel_"+self.name) # do nothing when sel == 0 items = sorted(self.source_encoding.items(), key=itemgetter(1)) cases = dict((v, self.storage.eq(self.id_to_source[k])) for k, v in items) self.sync += Case(self.sel, cases)