Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 09f46dab7087
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1feb7cfd692e
Choose a head ref
  • 3 commits
  • 9 files changed
  • 1 contributor

Commits on Sep 3, 2016

  1. sawg: tweak dds parameters

    jordens committed Sep 3, 2016
    Copy the full SHA
    921de81 View commit details
  2. Copy the full SHA
    be478d6 View commit details
  3. sawg: test phy, refactor

    jordens committed Sep 3, 2016
    Copy the full SHA
    1feb7cf View commit details
16 changes: 8 additions & 8 deletions artiq/coredevice/sawg.py
Original file line number Diff line number Diff line change
@@ -16,55 +16,55 @@ def __init__(self, dmgr, channel_base, parallelism=4, core_device="core"):
self.channel_base = channel_base
cordic_gain = 1.646760258057163 # Cordic(width=16, guard=None).gain
a_width = 16
f_width = 48
f_width = 32
p_width = 16
self.amplitude_scale = (1 << a_width) / 2 / cordic_gain
self.phase_scale = 1 << p_width
self.frequency_scale = ((1 << f_width) / self.core.coarse_ref_period /
self.frequency_scale = ((1 << f_width) * self.core.coarse_ref_period /
parallelism)

@kernel
def set_amplitude_mu(self, amplitude=0):
def set_amplitude_mu(self, amplitude: TInt32):
"""Set DDS amplitude (machine units).
:param amplitude: DDS amplitude in machine units.
"""
rtio_output(now_mu(), self.channel_base, 0, amplitude)

@kernel
def set_amplitude(self, amplitude=0):
def set_amplitude(self, amplitude: TFloat):
"""Set DDS amplitude.
:param amplitude: DDS amplitude relative to full-scale.
"""
self.set_amplitude_mu(amplitude*self.amplitude_scale)

@kernel
def set_frequency_mu(self, frequency=0):
def set_frequency_mu(self, frequency: TInt32):
"""Set DDS frequency (machine units).
:param frequency: DDS frequency in machine units.
"""
rtio_output(now_mu(), self.channel_base + 1, 0, frequency)

@kernel
def set_frequency(self, frequency=0):
def set_frequency(self, frequency: TFloat):
"""Set DDS frequency.
:param frequency: DDS frequency in Hz.
"""
self.set_frequency_mu(frequency*self.frequency_scale)

@kernel
def set_phase_mu(self, phase=0):
def set_phase_mu(self, phase: TInt32):
"""Set DDS phase (machine units).
:param phase: DDS phase in machine units.
"""
rtio_output(now_mu(), self.channel_base + 2, 0, phase)

@kernel
def set_phase(self, phase=0):
def set_phase(self, phase: TFloat):
"""Set DDS phase.
:param phase: DDS phase relative in turns.
3 changes: 2 additions & 1 deletion artiq/gateware/dsp/sawg.py
Original file line number Diff line number Diff line change
@@ -10,10 +10,11 @@ class DDSFast(Module):
def __init__(self, width, parallelism=4):
a_width = width
p_width = width
f_width = 3*width
f_width = 2*width

self.o = [Signal((width, True)) for i in range(parallelism)]

self.width = width
self.parallelism = parallelism
self.latency = 1 # will be accumulated

19 changes: 19 additions & 0 deletions artiq/gateware/dsp/tools.py
Original file line number Diff line number Diff line change
@@ -29,3 +29,22 @@ def xfer(dut, **kw):

def eqh(a, b):
return a[-len(b):].eq(b[-len(a):])


def szip(*iters):
active = {it: None for it in iters}
while active:
for it in list(active):
while True:
try:
val = it.send(active[it])
except StopIteration:
del active[it]
break
if val is None:
break
else:
active[it] = (yield val)
val = (yield None)
for it in active:
active[it] = val
10 changes: 6 additions & 4 deletions artiq/gateware/rtio/phy/sawg.py
Original file line number Diff line number Diff line change
@@ -8,13 +8,14 @@

_Phy = namedtuple("Phy", "rtlink probes overrides")

DDSFast_rtio = ClockDomainsRenamer("rio_phy")(DDSFast)

class Channel(Module):

class Channel(DDSFast_rtio):
def __init__(self, *args, **kwargs):
self.submodules._ll = ClockDomainsRenamer("rio_phy")(
DDSFast(*args, **kwargs))
DDSFast_rtio.__init__(self, *args, **kwargs)
self.phys = []
for i in self._ll.i:
for i in self.i:
rl = rtlink.Interface(rtlink.OInterface(
min(64, len(i.payload))))
self.comb += [
@@ -24,3 +25,4 @@ def __init__(self, *args, **kwargs):
]
# no probes, overrides
self.phys.append(_Phy(rl, [], []))
self.phys_names = dict(zip("afp", self.phys))
2 changes: 1 addition & 1 deletion artiq/gateware/targets/kc705.py
Original file line number Diff line number Diff line change
@@ -424,7 +424,7 @@ def __init__(self, cpu_type="or1k", **kwargs):
# TODO: dummy, hookup jesd204b phy here
o = Signal((16, True))
for ch in sawgs: # gather up dangling outputs
for oi in ch._ll.o:
for oi in ch.o:
o0, o = o, Signal.like(o)
self.sync += o.eq(o0 + oi)
self.sync.rio_phy += platform.request("dds").d.eq(o)
Empty file added artiq/test/gateware/__init__.py
Empty file.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -11,9 +11,9 @@ def _test_gen_dds(dut, o):
yield from xfer(dut,
a=dict(a=10),
p=dict(p=0),
f=dict(f=1 << 16),
f=dict(f=1 << 8),
)
for i in range(256):
for i in range(256//dut.parallelism):
yield
o.append((yield from [(yield _) for _ in dut.o]))

61 changes: 61 additions & 0 deletions artiq/test/gateware/test_sawg_phy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import numpy as np

from migen import *
from migen.fhdl.verilog import convert

from artiq.gateware.rtio.phy.sawg import Channel
from artiq.gateware.dsp.tools import xfer, szip


def rtio_xfer(dut, **kwargs):
yield from szip(*(
xfer(dut.phys_names[k].rtlink, o={"data": v})
for k, v in kwargs.items()))


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)


def gen_log(dut, o, n):
for i in range(3 + dut.latency):
yield
for i in range(n):
yield
o.append((yield from [(yield _) for _ in dut.o]))


def _test_channel():
width = 16
dut = ClockDomainsRenamer({"rio_phy": "sys"})(
Channel(width=width, parallelism=4)
)

if False:
print(convert(dut))
return

o = []
run_simulation(
dut,
[gen_rtio(dut), gen_log(dut, o, 256 * 2)],
) # vcd_name="dds.vcd")
o = np.array(o)/(1 << (width - 1))
o = o.ravel()
np.savez_compressed("dds.npz", o=o)

import matplotlib.pyplot as plt
fig, ax = plt.subplots(2)
ax[0].step(np.arange(o.size), o)
ax[1].psd(o, 1 << 10, Fs=1, noverlap=1 << 9, scale_by_freq=False)
fig.savefig("dds.pdf")
plt.show()


if __name__ == "__main__":
_test_channel()