dsp/sat_add: spell out logic more

This commit is contained in:
Robert Jördens 2017-06-22 16:54:17 +02:00
parent d0cf0f2b87
commit 9b940aa876
2 changed files with 22 additions and 18 deletions

View File

@ -183,9 +183,9 @@ class Channel(Module, SatAddMixin):
Cat(b.yi).eq(Cat(hbf[1].o)), Cat(b.yi).eq(Cat(hbf[1].o)),
] ]
self.sync += [ self.sync += [
hbf[0].i.eq(self.sat_add(a1.xo[0], a2.xo[0], hbf[0].i.eq(self.sat_add((a1.xo[0], a2.xo[0]),
limits=cfg.limits[1], clipped=cfg.clipped[1])), limits=cfg.limits[1], clipped=cfg.clipped[1])),
hbf[1].i.eq(self.sat_add(a1.yo[0], a2.yo[0], hbf[1].i.eq(self.sat_add((a1.yo[0], a2.yo[0]),
limits=cfg.limits[1], clipped=cfg.clipped[1])), limits=cfg.limits[1], clipped=cfg.clipped[1])),
] ]
# wire up outputs and q_{i,o} exchange # wire up outputs and q_{i,o} exchange
@ -199,9 +199,8 @@ class Channel(Module, SatAddMixin):
o_y.eq(Mux(cfg.iq_en[1], y, 0)), o_y.eq(Mux(cfg.iq_en[1], y, 0)),
] ]
self.sync += [ self.sync += [
o.eq(self.sat_add(o_offset, o_x, o_y, o.eq(self.sat_add((o_offset, o_x, o_y),
limits=cfg.limits[0], limits=cfg.limits[0], clipped=cfg.clipped[0])),
clipped=cfg.clipped[0])),
] ]
def connect_y(self, buddy): def connect_y(self, buddy):

View File

@ -30,34 +30,39 @@ def eqh(a, b):
class SatAddMixin: class SatAddMixin:
"""Signed saturating addition mixin""" """Signed saturating addition mixin"""
def sat_add(self, *a, limits=None, clipped=None): def sat_add(self, a, *, width=None, limits=None, clipped=None):
a = list(a) a = list(a)
# assert all(value_bits_sign(ai)[1] for ai in a) # assert all(value_bits_sign(ai)[1] for ai in a)
length = max(len(ai) for ai in a) if width is None:
width = max(value_bits_sign(ai)[0] for ai in a)
carry = log2_int(len(a), need_pow2=False) carry = log2_int(len(a), need_pow2=False)
full = Signal((length + carry, True)) full = Signal((width + carry, True))
limited = Signal((length, True)) limited = Signal((width, True))
clip = Signal(2) clip = Signal(2)
sign = Signal()
if clipped is not None: if clipped is not None:
self.comb += clipped.eq(clip) self.comb += clipped.eq(clip)
self.comb += [ self.comb += [
full.eq(reduce(add, a)), full.eq(reduce(add, a)),
sign.eq(full[-1]),
limited.eq(full)
] ]
if limits is None: if limits is None:
sign = Signal()
self.comb += [ self.comb += [
sign.eq(full[-1]), If(full[-1-carry:] != Replicate(sign, carry + 1),
If(full[-1-carry:] == Replicate(sign, carry + 1),
clip.eq(0),
limited.eq(full),
).Else(
clip.eq(Cat(sign, ~sign)), clip.eq(Cat(sign, ~sign)),
limited.eq(Cat(Replicate(~sign, length - 1), sign)), limited.eq(Cat(Replicate(~sign, width - 1), sign)),
) )
] ]
else: else:
self.comb += [ self.comb += [
clip.eq(Cat(full < limits[0], full > limits[1])), If(full < limits[0],
limited.eq(Array([full, limits[0], limits[1], 0])[clip]), clip.eq(0b01),
limited.eq(limits[0])
),
If(full > limits[1],
clip.eq(0b10),
limited.eq(limits[1]),
)
] ]
return limited return limited