forked from M-Labs/artiq
phaser: update sawg tests
This commit is contained in:
parent
51f23feeac
commit
d678bb3fb6
|
@ -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))
|
||||||
|
|
|
@ -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))
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()))
|
||||||
|
|
Loading…
Reference in New Issue