phaser: update sawg tests

This commit is contained in:
Robert Jördens 2016-11-18 15:23:56 +01:00
parent 51f23feeac
commit d678bb3fb6
5 changed files with 78 additions and 51 deletions

View File

@ -36,8 +36,8 @@ class ParallelDDS(Module):
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()])),
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),
@ -45,7 +45,7 @@ class ParallelDDS(Module):
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),
Cat(c.zi for c in cordic).eq(z_delay.o),
]
@ -71,8 +71,15 @@ class SplineParallelDUC(ParallelDDS):
f.o.ack.eq(self.ce),
eqh(self.i.f, f.o.a0),
eqh(self.i.p, p.o.a0),
self.i.clr.eq(self.clr),
self.i.stb.eq(p.o.stb & f.o.stb),
self.i.stb.eq(p.o.stb | f.o.stb),
]
assert p.latency == 1
self.sync += [
self.i.clr.eq(0),
If(p.i.stb,
self.i.clr.eq(self.clr),
),
]
@ -94,20 +101,24 @@ class SplineParallelDDS(SplineParallelDUC):
class Config(Module):
def __init__(self):
self.clr = Signal(4)
self.iq_en = Signal(2)
limit = [Signal((16, True)) for i in range(2*2)]
self.limit = [limit[i:i + 2] for i in range(0, len(limit), 2)]
self.i = Endpoint([("addr", bits_for(len(limit) + 2)), ("data", 16)])
def __init__(self, width):
self.clr = Signal(4, reset=0b1111)
self.iq_en = Signal(2, reset=0b01)
self.limit = [[Signal((width, True), reset=-(1 << width - 1)),
Signal((width, True), reset=(1 << width - 1) - 1)]
for i in range(2)]
self.i = Endpoint([("addr", bits_for(4 + 2*len(self.limit))),
("data", 16)])
self.ce = Signal()
###
div = Signal(16)
div = Signal(16, reset=0)
n = Signal.like(div)
pad = Signal()
reg = Array([Cat(self.clr, self.iq_en), Cat(div, n)] + self.limit)
reg = Array([Cat(div, n), self.clr, self.iq_en, pad] +
sum(self.limit, []))
self.comb += [
self.i.ack.eq(1),
@ -130,22 +141,22 @@ class Channel(Module, SatAddMixin):
orders = _Orders(a=4, f=2, p=1)
if widths is None:
widths = _Widths(t=width, a=orders.a*width, p=orders.p*width,
f=3*width + (orders.f - 1)*width)
f=(orders.f + 2)*width)
cfg = Config()
a1 = SplineParallelDDS(widths, orders)
a2 = SplineParallelDDS(widths, orders)
b = SplineParallelDUC(widths, orders, parallelism=parallelism,
a_delay=-a1.latency)
self.submodules.a1 = a1 = SplineParallelDDS(widths, orders)
self.submodules.a2 = a2 = SplineParallelDDS(widths, orders)
self.submodules.b = b = SplineParallelDUC(
widths, orders, parallelism=parallelism, a_delay=-a1.latency)
cfg = Config(widths.a)
u = Spline(width=widths.a, order=orders.a)
du = Delay(widths.a, a1.latency + b.latency - u.latency)
self.submodules += cfg, a1, a2, b, u, du
self.cfg = cfg.i
self.submodules += cfg, u, du
self.u = u.tri(widths.t)
self.i = [self.cfg, self.u, a1.a, a1.f, a1.p, a2.a, a2.f, a2.p, b.f, b.p]
self.y_in = [Signal((width, True)) for i in range(b.parallelism)]
self.y_out = b.yo
self.o = [Signal((width, True)) for i in range(b.parallelism)]
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()
self.i_named = dict(zip(self.i_names, self.i))
self.y_in = [Signal((width, True)) for i in range(parallelism)]
self.o = [Signal((width, True)) for i in range(parallelism)]
self.widths = widths
self.orders = orders
self.parallelism = parallelism
@ -167,10 +178,11 @@ class Channel(Module, SatAddMixin):
# 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,
o.eq(self.sat_add([
du.o,
Mux(cfg.iq_en[0], x, 0),
Mux(cfg.iq_en[1], y, 0)])),
]
def connect_q_from(self, buddy):
self.comb += Cat(self.y_in).eq(Cat(buddy.y_out))
def connect_y(self, buddy):
self.comb += Cat(buddy.y_in).eq(Cat(self.b.yo))

