mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-25 03:08:27 +08:00
Merge branch 'master' of https://github.com/m-labs/artiq
This commit is contained in:
commit
5ace0f8e7a
@ -17,7 +17,7 @@ before_install:
|
||||
- pip install coveralls
|
||||
install:
|
||||
- conda build conda/artiq
|
||||
- conda install $HOME/miniconda/conda-bld/linux-64/artiq-*.tar.bz2
|
||||
- conda install artiq --use-local
|
||||
script:
|
||||
- coverage run --source=artiq setup.py test
|
||||
- make -C doc/manual html
|
||||
|
@ -1,4 +1,2 @@
|
||||
from artiq.language.core import *
|
||||
from artiq.language.experiment import Experiment
|
||||
from artiq.language.db import *
|
||||
from artiq.language.units import *
|
||||
from artiq import language
|
||||
from artiq.language import *
|
||||
|
@ -18,9 +18,11 @@ def get_argparser():
|
||||
help="USB serial number of the device. "
|
||||
"The serial number is written on a sticker under "
|
||||
"the device, you should write for example "
|
||||
"-d \"SN:03461\". You must prepend enough 0 for it "
|
||||
"to be 5 digits."
|
||||
" Omit for simulation mode.")
|
||||
"-d \"SN:03461\". You must prepend enough 0s for "
|
||||
"it to be 5 digits. If omitted, the first "
|
||||
"available device will be used.")
|
||||
parser.add_argument("--simulation", action="store_true",
|
||||
help="Put the driver in simulation mode.")
|
||||
verbosity_args(parser)
|
||||
return parser
|
||||
|
||||
@ -28,7 +30,7 @@ def get_argparser():
|
||||
def main():
|
||||
args = get_argparser().parse_args()
|
||||
init_logger(args)
|
||||
if args.device is None:
|
||||
if args.simulation:
|
||||
lda = Ldasim()
|
||||
else:
|
||||
lda = Lda(args.device, args.product)
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from artiq.devices.novatech409b.driver import Novatech409B
|
||||
from artiq.protocols.pc_rpc import simple_server_loop
|
||||
@ -19,7 +20,10 @@ def get_argparser():
|
||||
simple_network_args(parser, 3254)
|
||||
parser.add_argument(
|
||||
"-d", "--device", default=None,
|
||||
help="serial port. Omit for simulation mode.")
|
||||
help="serial port.")
|
||||
parser.add_argument(
|
||||
"--simulation", action="store_true",
|
||||
help="Put the driver in simulation mode, even if --device is used.")
|
||||
verbosity_args(parser)
|
||||
return parser
|
||||
|
||||
@ -28,7 +32,12 @@ def main():
|
||||
args = get_argparser().parse_args()
|
||||
init_logger(args)
|
||||
|
||||
dev = Novatech409B(args.device)
|
||||
if not args.simulation and args.device is None:
|
||||
print("You need to specify either --simulation or -d/--device "
|
||||
"argument. Use --help for more information.")
|
||||
sys.exit(1)
|
||||
|
||||
dev = Novatech409B(args.device if not args.simulation else None)
|
||||
try:
|
||||
simple_server_loop(
|
||||
{"novatech409b": dev}, args.bind, args.port)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from artiq.devices.pdq2.driver import Pdq2
|
||||
from artiq.protocols.pc_rpc import simple_server_loop
|
||||
@ -12,7 +13,10 @@ def get_argparser():
|
||||
simple_network_args(parser, 3252)
|
||||
parser.add_argument(
|
||||
"-d", "--device", default=None,
|
||||
help="serial port. Omit for simulation mode.")
|
||||
help="serial port.")
|
||||
parser.add_argument(
|
||||
"--simulation", action="store_true",
|
||||
help="Put the driver in simulation mode, even if --device is used.")
|
||||
parser.add_argument(
|
||||
"--dump", default="pdq2_dump.bin",
|
||||
help="file to dump pdq2 data into, for later simulation")
|
||||
@ -24,7 +28,13 @@ def main():
|
||||
args = get_argparser().parse_args()
|
||||
init_logger(args)
|
||||
port = None
|
||||
if args.device is None:
|
||||
|
||||
if not args.simulation and args.device is None:
|
||||
print("You need to specify either --simulation or -d/--device "
|
||||
"argument. Use --help for more information.")
|
||||
sys.exit(1)
|
||||
|
||||
if args.simulation:
|
||||
port = open(args.dump, "wb")
|
||||
dev = Pdq2(url=args.device, dev=port)
|
||||
try:
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Yann Sionneau <ys@m-labs.hk>, 2015
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from artiq.protocols.pc_rpc import simple_server_loop
|
||||
from artiq.devices.pxi6733.driver import DAQmx, DAQmxSim
|
||||
@ -12,10 +13,12 @@ def get_argparser():
|
||||
parser = argparse.ArgumentParser(description="NI PXI 6733 controller")
|
||||
simple_network_args(parser, 3256)
|
||||
parser.add_argument("-C", "--channels", default=None,
|
||||
help="List of channels (e.g. Dev1/ao0, Dev1/ao1:3)."
|
||||
" Omit for simulation mode.")
|
||||
help="List of channels (e.g. Dev1/ao0, Dev1/ao1:3).")
|
||||
parser.add_argument("-c", "--clock", default="PFI5",
|
||||
help="Input clock pin name (default: PFI5)")
|
||||
parser.add_argument("--simulation", action='store_true',
|
||||
help="Put the driver in simulation mode, even if "
|
||||
"--channels is used.")
|
||||
verbosity_args(parser)
|
||||
return parser
|
||||
|
||||
@ -24,7 +27,12 @@ def main():
|
||||
args = get_argparser().parse_args()
|
||||
init_logger(args)
|
||||
|
||||
if args.channels is None:
|
||||
if not args.simulation and args.channels is None:
|
||||
print("You need to specify either --simulation or -C/--channels "
|
||||
"argument. Use --help for more information.")
|
||||
sys.exit(1)
|
||||
|
||||
if args.simulation:
|
||||
daq = DAQmxSim()
|
||||
else:
|
||||
daq = DAQmx(args.channels,
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from artiq.devices.thorlabs_tcube.driver import Tdc, Tpz, TdcSim, TpzSim
|
||||
from artiq.protocols.pc_rpc import simple_server_loop
|
||||
@ -14,8 +15,10 @@ def get_argparser():
|
||||
choices=["TDC001", "TPZ001"])
|
||||
parser.add_argument("-d", "--device", default=None,
|
||||
help="serial device. See documentation for how to "
|
||||
"specify a USB Serial Number. Omit for simulation "
|
||||
"mode.")
|
||||
"specify a USB Serial Number.")
|
||||
parser.add_argument("--simulation", action="store_true",
|
||||
help="Put the driver in simulation mode, even if "
|
||||
"--device is used.")
|
||||
simple_network_args(parser, 3255)
|
||||
verbosity_args(parser)
|
||||
return parser
|
||||
@ -25,7 +28,12 @@ def main():
|
||||
args = get_argparser().parse_args()
|
||||
init_logger(args)
|
||||
|
||||
if args.device is None:
|
||||
if not args.simulation and args.device is None:
|
||||
print("You need to specify either --simulation or -d/--device "
|
||||
"argument. Use --help for more information.")
|
||||
sys.exit(1)
|
||||
|
||||
if args.simulation:
|
||||
if args.product == "TDC001":
|
||||
dev = TdcSim()
|
||||
elif args.product == "TPZ001":
|
||||
|
@ -4,10 +4,22 @@ from mibuild.generic_platform import *
|
||||
papilio_adapter_io = [
|
||||
("ext_led", 0, Pins("B:7"), IOStandard("LVTTL")),
|
||||
|
||||
# to feed the 125 MHz clock (preferrably from DDS SYNC_CLK)
|
||||
# to the FPGA, use the xtrig pair.
|
||||
#
|
||||
# on papiliopro-adapter, xtrig (C:12) is connected to a GCLK
|
||||
#
|
||||
# on pipistrello, C:15 is the only GCLK in proximity, used as a button
|
||||
# input, BTN2/PMT2 in papiliopro-adapter
|
||||
# either improve the DDS box to feed 125MHz into the PMT2 pair, or:
|
||||
#
|
||||
# * disconnect C:15 from its periphery on the adapter board
|
||||
# * bridge C:15 to the xtrig output of the transciever
|
||||
# * optionally, disconnect C:12 from its periphery
|
||||
("xtrig", 0, Pins("C:12"), IOStandard("LVTTL")),
|
||||
("pmt", 0, Pins("C:13"), IOStandard("LVTTL")),
|
||||
("pmt", 1, Pins("C:14"), IOStandard("LVTTL")),
|
||||
("xtrig", 0, Pins("C:12"), IOStandard("LVTTL")),
|
||||
("dds_clock", 0, Pins("C:15"), IOStandard("LVTTL")), # PMT2
|
||||
("pmt", 2, Pins("C:15"), IOStandard("LVTTL")), # rarely equipped
|
||||
|
||||
("ttl", 0, Pins("C:11"), IOStandard("LVTTL")),
|
||||
("ttl", 1, Pins("C:10"), IOStandard("LVTTL")),
|
||||
|
@ -0,0 +1,4 @@
|
||||
from artiq.language.core import *
|
||||
from artiq.language.experiment import Experiment
|
||||
from artiq.language.db import *
|
||||
from artiq.language.units import *
|
120
artiq/test/coredevice.py
Normal file
120
artiq/test/coredevice.py
Normal file
@ -0,0 +1,120 @@
|
||||
from math import sqrt
|
||||
|
||||
from artiq.language import *
|
||||
from artiq.test.hardware_testbench import ExperimentCase
|
||||
from artiq.coredevice.runtime_exceptions import RTIOUnderflow
|
||||
|
||||
|
||||
class RTT(Experiment, AutoDB):
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
ttl_inout = Device()
|
||||
rtt = Result()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.ttl_inout.output()
|
||||
delay(1*us)
|
||||
with parallel:
|
||||
self.ttl_inout.gate_rising(2*us)
|
||||
with sequential:
|
||||
delay(1*us)
|
||||
t0 = now()
|
||||
self.ttl_inout.pulse(1*us)
|
||||
self.rtt = self.ttl_inout.timestamp() - t0
|
||||
|
||||
|
||||
class Loopback(Experiment, AutoDB):
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
loop_in = Device()
|
||||
loop_out = Device()
|
||||
rtt = Result()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
with parallel:
|
||||
self.loop_in.gate_rising(2*us)
|
||||
with sequential:
|
||||
delay(1*us)
|
||||
t0 = now()
|
||||
self.loop_out.pulse(1*us)
|
||||
self.rtt = self.loop_in.timestamp() - t0
|
||||
|
||||
|
||||
class PulseRate(Experiment, AutoDB):
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
loop_out = Device()
|
||||
pulse_rate = Result()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
dt = time_to_cycles(1000*ns)
|
||||
while True:
|
||||
try:
|
||||
for i in range(1000):
|
||||
self.loop_out.pulse(cycles_to_time(dt))
|
||||
delay(cycles_to_time(dt))
|
||||
except RTIOUnderflow:
|
||||
dt += 1
|
||||
self.core.break_realtime()
|
||||
else:
|
||||
self.pulse_rate = cycles_to_time(2*dt)
|
||||
break
|
||||
|
||||
|
||||
class CoredeviceTest(ExperimentCase):
|
||||
def test_rtt(self):
|
||||
rtt = self.execute(RTT)["rtt"]
|
||||
print(rtt)
|
||||
self.assertGreater(rtt, 0*ns)
|
||||
self.assertLess(rtt, 100*ns)
|
||||
|
||||
def test_loopback(self):
|
||||
rtt = self.execute(Loopback)["rtt"]
|
||||
print(rtt)
|
||||
self.assertGreater(rtt, 0*ns)
|
||||
self.assertLess(rtt, 40*ns)
|
||||
|
||||
def test_pulse_rate(self):
|
||||
rate = self.execute(PulseRate)["pulse_rate"]
|
||||
print(rate)
|
||||
self.assertGreater(rate, 100*ns)
|
||||
self.assertLess(rate, 2500*ns)
|
||||
|
||||
|
||||
class RPCTiming(Experiment, AutoDB):
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
repeats = Argument(100)
|
||||
rpc_time_mean = Result()
|
||||
rpc_time_stddev = Result()
|
||||
|
||||
def nop(self, x):
|
||||
pass
|
||||
|
||||
@kernel
|
||||
def bench(self):
|
||||
self.ts = [0. for _ in range(self.repeats)]
|
||||
for i in range(self.repeats):
|
||||
t1 = self.core.get_rtio_time()
|
||||
self.nop(1)
|
||||
t2 = self.core.get_rtio_time()
|
||||
self.ts[i] = t2 - t1
|
||||
|
||||
def run(self):
|
||||
self.bench()
|
||||
mean = sum(self.ts)/self.repeats
|
||||
self.rpc_time_stddev = sqrt(
|
||||
sum([(t - mean)**2 for t in self.ts])/self.repeats)*s
|
||||
self.rpc_time_mean = mean*s
|
||||
|
||||
|
||||
class RPCTest(ExperimentCase):
|
||||
def test_rpc_timing(self):
|
||||
res = self.execute(RPCTiming)
|
||||
print(res)
|
||||
self.assertGreater(res["rpc_time_mean"], 100*ns)
|
||||
self.assertLess(res["rpc_time_mean"], 10*ms)
|
||||
self.assertLess(res["rpc_time_stddev"], 1*ms)
|
43
artiq/test/hardware_testbench.py
Normal file
43
artiq/test/hardware_testbench.py
Normal file
@ -0,0 +1,43 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
from artiq.language import *
|
||||
from artiq.protocols.file_db import FlatFileDB
|
||||
from artiq.master.worker_db import DBHub, ResultDB
|
||||
from artiq.frontend.artiq_run import (
|
||||
DummyScheduler, DummyWatchdog, SimpleParamLogger)
|
||||
|
||||
|
||||
artiq_root = os.getenv("ARTIQ_ROOT")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@unittest.skipUnless(artiq_root, "no ARTIQ_ROOT")
|
||||
class ExperimentCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.ddb = FlatFileDB(os.path.join(artiq_root, "ddb.pyon"))
|
||||
self.pdb = FlatFileDB(os.path.join(artiq_root, "pdb.pyon"))
|
||||
self.rdb = ResultDB(lambda description: None, lambda mod: None)
|
||||
self.dbh = DBHub(self.ddb, self.pdb, self.rdb)
|
||||
|
||||
def execute(self, cls, **kwargs):
|
||||
expid = {
|
||||
"file": sys.modules[cls.__module__].__file__,
|
||||
"experiment": cls.__name__,
|
||||
"arguments": kwargs
|
||||
}
|
||||
sched = DummyScheduler(expid)
|
||||
try:
|
||||
try:
|
||||
exp = cls(self.dbh, scheduler=sched, **kwargs)
|
||||
except KeyError as e:
|
||||
# skip if ddb does not match requirements
|
||||
raise unittest.SkipTest(*e.args)
|
||||
self.rdb.build()
|
||||
exp.run()
|
||||
exp.analyze()
|
||||
return self.rdb.data.read
|
||||
finally:
|
||||
self.dbh.close_devices()
|
@ -1,18 +0,0 @@
|
||||
from artiq import *
|
||||
|
||||
import pulse_rate, rtio_skew, rpc_timing
|
||||
|
||||
|
||||
_exps = [pulse_rate.PulseRate, rtio_skew.RTIOSkew, rpc_timing.RPCTiming]
|
||||
|
||||
class AllBenchmarks(Experiment, AutoDB):
|
||||
"""All benchmarks"""
|
||||
|
||||
def build(self):
|
||||
self.se = []
|
||||
for exp in _exps:
|
||||
self.se.append(exp(self.dbh))
|
||||
|
||||
def run(self):
|
||||
for se in self.se:
|
||||
se.run()
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"comm": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.comm_tcp",
|
||||
"class": "Comm",
|
||||
"arguments": {"host": "192.168.0.42"}
|
||||
},
|
||||
"core": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.core",
|
||||
"class": "Core",
|
||||
"arguments": {}
|
||||
},
|
||||
|
||||
"pmt0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 0}
|
||||
},
|
||||
|
||||
"ttl0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 2}
|
||||
},
|
||||
}
|
@ -1 +0,0 @@
|
||||
{}
|
@ -1,26 +0,0 @@
|
||||
from artiq import *
|
||||
from artiq.coredevice.runtime_exceptions import RTIOUnderflow
|
||||
|
||||
|
||||
class PulseRate(Experiment, AutoDB):
|
||||
"""Sustained pulse rate"""
|
||||
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
ttl0 = Device()
|
||||
pulse_rate = Result()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
T = time_to_cycles(100*ns)
|
||||
while True:
|
||||
try:
|
||||
for i in range(1000):
|
||||
self.ttl0.pulse(cycles_to_time(T))
|
||||
delay(cycles_to_time(T))
|
||||
except RTIOUnderflow:
|
||||
T += 1
|
||||
self.core.break_realtime()
|
||||
else:
|
||||
self.pulse_rate = cycles_to_time(2*T)
|
||||
break
|
@ -1,32 +0,0 @@
|
||||
from math import sqrt
|
||||
|
||||
from artiq import *
|
||||
|
||||
|
||||
class RPCTiming(Experiment, AutoDB):
|
||||
"""RPC timing"""
|
||||
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
repeats = Argument(100)
|
||||
rpc_time_mean = Result()
|
||||
rpc_time_stddev = Result()
|
||||
|
||||
def nop(self, x):
|
||||
pass
|
||||
|
||||
@kernel
|
||||
def bench(self):
|
||||
self.ts = [0.0 for _ in range(self.repeats)]
|
||||
for i in range(self.repeats):
|
||||
t1 = self.core.get_rtio_time()
|
||||
self.nop(10)
|
||||
t2 = self.core.get_rtio_time()
|
||||
self.ts[i] = t2 - t1
|
||||
|
||||
def run(self):
|
||||
self.bench()
|
||||
mean = sum(self.ts)/self.repeats
|
||||
self.rpc_time_stddev = sqrt(
|
||||
sum([(t - mean)**2 for t in self.ts])/self.repeats)*s
|
||||
self.rpc_time_mean = mean*s
|
@ -1,29 +0,0 @@
|
||||
from artiq import *
|
||||
|
||||
|
||||
class PulseNotReceived(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RTIOSkew(Experiment, AutoDB):
|
||||
"""RTIO skew"""
|
||||
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
pmt0 = Device()
|
||||
rtio_skew = Result()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.pmt0.output()
|
||||
delay(1*us)
|
||||
with parallel:
|
||||
self.pmt0.gate_rising(10*us)
|
||||
with sequential:
|
||||
delay(5*us)
|
||||
out_t = now()
|
||||
self.pmt0.pulse(5*us)
|
||||
in_t = self.pmt0.timestamp()
|
||||
if in_t < 0*s:
|
||||
raise PulseNotReceived
|
||||
self.rtio_skew = out_t - in_t
|
@ -177,7 +177,7 @@ General guidelines
|
||||
* Use new-style formatting (``str.format``) except for logging where it is not well supported, and double quotes for strings.
|
||||
* The device identification (e.g. serial number, or entry in ``/dev``) to attach to must be passed as a command-line parameter to the controller. We suggest using ``-d`` and ``--device`` as parameter name.
|
||||
* Controllers must be able to operate in "simulation" mode, where they behave properly even if the associated hardware is not connected. For example, they can print the data to the console instead of sending it to the device, or dump it into a file.
|
||||
* We suggest that the simulation mode is entered whenever the ``-d/--device`` option is omitted.
|
||||
* The simulation mode is entered whenever the ``--simulation`` option is specified.
|
||||
* Keep command line parameters consistent across clients/controllers. When adding new command line options, look for a client/controller that does a similar thing and follow its use of ``argparse``. If the original client/controller could use ``argparse`` in a better way, improve it.
|
||||
* Use docstrings for all public methods of the driver (note that those will be retrieved by ``artiq_rpctool``).
|
||||
* Choose a free default TCP port and add it to the default port list in this manual.
|
||||
|
@ -13,20 +13,24 @@ The low-cost Pipistrello FPGA board can be used as a lower-cost but slower alter
|
||||
|
||||
When plugged to an adapter, the NIST QC1 hardware can be used. The TTL lines are mapped to RTIO channels as follows:
|
||||
|
||||
+--------------+----------+-----------------+
|
||||
| RTIO channel | TTL line | Capability |
|
||||
+==============+==========+=================+
|
||||
| 0 | PMT0 | Input only |
|
||||
+--------------+----------+-----------------+
|
||||
| 1 | PMT1 | Input only |
|
||||
+--------------+----------+-----------------+
|
||||
| 2-18 | TTL0-16 | Output only |
|
||||
+--------------+----------+-----------------+
|
||||
| 19-21 | LEDs | Output only |
|
||||
+--------------+----------+-----------------+
|
||||
| 22 | TTL2 | Output only |
|
||||
+--------------+----------+-----------------+
|
||||
+--------------+----------+------------+
|
||||
| RTIO channel | TTL line | Capability |
|
||||
+==============+==========+============+
|
||||
| 0 | PMT0 | Input |
|
||||
+--------------+----------+------------+
|
||||
| 1 | PMT1 | Input |
|
||||
+--------------+----------+------------+
|
||||
| 2-17 | TTL0-15 | Output |
|
||||
+--------------+----------+------------+
|
||||
| 18 | EXT_LED | Output |
|
||||
+--------------+----------+------------+
|
||||
| 19 | USER_LED | Output |
|
||||
+--------------+----------+------------+
|
||||
| 20 | DDS | Output |
|
||||
+--------------+----------+------------+
|
||||
|
||||
The input only limitation on channels 0 and 1 comes from the QC-DAQ adapter. When the adapter is not used (and physically unplugged from the Pipistrello board), the corresponding pins on the Pipistrello can be used as outputs. Do not configure these channels as outputs when the adapter is plugged, as this would cause electrical contention.
|
||||
|
||||
The board can accept an external RTIO clock connected to PMT2.
|
||||
The board can accept an external RTIO clock connected to PMT2. If the DDS box
|
||||
does not drive the PMT2 pair, use XTRIG and patch the XTRIG transciever output
|
||||
on the adapter board onto C:15 disconnecting PMT2.
|
||||
|
@ -24,7 +24,7 @@ class _RTIOCRG(Module, AutoCSR):
|
||||
self.specials += Instance("DCM_CLKGEN",
|
||||
p_CLKFXDV_DIVIDE=2,
|
||||
p_CLKFX_DIVIDE=f.denominator,
|
||||
p_CLKFX_MD_MAX=1.6,
|
||||
p_CLKFX_MD_MAX=float(f),
|
||||
p_CLKFX_MULTIPLY=f.numerator,
|
||||
p_CLKIN_PERIOD=1e9/clk_freq,
|
||||
p_SPREAD_SPECTRUM="NONE",
|
||||
@ -34,7 +34,7 @@ class _RTIOCRG(Module, AutoCSR):
|
||||
i_FREEZEDCM=0,
|
||||
i_RST=ResetSignal())
|
||||
|
||||
rtio_external_clk = platform.request("dds_clock")
|
||||
rtio_external_clk = platform.request("pmt", 2)
|
||||
platform.add_period_constraint(rtio_external_clk, 8.0)
|
||||
self.specials += Instance("BUFGMUX",
|
||||
i_I0=rtio_internal_clk,
|
||||
@ -83,6 +83,8 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
|
||||
self.submodules.leds = gpio.GPIOOut(Cat(
|
||||
platform.request("user_led", 0),
|
||||
platform.request("user_led", 1),
|
||||
platform.request("user_led", 2),
|
||||
platform.request("user_led", 3),
|
||||
))
|
||||
|
||||
self.comb += [
|
||||
@ -95,11 +97,8 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
|
||||
for i in range(2):
|
||||
phy = ttl_simple.Inout(platform.request("pmt", i))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
||||
|
||||
phy = ttl_simple.Inout(platform.request("xtrig", 0))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4))
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512,
|
||||
ofifo_depth=4))
|
||||
|
||||
for i in range(16):
|
||||
phy = ttl_simple.Output(platform.request("ttl", i))
|
||||
@ -110,10 +109,10 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))
|
||||
|
||||
for i in range(2, 5):
|
||||
phy = ttl_simple.Output(platform.request("user_led", i))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))
|
||||
phy = ttl_simple.Output(platform.request("user_led", 4))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))
|
||||
|
||||
self.add_constant("RTIO_TTL_COUNT", len(rtio_channels))
|
||||
|
||||
self.add_constant("RTIO_DDS_CHANNEL", len(rtio_channels))
|
||||
|
Loading…
Reference in New Issue
Block a user