forked from M-Labs/artiq
artiq_run: reference module by filename
This commit is contained in:
parent
bfe980d458
commit
fd28bfbb7c
15
artiq/management/file_import.py
Normal file
15
artiq/management/file_import.py
Normal file
@ -0,0 +1,15 @@
|
||||
import importlib.machinery
|
||||
|
||||
|
||||
def file_import(filename):
|
||||
modname = filename
|
||||
i = modname.rfind("/")
|
||||
if i > 0:
|
||||
modname = modname[i+1:]
|
||||
i = modname.find(".")
|
||||
if i > 0:
|
||||
modname = modname[:i]
|
||||
modname = "file_import_" + modname
|
||||
|
||||
loader = importlib.machinery.SourceFileLoader(modname, filename)
|
||||
return loader.load_module()
|
@ -23,7 +23,7 @@ Copy the files ``ddb.pyon`` and ``pdb.pyon`` (containing the device and paramete
|
||||
|
||||
Run your code using ``artiq_run.py``, which is part of the ARTIQ front-end tools: ::
|
||||
|
||||
$ artiq_run.py led
|
||||
$ artiq_run.py led.py
|
||||
|
||||
The LED of the device should turn on. Congratulations! You have a basic ARTIQ system up and running.
|
||||
|
||||
@ -49,9 +49,9 @@ Modify the code as follows: ::
|
||||
|
||||
You can then turn the LED off and on by entering 0 or 1 at the prompt that appears: ::
|
||||
|
||||
$ artiq_run.py led
|
||||
$ artiq_run.py led.py
|
||||
Enter desired LED state: 1
|
||||
$ artiq_run.py led
|
||||
$ artiq_run.py led.py
|
||||
Enter desired LED state: 0
|
||||
|
||||
What happens is the ARTIQ compiler notices that the ``input_led_state`` function does not have a ``@kernel`` decorator and thus must be executed on the host. When the core device calls it, it sends a request to the host to execute it. The host displays the prompt, collects user input, and sends the result back to the core device, which sets the LED state accordingly.
|
||||
@ -89,7 +89,7 @@ Create a new file ``rtio.py`` containing the following: ::
|
||||
delay(2*us)
|
||||
|
||||
|
||||
Connect an oscilloscope or logic analyzer to TTL0 (pin C11 on the Papilio Pro) and run ``artiq_run.py led``. 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.
|
||||
Connect an oscilloscope or logic analyzer to TTL0 (pin C11 on the Papilio Pro) 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.runtime_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.
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import importlib
|
||||
import sys
|
||||
from inspect import isclass
|
||||
from operator import itemgetter
|
||||
|
||||
from artiq.management.file_import import file_import
|
||||
from artiq.language.context import *
|
||||
from artiq.management import pyon
|
||||
from artiq.management.dpdb import DeviceParamDB
|
||||
@ -37,8 +37,8 @@ def _get_args():
|
||||
help="function to run")
|
||||
parser.add_argument("-u", "--unit", default=None,
|
||||
help="unit to run")
|
||||
parser.add_argument("module",
|
||||
help="module containing the unit to run")
|
||||
parser.add_argument("file",
|
||||
help="file containing the unit to run")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
@ -54,8 +54,7 @@ def main():
|
||||
unit_inst = ELFRunner(dpdb)
|
||||
unit_inst.run(args.file, args.function)
|
||||
else:
|
||||
sys.path.append(".")
|
||||
module = importlib.import_module(args.module)
|
||||
module = file_import(args.file)
|
||||
if args.unit is None:
|
||||
units = [(k, v) for k, v in module.__dict__.items()
|
||||
if k[0] != "_" and isclass(v) and issubclass(v, AutoContext) and v is not AutoContext]
|
||||
|
Loading…
Reference in New Issue
Block a user