forked from M-Labs/artiq
Merge branch 'master' into spimaster
* master: artiq_flash: use term 'gateware' targets/kc705-nist_clock: add clock generator on LA32 for testing purposes doc: insist that output() must be called on TTLInOut. Closes #297 doc: update install instructions coredevice: do not give up on UTF-8 errors in log. Closes #300 use m-labs setup for defaults fix indentation
This commit is contained in:
commit
7ab7f7d75d
@ -158,7 +158,7 @@ class CommGeneric:
|
||||
return self._read_chunk(self._read_int32())
|
||||
|
||||
def _read_string(self):
|
||||
return self._read_bytes()[:-1].decode('utf-8')
|
||||
return self._read_bytes()[:-1].decode("utf-8")
|
||||
|
||||
#
|
||||
# Writer interface
|
||||
@ -242,7 +242,7 @@ class CommGeneric:
|
||||
|
||||
self._read_header()
|
||||
self._read_expect(_D2HMsgType.LOG_REPLY)
|
||||
return self._read_chunk(self._read_length).decode("utf-8")
|
||||
return self._read_chunk(self._read_length).decode("utf-8", "replace")
|
||||
|
||||
def clear_log(self):
|
||||
self._write_empty(_H2DMsgType.LOG_CLEAR)
|
||||
|
@ -91,6 +91,11 @@ class TTLInOut:
|
||||
|
||||
This should be used with bidirectional channels.
|
||||
|
||||
Note that the channel is in input mode by default. If you need to drive a
|
||||
signal, you must call ``output``. If the channel is in output mode most of
|
||||
the time in your setup, it is a good idea to call ``output`` in the
|
||||
startup kernel.
|
||||
|
||||
:param channel: channel number
|
||||
"""
|
||||
def __init__(self, dmgr, channel):
|
||||
@ -107,12 +112,18 @@ class TTLInOut:
|
||||
|
||||
@kernel
|
||||
def output(self):
|
||||
"""Set the direction to output."""
|
||||
"""Set the direction to output.
|
||||
|
||||
There must be a delay of at least one RTIO clock cycle before any
|
||||
other command can be issued."""
|
||||
self.set_oe(True)
|
||||
|
||||
@kernel
|
||||
def input(self):
|
||||
"""Set the direction to input."""
|
||||
"""Set the direction to input.
|
||||
|
||||
There must be a delay of at least one RTIO clock cycle before any
|
||||
other command can be issued."""
|
||||
self.set_oe(False)
|
||||
|
||||
@kernel
|
||||
|
@ -6,7 +6,6 @@ import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
import artiq
|
||||
from artiq import __artiq_dir__ as artiq_dir
|
||||
from artiq.frontend.bit2bin import bit2bin
|
||||
|
||||
@ -18,13 +17,13 @@ def get_argparser():
|
||||
epilog="""\
|
||||
Valid actions:
|
||||
|
||||
* proxy: load the flash proxy bitstream
|
||||
* bitstream: write bitstream to flash
|
||||
* proxy: load the flash proxy gateware bitstream
|
||||
* gateware: write gateware bitstream to flash
|
||||
* bios: write bios to flash
|
||||
* runtime: write runtime to flash
|
||||
* storage: write storage image to flash
|
||||
* load: load bitstream into device (volatile but fast)
|
||||
* start: trigger the target to (re)load its bitstream from flash
|
||||
* load: load gateware bitstream into device (volatile but fast)
|
||||
* start: trigger the target to (re)load its gateware bitstream from flash
|
||||
|
||||
Prerequisites:
|
||||
|
||||
@ -37,12 +36,12 @@ Prerequisites:
|
||||
""")
|
||||
parser.add_argument("-t", "--target", default="kc705",
|
||||
help="target board, default: %(default)s")
|
||||
parser.add_argument("-m", "--adapter", default="qc2",
|
||||
parser.add_argument("-m", "--adapter", default="clock",
|
||||
help="target adapter, default: %(default)s")
|
||||
parser.add_argument("-f", "--storage", help="write file to storage area")
|
||||
parser.add_argument("-d", "--dir", help="look for files in this directory")
|
||||
parser.add_argument("ACTION", nargs="*",
|
||||
default="proxy bitstream bios runtime start".split(),
|
||||
default="proxy gateware bios runtime start".split(),
|
||||
help="actions to perform, default: %(default)s")
|
||||
return parser
|
||||
|
||||
@ -55,7 +54,7 @@ def main():
|
||||
"kc705": {
|
||||
"chip": "xc7k325t",
|
||||
"start": "xc7_program xc7.tap",
|
||||
"bitstream": 0x000000,
|
||||
"gateware": 0x000000,
|
||||
"bios": 0xaf0000,
|
||||
"runtime": 0xb00000,
|
||||
"storage": 0xb80000,
|
||||
@ -63,7 +62,7 @@ def main():
|
||||
"pipistrello": {
|
||||
"chip": "xc6slx45",
|
||||
"start": "xc6s_program xc6s.tap",
|
||||
"bitstream": 0x000000,
|
||||
"gateware": 0x000000,
|
||||
"bios": 0x170000,
|
||||
"runtime": 0x180000,
|
||||
"storage": 0x200000,
|
||||
@ -83,23 +82,23 @@ def main():
|
||||
proxy_base = "bscan_spi_{}.bit".format(config["chip"])
|
||||
proxy = None
|
||||
for p in [opts.dir, os.path.expanduser("~/.migen"),
|
||||
"/usr/local/share/migen", "/usr/share/migen"]:
|
||||
"/usr/local/share/migen", "/usr/share/migen"]:
|
||||
proxy_ = os.path.join(p, proxy_base)
|
||||
if os.access(proxy_, os.R_OK):
|
||||
proxy = "jtagspi_init 0 {}".format(proxy_)
|
||||
break
|
||||
if not proxy:
|
||||
raise SystemExit(
|
||||
"proxy bitstream {} not found".format(proxy_base))
|
||||
"proxy gateware bitstream {} not found".format(proxy_base))
|
||||
prog.append(proxy)
|
||||
elif action == "bitstream":
|
||||
elif action == "gateware":
|
||||
bin = os.path.join(opts.dir, "top.bin")
|
||||
if not os.access(bin, os.R_OK):
|
||||
bin = tempfile.mkstemp()[1]
|
||||
bit = os.path.join(opts.dir, "top.bit")
|
||||
conv = True
|
||||
prog.append("jtagspi_program {} 0x{:x}".format(
|
||||
bin, config["bitstream"]))
|
||||
bin, config["gateware"]))
|
||||
elif action == "bios":
|
||||
prog.append("jtagspi_program {} 0x{:x}".format(
|
||||
os.path.join(opts.dir, "bios.bin"), config["bios"]))
|
||||
|
@ -48,10 +48,8 @@ fmc_adapter_io = [
|
||||
Subsignal("n", Pins("LPC:CLK1_M2C_N")),
|
||||
IOStandard("LVDS")),
|
||||
|
||||
("la32", 0,
|
||||
Subsignal("p", Pins("LPC:LA32_P")),
|
||||
Subsignal("n", Pins("LPC:LA32_N")),
|
||||
IOStandard("LVDS")),
|
||||
("la32_p", 0, Pins("LPC:LA32_P"), IOStandard("LVTTL")),
|
||||
("la32_n", 0, Pins("LPC:LA32_N"), IOStandard("LVTTL")),
|
||||
|
||||
("spi", 0,
|
||||
Subsignal("clk", Pins("LPC:LA13_N")),
|
||||
|
@ -249,13 +249,12 @@ class NIST_CLOCK(_NIST_Ions):
|
||||
phy = ttl_simple.Output(platform.request("user_led", 2))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)
|
||||
|
||||
spi_pins = self.platform.request("ams101_dac", 0)
|
||||
phy = ttl_simple.Output(spi_pins.ldac)
|
||||
self.submodules += phy
|
||||
self.config["RTIO_SPI_LDAC_CHANNEL"] = len(rtio_channels)
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)
|
||||
|
||||
phy = spi.SPIMaster(spi_pins)
|
||||
self.submodules += phy
|
||||
@ -263,6 +262,10 @@ class NIST_CLOCK(_NIST_Ions):
|
||||
rtio_channels.append(rtio.Channel.from_phy(
|
||||
phy, ofifo_depth=4, ififo_depth=4))
|
||||
|
||||
phy = ttl_simple.ClockGen(platform.request("la32_p"))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
|
||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["DDS_CHANNEL_COUNT"] = 11
|
||||
self.config["DDS_AD9914"] = True
|
||||
@ -341,7 +344,7 @@ def main():
|
||||
"+ NIST Ions QC1/CLOCK/QC2 hardware adapters")
|
||||
builder_args(parser)
|
||||
soc_kc705_args(parser)
|
||||
parser.add_argument("-H", "--hw-adapter", default="qc1",
|
||||
parser.add_argument("-H", "--hw-adapter", default="clock",
|
||||
help="hardware adapter type: qc1/clock/qc2 "
|
||||
"(default: %(default)s)")
|
||||
args = parser.parse_args()
|
||||
|
@ -198,7 +198,7 @@ class PrepareStage(TaskObject):
|
||||
await self.pool.state_changed.wait()
|
||||
elif isinstance(run, float):
|
||||
await asyncio_wait_or_cancel([self.pool.state_changed.wait()],
|
||||
timeout=run)
|
||||
timeout=run)
|
||||
else:
|
||||
if run.flush:
|
||||
run.status = RunStatus.flushing
|
||||
|
@ -137,9 +137,9 @@ static void network_init(void)
|
||||
struct ip4_addr gateway_ip;
|
||||
|
||||
init_macadr();
|
||||
fsip_or_default(&local_ip, "ip", 192, 168, 0, 42);
|
||||
fsip_or_default(&local_ip, "ip", 192, 168, 1, 50);
|
||||
fsip_or_default(&netmask, "netmask", 255, 255, 255, 0);
|
||||
fsip_or_default(&gateway_ip, "gateway", 192, 168, 0, 1);
|
||||
fsip_or_default(&gateway_ip, "gateway", 192, 168, 1, 1);
|
||||
|
||||
lwip_init();
|
||||
|
||||
|
@ -64,6 +64,8 @@ With the CLOCK hardware, the TTL lines are mapped as follows:
|
||||
+--------------------+-----------------------+--------------+
|
||||
| 19 | LED | Output |
|
||||
+--------------------+-----------------------+--------------+
|
||||
| 20 | LA32_P | Clock |
|
||||
+--------------------+-----------------------+--------------+
|
||||
|
||||
|
||||
Pipistrello
|
||||
|
@ -108,6 +108,10 @@ Create a new file ``rtio.py`` containing the following: ::
|
||||
delay(2*us)
|
||||
|
||||
|
||||
.. note::
|
||||
If ``ttl0`` is a bidirectional channel (``TTLInOut``), it is in input (non-driving) mode by default. You need to call ``self.ttl0.output()`` as explained above for the LED.
|
||||
|
||||
|
||||
Connect an oscilloscope or logic analyzer to TTL0 and run ``artiq_run.py led.py``. Notice that the generated signal's period is precisely 4 microseconds, and that it has a duty cycle of precisely 50%. This is not what you would expect if the delay and the pulse were implemented with CPU-controlled GPIO: overhead from the loop management, function calls, etc. would increase the signal's period, and asymmetry in the overhead would cause duty cycle distortion.
|
||||
|
||||
Instead, inside the core device, output timing is generated by the gateware and the CPU only programs switching commands with certain timestamps that the CPU computes. This guarantees precise timing as long as the CPU can keep generating timestamps that are increasing fast enough. In case it fails to do that (and attempts to program an event with a timestamp in the past), the :class:`artiq.coredevice.exceptions.RTIOUnderflow` exception is raised. The kernel causing it may catch it (using a regular ``try... except...`` construct), or it will be propagated to the host.
|
||||
|
@ -40,13 +40,16 @@ If your ``$PATH`` misses reference the ``miniconda3/bin`` or ``anaconda3/bin`` y
|
||||
|
||||
$ export PATH=$HOME/miniconda3/bin:$PATH
|
||||
|
||||
Installing the host side software
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Installing the ARTIQ packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
For this, you need to add our Anaconda repository to your conda configuration::
|
||||
|
||||
$ conda config --add channels http://conda.anaconda.org/m-labs/channel/main
|
||||
$ conda config --add channels http://conda.anaconda.org/m-labs/channel/dev
|
||||
|
||||
.. note::
|
||||
To use the development versions of ARTIQ, also add the ``dev`` channel (http://conda.anaconda.org/m-labs/channel/dev).
|
||||
Development versions contain more features, but are not as well-tested and are more likely to contain bugs or inconsistencies.
|
||||
|
||||
Then you can install the ARTIQ package, it will pull all the necessary dependencies.
|
||||
|
||||
@ -60,7 +63,12 @@ Then you can install the ARTIQ package, it will pull all the necessary dependenc
|
||||
$ ENV=$(date +artiq-%Y-%m-%d); conda create -n $ENV artiq-kc705-nist_qc1; \
|
||||
echo "Created environment $ENV for ARTIQ"
|
||||
|
||||
* For the KC705 board with the FMC backplane and AD9914 DDS chips::
|
||||
* For the KC705 board with the "clock" FMC backplane and AD9914 DDS chips::
|
||||
|
||||
$ ENV=$(date +artiq-%Y-%m-%d); conda create -n $ENV artiq-kc705-nist_clock; \
|
||||
echo "Created environment $ENV for ARTIQ"
|
||||
|
||||
* For the KC705 board with the QC2 FMC backplane and AD9914 DDS chips::
|
||||
|
||||
$ ENV=$(date +artiq-%Y-%m-%d); conda create -n $ENV artiq-kc705-nist_qc2; \
|
||||
echo "Created environment $ENV for ARTIQ"
|
||||
@ -89,7 +97,9 @@ You now need to flash 3 things on the FPGA board:
|
||||
2. The BIOS
|
||||
3. The ARTIQ runtime
|
||||
|
||||
First you need to :ref:`install openocd <install-openocd>`. Then, you can flash the board:
|
||||
They are all shipped in our Conda packages, along with the required flash proxy bitstreams.
|
||||
|
||||
First you need to install OpenOCD. Then, you can flash the board:
|
||||
|
||||
* For the Pipistrello board::
|
||||
|
||||
@ -97,11 +107,9 @@ First you need to :ref:`install openocd <install-openocd>`. Then, you can flash
|
||||
|
||||
* For the KC705 board::
|
||||
|
||||
$ artiq_flash
|
||||
$ artiq_flash -m [qc1/clock/qc2]
|
||||
|
||||
Next step (for KC705) is to flash MAC and IP addresses to the board:
|
||||
|
||||
* See :ref:`those instructions <flash-mac-ip-addr>` to flash MAC and IP addresses.
|
||||
For the KC705, the next step is to flash the MAC and IP addresses to the board. See :ref:`those instructions <flash-mac-ip-addr>`.
|
||||
|
||||
.. _install-from-sources:
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
# This is an example device database that needs to be adapted to your setup.
|
||||
# The RTIO channel numbers here are for NIST QC1 on KC705.
|
||||
# The RTIO channel numbers here are for NIST CLOCK on KC705.
|
||||
|
||||
{
|
||||
"comm": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.comm_tcp",
|
||||
"class": "Comm",
|
||||
"arguments": {"host": "192.168.0.42"}
|
||||
"arguments": {"host": "kc705.lab.m-labs.hk"}
|
||||
},
|
||||
"core": {
|
||||
"type": "local",
|
||||
@ -15,73 +15,77 @@
|
||||
"arguments": {"ref_period": 1e-9}
|
||||
},
|
||||
|
||||
"pmt0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 0}
|
||||
},
|
||||
"pmt1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 1}
|
||||
},
|
||||
|
||||
"ttl0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 2},
|
||||
"arguments": {"channel": 0},
|
||||
"comment": "This is a fairly long comment to test word wrapping in GUI."
|
||||
},
|
||||
"ttl1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 3},
|
||||
"arguments": {"channel": 1},
|
||||
"comment": "Hello World"
|
||||
},
|
||||
"ttl2": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 4}
|
||||
"arguments": {"channel": 2}
|
||||
},
|
||||
"ttl3": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 5}
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 3}
|
||||
},
|
||||
|
||||
"ttl4": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 6}
|
||||
"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": "TTLInOut",
|
||||
"arguments": {"channel": 7}
|
||||
},
|
||||
|
||||
|
||||
"ttl_sma": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 17}
|
||||
"arguments": {"channel": 18}
|
||||
},
|
||||
"ttl_clock_la32_p": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLClockGen",
|
||||
"arguments": {"channel": 20}
|
||||
},
|
||||
|
||||
|
||||
"led": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 18}
|
||||
},
|
||||
"ttl15": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLClockGen",
|
||||
"arguments": {"channel": 19}
|
||||
},
|
||||
|
||||
@ -94,21 +98,21 @@
|
||||
"dds0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "AD9858",
|
||||
"arguments": {"sysclk": 1e9, "channel": 0},
|
||||
"class": "AD9914",
|
||||
"arguments": {"sysclk": 3e9, "channel": 0},
|
||||
"comment": "Comments work in DDS panel as well"
|
||||
},
|
||||
"dds1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "AD9858",
|
||||
"arguments": {"sysclk": 1e9, "channel": 1}
|
||||
"class": "AD9914",
|
||||
"arguments": {"sysclk": 3e9, "channel": 1}
|
||||
},
|
||||
"dds2": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "AD9858",
|
||||
"arguments": {"sysclk": 1e9, "channel": 2}
|
||||
"class": "AD9914",
|
||||
"arguments": {"sysclk": 3e9, "channel": 2}
|
||||
},
|
||||
|
||||
"qc_q1_0": {
|
||||
@ -160,7 +164,12 @@
|
||||
"ttl_out": "ttl0",
|
||||
"ttl_out_serdes": "ttl0",
|
||||
|
||||
"pmt": "pmt0",
|
||||
"loop_out": "ttl0",
|
||||
"loop_in": "ttl3",
|
||||
"loop_clock_out": "ttl_clock_la32_p",
|
||||
"loop_clock_in": "ttl7",
|
||||
|
||||
"pmt": "ttl3",
|
||||
"bd_dds": "dds0",
|
||||
"bd_sw": "ttl0",
|
||||
"bdd_dds": "dds1",
|
||||
|
Loading…
Reference in New Issue
Block a user