From be693bc8a95a7311e8bab5780248afb5fbf404c5 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Tue, 13 Feb 2018 14:21:05 +0100 Subject: [PATCH] opticlock: examples --- artiq/examples/kasli/device_db.py | 306 ++++++++++++++++++++++ artiq/examples/kasli/idle_kernel.py | 21 ++ artiq/examples/kasli/repository/urukul.py | 83 ++++++ artiq/gateware/targets/kasli.py | 14 +- 4 files changed, 419 insertions(+), 5 deletions(-) create mode 100644 artiq/examples/kasli/device_db.py create mode 100644 artiq/examples/kasli/idle_kernel.py create mode 100644 artiq/examples/kasli/repository/urukul.py diff --git a/artiq/examples/kasli/device_db.py b/artiq/examples/kasli/device_db.py new file mode 100644 index 000000000..418a4119a --- /dev/null +++ b/artiq/examples/kasli/device_db.py @@ -0,0 +1,306 @@ +# This is an example device database that needs to be adapted to your setup. +# The RTIO channel numbers here are for OPTICLOCK on KASLI. +# The list of devices here is not exhaustive. + +core_addr = "vettel.ber.quartiq.de" + +device_db = { + "core": { + "type": "local", + "module": "artiq.coredevice.core", + "class": "Core", + "arguments": {"host": core_addr, "ref_period": 1e-9} + }, + "core_log": { + "type": "controller", + "host": "::1", + "port": 1068, + "command": "aqctl_corelog -p {port} --bind {bind} " + core_addr + }, + "core_cache": { + "type": "local", + "module": "artiq.coredevice.cache", + "class": "CoreCache" + }, + "core_dma": { + "type": "local", + "module": "artiq.coredevice.dma", + "class": "CoreDMA" + }, + + "i2c_switch0": { + "type": "local", + "module": "artiq.coredevice.i2c", + "class": "PCA9548", + "arguments": {"address": 0x70} + }, + "i2c_switch1": { + "type": "local", + "module": "artiq.coredevice.i2c", + "class": "PCA9548", + "arguments": {"address": 0x71} + }, + + "ttl0": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLInOut", + "arguments": {"channel": 0}, + }, + "ttl1": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLInOut", + "arguments": {"channel": 1}, + }, + "ttl2": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLInOut", + "arguments": {"channel": 2}, + }, + "ttl3": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLInOut", + "arguments": {"channel": 3}, + }, + + "ttl4": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 4}, + }, + "ttl5": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 5}, + }, + "ttl6": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 6}, + }, + "ttl7": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 7}, + }, + "ttl8": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 8}, + }, + "ttl9": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 9}, + }, + "ttl10": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 10}, + }, + "ttl11": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 11}, + }, + "ttl12": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 12}, + }, + "ttl13": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 13}, + }, + "ttl14": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 14}, + }, + "ttl15": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 15}, + }, + "ttl16": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 16}, + }, + "ttl17": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 17}, + }, + "ttl18": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 18}, + }, + "ttl19": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 19}, + }, + "ttl20": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 20}, + }, + "ttl21": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 21}, + }, + "ttl22": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 22}, + }, + "ttl23": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 23}, + }, + + "spi_novogorny0": { + "type": "local", + "module": "artiq.coredevice.spi", + "class": "SPIMaster", + "arguments": {"channel": 24} + }, + "ttl_novogorny0_conv": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 25} + }, + + "spi_urukul0": { + "type": "local", + "module": "artiq.coredevice.spi", + "class": "SPIMaster", + "arguments": {"channel": 26} + }, + "ttl_urukul0_io_update": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 27} + }, + "ttl_urukul0_sw0": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 28} + }, + "ttl_urukul0_sw1": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 29} + }, + "ttl_urukul0_sw2": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 30} + }, + "ttl_urukul0_sw3": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 31} + }, + "urukul0_cpld": { + "type": "local", + "module": "artiq.coredevice.urukul", + "class": "CPLD", + "arguments": { + "spi_device": "spi_urukul0", + "io_update_device": "ttl_urukul0_io_update", + "refclk": 100e6 + } + }, + "urukul0_ch0": { + "type": "local", + "module": "artiq.coredevice.ad9912", + "class": "AD9912", + "arguments": { + "pll_n": 10, + "chip_select": 4, + "cpld_device": "urukul0_cpld", + "sw_device": "ttl_urukul0_sw0" + } + }, + "urukul0_ch1": { + "type": "local", + "module": "artiq.coredevice.ad9912", + "class": "AD9912", + "arguments": { + "pll_n": 10, + "chip_select": 5, + "cpld_device": "urukul0_cpld", + "sw_device": "ttl_urukul0_sw1" + } + }, + "urukul0_ch2": { + "type": "local", + "module": "artiq.coredevice.ad9912", + "class": "AD9912", + "arguments": { + "pll_n": 10, + "chip_select": 6, + "cpld_device": "urukul0_cpld", + "sw_device": "ttl_urukul0_sw2" + } + }, + "urukul0_ch3": { + "type": "local", + "module": "artiq.coredevice.ad9912", + "class": "AD9912", + "arguments": { + "pll_n": 10, + "chip_select": 7, + "cpld_device": "urukul0_cpld", + "sw_device": "ttl_urukul0_sw3" + } + }, + + "led0": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 32} + }, + "led1": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLOut", + "arguments": {"channel": 33} + } +} diff --git a/artiq/examples/kasli/idle_kernel.py b/artiq/examples/kasli/idle_kernel.py new file mode 100644 index 000000000..05184f731 --- /dev/null +++ b/artiq/examples/kasli/idle_kernel.py @@ -0,0 +1,21 @@ +from artiq.experiment import * + + +class IdleKernel(EnvExperiment): + def build(self): + self.setattr_device("core") + self.setattr_device("led0") + + @kernel + def run(self): + start_time = now_mu() + self.core.seconds_to_mu(500*ms) + while self.core.get_rtio_counter_mu() < start_time: + pass + self.core.reset() + while True: + self.led0.pulse(250*ms) + delay(125*ms) + self.led0.pulse(125*ms) + delay(125*ms) + self.led0.pulse(125*ms) + delay(250*ms) diff --git a/artiq/examples/kasli/repository/urukul.py b/artiq/examples/kasli/repository/urukul.py new file mode 100644 index 000000000..3fc40a5fc --- /dev/null +++ b/artiq/examples/kasli/repository/urukul.py @@ -0,0 +1,83 @@ +from artiq.experiment import * + + +class UrukulTest(EnvExperiment): + def build(self): + self.setattr_device("core") + self.setattr_device("urukul0_cpld") + self.setattr_device("urukul0_ch0") + self.setattr_device("urukul0_ch1") + self.setattr_device("urukul0_ch2") + self.setattr_device("urukul0_ch3") + self.setattr_device("led0") + + def p(self, f, *a): + print(f % a) + + @kernel + def run(self): + self.core.reset() + self.led0.on() + delay(5*ms) + self.led0.off() + + self.urukul0_cpld.init(clk_sel=0) + self.urukul0_ch0.init() + self.urukul0_ch1.init() + self.urukul0_ch2.init() + self.urukul0_ch3.init() + + delay(1000*us) + self.urukul0_ch0.set(100*MHz) + self.urukul0_ch0.sw.on() + self.urukul0_ch0.set_att(10.) + + delay(1000*us) + self.urukul0_ch1.set(10*MHz, 0.5) + self.urukul0_ch1.sw.on() + self.urukul0_ch1.set_att(0.) + + delay(1000*us) + self.urukul0_ch2.set(400*MHz) + self.urukul0_ch2.sw.on() + self.urukul0_ch2.set_att(0.) + + delay(1000*us) + self.urukul0_ch3.set(1*MHz) + self.urukul0_ch3.sw.on() + self.urukul0_ch3.set_att(20.) + + i = 0 + j = 0 + while True: + delay(13*us) + self.urukul0_ch0.write32(0x07, i) + self.urukul0_cpld.io_update.pulse(10*ns) + k = self.urukul0_ch0.read32(0x07) + delay(100*us) + if k != i: + #print(i) + #print(k) + #if j > 20: + # return + j += 1 + #delay(20*ms) + i += 1 + + while True: + self.urukul0_ch0.sw.pulse(5*ms) + delay(5*ms) + + while False: + self.led0.pulse(.5*s) + delay(.5*s) + + @kernel + def test_att_noise(self, n=1024): + bus = self.urukul0_cpld.bus + bus.set_config_mu(_SPI_CONFIG, _SPIT_ATT_WR, _SPIT_ATT_RD) + bus.set_xfer(CS_ATT, 32, 0) + for i in range(n): + delay(5*us) + bus.write(self.att_reg) + bus.set_config_mu(_SPI_CONFIG, _SPIT_DDS_WR, _SPIT_DDS_RD) diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index c38fd3355..7684a8f1b 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -8,6 +8,7 @@ from migen.genlib.cdc import MultiReg from migen.build.generic_platform import * from migen.build.xilinx.vivado import XilinxVivadoToolchain from migen.build.xilinx.ise import XilinxISEToolchain +from migen.genlib.io import DifferentialOutput from misoc.interconnect.csr import * from misoc.cores import gpio @@ -231,7 +232,7 @@ class Opticlock(_StandaloneBase): platform.add_extension(_dio("eem1")) platform.add_extension(_dio("eem2")) platform.add_extension(_novogorny("eem3")) - platform.add_extension(_urukul("eem4", "eem5")) + platform.add_extension(_urukul("eem5", "eem4")) # EEM clock fan-out from Si5324, not MMCX self.comb += platform.request("clk_sel").eq(1) @@ -259,13 +260,16 @@ class Opticlock(_StandaloneBase): self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy)) - phy = spi.SPIMaster(self.platform.request("eem4_spi_p"), - self.platform.request("eem4_spi_n")) + phy = spi.SPIMaster(self.platform.request("eem5_spi_p"), + self.platform.request("eem5_spi_n")) self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) - for signal in "io_update dds_reset sw0 sw1 sw2 sw3".split(): - pads = platform.request("eem4_{}".format(signal)) + pads = platform.request("eem5_dds_reset") + self.specials += DifferentialOutput(0, pads.p, pads.n) + + for signal in "io_update sw0 sw1 sw2 sw3".split(): + pads = platform.request("eem5_{}".format(signal)) phy = ttl_serdes_7series.Output_8X(pads.p, pads.n) self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy))