Merge branch 'master' into new-py2llvm

pull/235/head
whitequark 2015-11-07 09:44:20 +03:00
commit d6d0a3e3e9
92 changed files with 538 additions and 410 deletions

1
.gitignore vendored
View File

@ -6,7 +6,6 @@ __pycache__
*.elf
*.fbi
*.pyc
soc/runtime/service_table.h
doc/manual/_build
/build
/dist

6
.gitmodules vendored
View File

@ -1,4 +1,4 @@
[submodule "soc/runtime/lwip"]
path = soc/runtime/lwip
[submodule "artiq/runtime/lwip"]
path = artiq/runtime/lwip
url = git://git.savannah.nongnu.org/lwip.git
ignore = untracked
ignore = untracked

View File

@ -18,7 +18,6 @@ install:
- if [ $TRAVIS_PULL_REQUEST != false ]; then BUILD_SOC=none; fi
- if [ $BUILD_SOC != none ]; then ./.travis/get-xilinx.sh; fi
- if [ $BUILD_SOC != none ]; then ./.travis/get-toolchain.sh; fi
- if [ $BUILD_SOC != none ]; then ./.travis/get-misoc.sh; fi
- . ./.travis/get-anaconda.sh
- source $HOME/miniconda/bin/activate py35
- conda install -q pip coverage anaconda-client cython

View File

@ -1,6 +1,8 @@
#!/bin/sh
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
set -e
export PATH=$HOME/miniconda/bin:$PATH
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
bash miniconda.sh -b -p $HOME/miniconda

View File

@ -1,4 +0,0 @@
#!/bin/sh
git clone --recursive https://github.com/m-labs/misoc $HOME/misoc
echo "export MSCDIR=$HOME/misoc" >> $HOME/.m-labs/build_settings.sh

View File

@ -1,5 +1,7 @@
#!/bin/sh
set -e
packages="http://us.archive.ubuntu.com/ubuntu/pool/universe/i/iverilog/iverilog_0.9.7-1_amd64.deb"
mkdir -p packages

View File

@ -2,6 +2,8 @@
# Copyright (C) 2014, 2015 M-Labs Limited
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
set -e
wget http://sionneau.net/artiq/Xilinx/xilinx_ise_14.7_s3_s6.tar.gz.gpg
echo "$secret" | gpg --passphrase-fd 0 xilinx_ise_14.7_s3_s6.tar.gz.gpg
tar -C $HOME/ -xzf xilinx_ise_14.7_s3_s6.tar.gz
@ -26,13 +28,13 @@ echo "$secret" | gpg --passphrase-fd 0 Xilinx.lic.gpg
mkdir -p ~/.Xilinx
mv Xilinx.lic ~/.Xilinx/Xilinx.lic
git clone https://github.com/fallen/impersonate_macaddress
git clone https://github.com/m-labs/impersonate_macaddress
make -C impersonate_macaddress
# Tell mibuild where Xilinx toolchains are installed
# and feed it the mac address corresponding to the license
cat >> $HOME/.m-labs/build_settings.sh << EOF
MISOC_EXTRA_VIVADO_CMDLINE="-Ob vivado_path $HOME/Xilinx/Vivado"
MISOC_EXTRA_ISE_CMDLINE="-Ob ise_path $HOME/opt/Xilinx/"
MISOC_EXTRA_ISE_CMDLINE="--gateware-toolchain-path $HOME/opt/Xilinx/"
MISOC_EXTRA_VIVADO_CMDLINE="--gateware-toolchain-path $HOME/Xilinx/Vivado"
export MACADDR=$macaddress
export LD_PRELOAD=$PWD/impersonate_macaddress/impersonate_macaddress.so
EOF

View File

@ -11,17 +11,14 @@ def run(script):
file.close()
run("""
# exit on error
set -e
# print commands
#set -x
ARTIQ_PREFIX=$(python3 -c "import artiq; print(artiq.__path__[0])")
# Default is kc705
BOARD=kc705
# Default mezzanine board is nist_qc1
MEZZANINE_BOARD=nist_qc1
# Default hardware adapter is qc1
HARDWARE_ADAPTER=qc1
while getopts "bBrht:d:f:m:" opt
do
@ -67,14 +64,14 @@ do
fi
;;
m)
if [ "$OPTARG" == "nist_qc1" ]
if [ "$OPTARG" == "qc1" ]
then
MEZZANINE_BOARD=nist_qc1
elif [ "$OPTARG" == "nist_qc2" ]
HARDWARE_ADAPTER=qc1
elif [ "$OPTARG" == "qc2" ]
then
MEZZANINE_BOARD=nist_qc2
HARDWARE_ADAPTER=qc2
else
echo "KC705 mezzanine board is either nist_qc1 or nist_qc2"
echo "Hardware adapter should be qc1 or qc2"
exit 1
fi
;;
@ -88,8 +85,8 @@ do
echo "-B Flash BIOS"
echo "-r Flash ARTIQ runtime"
echo "-h Show this help message"
echo "-t Target (kc705, pipistrello, default is: kc705)"
echo "-m Mezzanine board (nist_qc1, nist_qc2, default is: nist_qc1)"
echo "-t Target (kc705/pipistrello, default: kc705)"
echo "-m Hardware adapter (qc1/qc2, default: qc1)"
echo "-f Flash storage image generated with artiq_mkfs"
echo "-d Directory containing the binaries to be flashed"
exit 1
@ -129,30 +126,28 @@ fi
if [ "$BOARD" == "kc705" ]
then
UDEV_RULES=99-kc705.rules
BITSTREAM=artiq_kc705-${MEZZANINE_BOARD}-kc705.bit
CABLE=jtaghs1_fast
PROXY=bscan_spi_kc705.bit
BIOS_ADDR=0xaf0000
RUNTIME_ADDR=0xb00000
RUNTIME_FILE=runtime.fbi
FS_ADDR=0xb40000
if [ -z "$BIN_PREFIX" ]
then
RUNTIME_FILE=${MEZZANINE_BOARD}/runtime.fbi
BIN_PREFIX=$ARTIQ_PREFIX/binaries/kc705
BIN_PREFIX=$ARTIQ_PREFIX/binaries/kc705-$HARDWARE_ADAPTER
fi
search_for_proxy $PROXY
elif [ "$BOARD" == "pipistrello" ]
then
UDEV_RULES=99-papilio.rules
BITSTREAM=artiq_pipistrello-nist_qc1-pipistrello.bit
CABLE=papilio
PROXY=bscan_spi_lx45_csg324.bit
BIOS_ADDR=0x170000
RUNTIME_ADDR=0x180000
RUNTIME_FILE=runtime.fbi
FS_ADDR=0x1c0000
if [ -z "$BIN_PREFIX" ]; then BIN_PREFIX=$ARTIQ_PREFIX/binaries/pipistrello; fi
if [ -z "$BIN_PREFIX" ];
then
BIN_PREFIX=$ARTIQ_PREFIX/binaries/pipistrello-$HARDWARE_ADAPTER
fi
search_for_proxy $PROXY
fi
@ -195,7 +190,7 @@ fi
if [ "${FLASH_BITSTREAM}" == "1" ]
then
echo "Flashing FPGA bitstream..."
xc3sprog -v -c $CABLE -I$PROXY_PATH/$PROXY $BIN_PREFIX/$BITSTREAM:w:0x0:BIT
xc3sprog -v -c $CABLE -I$PROXY_PATH/$PROXY $BIN_PREFIX/top.bit:w:0x0:BIT
fi
if [ "${FLASH_BIOS}" == "1" ]
@ -207,7 +202,7 @@ fi
if [ "${FLASH_RUNTIME}" == "1" ]
then
echo "Flashing ARTIQ runtime..."
xc3sprog -v -c $CABLE -I$PROXY_PATH/$PROXY $BIN_PREFIX/${RUNTIME_FILE}:w:$RUNTIME_ADDR:BIN
xc3sprog -v -c $CABLE -I$PROXY_PATH/$PROXY $BIN_PREFIX/runtime.fbi:w:$RUNTIME_ADDR:BIN
fi
echo "Done."
xc3sprog -v -c $CABLE -R > /dev/null 2>&1

View File

@ -10,7 +10,7 @@ import os
from quamash import QEventLoop, QtGui, QtCore
from pyqtgraph import dockarea
from artiq.tools import verbosity_args, init_logger
from artiq.tools import verbosity_args, init_logger, artiq_dir
from artiq.protocols.pc_rpc import AsyncioClient
from artiq.gui.state import StateManager
from artiq.gui.explorer import ExplorerDock
@ -21,10 +21,6 @@ from artiq.gui.log import LogDock
from artiq.gui.console import ConsoleDock
data_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
"..", "gui")
def get_argparser():
parser = argparse.ArgumentParser(description="ARTIQ GUI client")
parser.add_argument(
@ -46,7 +42,8 @@ def get_argparser():
class MainWindow(QtGui.QMainWindow):
def __init__(self, app, server):
QtGui.QMainWindow.__init__(self)
self.setWindowIcon(QtGui.QIcon(os.path.join(data_dir, "icon.png")))
icon = QtGui.QIcon(os.path.join(artiq_dir, "gui", "icon.png"))
self.setWindowIcon(icon)
self.setWindowTitle("ARTIQ - {}".format(server))
self.exit_request = asyncio.Event()
@ -67,15 +64,18 @@ def main():
app = QtGui.QApplication([])
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
atexit.register(lambda: loop.close())
atexit.register(loop.close)
rpc_clients = dict()
for target in "schedule", "repository", "dataset_db":
client = AsyncioClient()
loop.run_until_complete(client.connect_rpc(
args.server, args.port_control, "master_" + target))
atexit.register(client.close_rpc)
rpc_clients[target] = client
smgr = StateManager(args.db_file)
schedule_ctl = AsyncioClient()
loop.run_until_complete(schedule_ctl.connect_rpc(
args.server, args.port_control, "master_schedule"))
atexit.register(lambda: schedule_ctl.close_rpc())
win = MainWindow(app, args.server)
area = dockarea.DockArea()
smgr.register(area)
@ -85,7 +85,9 @@ def main():
status_bar.showMessage("Connected to {}".format(args.server))
win.setStatusBar(status_bar)
d_explorer = ExplorerDock(win, status_bar, schedule_ctl)
d_explorer = ExplorerDock(win, status_bar,
rpc_clients["schedule"],
rpc_clients["repository"])
smgr.register(d_explorer)
loop.run_until_complete(d_explorer.sub_connect(
args.server, args.port_notify))
@ -110,10 +112,11 @@ def main():
area.addDock(d_datasets, "top")
area.addDock(d_explorer, "above", d_datasets)
d_schedule = ScheduleDock(status_bar, schedule_ctl)
d_schedule = ScheduleDock(status_bar, rpc_clients["schedule"])
loop.run_until_complete(d_schedule.sub_connect(
args.server, args.port_notify))
atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close()))
d_explorer.get_current_schedule = d_schedule.get_current_schedule
d_log = LogDock()
smgr.register(d_log)
@ -121,14 +124,10 @@ def main():
args.server, args.port_notify))
atexit.register(lambda: loop.run_until_complete(d_log.sub_close()))
dataset_db = AsyncioClient()
loop.run_until_complete(dataset_db.connect_rpc(
args.server, args.port_control, "master_dataset_db"))
atexit.register(lambda: dataset_db.close_rpc())
def _set_dataset(k, v):
asyncio.ensure_future(dataset_db.set(k, v))
asyncio.ensure_future(rpc_clients["dataset_db"].set(k, v))
def _del_dataset(k):
asyncio.ensure_future(dataset_db.delete(k))
asyncio.ensure_future(rpc_clients["dataset_db"].delete(k))
d_console = ConsoleDock(
d_datasets.get_dataset,
_set_dataset,

View File

@ -11,8 +11,8 @@ from artiq.tools import verbosity_args, simple_network_args, init_logger
def get_argparser():
parser = argparse.ArgumentParser()
parser.add_argument("-P", "--product", required=True,
help="type of the Thorlabs T-Cube device to control",
choices=["tdc001", "tpz001"])
help="type of the Thorlabs T-Cube device to control: "
"tdc001/tpz001")
parser.add_argument("-d", "--device", default=None,
help="serial device. See documentation for how to "
"specify a USB Serial Number.")
@ -39,11 +39,19 @@ def main():
dev = TdcSim()
elif product == "tpz001":
dev = TpzSim()
else:
print("Invalid product string (-P/--product), "
"choose from tdc001 or tpz001")
sys.exit(1)
else:
if product == "tdc001":
dev = Tdc(args.device)
elif product == "tpz001":
dev = Tpz(args.device)
else:
print("Invalid product string (-P/--product), "
"choose from tdc001 or tpz001")
sys.exit(1)
try:
simple_server_loop({product: dev}, args.bind, args.port)

View File

@ -1,18 +1,16 @@
from migen.fhdl.std import *
from migen import *
from migen.genlib.fsm import *
from migen.genlib.misc import WaitTimer
from migen.bus import wishbone
from migen.bus.transactions import *
from migen.sim.generic import run_simulation
from misoc.interconnect import wishbone
class AD9xxx(Module):
"""Wishbone interface to the AD9858 and AD9914 DDS chips.
Addresses 0-2**flen(pads.a)-1 map the AD9xxx registers.
Addresses 0-2**len(pads.a)-1 map the AD9xxx registers.
Write to address 2**flen(pads.a) to pulse the FUD signal.
Address 2**flen(pads.a)+1 is a GPIO register that controls the
Write to address 2**len(pads.a) to pulse the FUD signal.
Address 2**len(pads.a)+1 is a GPIO register that controls the
sel and reset signals. rst is mapped to bit 0, followed by sel.
Write timing:
@ -38,15 +36,15 @@ class AD9xxx(Module):
read_wait_cycles=10, hiz_wait_cycles=3,
bus=None):
if bus is None:
bus = wishbone.Interface(data_width=flen(pads.d))
bus = wishbone.Interface(data_width=len(pads.d))
self.bus = bus
# # #
dts = TSTriple(flen(pads.d))
dts = TSTriple(len(pads.d))
self.specials += dts.get_tristate(pads.d)
hold_address = Signal()
dr = Signal(flen(pads.d))
dr = Signal(len(pads.d))
rx = Signal()
self.sync += [
If(~hold_address, pads.a.eq(bus.adr)),
@ -56,9 +54,9 @@ class AD9xxx(Module):
]
if hasattr(pads, "sel"):
sel_len = flen(pads.sel)
sel_len = len(pads.sel)
else:
sel_len = flen(pads.sel_n)
sel_len = len(pads.sel_n)
gpio = Signal(sel_len + 1)
gpio_load = Signal()
self.sync += If(gpio_load, gpio.eq(bus.dat_w))
@ -98,7 +96,7 @@ class AD9xxx(Module):
fsm.act("IDLE",
If(bus.cyc & bus.stb,
If(bus.adr[flen(pads.a)],
If(bus.adr[len(pads.a)],
If(bus.adr[0],
NextState("GPIO")
).Else(
@ -157,20 +155,20 @@ class AD9xxx(Module):
)
def _test_gen():
def _test_gen(bus):
# Test external bus writes
yield TWrite(4, 2)
yield TWrite(5, 3)
yield from bus.write(4, 2)
yield from bus.write(5, 3)
yield
# Test external bus reads
yield TRead(14)
yield TRead(15)
yield from bus.read(14)
yield from bus.read(15)
yield
# Test FUD
yield TWrite(64, 0)
yield from bus.write(64, 0)
yield
# Test GPIO
yield TWrite(65, 0xff)
yield from bus.write(65, 0xff)
yield
@ -185,14 +183,7 @@ class _TestPads:
self.rst_n = Signal()
class _TB(Module):
def __init__(self):
pads = _TestPads()
self.submodules.dut = AD9xxx(pads, drive_fud=True)
self.submodules.initiator = wishbone.Initiator(_test_gen())
self.submodules.interconnect = wishbone.InterconnectPointToPoint(
self.initiator.bus, self.dut.bus)
if __name__ == "__main__":
run_simulation(_TB(), vcd_name="ad9xxx.vcd")
pads = _TestPads()
dut = AD9xxx(pads)
run_simulation(dut, _test_gen(dut.bus), vcd_name="ad9xxx.vcd")

View File

@ -1,9 +1,8 @@
from migen.fhdl.std import *
from migen.bank.description import *
from migen.bus import wishbone
from misoclib.cpu import mor1kx
from misoclib.soc import mem_decoder
from migen import *
from misoc.interconnect.csr import *
from misoc.interconnect import wishbone
from misoc.cores import mor1kx
from misoc.integration.soc_core import mem_decoder
class KernelCPU(Module):
@ -23,9 +22,8 @@ class KernelCPU(Module):
self.cd_sys_kernel.clk.eq(ClockSignal()),
self.cd_sys_kernel.rst.eq(self._reset.storage)
]
self.submodules.cpu = RenameClockDomains(
mor1kx.MOR1KX(platform, exec_address),
"sys_kernel")
self.submodules.cpu = ClockDomainsRenamer("sys_kernel")(
mor1kx.MOR1KX(platform, exec_address))
# DRAM access
self.wb_sdram = wishbone.Interface()

View File

@ -1,5 +1,5 @@
from migen.fhdl.std import *
from migen.bus import wishbone
from migen import *
from misoc.interconnect import wishbone
class Mailbox(Module):

View File

@ -1,4 +1,4 @@
from mibuild.generic_platform import *
from migen.build.generic_platform import *
papilio_adapter_io = [

View File

@ -1,4 +1,4 @@
from mibuild.generic_platform import *
from migen.build.generic_platform import *
fmc_adapter_io = [

View File

@ -1,10 +1,12 @@
from migen.fhdl.std import *
from migen.bank.description import *
from migen.genlib.misc import optree
from functools import reduce
from operator import and_
from migen import *
from migen.genlib.record import Record
from migen.genlib.cdc import *
from migen.genlib.fifo import AsyncFIFO
from migen.genlib.resetsync import AsyncResetSynchronizer
from misoc.interconnect.csr import *
from artiq.gateware.rtio import rtlink
@ -105,9 +107,15 @@ class _OutputManager(Module):
# # #
# FIFO
fifo = RenameClockDomains(AsyncFIFO(ev_layout, fifo_depth),
{"write": "rsys", "read": "rio"})
fifo = ClockDomainsRenamer({"write": "rsys", "read": "rio"})(
AsyncFIFO(layout_len(ev_layout), fifo_depth))
self.submodules += fifo
fifo_in = Record(ev_layout)
fifo_out = Record(ev_layout)
self.comb += [
fifo.din.eq(fifo_in.raw_bits()),
fifo_out.raw_bits().eq(fifo.dout)
]
# Buffer
buf_pending = Signal()
@ -138,13 +146,15 @@ class _OutputManager(Module):
if interface.suppress_nop:
# disable NOP at reset: do not suppress a first write with all 0s
nop_en = Signal(reset=0)
addresses_equal = [getattr(self.ev, a) == getattr(buf, a)
for a in ("data", "address")
if hasattr(self.ev, a)]
if addresses_equal:
self.sync.rsys += nop.eq(
nop_en & reduce(and_, addresses_equal))
else:
self.comb.eq(nop.eq(0))
self.sync.rsys += [
nop.eq(nop_en &
optree("&",
[getattr(self.ev, a) == getattr(buf, a)
for a in ("data", "address")
if hasattr(self.ev, a)],
default=0)),
# buf now contains valid data. enable NOP.
If(self.we & ~any_error, nop_en.eq(1)),
# underflows cancel the write. allow it to be retried.
@ -156,7 +166,7 @@ class _OutputManager(Module):
]
# Buffer read and FIFO write
self.comb += fifo.din.eq(buf)
self.comb += fifo_in.eq(buf)
in_guard_time = Signal()
self.comb += in_guard_time.eq(
buf.timestamp[fine_ts_width:]
@ -195,7 +205,7 @@ class _OutputManager(Module):
self.sync.rio += \
If(fifo.re,
dout_stb.eq(1),
dout.eq(fifo.dout)
dout.eq(fifo_out)
).Elif(dout_ack,
dout_stb.eq(0)
)
@ -235,24 +245,30 @@ class _InputManager(Module):
# # #
fifo = RenameClockDomains(AsyncFIFO(ev_layout, fifo_depth),
{"read": "rsys", "write": "rio"})
fifo = ClockDomainsRenamer({"read": "rsys", "write": "rio"})(
AsyncFIFO(layout_len(ev_layout), fifo_depth))
self.submodules += fifo
fifo_in = Record(ev_layout)
fifo_out = Record(ev_layout)
self.comb += [
fifo.din.eq(fifo_in.raw_bits()),
fifo_out.raw_bits().eq(fifo.dout)
]
# FIFO write
if data_width:
self.comb += fifo.din.data.eq(interface.data)
self.comb += fifo_in.data.eq(interface.data)
if interface.timestamped:
if fine_ts_width:
full_ts = Cat(interface.fine_ts, counter.value_rio)
else:
full_ts = counter.value_rio
self.comb += fifo.din.timestamp.eq(full_ts)
self.comb += fifo_in.timestamp.eq(full_ts)
self.comb += fifo.we.eq(interface.stb)
# FIFO read
self.comb += [
self.ev.eq(fifo.dout),
self.ev.eq(fifo_out),
self.readable.eq(fifo.readable),
fifo.re.eq(self.re)
]
@ -376,8 +392,8 @@ class RTIO(Module):
if hasattr(o_manager.ev, "address"):
self.comb += o_manager.ev.address.eq(
self.kcsrs.o_address.storage)
ts_shift = (flen(self.kcsrs.o_timestamp.storage)
- flen(o_manager.ev.timestamp))
ts_shift = (len(self.kcsrs.o_timestamp.storage)
- len(o_manager.ev.timestamp))
self.comb += o_manager.ev.timestamp.eq(
self.kcsrs.o_timestamp.storage[ts_shift:])
@ -412,8 +428,8 @@ class RTIO(Module):
else:
i_datas.append(0)
if channel.interface.i.timestamped:
ts_shift = (flen(self.kcsrs.i_timestamp.status)
- flen(i_manager.ev.timestamp))
ts_shift = (len(self.kcsrs.i_timestamp.status)
- len(i_manager.ev.timestamp))
i_timestamps.append(i_manager.ev.timestamp << ts_shift)
else:
i_timestamps.append(0)

View File

@ -1,6 +1,6 @@
from migen.fhdl.std import *
from migen.bank.description import *
from migen import *
from migen.genlib.cdc import BusSynchronizer, MultiReg
from misoc.interconnect.csr import *
class Monitor(Module, AutoCSR):
@ -8,7 +8,7 @@ class Monitor(Module, AutoCSR):
chan_probes = [c.probes for c in channels]
max_chan_probes = max(len(cp) for cp in chan_probes)
max_probe_len = max(flen(p) for cp in chan_probes for p in cp)
max_probe_len = max(len(p) for cp in chan_probes for p in cp)
self.chan_sel = CSRStorage(bits_for(len(chan_probes)-1))
self.probe_sel = CSRStorage(bits_for(max_chan_probes-1))
self.value_update = CSR()
@ -20,7 +20,7 @@ class Monitor(Module, AutoCSR):
for cp in chan_probes:
cp_sys = []
for p in cp:
vs = BusSynchronizer(flen(p), "rio", "rsys")
vs = BusSynchronizer(len(p), "rio", "rsys")
self.submodules += vs
self.comb += vs.i.eq(p)
cp_sys.append(vs.o)
@ -36,7 +36,7 @@ class Injector(Module, AutoCSR):
chan_overrides = [c.overrides for c in channels]
max_chan_overrides = max(len(co) for co in chan_overrides)
max_override_len = max(flen(o) for co in chan_overrides for o in co)
max_override_len = max(len(o) for co in chan_overrides for o in co)
self.chan_sel = CSRStorage(bits_for(len(chan_overrides)-1))
self.override_sel = CSRStorage(bits_for(max_chan_overrides-1))
self.value = CSR(max_override_len)

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import *
from migen import *
from artiq.gateware import ad9xxx
from artiq.gateware.rtio.phy.wishbone import RT2WB
@ -6,9 +6,9 @@ from artiq.gateware.rtio.phy.wishbone import RT2WB
class _AD9xxx(Module):
def __init__(self, ftw_base, pads, nchannels, onehot=False, **kwargs):
self.submodules._ll = RenameClockDomains(
ad9xxx.AD9xxx(pads, **kwargs), "rio")
self.submodules._rt2wb = RT2WB(flen(pads.a)+1, self._ll.bus)
self.submodules._ll = ClockDomainsRenamer("rio")(
ad9xxx.AD9xxx(pads, **kwargs))
self.submodules._rt2wb = RT2WB(len(pads.a)+1, self._ll.bus)
self.rtlink = self._rt2wb.rtlink
self.probes = [Signal(32) for i in range(nchannels)]
@ -22,8 +22,8 @@ class _AD9xxx(Module):
current_data.eq(self.rtlink.o.data))
# keep track of the currently selected channel(s)
current_sel = Signal(flen(current_data)-1)
self.sync.rio += If(current_address == 2**flen(pads.a) + 1,
current_sel = Signal(len(current_data)-1)
self.sync.rio += If(current_address == 2**len(pads.a) + 1,
current_sel.eq(current_data[1:])) # strip reset
def selected(c):
@ -35,13 +35,13 @@ class _AD9xxx(Module):
# keep track of frequency tuning words, before they are FUDed
ftws = [Signal(32) for i in range(nchannels)]
for c, ftw in enumerate(ftws):
if flen(pads.d) == 8:
if len(pads.d) == 8:
self.sync.rio_phy += \
If(selected(c), [
If(current_address == ftw_base+i,
ftw[i*8:(i+1)*8].eq(current_data))
for i in range(4)])
elif flen(pads.d) == 16:
elif len(pads.d) == 16:
self.sync.rio_phy += \
If(selected(c), [
If(current_address == ftw_base+2*i,
@ -51,7 +51,7 @@ class _AD9xxx(Module):
raise NotImplementedError
# FTW to probe on FUD
self.sync.rio_phy += If(current_address == 2**flen(pads.a), [
self.sync.rio_phy += If(current_address == 2**len(pads.a), [
If(selected(c), probe.eq(ftw))
for c, (probe, ftw) in enumerate(zip(self.probes, ftws))])

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import *
from migen import *
from artiq.gateware.rtio.phy import ttl_serdes_generic

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import *
from migen import *
from migen.genlib.coding import PriorityEncoder
from artiq.gateware.rtio import rtlink
@ -18,7 +18,7 @@ def _mk_edges(w, direction):
class _SerdesDriver(Module):
def __init__(self, serdes_o, stb, data, fine_ts, override_en, override_o):
previous_data = Signal()
serdes_width = flen(serdes_o)
serdes_width = len(serdes_o)
edges = Array(_mk_edges(serdes_width, "rising"))
edges_n = Array(_mk_edges(serdes_width, "falling"))
self.sync.rio_phy += [
@ -40,7 +40,7 @@ class _SerdesDriver(Module):
class Output(Module):
def __init__(self, serdes):
self.rtlink = rtlink.Interface(
rtlink.OInterface(1, fine_ts_width=log2_int(flen(serdes.o))))
rtlink.OInterface(1, fine_ts_width=log2_int(len(serdes.o))))
self.probes = [serdes.o[-1]]
override_en = Signal()
override_o = Signal()
@ -56,8 +56,8 @@ class Output(Module):
class Inout(Module):
def __init__(self, serdes):
serdes_width = flen(serdes.o)
assert flen(serdes.i) == serdes_width
serdes_width = len(serdes.o)
assert len(serdes.i) == serdes_width
self.rtlink = rtlink.Interface(
rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)),
rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width)))

View File

@ -1,6 +1,6 @@
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
from migen.fhdl.std import *
from migen import *
from artiq.gateware.rtio.phy import ttl_serdes_generic

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import *
from migen import *
from migen.genlib.cdc import MultiReg
from artiq.gateware.rtio import rtlink

View File

@ -1,5 +1,5 @@
from migen.fhdl.std import *
from migen.bus import wishbone
from migen import *
from misoc.interconnect import wishbone
from artiq.gateware.rtio import rtlink
@ -11,11 +11,11 @@ class RT2WB(Module):
self.wb = wb
self.rtlink = rtlink.Interface(
rtlink.OInterface(
flen(wb.dat_w),
len(wb.dat_w),
address_width + 1,
suppress_nop=False),
rtlink.IInterface(
flen(wb.dat_r),
len(wb.dat_r),
timestamped=False)
)
@ -28,7 +28,7 @@ class RT2WB(Module):
wb.adr.eq(self.rtlink.o.address[:address_width]),
wb.we.eq(~self.rtlink.o.address[address_width]),
wb.dat_w.eq(self.rtlink.o.data),
wb.sel.eq(2**flen(wb.sel) - 1)
wb.sel.eq(2**len(wb.sel) - 1)
),
If(wb.ack,
active.eq(0)

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import *
from migen import *
class OInterface:
@ -64,7 +64,7 @@ def _get_or_zero(interface, attr):
_get_or_zero(interface.o, attr))
else:
if hasattr(interface, attr):
return flen(getattr(interface, attr))
return len(getattr(interface, attr))
else:
return 0

View File

@ -1,5 +1,5 @@
from misoclib.soc import mem_decoder
from misoclib.cpu import timer
from misoc.integration.soc_core import mem_decoder
from misoc.cores import timer
from artiq.gateware import amp
@ -11,7 +11,7 @@ class AMPSoC:
a "mailbox" entry in the memory map.
"""
def __init__(self):
if not hasattr(self, "cpu_or_bridge"):
if not hasattr(self, "cpu"):
raise ValueError("Platform SoC must be initialized first")
if hasattr(self, "timer0"):
raise ValueError("Timer already exists. "

View File

@ -1,20 +1,26 @@
from migen.fhdl.std import *
#!/usr/bin/env python3
import argparse
import os
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import MultiReg
from migen.bank.description import *
from migen.bank import wbgen
from mibuild.generic_platform import *
from mibuild.xilinx.vivado import XilinxVivadoToolchain
from mibuild.xilinx.ise import XilinxISEToolchain
from migen.build.generic_platform import *
from migen.build.xilinx.vivado import XilinxVivadoToolchain
from migen.build.xilinx.ise import XilinxISEToolchain
from misoclib.com import gpio
from misoclib.soc import mem_decoder
from misoclib.mem.sdram.core.minicon import MiniconSettings
from targets.kc705 import MiniSoC
from misoc.interconnect.csr import *
from misoc.interconnect import wishbone
from misoc.cores import gpio
from misoc.integration.soc_core import mem_decoder
from misoc.integration.builder import *
from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict
from artiq.gateware.soc import AMPSoC
from artiq.gateware import rtio, nist_qc1, nist_qc2
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds
from artiq.tools import artiq_dir
class _RTIOCRG(Module, AutoCSR):
@ -87,15 +93,17 @@ class _NIST_QCx(MiniSoC, AMPSoC):
}
mem_map.update(MiniSoC.mem_map)
def __init__(self, platform, cpu_type="or1k", **kwargs):
MiniSoC.__init__(self, platform,
def __init__(self, cpu_type="or1k", **kwargs):
MiniSoC.__init__(self,
cpu_type=cpu_type,
sdram_controller_settings=MiniconSettings(l2_size=128*1024),
sdram_controller_type="minicon",
l2_size=128*1024,
with_timer=False, **kwargs)
AMPSoC.__init__(self)
self.submodules.leds = gpio.GPIOOut(Cat(
platform.request("user_led", 0),
platform.request("user_led", 1)))
self.platform.request("user_led", 0),
self.platform.request("user_led", 1)))
def add_rtio(self, rtio_channels):
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
@ -121,7 +129,7 @@ TIMESPEC "TSfix_cdc2" = FROM "GRPrio_clk" TO "GRPrsys_clk" TIG;
""", rio_clk=self.rtio_crg.cd_rtio.clk)
rtio_csrs = self.rtio.get_csrs()
self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
self.submodules.rtiowb = wishbone.CSRBank(rtio_csrs)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
@ -129,8 +137,10 @@ TIMESPEC "TSfix_cdc2" = FROM "GRPrio_clk" TO "GRPrsys_clk" TIG;
class NIST_QC1(_NIST_QCx):
def __init__(self, platform, cpu_type="or1k", **kwargs):
_NIST_QCx.__init__(self, platform, cpu_type, **kwargs)
def __init__(self, cpu_type="or1k", **kwargs):
_NIST_QCx.__init__(self, cpu_type, **kwargs)
platform = self.platform
platform.add_extension(nist_qc1.fmc_adapter_io)
self.comb += [
@ -172,8 +182,10 @@ class NIST_QC1(_NIST_QCx):
class NIST_QC2(_NIST_QCx):
def __init__(self, platform, cpu_type="or1k", **kwargs):
_NIST_QCx.__init__(self, platform, cpu_type, **kwargs)
def __init__(self, cpu_type="or1k", **kwargs):
_NIST_QCx.__init__(self, cpu_type, **kwargs)
platform = self.platform
platform.add_extension(nist_qc2.fmc_adapter_io)
rtio_channels = []
@ -214,4 +226,34 @@ class NIST_QC2(_NIST_QCx):
self.add_rtio(rtio_channels)
default_subtarget = NIST_QC1
def main():
parser = argparse.ArgumentParser(
description="ARTIQ core device builder / KC705 "
"+ NIST Ions QC1/QC2 hardware adapters")
builder_args(parser)
soc_kc705_args(parser)
parser.add_argument("-H", "--hw-adapter", default="qc1",
help="hardware adapter type: qc1/qc2 "
"(default: %(default)s)")
args = parser.parse_args()
hw_adapter = args.hw_adapter.lower()
if hw_adapter == "qc1":
cls = NIST_QC1
elif hw_adapter == "qc2":
cls = NIST_QC2
else:
print("Invalid hardware adapter string (-H/--hw-adapter), "
"choose from qc1 or qc2")
sys.exit(1)
soc = cls(**soc_kc705_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.add_software_package("liblwip", os.path.join(artiq_dir, "runtime",
"liblwip"))
builder.add_software_package("runtime", os.path.join(artiq_dir, "runtime"))
builder.build()
if __name__ == "__main__":
main()

View File

@ -1,22 +1,26 @@
#!/usr/bin/env python3
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
# Copyright (C) 2014, 2015 M-Labs Limited
import argparse
import os
from fractions import Fraction
from migen.fhdl.std import *
from migen.bank.description import *
from migen.bank import wbgen
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import MultiReg
from misoclib.com import gpio
from misoclib.soc import mem_decoder
from misoclib.mem.sdram.core.minicon import MiniconSettings
from targets.pipistrello import BaseSoC
from misoc.interconnect.csr import *
from misoc.interconnect import wishbone
from misoc.cores import gpio
from misoc.integration.soc_core import mem_decoder
from misoc.targets.pipistrello import *
from artiq.gateware.soc import AMPSoC
from artiq.gateware import rtio, nist_qc1
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_spartan6, dds
from artiq.tools import artiq_dir
class _RTIOCRG(Module, AutoCSR):
@ -110,12 +114,15 @@ class NIST_QC1(BaseSoC, AMPSoC):
}
mem_map.update(BaseSoC.mem_map)
def __init__(self, platform, cpu_type="or1k", **kwargs):
BaseSoC.__init__(self, platform,
def __init__(self, cpu_type="or1k", **kwargs):
BaseSoC.__init__(self,
cpu_type=cpu_type,
sdram_controller_settings=MiniconSettings(l2_size=64*1024),
l2_size=64*1024,
with_timer=False, **kwargs)
AMPSoC.__init__(self)
platform = self.platform
platform.toolchain.ise_commands += """
trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf
"""
@ -192,11 +199,28 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
# CPU connections
rtio_csrs = self.rtio.get_csrs()
self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
self.submodules.rtiowb = wishbone.CSRBank(rtio_csrs)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
rtio_csrs)
default_subtarget = NIST_QC1
def main():
parser = argparse.ArgumentParser(
description="ARTIQ core device builder / Pipistrello "
"+ NIST Ions QC1 hardware adapter")
builder_args(parser)
soc_pipistrello_args(parser)
args = parser.parse_args()
soc = NIST_QC1(**soc_pipistrello_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.add_software_package("liblwip", os.path.join(artiq_dir, "runtime",
"liblwip"))
builder.add_software_package("runtime", os.path.join(artiq_dir, "runtime"))
builder.build()
if __name__ == "__main__":
main()

View File

@ -216,7 +216,7 @@ class _ArgumentEditor(QtGui.QTreeWidget):
class ExplorerDock(dockarea.Dock):
def __init__(self, main_window, status_bar, schedule_ctl):
def __init__(self, main_window, status_bar, schedule_ctl, repository_ctl):
dockarea.Dock.__init__(self, "Explorer", size=(1500, 500))
self.main_window = main_window
@ -263,8 +263,7 @@ class ExplorerDock(dockarea.Dock):
grid.addWidget(self.log_level, 3, 3)
submit = QtGui.QPushButton("Submit")
submit.setShortcut("CTRL+RETURN")
submit.setToolTip("Schedule the selected experiment (CTRL+ENTER)")
submit.setToolTip("Schedule the selected experiment (Ctrl+Return)")
grid.addWidget(submit, 4, 0, colspan=4)
submit.clicked.connect(self.submit_clicked)
@ -276,9 +275,29 @@ class ExplorerDock(dockarea.Dock):
self.shortcuts = ShortcutManager(self.main_window, self)
self.el.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
submit_action = QtGui.QAction("Submit", self.el)
submit_action.triggered.connect(self.submit_clicked)
submit_action.setShortcut("CTRL+RETURN")
self.el.addAction(submit_action)
reqterm_action = QtGui.QAction("Request termination of instances", self.el)
reqterm_action.triggered.connect(self.request_inst_term)
reqterm_action.setShortcut("CTRL+BACKSPACE")
self.el.addAction(reqterm_action)
sep = QtGui.QAction(self.el)
sep.setSeparator(True)
self.el.addAction(sep)
edit_shortcuts_action = QtGui.QAction("Edit shortcuts", self.el)
edit_shortcuts_action.triggered.connect(self.edit_shortcuts)
self.el.addAction(edit_shortcuts_action)
scan_repository_action = QtGui.QAction("(Re)scan repository HEAD",
self.el)
def scan_repository():
asyncio.ensure_future(repository_ctl.scan_async())
self.status_bar.showMessage("Requested repository scan")
scan_repository_action.triggered.connect(scan_repository)
self.el.addAction(scan_repository_action)
def update_selection(self, selected, deselected):
if deselected:
@ -385,6 +404,28 @@ class ExplorerDock(dockarea.Dock):
due_date,
self.flush.isChecked())
async def request_term_multiple(self, rids):
for rid in rids:
try:
await self.schedule_ctl.request_termination(rid)
except:
pass
def request_inst_term(self):
if self.selected_key is not None:
expinfo = self.explist_model.backing_store[self.selected_key]
# attribute get_current_schedule must be set externally after
# instance creation
current_schedule = self.get_current_schedule()
rids = []
for rid, desc in current_schedule.items():
expid = desc["expid"]
if ("repo_rev" in expid # only consider runs from repository
and expid["file"] == expinfo["file"]
and expid["class_name"] == expinfo["class_name"]):
rids.append(rid)
asyncio.ensure_future(self.request_term_multiple(rids))
def edit_shortcuts(self):
experiments = sorted(self.explist_model.backing_store.keys())
self.shortcuts.edit(experiments)

View File

@ -191,10 +191,14 @@ class LogDock(dockarea.Dock):
await self.subscriber.close()
def filter_level_changed(self):
if not hasattr(self, "table_model_filter"):
return
self.table_model_filter.set_min_level(
getattr(logging, self.filter_level.currentText()))
def filter_freetext_changed(self):
if not hasattr(self, "table_model_filter"):
return
self.table_model_filter.set_freetext(self.filter_freetext.text())
def rows_inserted_before(self):

View File

@ -82,7 +82,6 @@ class ScheduleDock(dockarea.Dock):
delete_action.setShortcut("SHIFT+DELETE")
self.table.addAction(delete_action)
async def sub_connect(self, host, port):
self.subscriber = Subscriber("schedule", self.init_schedule_model)
await self.subscriber.connect(host, port)
@ -90,6 +89,13 @@ class ScheduleDock(dockarea.Dock):
async def sub_close(self):
await self.subscriber.close()
def get_current_schedule(self):
try:
table_model = self.table_model
except AttributeError:
return dict()
return table_model.backing_store
def init_schedule_model(self, init):
self.table_model = _ScheduleModel(self.table, init)
self.table.setModel(self.table_model)

68
artiq/runtime/Makefile Normal file
View File

@ -0,0 +1,68 @@
include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak
PYTHON ?= python3
OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
session.o log.o moninj.o net_server.o bridge_ctl.o \
ksupport_data.o kloader.o test_mode.o main.o
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
bridge.o rtio.o ttl.o dds.o
CFLAGS += -I$(MISOC_DIRECTORY)/software/include/dyld \
-I$(LIBDYLD_DIRECTORY)/include \
-I$(LIBUNWIND_DIRECTORY) \
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
-I$(LIBLWIP_DIRECTORY)/../lwip/src/include \
-I$(LIBLWIP_DIRECTORY)
all: runtime.bin runtime.fbi
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@
%.fbi: %.bin
@echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $<
runtime.elf: $(OBJECTS)
$(LD) $(LDFLAGS) \
-T $(RUNTIME_DIRECTORY)/runtime.ld \
-N -o $@ \
../libbase/crt0-$(CPU).o \
$(OBJECTS) \
-L../libbase \
-L../libcompiler_rt \
-L../liblwip \
-lbase -lcompiler_rt -llwip
@chmod -x $@
ksupport.elf: $(OBJECTS_KSUPPORT)
$(LD) $(LDFLAGS) \
--eh-frame-hdr \
-T $(RUNTIME_DIRECTORY)/ksupport.ld \
-N -o $@ \
../libbase/crt0-$(CPU).o \
$^ \
-L../libbase \
-L../libcompiler_rt \
-L../libunwind \
-L../libdyld \
-lbase -lcompiler_rt -lunwind -ldyld
@chmod -x $@
ksupport_data.o: ksupport.elf
$(LD) -r -b binary -o $@ $<
%.o: $(RUNTIME_DIRECTORY)/%.c
$(compile)
%.o: $(RUNTIME_DIRECTORY)/%.S
$(assemble)
clean:
$(RM) $(OBJECTS) $(OBJECTS_KSUPPORT)
$(RM) runtime.elf runtime.bin runtime.fbi .*~ *~
$(RM) ksupport.elf ksupport.bin
.PHONY: all clean

View File

@ -92,7 +92,7 @@ static int kloader_start_flash_kernel(char *key)
{
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
char buffer[32*1024];
int length, remain;
unsigned int length, remain;
length = fs_read(key, buffer, sizeof(buffer), &remain);
if(length <= 0)

View File

@ -0,0 +1,66 @@
include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak
LWIPDIR=$(LIBLWIP_DIRECTORY)/../lwip/src
CFLAGS += $(CPPFLAGS) -I. \
-I$(LWIPDIR)/include \
-I$(LWIPDIR)/include/ipv4
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREFILES=core/mem.c \
core/memp.c \
core/netif.c \
core/pbuf.c \
core/raw.c \
core/stats.c \
core/sys.c \
core/tcp.c \
core/tcp_in.c \
core/tcp_out.c \
core/udp.c \
core/dhcp.c \
core/inet_chksum.c \
core/timers.c \
core/init.c
CORE4FILES=core/ipv4/icmp.c \
core/ipv4/ip4.c \
core/ipv4/ip4_addr.c \
core/ipv4/ip_frag.c
# NETIFFILES: Files implementing various generic network interface functions.
NETIFFILES=netif/etharp.c
# LWIPFILES: All the above.
LWIPFILES=$(COREFILES) $(CORE4FILES) $(NETIFFILES)
LWIPOBJS:=$(LWIPFILES:.c=.o) liteethif.o
all: prepare liblwip.a
prepare:
ln -sf $(LIBLWIP_DIRECTORY)/lwipopts.h lwipopts.h
ln -sf $(LIBLWIP_DIRECTORY)/arch arch
mkdir -p core/ipv4
mkdir -p netif
core/%.o: $(LWIPDIR)/core/%.c
$(compile)
core/ipv4/%.o: $(LWIPDIR)/core/ipv4/%.c
$(compile)
netif/%.o: $(LWIPDIR)/netif/%.c
$(compile)
%.o: $(LIBLWIP_DIRECTORY)/%.c
$(compile)
.PHONY: all clean prepare
clean:
rm -f $(LWIPOBJS) liblwip.a
liblwip.a: $(LWIPOBJS)
$(AR) clr liblwip.a $(LWIPOBJS)

View File

@ -10,7 +10,7 @@
#include <lwip/mem.h>
#include <netif/etharp.h>
#include "netif/liteethif.h"
#include "liteethif.h"
#include <hw/flags.h>
#include <hw/ethmac_mem.h>

View File

@ -8,8 +8,6 @@
#include <hw/flags.h>
#ifdef CSR_ETHMAC_BASE
#include <netif/etharp.h>
#include <netif/liteethif.h>
#include <lwip/init.h>
#include <lwip/memp.h>
#include <lwip/ip4_addr.h>
@ -18,6 +16,8 @@
#include <lwip/sys.h>
#include <lwip/tcp.h>
#include <lwip/timers.h>
#include <netif/etharp.h>
#include <liteethif.h>
#endif
#include "bridge_ctl.h"

View File

@ -2,8 +2,6 @@
#ifdef CSR_ETHMAC_BASE
#include <netif/etharp.h>
#include <netif/liteethif.h>
#include <lwip/init.h>
#include <lwip/memp.h>
#include <lwip/ip4_addr.h>
@ -12,6 +10,8 @@
#include <lwip/sys.h>
#include <lwip/tcp.h>
#include <lwip/timers.h>
#include <netif/etharp.h>
#include <liteethif.h>
#include "session.h"
#include "net_server.h"

View File

@ -1,6 +1,5 @@
#include <generated/csr.h>
#include "exceptions.h"
#include "rtio.h"
void rtio_init(void)
@ -22,17 +21,20 @@ void rtio_process_exceptional_status(int status, long long int timestamp, int ch
while(rtio_o_status_read() & RTIO_O_STATUS_FULL);
if(status & RTIO_O_STATUS_UNDERFLOW) {
rtio_o_underflow_reset_write(1);
exception_raise_params(EID_RTIO_UNDERFLOW,
artiq_raise_from_c("RTIOUnderflow",
"RTIO underflow at {0} mu, channel {1}, counter {2}",
timestamp, channel, rtio_get_counter());
}
if(status & RTIO_O_STATUS_SEQUENCE_ERROR) {
rtio_o_sequence_error_reset_write(1);
exception_raise_params(EID_RTIO_SEQUENCE_ERROR,
artiq_raise_from_c("RTIOSequenceError",
"RTIO sequence error at {0} mu, channel {1}",
timestamp, channel, 0);
}
if(status & RTIO_O_STATUS_COLLISION_ERROR) {
rtio_o_collision_error_reset_write(1);
exception_raise_params(EID_RTIO_COLLISION_ERROR,
artiq_raise_from_c("RTIOCollisionError",
"RTIO collision error at {0} mu, channel {1}",
timestamp, channel, 0);
}
}

View File

@ -299,6 +299,7 @@ void session_startup_kernel(void)
if(!kloader_start_startup_kernel())
return;
log("Startup kernel started");
while(1) {
kloader_service_essential_kmsg();

View File

@ -6,7 +6,7 @@ import sys
import asyncio
import time
import collections
import os.path
import os
import numpy as np
@ -16,6 +16,8 @@ from artiq.protocols import pyon
logger = logging.getLogger(__name__)
artiq_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)))
def parse_arguments(arguments):
d = {}

View File

@ -3,24 +3,13 @@
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705
mkdir -p $SOC_PREFIX/nist_qc1
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-qc1
mkdir -p $SOC_PREFIX
SOC_ROOT=$PWD/soc
$PYTHON -m artiq.gateware.targets.kc705 -H qc1 --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE
cp misoc_nist_qc1_kc705/gateware/top.bit $SOC_PREFIX
cp misoc_nist_qc1_kc705/software/bios/bios.bin $SOC_PREFIX
cp misoc_nist_qc1_kc705/software/runtime/runtime.fbi $SOC_PREFIX
# build bitstream
(cd $MSCDIR; $PYTHON make.py -X $SOC_ROOT -t artiq_kc705 $MISOC_EXTRA_VIVADO_CMDLINE build-bitstream)
cp $MSCDIR/build/artiq_kc705-nist_qc1-kc705.bit $SOC_PREFIX/
wget http://sionneau.net/artiq/binaries/kc705/flash_proxy/bscan_spi_kc705.bit
mv bscan_spi_kc705.bit $SOC_PREFIX/
# build BIOS
(cd $MSCDIR; $PYTHON make.py -X $SOC_ROOT -t artiq_kc705 build-headers build-bios)
cp $MSCDIR/software/bios/bios.bin $SOC_PREFIX/
# build runtime
make -C soc/runtime clean runtime.fbi
cp soc/runtime/runtime.fbi $SOC_PREFIX/nist_qc1/
mv bscan_spi_kc705.bit $SOC_PREFIX

View File

@ -15,7 +15,8 @@ requirements:
build:
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
- artiq 0.0
- migen 0.0
- migen 0.2
- misoc 0.1
- llvm-or1k
- binutils-or1k-linux
run:

View File

@ -3,24 +3,13 @@
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705
mkdir -p $SOC_PREFIX/nist_qc2
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-qc2
mkdir -p $SOC_PREFIX
SOC_ROOT=$PWD/soc
$PYTHON -m artiq.gateware.targets.kc705 -H qc2 --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE
cp misoc_nist_qc2_kc705/gateware/top.bit $SOC_PREFIX
cp misoc_nist_qc2_kc705/software/bios/bios.bin $SOC_PREFIX
cp misoc_nist_qc2_kc705/software/runtime/runtime.fbi $SOC_PREFIX
# build bitstream
(cd $MSCDIR; $PYTHON make.py -X $SOC_ROOT -t artiq_kc705 -s NIST_QC2 $MISOC_EXTRA_VIVADO_CMDLINE build-bitstream)
cp $MSCDIR/build/artiq_kc705-nist_qc2-kc705.bit $SOC_PREFIX/
wget http://sionneau.net/artiq/binaries/kc705/flash_proxy/bscan_spi_kc705.bit
mv bscan_spi_kc705.bit $SOC_PREFIX/
# build BIOS
(cd $MSCDIR; $PYTHON make.py -X $SOC_ROOT -t artiq_kc705 -s NIST_QC2 build-headers build-bios)
cp $MSCDIR/software/bios/bios.bin $SOC_PREFIX/
# build runtime
make -C soc/runtime clean runtime.fbi
cp soc/runtime/runtime.fbi $SOC_PREFIX/nist_qc2/
mv bscan_spi_kc705.bit $SOC_PREFIX

View File

@ -15,7 +15,8 @@ requirements:
build:
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
- artiq 0.0
- migen 0.0
- migen 0.2
- misoc 0.1
- llvm-or1k
- binutils-or1k-linux
run:

View File

@ -3,24 +3,13 @@
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/pipistrello
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/pipistrello-qc1
mkdir -p $SOC_PREFIX
SOC_ROOT=$PWD/soc
$PYTHON -m artiq.gateware.targets.pipistrello $MISOC_EXTRA_ISE_CMDLINE
cp misoc_nist_qc1_pipistrello/gateware/top.bit $SOC_PREFIX
cp misoc_nist_qc1_pipistrello/software/bios/bios.bin $SOC_PREFIX
cp misoc_nist_qc1_pipistrello/software/runtime/runtime.fbi $SOC_PREFIX
# build bitstream
(cd $MSCDIR; $PYTHON make.py -X $SOC_ROOT -t artiq_pipistrello $MISOC_EXTRA_ISE_CMDLINE build-bitstream)
cp $MSCDIR/build/artiq_pipistrello-nist_qc1-pipistrello.bit $SOC_PREFIX/
wget https://people.phys.ethz.ch/~robertjo/bscan_spi_lx45_csg324.bit
mv bscan_spi_lx45_csg324.bit $SOC_PREFIX/
# build BIOS
(cd $MSCDIR; $PYTHON make.py -X $SOC_ROOT -t artiq_pipistrello build-headers build-bios)
cp $MSCDIR/software/bios/bios.bin $SOC_PREFIX/
# build runtime
make -C soc/runtime clean runtime.fbi
cp soc/runtime/runtime.fbi $SOC_PREFIX/
mv bscan_spi_lx45_csg324.bit $SOC_PREFIX

View File

@ -15,7 +15,8 @@ requirements:
build:
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
- artiq 0.0
- migen 0.0
- migen 0.2
- misoc 0.1
- llvm-or1k
- binutils-or1k-linux
run:

View File

@ -33,7 +33,6 @@ requirements:
- python >=3.5.0
- setuptools
- numpy
- migen 0.0
- pyelftools
- binutils-or1k-linux
run:

View File

@ -220,16 +220,18 @@ These steps are required to generate bitstream (``.bit``) files, build the MiSoC
Then copy the generated ``bscan_spi_kc705.bit`` to ``~/.migen``, ``/usr/local/share/migen`` or ``/usr/share/migen``.
* Download MiSoC: ::
* Download and install MiSoC: ::
$ cd ~/artiq-dev
$ git clone --recursive https://github.com/m-labs/misoc
$ export MSCDIR=~/artiq-dev/misoc # append this line to .bashrc
$ cd misoc
$ python3 setup.py develop --user
* Download and install ARTIQ: ::
$ cd ~/artiq-dev
$ git clone --recursive https://github.com/m-labs/artiq
$ cd artiq
$ python3 setup.py develop --user
.. note::
@ -238,26 +240,30 @@ These steps are required to generate bitstream (``.bit``) files, build the MiSoC
:ref:`installing the host-side software <installing-the-host-side-software>`.
* Build and flash the bitstream and BIOS by running `from the MiSoC top-level directory`:
* Build the bitstream, BIOS and runtime by running:
::
$ cd ~/artiq-dev/misoc
$ cd ~/artiq-dev
$ export PATH=/usr/local/llvm-or1k/bin:$PATH
.. note:: Make sure that ``/usr/local/llvm-or1k/bin`` is first in your ``PATH``, so that the ``clang`` command you just built is found instead of the system one, if any.
* For Pipistrello::
$ ./make.py -X ~/artiq-dev/artiq/soc -t artiq_pipistrello all
$ python3 -m artiq.gateware.targets.pipistrello
* For KC705::
$ ./make.py -X ~/artiq-dev/artiq/soc -t artiq_kc705 all
$ python3 -m artiq.gateware.targets.kc705 -H qc1 # or qc2
* Then, build and flash the ARTIQ runtime: ::
* Then, gather the binaries and flash them: ::
$ cd ~/artiq-dev/artiq/soc/runtime && make runtime.fbi
$ ~/artiq-dev/artiq/artiq/frontend/artiq_flash.sh -t pipistrello -d $PWD -r
$ mkdir binaries
$ cp misoc_nist_qcX_<board>/gateware/top.bit binaries
$ cp misoc_nist_qcX_<board>/software/bios/bios.bin binaries
$ cp misoc_nist_qcX_<board>/software/runtime/runtime.fbi binaries
$ cd binaries
$ artiq_flash.sh -d . -t <board>
.. note:: The `-t` option specifies the board your are targeting. Available options are ``kc705`` and ``pipistrello``.
@ -323,7 +329,7 @@ Installing the host-side software
Configuring the core device
---------------------------
This should be done after either installation methods (conda or source).
This should be done after either installation method (conda or source).
.. _flash-mac-ip-addr:
@ -371,16 +377,16 @@ This should be done after either installation methods (conda or source).
.. note:: The reset button of the KC705 board is the "CPU_RST" labeled button.
.. warning:: Both those instructions will result in the flash storage being wiped out. However you can use the test mode to change the IP/MAC without erasing everything if you skip the "fserase" command.
* (optional) Flash the ``idle`` kernel
* (optional) Flash the idle kernel
The ``idle`` kernel is the kernel (some piece of code running on the core device) which the core device runs whenever it is not connected to a PC via ethernet.
The idle kernel is the kernel (some piece of code running on the core device) which the core device runs whenever it is not connected to a PC via ethernet.
This kernel is therefore stored in the :ref:`core device configuration flash storage <core-device-flash-storage>`.
To flash the ``idle`` kernel:
To flash the idle kernel:
* Compile the ``idle`` experiment:
The ``idle`` experiment's ``run()`` method must be a kernel: it must be decorated with the ``@kernel`` decorator (see :ref:`next topic <connecting-to-the-core-device>` for more information about kernels).
* Compile the idle experiment:
The idle experiment's ``run()`` method must be a kernel: it must be decorated with the ``@kernel`` decorator (see :ref:`next topic <connecting-to-the-core-device>` for more information about kernels).
Since the core device is not connected to the PC, RPCs (calling Python code running on the PC from the kernel) are forbidden in the ``idle`` experiment.
Since the core device is not connected to the PC, RPCs (calling Python code running on the PC from the kernel) are forbidden in the idle experiment.
::
$ artiq_compile idle.py
@ -391,6 +397,17 @@ To flash the ``idle`` kernel:
.. note:: You can find more information about how to use the ``artiq_coretool`` utility on the :ref:`Utilities <core-device-access-tool>` page.
* (optional) Flash the startup kernel
The startup kernel is executed once when the core device powers up. It should initialize DDSes, set up TTL directions, etc. Proceed as with the idle kernel, but using the ``startup_kernel`` key in ``artiq_coretool``.
* (optional) Select the startup clock
The core device may use either an external clock signal or its internal clock. This clock can be switched dynamically after the PC is connected using the ``external_clock`` parameter of the core device driver; however, one may want to select the clock at power-up so that it is used for the startup and idle kernels. Use one of these commands: ::
$ artiq_coretool cfg-write -s startup_clock i # internal clock (default)
$ artiq_coretool cfg-write -s startup_clock e # external clock
Ubuntu 14.04 specific instructions
----------------------------------

View File

@ -104,7 +104,7 @@ The artiq_coretool utility allows to perform maintenance on the core device:
* as well as read, write and remove key-value records from the :ref:`core-device-flash-storage`;
* erase the entire flash storage area.
To use this tool, you need to specify a ``device_db.pyon`` device database file which contains a ``comm`` device (an example is provided in ``artiq/examples/master/device_db.pyon``). This tells the tool how to connect to the core device (via serial or via TCP) and with which parameters (baudrate, serial device, IP address, TCP port). When not specified, the artiq_coretool utility will assume that there is a file named ``device_db.pyon`` in the current directory.
To use this tool, you need to specify a ``device_db.pyon`` device database file which contains a ``comm`` device (an example is provided in ``examples/master/device_db.pyon``). This tells the tool how to connect to the core device (via serial or via TCP) and with which parameters (baudrate, serial device, IP address, TCP port). When not specified, the artiq_coretool utility will assume that there is a file named ``device_db.pyon`` in the current directory.
To read the record whose key is ``mac``::
@ -117,7 +117,7 @@ To write the value ``test_value`` in the key ``my_key``::
$ artiq_coretool cfg-read my_key
b'test_value'
You can also write entire files in a record using the ``-f`` parameter. This is useful for instance to write the ``idle`` kernel in the flash storage::
You can also write entire files in a record using the ``-f`` parameter. This is useful for instance to write the startup and idle kernels in the flash storage::
$ artiq_coretool cfg-write -f idle_kernel idle.elf
$ artiq_coretool cfg-read idle_kernel | head -c9

View File

@ -1,3 +1,6 @@
# 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.
{
"comm": {
"type": "local",

View File

@ -6,6 +6,8 @@ from artiq import *
class DDSSetter(EnvExperiment):
"""DDS Setter"""
def build(self):
self.setattr_device("core")
self.dds = dict()
device_db = self.get_device_db()
@ -16,10 +18,16 @@ class DDSSetter(EnvExperiment):
and v["class"] in {"AD9858", "AD9914"}):
self.dds[k] = {
"driver": self.get_device(k),
"frequency": self.get_argument("{}_frequency".format(k),
NumberValue())
"frequency": self.get_argument(
"{}_frequency".format(k),
NumberValue(100e6, scale=1e6, unit="MHz", ndecimals=6))
}
@kernel
def set_dds(self, dds, frequency):
dds.set(frequency)
delay(200*ms)
def run(self):
for k, v in self.dds.items():
v["driver"].set(v["frequency"])
self.set_dds(v["driver"], v["frequency"])

View File

@ -1,77 +0,0 @@
include $(MSCDIR)/software/common.mak
OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
session.o log.o moninj.o net_server.o bridge_ctl.o \
ksupport_data.o kloader.o test_mode.o main.o
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
bridge.o rtio.o ttl.o dds.o
CFLAGS += -I$(MSCDIR)/software/include/dyld \
-I$(MSCDIR)/software/unwinder/include \
-I$(MSCDIR)/software/libunwind \
-Ilwip/src/include -Iliblwip
all: runtime.bin runtime.fbi
# pull in dependency info for *existing* .o files
-include $(OBJECTS:.o=.d)
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@
%.fbi: %.bin
@echo " MSCIMG " $@ && $(MSCDIR)/mkmscimg.py -f -o $@ $<
runtime.elf: $(OBJECTS) libs
$(LD) $(LDFLAGS) \
-T runtime.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
$(OBJECTS) \
-L$(MSCDIR)/software/libbase \
-L$(MSCDIR)/software/libcompiler-rt \
-Lliblwip \
-lbase -lcompiler-rt -llwip
@chmod -x $@
ksupport.elf: $(OBJECTS_KSUPPORT) libs
$(LD) $(LDFLAGS) \
--eh-frame-hdr \
-T ksupport.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
$(OBJECTS_KSUPPORT) \
-L$(MSCDIR)/software/libbase \
-L$(MSCDIR)/software/libcompiler-rt \
-L$(MSCDIR)/software/libunwind \
-L$(MSCDIR)/software/libdyld \
-lbase -lcompiler-rt -lunwind -ldyld
@chmod -x $@
ksupport_data.o: ksupport.elf
$(LD) -r -b binary -o $@ $<
main.o: main.c
$(compile-dep)
%.o: %.c
$(compile-dep)
%.o: %.S
$(assemble)
libs:
$(MAKE) -C $(MSCDIR)/software/libcompiler-rt
$(MAKE) -C $(MSCDIR)/software/libunwind
$(MAKE) -C $(MSCDIR)/software/libbase
$(MAKE) -C $(MSCDIR)/software/libdyld
$(MAKE) -C liblwip
clean:
$(MAKE) -C liblwip clean
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) $(OBJECTS_KSUPPORT) $(OBJECTS_KSUPPORT:.o=.d)
$(RM) runtime.elf runtime.bin runtime.fbi .*~ *~
$(RM) ksupport.elf ksupport.bin
.PHONY: all main.o clean libs load

View File

@ -1,55 +0,0 @@
include $(MSCDIR)/software/common.mak
LWIPDIR=../lwip/src
CFLAGS += $(CPPFLAGS) -I. \
-I$(LWIPDIR)/include \
-I$(LWIPDIR)/include/ipv4
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREOBJS=$(LWIPDIR)/core/mem.o \
$(LWIPDIR)/core/memp.o \
$(LWIPDIR)/core/netif.o \
$(LWIPDIR)/core/pbuf.o \
$(LWIPDIR)/core/raw.o \
$(LWIPDIR)/core/stats.o \
$(LWIPDIR)/core/sys.o \
$(LWIPDIR)/core/tcp.o \
$(LWIPDIR)/core/tcp_in.o \
$(LWIPDIR)/core/tcp_out.o \
$(LWIPDIR)/core/udp.o \
$(LWIPDIR)/core/dhcp.o \
$(LWIPDIR)/core/inet_chksum.o \
$(LWIPDIR)/core/timers.o \
$(LWIPDIR)/core/init.o
CORE4OBJS=$(LWIPDIR)/core/ipv4/icmp.o \
$(LWIPDIR)/core/ipv4/ip4.o \
$(LWIPDIR)/core/ipv4/ip4_addr.o \
$(LWIPDIR)/core/ipv4/ip_frag.o
# NETIFOBJS: Files implementing various generic network interface functions.
NETIFOBJS=$(LWIPDIR)/netif/etharp.o \
netif/liteethif.o
# LWIPOBJS: All the above.
LWIPOBJS=$(COREOBJS) $(CORE4OBJS) $(NETIFOBJS)
OBJS_LIB+=$(LWIPOBJS)
LWIPLIB=liblwip.a
all: $(LWIPLIB)
.PHONY: all compile clean
%.o: %.c
$(compile-dep)
%.o: %.S
$(assemble)
clean:
rm -f $(LWIPOBJS) $(LWIPOBJS:.o=.d) $(LWIPLIB)
liblwip.a: $(LWIPOBJS)
$(AR) clr liblwip.a $(LWIPOBJS)