forked from M-Labs/artiq
dsp/sat_add: spell out logic more
This commit is contained in:
parent
d0cf0f2b87
commit
9b940aa876
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue