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: 4c10182c9fcc
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: 9795e83bfca3
Choose a head ref
  • 7 commits
  • 5 files changed
  • 1 contributor

Commits on Apr 15, 2015

  1. pipistrello: basesoc, cleanup

    jordens committed Apr 15, 2015

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6217cf5 View commit details
  2. pipistrello: timing report

    jordens committed Apr 15, 2015
    Copy the full SHA
    066adbd View commit details
  3. test/pdq2: don't write vcd

    jordens committed Apr 15, 2015
    Copy the full SHA
    bc1acef View commit details
  4. pdq2: refactor program_frame(), cleanup test, stall correctly

    Once the Sequencer ack's a line, the Parser starts preparing the
    next one. This includes jumping through the frame table if necessary.
    To stall the Parser while the Sequencer executes the last line of a
    frame and to ensure that the frame select lines can be set up and their
    sampling is synchronized to a trigger, we add a triggered stall line
    at the end of the frame.
    
    When that line is triggered the Parser jumps through the table and starts
    parsing the first line of the next frame. We let the duration of this
    last stall line be 10 cycles (200ns@50MHz) to be able to distinguish this
    sampling of the frame select lines from the triggering of the first line
    in the next frame.
    
    frame           f
    parser     n     f 0
    stb        __---________---___
    trigger    ___----_______----_
    ack        ____-__________-___
    sequencer  n-1 n          0
    jordens committed Apr 15, 2015
    Copy the full SHA
    6a0e97f View commit details
  5. Copy the full SHA
    70916aa View commit details
  6. ppro: ignore all async paths

    jordens committed Apr 15, 2015
    Copy the full SHA
    9e726d7 View commit details
  7. Copy the full SHA
    9795e83 View commit details
Showing with 99 additions and 53 deletions.
  1. +25 −20 artiq/devices/pdq2/driver.py
  2. +4 −4 artiq/test/pdq2.py
  3. +32 −11 artiq/wavesynth/coefficients.py
  4. +29 −14 soc/targets/artiq_pipistrello.py
  5. +9 −4 soc/targets/artiq_ppro.py
45 changes: 25 additions & 20 deletions artiq/devices/pdq2/driver.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Robert Jordens <jordens@gmail.com>, 2012-2015

from math import log2, sqrt
from math import log, sqrt
import logging
import struct

@@ -95,7 +95,6 @@ def clear(self):
del self.segments[:]

def new_segment(self):
# assert len(self.segments) < self.num_frames
segment = Segment()
self.segments.append(segment)
return segment
@@ -186,25 +185,31 @@ def write_segment(self, channel, segment):
s = self.channels[channel].segments[segment]
self.write_mem(channel, s.data, s.adr)

def program_frame(self, frame_data):
segments = [c.new_segment() for c in self.channels]
for i, line in enumerate(frame_data): # segments are concatenated
dac_divider = line.get("dac_divider", 1)
shift = int(log(dac_divider, 2))
if 2**shift != dac_divider:
raise ValueError("only power-of-two dac_dividers supported")
duration = line["duration"]
trigger = line.get("trigger", False)
for segment, data in zip(segments, line["channel_data"]):
if len(data) != 1:
raise ValueError("only one target per channel and line "
"supported")
for target, target_data in data.items():
getattr(segment, target)(
shift=shift, duration=duration, trigger=trigger,
**target_data)
# append an empty line to stall the memory reader before jumping
# through the frame table
for segment in segments:
segment.line(typ=3, data=b"", trigger=True, duration=10)
return segments

def program(self, program):
self.clear_all()
for frame_data in program:
segments = [c.new_segment() for c in self.channels]
for i, line in enumerate(frame_data): # segments are concatenated
dac_divider = line.get("dac_divider", 1)
shift = int(log2(dac_divider))
assert 2**shift == dac_divider
duration = line["duration"]
trigger = line.get("trigger", False)
if i == 0:
assert trigger
trigger = False # use wait on the last line
eof = i == len(frame_data) - 1
for segment, data in zip(segments, line.get("channel_data")):
assert len(data) == 1
for target, target_data in data.items():
getattr(segment, target)(
shift=shift, duration=duration,
trigger=trigger, wait=eof, jump=eof,
**target_data)
self.program_frame(frame_data)
self.write_all()
8 changes: 4 additions & 4 deletions artiq/test/pdq2.py
Original file line number Diff line number Diff line change
@@ -46,8 +46,8 @@ def run_gateware(self):

buf = self.test_cmd_program()
tb = Pdq2Sim(buf)
tb.ctrl_pads.trigger.reset = 0
run_simulation(tb, vcd_name="pdq2.vcd", ncycles=len(buf) + 250)
tb.ctrl_pads.trigger.reset = 1
run_simulation(tb, ncycles=len(buf) + 250)
delays = 7, 10, 30
y = list(zip(*tb.outputs[len(buf) + 130:]))
y = list(zip(*(yi[di:] for yi, di in zip(y, delays))))
@@ -65,8 +65,8 @@ def test_run_compare(self):
yij = yij*20./2**16
if yij > 10:
yij -= 20
self.assertAlmostEqual(yij, yij_ref, 2,
"foo t={}, c={}".format(i, j))
self.assertAlmostEqual(yij, yij_ref, 2, "disagreement at "
"t={}, c={}".format(i, j))

@unittest.skipUnless(pdq2_gateware, "no pdq2 gateware")
@unittest.skip("manual/visual test")
43 changes: 32 additions & 11 deletions artiq/wavesynth/coefficients.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import numpy as np
from scipy.interpolate import splrep, splev
from scipy.interpolate import splrep, splev, spalde


class CoefficientSource:
def get_times(self, t, speed, clock):
pass

def get_coefficients(self, t, speed):
pass

def get_program(self, dt, u):
pass


def _round_times(times, sample_times=None):
@@ -23,16 +34,6 @@ def _interpolate(time, data, sample_times, order=3):
return coeffs


def discrete_compensate(c):
l = len(c)
if l > 2:
c[1] += c[2]/2.
if l > 3:
c[1] += c[3]/6.
c[2] += c[3]
if l > 4:
raise ValueError("only third-order splines supported")


def _zip_program(times, channels, target):
for tc in zip(times, *channels):
@@ -54,3 +55,23 @@ def interpolate_channels(times, data, sample_times=None, **kwargs):
channel_coeff = [_interpolate(sample_times, i, **kwargs) for i in data.T]
return _zip_program(duration, np.array(channel_coeff))
# v = np.clip(v/self.max_out, -1, 1)
#
#

def discrete_compensate(c):
"""Compensate spline coefficients for discrete accumulators
Given continuous time b-spline coefficients, this function
compensates for the effect of discrete time steps in the
target devices.
The compensation is performed in-place.
"""
l = len(c)
if l > 2:
c[1] += c[2]/2.
if l > 3:
c[1] += c[3]/6.
c[2] += c[3]
if l > 4:
raise ValueError("only third-order splines supported")
43 changes: 29 additions & 14 deletions soc/targets/artiq_pipistrello.py
Original file line number Diff line number Diff line change
@@ -39,11 +39,16 @@ def __init__(self, platform):
o_O=self.cd_rtio.clk)

