sawg: wire up all HBF outputs, latency compensation in phys, simplify

This commit is contained in:
Robert Jördens 2016-12-13 18:37:21 +01:00
parent 6cdb96c5e0
commit 8381db279f
3 changed files with 58 additions and 59 deletions

View File

@ -5,7 +5,7 @@ from misoc.interconnect.stream import Endpoint
from misoc.cores.cordic import Cordic
from .accu import PhasedAccu
from .tools import eqh, Delay, SatAddMixin
from .tools import eqh, SatAddMixin
from .spline import Spline
from .fir import ParallelHBFUpsampler, halfgen4_cascade
@ -14,44 +14,10 @@ _Widths = namedtuple("_Widths", "t a p f")
_Orders = namedtuple("_Orders", "a p f")
class ParallelDDS(Module):
def __init__(self, widths, parallelism=1, a_delay=0):
self.i = Endpoint([("x", widths.a), ("y", widths.a),
("f", widths.f), ("p", widths.f), ("clr", 1)])
class SplineParallelDUC(Module):
def __init__(self, widths, orders, parallelism=1, **kwargs):
self.parallelism = parallelism
self.widths = widths
###
accu = PhasedAccu(widths.f, parallelism)
cordic = [Cordic(width=widths.a, widthz=widths.p, guard=None,
eval_mode="pipelined") for i in range(parallelism)]
self.xo = [c.xo for c in cordic]
self.yo = [c.yo for c in cordic]
a_delay += accu.latency
xy_delay = Delay(2*widths.a, max(0, a_delay))
z_delay = Delay(parallelism*widths.p, max(0, -a_delay))
self.submodules += accu, xy_delay, z_delay, cordic
self.latency = max(0, a_delay) + cordic[0].latency
self.gain = cordic[0].gain
self.comb += [
xy_delay.i.eq(Cat(self.i.x, self.i.y)),
z_delay.i.eq(Cat(zi[-widths.p:]
for zi in accu.o.payload.flatten())),
eqh(accu.i.p, self.i.p),
accu.i.f.eq(self.i.f),
accu.i.clr.eq(self.i.clr),
accu.i.stb.eq(self.i.stb),
self.i.ack.eq(accu.i.ack),
accu.o.ack.eq(1),
[Cat(c.xi, c.yi).eq(xy_delay.o) for c in cordic],
Cat(c.zi for c in cordic).eq(z_delay.o),
]
class SplineParallelDUC(ParallelDDS):
def __init__(self, widths, orders, **kwargs):
p = Spline(order=orders.p, width=widths.p)
f = Spline(order=orders.f, width=widths.f)
self.f = f.tri(widths.t)
@ -59,27 +25,41 @@ class SplineParallelDUC(ParallelDDS):
self.submodules += p, f
self.ce = Signal(reset=1)
self.clr = Signal()
super().__init__(widths._replace(p=len(self.p.a0), f=len(self.f.a0)),
**kwargs)
self.latency += f.latency
###
accu = PhasedAccu(len(self.f.a0), parallelism)
cordic = [Cordic(width=widths.a, widthz=len(self.p.a0), guard=None,
eval_mode="pipelined") for i in range(parallelism)]
self.submodules += accu, cordic
self.xi = [c.xi for c in cordic]
self.yi = [c.yi for c in cordic]
self.xo = [c.xo for c in cordic]
self.yo = [c.yo for c in cordic]
self.latency = cordic[0].latency
self.gain = cordic[0].gain
self.f.latency += accu.latency + self.latency
self.p.latency += accu.latency + self.latency
###
assert p.latency == f.latency
self.comb += [
p.o.ack.eq(self.ce),
f.o.ack.eq(self.ce),
eqh(self.i.f, f.o.a0),
eqh(self.i.p, p.o.a0),
self.i.stb.eq(p.o.stb | f.o.stb),
eqh(accu.i.f, f.o.a0),
eqh(accu.i.p, p.o.a0),
accu.i.stb.eq(p.o.stb | f.o.stb),
accu.o.ack.eq(1),
[eqh(c.zi, zi) for c, zi in
zip(cordic, accu.o.payload.flatten())]
]
assert p.latency == 1
self.sync += [
self.i.clr.eq(0),
accu.i.clr.eq(0),
If(p.i.stb,
self.i.clr.eq(self.clr),
accu.i.clr.eq(self.clr),
),
]
@ -91,12 +71,14 @@ class SplineParallelDDS(SplineParallelDUC):
self.submodules += a
super().__init__(widths._replace(a=len(self.a.a0)), orders, **kwargs)
self.a.latency += self.latency
###
self.comb += [
a.o.ack.eq(self.ce),
eqh(self.i.x, a.o.a0),
self.i.y.eq(0),
[eqh(x, a.o.a0) for x in self.xi],
[y.eq(0) for y in self.yi],
]
@ -151,12 +133,11 @@ class Channel(Module, SatAddMixin):
hbf = [ParallelHBFUpsampler(coeff, width=width, shift=17)
for i in range(2)]
self.submodules.b = b = SplineParallelDUC(
widths._replace(a=len(a1.xo[0]), f=widths.f - width), orders,
parallelism=parallelism, a_delay=-a1.latency-hbf[0].latency)
widths._replace(a=len(hbf[0].o[0]), f=widths.f - width), orders,
parallelism=parallelism)
cfg = Config(widths.a)
u = Spline(width=widths.a, order=orders.a)
du = Delay(width, a1.latency + hbf[0].latency + b.latency - u.latency)
self.submodules += cfg, u, du, hbf
self.submodules += cfg, u, hbf
self.u = u.tri(widths.t)
self.i = [cfg.i, self.u, a1.a, a1.f, a1.p, a2.a, a2.f, a2.p, b.f, b.p]
self.i_names = "cfg u a1 f1 p1 a2 f2 p2 f0 p0".split()
@ -166,9 +147,23 @@ class Channel(Module, SatAddMixin):
self.widths = widths
self.orders = orders
self.parallelism = parallelism
self.latency = a1.latency + hbf[0].latency + b.latency + 2
self.cordic_gain = a1.gain*b.gain
self.u.latency += 1
b.p.latency += 2
b.f.latency += 2
a_latency_delta = hbf[0].latency + b.latency + 2
for a in a1, a2:
a.a.latency += a_latency_delta
a.p.latency += a_latency_delta
a.f.latency += a_latency_delta
self.latency = max(_.latency for _ in self.i[1:])
for i in self.i[1:]:
i.latency -= self.latency
assert i.latency <= 0
cfg.i.latency = 0
###
self.comb += [
@ -177,8 +172,8 @@ class Channel(Module, SatAddMixin):
b.ce.eq(cfg.ce),
u.o.ack.eq(cfg.ce),
Cat(a1.clr, a2.clr, b.clr).eq(cfg.clr),
b.i.x.eq(hbf[0].o[0]), # FIXME: rip up
b.i.y.eq(hbf[1].o[0]),
Cat(b.xi).eq(Cat(hbf[0].o)),
Cat(b.yi).eq(Cat(hbf[1].o)),
]
self.sync += [
hbf[0].i.eq(self.sat_add(a1.xo[0], a2.xo[0],
@ -187,14 +182,16 @@ class Channel(Module, SatAddMixin):
hbf[1].i.eq(self.sat_add(a1.yo[0], a2.yo[0],
limits=cfg.limits[1],
clipped=cfg.clipped[1])),
eqh(du.i, u.o.a0),
]
# wire up outputs and q_{i,o} exchange
for o, x, y in zip(self.o, b.xo, self.y_in):
self.sync += [
o.eq(self.sat_add(
du.o, Mux(cfg.iq_en[0], x, 0), Mux(cfg.iq_en[1], y, 0),
limits=cfg.limits[2], clipped=cfg.clipped[2])),
u.o.a0[-len(o):],
Mux(cfg.iq_en[0], x, 0),
Mux(cfg.iq_en[1], y, 0),
limits=cfg.limits[2],
clipped=cfg.clipped[2])),
]
def connect_y(self, buddy):

View File

@ -37,6 +37,7 @@ class Spline(Module):
enumerate(self.i.payload.layout[::-1])]
layout.reverse()
i = Endpoint(layout)
i.latency = self.latency
self.comb += [
self.i.stb.eq(i.stb),
i.ack.eq(self.i.ack),

View File

@ -16,7 +16,8 @@ class Channel(_ChannelPHY):
_ChannelPHY.__init__(self, *args, **kwargs)
self.phys = []
for i in self.i:
rl = rtlink.Interface(rtlink.OInterface(len(i.payload)))
rl = rtlink.Interface(rtlink.OInterface(len(i.payload),
delay=-i.latency))
self.comb += [
i.stb.eq(rl.o.stb),
rl.o.busy.eq(~i.ack),