litex/migen/pytholite/reg.py

52 lines
1.3 KiB
Python
Raw Normal View History

from operator import itemgetter
from migen.fhdl.structure import *
from migen.fhdl import visit as fhdl
class FinalizeError(Exception):
pass
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[self.source])
class LowerAbstractLoad(fhdl.NodeTransformer):
def visit_unknown(self, node):
if isinstance(node, AbstractLoad):
return node.lower()
else:
return node
class ImplRegister:
def __init__(self, name, nbits):
self.name = name
self.storage = Signal(BV(nbits), name=self.name)
self.source_encoding = {}
self.finalized = False
def load(self, source):
if source not in self.source_encoding:
self.source_encoding[source] = len(self.source_encoding) + 1
return AbstractLoad(self, source)
def finalize(self):
if self.finalized:
raise FinalizeError
self.sel = Signal(BV(bits_for(len(self.source_encoding) + 1)), name="pl_regsel_"+self.name)
self.finalized = True
def get_fragment(self):
if not self.finalized:
raise FinalizeError
# do nothing when sel == 0
items = sorted(self.source_encoding.items(), key=itemgetter(1))
2012-11-28 17:18:43 -05:00
cases = [(v, self.storage.eq(k)) for k, v in items]
sync = [Case(self.sel, *cases)]
return Fragment(sync=sync)