platform.add_platform_command("""
NET "{rtio_clk}" TNM_NET = "GRPrtio_clk";
NET "{int_clk}" TNM_NET = "GRPint_clk";
NET "{ext_clk}" TNM_NET = "GRPext_clk";
NET "sys_clk" TNM_NET = "GRPsys_clk";
TIMESPEC "TSfix_ise1" = FROM "GRPrtio_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSfix_ise2" = FROM "GRPsys_clk" TO "GRPrtio_clk" TIG;
""", rtio_clk=rtio_internal_clk)
TIMESPEC "TSfix_ise1" = FROM "GRPint_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSfix_ise2" = FROM "GRPsys_clk" TO "GRPint_clk" TIG;
TIMESPEC "TSfix_ise3" = FROM "GRPext_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSfix_ise4" = FROM "GRPsys_clk" TO "GRPext_clk" TIG;
TIMESPEC "TSfix_ise5" = FROM "GRPext_clk" TO "GRPint_clk" TIG;
TIMESPEC "TSfix_ise6" = FROM "GRPint_clk" TO "GRPext_clk" TIG;
""", int_clk=rtio_internal_clk, ext_clk=rtio_external_clk)


class _Peripherals(BaseSoC):
@@ -53,13 +58,16 @@ class _Peripherals(BaseSoC):
}
csr_map.update(BaseSoC.csr_map)
mem_map = {
"rtio": 0x20000000, # (shadow @0xa0000000)
"dds": 0x50000000, # (shadow @0xd0000000)
"rtio": 0x20000000, # (shadow @0xa0000000)
"dds": 0x50000000, # (shadow @0xd0000000)
}
mem_map.update(BaseSoC.mem_map)

def __init__(self, platform, cpu_type="or1k", **kwargs):
BaseSoC.__init__(self, platform, cpu_type=cpu_type, **kwargs)
platform.toolchain.ise_commands += """
trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf
"""
platform.add_extension(nist_qc1.papilio_adapter_io)

self.submodules.leds = gpio.GPIOOut(Cat(
@@ -120,18 +128,20 @@ def __init__(self, platform, **kwargs):
rtio_csrs = self.rtio.get_csrs()
self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
self.add_wb_slave(mem_decoder(self.mem_map["rtio"]), self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] + 0x80000000, 32, rtio_csrs)
self.add_csr_region("rtio", self.mem_map["rtio"] + 0x80000000, 32,
rtio_csrs)

self.add_wb_slave(mem_decoder(self.mem_map["dds"]), self.dds.bus)
self.add_memory_region("dds", self.mem_map["dds"] + 0x80000000, 64*4)


class AMP(_Peripherals):
csr_map = {
"kernel_cpu": 14
}
csr_map.update(_Peripherals.csr_map)
mem_map = {
"mailbox": 0x70000000 # (shadow @0xf0000000)
"mailbox": 0x70000000 # (shadow @0xf0000000)
}
mem_map.update(_Peripherals.mem_map)

@@ -141,16 +151,21 @@ def __init__(self, platform, *args, **kwargs):
self.submodules.kernel_cpu = amp.KernelCPU(
platform, self.sdram.crossbar.get_master())
self.submodules.mailbox = amp.Mailbox()
self.add_wb_slave(mem_decoder(self.mem_map["mailbox"]), self.mailbox.i1)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["mailbox"]), self.mailbox.i2)
self.add_wb_slave(mem_decoder(self.mem_map["mailbox"]),
self.mailbox.i1)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["mailbox"]),
self.mailbox.i2)

rtio_csrs = self.rtio.get_csrs()
self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]), self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] + 0x80000000, 32, rtio_csrs)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] + 0x80000000, 32,
rtio_csrs)

self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["dds"]), self.dds.bus)
self.kernel_cpu.add_memory_region("dds", self.mem_map["dds"] + 0x80000000, 64*4)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["dds"]),
self.dds.bus)
self.add_memory_region("dds", self.mem_map["dds"] + 0x80000000, 64*4)


default_subtarget = UP
13 changes: 9 additions & 4 deletions soc/targets/artiq_ppro.py
Original file line number Diff line number Diff line change
@@ -48,11 +48,16 @@ def __init__(self, platform):
o_O=self.cd_rtio.clk)

platform.add_platform_command("""
NET "{rtio_clk}" TNM_NET = "GRPrtio_clk";
NET "{int_clk}" TNM_NET = "GRPint_clk";
NET "{ext_clk}" TNM_NET = "GRPext_clk";
NET "sys_clk" TNM_NET = "GRPsys_clk";
TIMESPEC "TSfix_ise1" = FROM "GRPrtio_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSfix_ise2" = FROM "GRPsys_clk" TO "GRPrtio_clk" TIG;
""", rtio_clk=rtio_internal_clk)
TIMESPEC "TSfix_ise1" = FROM "GRPint_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSfix_ise2" = FROM "GRPsys_clk" TO "GRPint_clk" TIG;
TIMESPEC "TSfix_ise3" = FROM "GRPext_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSfix_ise4" = FROM "GRPsys_clk" TO "GRPext_clk" TIG;
TIMESPEC "TSfix_ise5" = FROM "GRPext_clk" TO "GRPint_clk" TIG;
TIMESPEC "TSfix_ise6" = FROM "GRPint_clk" TO "GRPext_clk" TIG;
""", int_clk=rtio_internal_clk, ext_clk=rtio_external_clk)


class UP(BaseSoC):