From 785691ab98d9db852b8bdf3acb7fe41682b47224 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 29 Feb 2016 21:32:48 +0800 Subject: [PATCH 1/7] fix indentation --- artiq/master/scheduler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artiq/master/scheduler.py b/artiq/master/scheduler.py index 8b7c52553..6e41a8d48 100644 --- a/artiq/master/scheduler.py +++ b/artiq/master/scheduler.py @@ -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 From 572c49f475bc0528fa6f27fa7f2929006f45f1fb Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 29 Feb 2016 21:35:23 +0800 Subject: [PATCH 2/7] use m-labs setup for defaults --- artiq/frontend/artiq_flash.py | 2 +- artiq/gateware/targets/kc705.py | 2 +- artiq/runtime/main.c | 4 +- examples/master/device_db.pyon | 72 +++++++++++++++++---------------- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/artiq/frontend/artiq_flash.py b/artiq/frontend/artiq_flash.py index 82cb27939..00e217bcf 100755 --- a/artiq/frontend/artiq_flash.py +++ b/artiq/frontend/artiq_flash.py @@ -37,7 +37,7 @@ 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") diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 719876220..6d2367cc4 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -315,7 +315,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() diff --git a/artiq/runtime/main.c b/artiq/runtime/main.c index 372176732..5897b1eef 100644 --- a/artiq/runtime/main.c +++ b/artiq/runtime/main.c @@ -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(); diff --git a/examples/master/device_db.pyon b/examples/master/device_db.pyon index 59b32de2f..da3417e9c 100644 --- a/examples/master/device_db.pyon +++ b/examples/master/device_db.pyon @@ -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,70 @@ "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} }, + "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 +91,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 +157,12 @@ "ttl_out": "ttl0", "ttl_out_serdes": "ttl0", - "pmt": "pmt0", + "loop_out": "ttl0", + "loop_in": "ttl3", + #"loop_clock_out": "TODO", + "loop_clock_in": "ttl7", + + "pmt": "ttl3", "bd_dds": "dds0", "bd_sw": "ttl0", "bdd_dds": "dds1", From 4467f91cbfef9f57af5a29d8888555db680714d0 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 29 Feb 2016 22:21:10 +0800 Subject: [PATCH 3/7] coredevice: do not give up on UTF-8 errors in log. Closes #300 --- artiq/coredevice/comm_generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index b4059fdcc..f4e1d2eee 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -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) From d0d56bd3fe4108967497a1fa26d2805aff33f245 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 1 Mar 2016 00:19:50 +0800 Subject: [PATCH 4/7] doc: update install instructions --- doc/manual/installing.rst | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/manual/installing.rst b/doc/manual/installing.rst index 751480058..33246d27f 100644 --- a/doc/manual/installing.rst +++ b/doc/manual/installing.rst @@ -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 `. 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 `. 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 ` 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 `. .. _install-from-sources: From a1e1f2b387ebd1a1c02d94233eee3e0f5f5226a9 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 1 Mar 2016 00:28:40 +0800 Subject: [PATCH 5/7] doc: insist that output() must be called on TTLInOut. Closes #297 --- artiq/coredevice/ttl.py | 15 +++++++++++++-- doc/manual/getting_started_core.rst | 4 ++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/artiq/coredevice/ttl.py b/artiq/coredevice/ttl.py index be410d919..91c8c5531 100644 --- a/artiq/coredevice/ttl.py +++ b/artiq/coredevice/ttl.py @@ -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 diff --git a/doc/manual/getting_started_core.rst b/doc/manual/getting_started_core.rst index 2189e65bd..4dde970cc 100644 --- a/doc/manual/getting_started_core.rst +++ b/doc/manual/getting_started_core.rst @@ -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. From 5fad570f5e2b7fdd65294ef5ed2eb29ef9da49a8 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 1 Mar 2016 00:35:26 +0800 Subject: [PATCH 6/7] targets/kc705-nist_clock: add clock generator on LA32 for testing purposes --- artiq/gateware/nist_clock.py | 6 ++---- artiq/gateware/targets/kc705.py | 4 ++++ doc/manual/core_device.rst | 2 ++ examples/master/device_db.pyon | 9 ++++++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/artiq/gateware/nist_clock.py b/artiq/gateware/nist_clock.py index 363a339b5..3b621ac41 100644 --- a/artiq/gateware/nist_clock.py +++ b/artiq/gateware/nist_clock.py @@ -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")), diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 6d2367cc4..6dd32def8 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -237,6 +237,10 @@ class NIST_CLOCK(_NIST_Ions): rtio_channels.append(rtio.Channel.from_phy(phy)) self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels) + 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 diff --git a/doc/manual/core_device.rst b/doc/manual/core_device.rst index f22763151..8000a6770 100644 --- a/doc/manual/core_device.rst +++ b/doc/manual/core_device.rst @@ -64,6 +64,8 @@ With the CLOCK hardware, the TTL lines are mapped as follows: +--------------------+-----------------------+--------------+ | 19 | LED | Output | +--------------------+-----------------------+--------------+ +| 20 | LA32_P | Clock | ++--------------------+-----------------------+--------------+ Pipistrello diff --git a/examples/master/device_db.pyon b/examples/master/device_db.pyon index da3417e9c..4dbb92ab7 100644 --- a/examples/master/device_db.pyon +++ b/examples/master/device_db.pyon @@ -74,6 +74,13 @@ "class": "TTLInOut", "arguments": {"channel": 18} }, + "ttl_clock_la32_p": { + "type": "local", + "module": "artiq.coredevice.ttl", + "class": "TTLClockGen", + "arguments": {"channel": 20} + }, + "led": { "type": "local", @@ -159,7 +166,7 @@ "loop_out": "ttl0", "loop_in": "ttl3", - #"loop_clock_out": "TODO", + "loop_clock_out": "ttl_clock_la32_p", "loop_clock_in": "ttl7", "pmt": "ttl3", From 6dd1eb2e928476fdc4c364fae26b8bc14c0fea54 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 29 Feb 2016 20:45:41 +0100 Subject: [PATCH 7/7] artiq_flash: use term 'gateware' --- artiq/frontend/artiq_flash.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/artiq/frontend/artiq_flash.py b/artiq/frontend/artiq_flash.py index 00e217bcf..b29128a35 100755 --- a/artiq/frontend/artiq_flash.py +++ b/artiq/frontend/artiq_flash.py @@ -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: @@ -42,7 +41,7 @@ Prerequisites: 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"]))