fhdl/tools/_ArrayLowerer: complete support for arrays as targets

This commit is contained in:
Sebastien Bourdeauducq 2013-03-18 14:38:01 +01:00
parent e95d2f4779
commit dc55289323

View file

@ -171,30 +171,43 @@ def value_bits_sign(v):
class _ArrayLowerer(NodeTransformer): class _ArrayLowerer(NodeTransformer):
def __init__(self): def __init__(self):
self.comb = [] self.comb = []
self.target_context = False
self.extra_stmts = []
def visit_Assign(self, node): def visit_Assign(self, node):
if isinstance(node.l, _ArrayProxy): old_target_context, old_extra_stmts = self.target_context, self.extra_stmts
k = self.visit(node.l.key) self.extra_stmts = []
cases = {}
for n, choice in enumerate(node.l.choices): self.target_context = True
assign = self.visit_Assign(_Assign(choice, node.r)) lhs = self.visit(node.l)
cases[n] = [assign] self.target_context = False
return Case(k, cases).makedefault() rhs = self.visit(node.r)
else: r = _Assign(lhs, rhs)
return NodeTransformer.visit_Assign(self, node) if self.extra_stmts:
r = [r] + self.extra_stmts
self.target_context, self.extra_stmts = old_target_context, old_extra_stmts
return r
def visit_ArrayProxy(self, node): def visit_ArrayProxy(self, node):
array_muxed = Signal(value_bits_sign(node)) array_muxed = Signal(value_bits_sign(node), variable=True)
cases = dict((n, _Assign(array_muxed, self.visit(choice))) if self.target_context:
for n, choice in enumerate(node.choices)) k = self.visit(node.key)
self.comb.append(Case(self.visit(node.key), cases).makedefault()) cases = {}
for n, choice in enumerate(node.choices):
cases[n] = [self.visit_Assign(_Assign(choice, array_muxed))]
self.extra_stmts.append(Case(k, cases).makedefault())
else:
cases = dict((n, _Assign(array_muxed, self.visit(choice)))
for n, choice in enumerate(node.choices))
self.comb.append(Case(self.visit(node.key), cases).makedefault())
return array_muxed return array_muxed
def lower_arrays(f): def lower_arrays(f):
al = _ArrayLowerer() al = _ArrayLowerer()
f2 = al.visit(f) tf = al.visit(f)
f2.comb += al.comb tf.comb += al.comb
return f2 return tf
def bitreverse(s): def bitreverse(s):
length, signed = value_bits_sign(s) length, signed = value_bits_sign(s)