42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
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)
|