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 += [ self.comb += [
xy_delay.i.eq(Cat(self.i.x, self.i.y)), xy_delay.i.eq(Cat(self.i.x, self.i.y)),
z_delay.i.eq(Cat([zi[-widths.p:] z_delay.i.eq(Cat(zi[-widths.p:]
for zi in accu.o.payload.flatten()])), for zi in accu.o.payload.flatten())),
eqh(accu.i.p, self.i.p), eqh(accu.i.p, self.i.p),
accu.i.f.eq(self.i.f), accu.i.f.eq(self.i.f),
accu.i.clr.eq(self.i.clr), accu.i.clr.eq(self.i.clr),
@ -45,7 +45,7 @@ class ParallelDDS(Module):
self.i.ack.eq(accu.i.ack), self.i.ack.eq(accu.i.ack),
accu.o.ack.eq(1), accu.o.ack.eq(1),
[Cat(c.xi, c.yi).eq(xy_delay.o) for c in cordic], [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), f.o.ack.eq(self.ce),
eqh(self.i.f, f.o.a0), eqh(self.i.f, f.o.a0),
eqh(self.i.p, p.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): class Config(Module):
def __init__(self): def __init__(self, width):
self.clr = Signal(4) self.clr = Signal(4, reset=0b1111)
self.iq_en = Signal(2) self.iq_en = Signal(2, reset=0b01)
limit = [Signal((16, True)) for i in range(2*2)] self.limit = [[Signal((width, True), reset=-(1 << width - 1)),
self.limit = [limit[i:i + 2] for i in range(0, len(limit), 2)] Signal((width, True), reset=(1 << width - 1) - 1)]
self.i = Endpoint([("addr", bits_for(len(limit) + 2)), ("data", 16)]) for i in range(2)]
self.i = Endpoint([("addr", bits_for(4 + 2*len(self.limit))),
("data", 16)])
self.ce = Signal() self.ce = Signal()
### ###
div = Signal(16) div = Signal(16, reset=0)
n = Signal.like(div) 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.comb += [
self.i.ack.eq(1), self.i.ack.eq(1),
@ -130,22 +141,22 @@ class Channel(Module, SatAddMixin):
orders = _Orders(a=4, f=2, p=1) orders = _Orders(a=4, f=2, p=1)
if widths is None: if widths is None:
widths = _Widths(t=width, a=orders.a*width, p=orders.p*width, 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() self.submodules.a1 = a1 = SplineParallelDDS(widths, orders)
a1 = SplineParallelDDS(widths, orders) self.submodules.a2 = a2 = SplineParallelDDS(widths, orders)
a2 = SplineParallelDDS(widths, orders) self.submodules.b = b = SplineParallelDUC(
b = SplineParallelDUC(widths, orders, parallelism=parallelism, widths, orders, parallelism=parallelism, a_delay=-a1.latency)
a_delay=-a1.latency) cfg = Config(widths.a)
u = Spline(width=widths.a, order=orders.a) u = Spline(width=widths.a, order=orders.a)
du = Delay(widths.a, a1.latency + b.latency - u.latency) du = Delay(widths.a, a1.latency + b.latency - u.latency)
self.submodules += cfg, a1, a2, b, u, du self.submodules += cfg, u, du
self.cfg = cfg.i
self.u = u.tri(widths.t) 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.i = [cfg.i, 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.i_names = "cfg u a1 f1 p1 a2 f2 p2 f0 p0".split()
self.y_out = b.yo self.i_named = dict(zip(self.i_names, self.i))
self.o = [Signal((width, True)) for i in range(b.parallelism)] 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.widths = widths
self.orders = orders self.orders = orders
self.parallelism = parallelism self.parallelism = parallelism
@ -167,10 +178,11 @@ class Channel(Module, SatAddMixin):
# wire up outputs and q_{i,o} exchange # wire up outputs and q_{i,o} exchange
for o, x, y in zip(self.o, b.xo, self.y_in): for o, x, y in zip(self.o, b.xo, self.y_in):
self.sync += [ 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[0], x, 0),
Mux(cfg.iq_en[1], y, 0)])), Mux(cfg.iq_en[1], y, 0)])),
] ]
def connect_q_from(self, buddy): def connect_y(self, buddy):
self.comb += Cat(self.y_in).eq(Cat(buddy.y_out)) 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) _ChannelPHY.__init__(self, *args, **kwargs)
self.phys = [] self.phys = []
for i in self.i: for i in self.i:
rl = rtlink.Interface(rtlink.OInterface( rl = rtlink.Interface(rtlink.OInterface(len(i.payload)))
min(32, len(i.payload)))) # TODO: test/expand
self.comb += [ self.comb += [
i.stb.eq(rl.o.stb), i.stb.eq(rl.o.stb),
rl.o.busy.eq(~i.ack), 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.append(_Phy(rl, [], []))
self.phys_names = dict(zip("cfg f0 p0 a1 f1 p1 a2 f2 p2".split(), self.phys_named = dict(zip(self.i_names, self.phys))
self.phys))

View File

@ -3,23 +3,25 @@ import numpy as np
from migen import * from migen import *
from migen.fhdl.verilog import convert from migen.fhdl.verilog import convert
from artiq.gateware.dsp.sawg import DDSFast from artiq.gateware.dsp import sawg
from .tools import xfer from .tools import xfer
def _test_gen_dds(dut, o): def _test_gen_dds(dut, o):
yield from xfer(dut, yield from xfer(dut,
a=dict(a=10), a=dict(a0=10),
p=dict(p=0), p=dict(a0=0),
f=dict(f=1 << 8), f=dict(a0=1),
) )
for i in range(256//dut.parallelism): for i in range(256//dut.parallelism):
yield yield
o.append((yield from [(yield _) for _ in dut.o])) o.append((yield from [(yield _) for _ in dut.xo]))
def _test_channel(): 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: if False:
print(convert(dut)) print(convert(dut))

View File

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

View File

@ -41,3 +41,9 @@ def szip(*iters):
val = (yield None) val = (yield None)
for it in active: for it in active:
active[it] = val 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()))