View File

@ -16,14 +16,12 @@ class Channel(_ChannelPHY):
_ChannelPHY.__init__(self, *args, **kwargs)
self.phys = []
for i in self.i:
rl = rtlink.Interface(rtlink.OInterface(
min(32, len(i.payload)))) # TODO: test/expand
rl = rtlink.Interface(rtlink.OInterface(len(i.payload)))
self.comb += [
i.stb.eq(rl.o.stb),
rl.o.busy.eq(~i.ack),
Cat(i.payload.flatten()).eq(rl.o.data),
i.payload.raw_bits().eq(rl.o.data),
]
# no probes, overrides
# TODO probes, overrides
self.phys.append(_Phy(rl, [], []))
self.phys_names = dict(zip("cfg f0 p0 a1 f1 p1 a2 f2 p2".split(),
self.phys))
self.phys_named = dict(zip(self.i_names, self.phys))

View File

@ -3,23 +3,25 @@ import numpy as np
from migen import *
from migen.fhdl.verilog import convert
from artiq.gateware.dsp.sawg import DDSFast
from artiq.gateware.dsp import sawg
from .tools import xfer
def _test_gen_dds(dut, o):
yield from xfer(dut,
a=dict(a=10),
p=dict(p=0),
f=dict(f=1 << 8),
a=dict(a0=10),
p=dict(a0=0),
f=dict(a0=1),
)
for i in range(256//dut.parallelism):
yield
o.append((yield from [(yield _) for _ in dut.o]))
o.append((yield from [(yield _) for _ in dut.xo]))
def _test_channel():
dut = DDSFast(width=8, parallelism=2)
widths = sawg._Widths(t=8, a=4*8, p=8, f=16)
orders = sawg._Orders(a=4, p=1, f=2)
dut = sawg.SplineParallelDDS(widths, orders, parallelism=2)
if False:
print(convert(dut))

View File

@ -1,25 +1,32 @@
import numpy as np
from operator import or_
from migen import *
from migen.fhdl.verilog import convert
from artiq.gateware.rtio.phy.sawg import Channel
from .tools import xfer, szip
from .tools import rtio_xfer
def rtio_xfer(dut, **kwargs):
yield from szip(*(
xfer(dut.phys_names[k].rtlink, o={"data": v})
for k, v in kwargs.items()))
def pack_tri(port, *v):
r = 0
w = 0
for vi, p in zip(v, port.payload.flatten()):
w += len(p)
r |= int(vi*(1 << w))
return r
def gen_rtio(dut):
width = dut.width
yield
yield from rtio_xfer(
dut, a=int(.1 * (1 << width)),
f=int(.01234567 * (1 << 2*width)),
p=0)
dut,
a1=pack_tri(dut.a1.a, .1),
f0=pack_tri(dut.b.f, .01234567),
f1=pack_tri(dut.a1.f, .01234567),
a2=pack_tri(dut.a1.a, .05),
f2=pack_tri(dut.a1.f, .00534567),
)
def gen_log(dut, o, n):
@ -28,10 +35,12 @@ def gen_log(dut, o, n):
for i in range(n):
yield
o.append((yield from [(yield _) for _ in dut.o]))
#o.append([(yield dut.a1.xo[0])])
def _test_channel():
width = 16
dut = ClockDomainsRenamer({"rio_phy": "sys"})(
Channel(width=width, parallelism=4)
)
@ -43,8 +52,8 @@ def _test_channel():
o = []
run_simulation(
dut,
[gen_rtio(dut), gen_log(dut, o, 256 * 2)],
) # vcd_name="dds.vcd")
[gen_rtio(dut), gen_log(dut, o, 128)],
vcd_name="dds.vcd")
o = np.array(o)/(1 << (width - 1))
o = o.ravel()
np.savez_compressed("dds.npz", o=o)

View File

@ -41,3 +41,9 @@ def szip(*iters):
val = (yield None)
for it in active:
active[it] = val
def rtio_xfer(dut, **kwargs):
yield from szip(*(
xfer(dut.phys_named[k].rtlink, o={"data": v})
for k, v in kwargs.items()))