forked from M-Labs/artiq
Merge branch 'master' into new-py2llvm
This commit is contained in:
commit
d6d0a3e3e9
|
@ -6,7 +6,6 @@ __pycache__
|
||||||
*.elf
|
*.elf
|
||||||
*.fbi
|
*.fbi
|
||||||
*.pyc
|
*.pyc
|
||||||
soc/runtime/service_table.h
|
|
||||||
doc/manual/_build
|
doc/manual/_build
|
||||||
/build
|
/build
|
||||||
/dist
|
/dist
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[submodule "soc/runtime/lwip"]
|
[submodule "artiq/runtime/lwip"]
|
||||||
path = soc/runtime/lwip
|
path = artiq/runtime/lwip
|
||||||
url = git://git.savannah.nongnu.org/lwip.git
|
url = git://git.savannah.nongnu.org/lwip.git
|
||||||
ignore = untracked
|
ignore = untracked
|
||||||
|
|
|
@ -18,7 +18,6 @@ install:
|
||||||
- if [ $TRAVIS_PULL_REQUEST != false ]; then BUILD_SOC=none; fi
|
- 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-xilinx.sh; fi
|
||||||
- if [ $BUILD_SOC != none ]; then ./.travis/get-toolchain.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
|
- . ./.travis/get-anaconda.sh
|
||||||
- source $HOME/miniconda/bin/activate py35
|
- source $HOME/miniconda/bin/activate py35
|
||||||
- conda install -q pip coverage anaconda-client cython
|
- conda install -q pip coverage anaconda-client cython
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export PATH=$HOME/miniconda/bin:$PATH
|
export PATH=$HOME/miniconda/bin:$PATH
|
||||||
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
|
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
|
||||||
bash miniconda.sh -b -p $HOME/miniconda
|
bash miniconda.sh -b -p $HOME/miniconda
|
||||||
|
|
|
@ -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
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
packages="http://us.archive.ubuntu.com/ubuntu/pool/universe/i/iverilog/iverilog_0.9.7-1_amd64.deb"
|
packages="http://us.archive.ubuntu.com/ubuntu/pool/universe/i/iverilog/iverilog_0.9.7-1_amd64.deb"
|
||||||
|
|
||||||
mkdir -p packages
|
mkdir -p packages
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
# Copyright (C) 2014, 2015 M-Labs Limited
|
# Copyright (C) 2014, 2015 M-Labs Limited
|
||||||
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
# 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
|
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
|
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
|
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
|
mkdir -p ~/.Xilinx
|
||||||
mv Xilinx.lic ~/.Xilinx/Xilinx.lic
|
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
|
make -C impersonate_macaddress
|
||||||
# Tell mibuild where Xilinx toolchains are installed
|
# Tell mibuild where Xilinx toolchains are installed
|
||||||
# and feed it the mac address corresponding to the license
|
# and feed it the mac address corresponding to the license
|
||||||
cat >> $HOME/.m-labs/build_settings.sh << EOF
|
cat >> $HOME/.m-labs/build_settings.sh << EOF
|
||||||
MISOC_EXTRA_VIVADO_CMDLINE="-Ob vivado_path $HOME/Xilinx/Vivado"
|
MISOC_EXTRA_ISE_CMDLINE="--gateware-toolchain-path $HOME/opt/Xilinx/"
|
||||||
MISOC_EXTRA_ISE_CMDLINE="-Ob ise_path $HOME/opt/Xilinx/"
|
MISOC_EXTRA_VIVADO_CMDLINE="--gateware-toolchain-path $HOME/Xilinx/Vivado"
|
||||||
export MACADDR=$macaddress
|
export MACADDR=$macaddress
|
||||||
export LD_PRELOAD=$PWD/impersonate_macaddress/impersonate_macaddress.so
|
export LD_PRELOAD=$PWD/impersonate_macaddress/impersonate_macaddress.so
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -11,17 +11,14 @@ def run(script):
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
run("""
|
run("""
|
||||||
# exit on error
|
|
||||||
set -e
|
set -e
|
||||||
# print commands
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
ARTIQ_PREFIX=$(python3 -c "import artiq; print(artiq.__path__[0])")
|
ARTIQ_PREFIX=$(python3 -c "import artiq; print(artiq.__path__[0])")
|
||||||
|
|
||||||
# Default is kc705
|
# Default is kc705
|
||||||
BOARD=kc705
|
BOARD=kc705
|
||||||
# Default mezzanine board is nist_qc1
|
# Default hardware adapter is qc1
|
||||||
MEZZANINE_BOARD=nist_qc1
|
HARDWARE_ADAPTER=qc1
|
||||||
|
|
||||||
while getopts "bBrht:d:f:m:" opt
|
while getopts "bBrht:d:f:m:" opt
|
||||||
do
|
do
|
||||||
|
@ -67,14 +64,14 @@ do
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
m)
|
m)
|
||||||
if [ "$OPTARG" == "nist_qc1" ]
|
if [ "$OPTARG" == "qc1" ]
|
||||||
then
|
then
|
||||||
MEZZANINE_BOARD=nist_qc1
|
HARDWARE_ADAPTER=qc1
|
||||||
elif [ "$OPTARG" == "nist_qc2" ]
|
elif [ "$OPTARG" == "qc2" ]
|
||||||
then
|
then
|
||||||
MEZZANINE_BOARD=nist_qc2
|
HARDWARE_ADAPTER=qc2
|
||||||
else
|
else
|
||||||
echo "KC705 mezzanine board is either nist_qc1 or nist_qc2"
|
echo "Hardware adapter should be qc1 or qc2"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
@ -88,8 +85,8 @@ do
|
||||||
echo "-B Flash BIOS"
|
echo "-B Flash BIOS"
|
||||||
echo "-r Flash ARTIQ runtime"
|
echo "-r Flash ARTIQ runtime"
|
||||||
echo "-h Show this help message"
|
echo "-h Show this help message"
|
||||||
echo "-t Target (kc705, pipistrello, default is: kc705)"
|
echo "-t Target (kc705/pipistrello, default: kc705)"
|
||||||
echo "-m Mezzanine board (nist_qc1, nist_qc2, default is: nist_qc1)"
|
echo "-m Hardware adapter (qc1/qc2, default: qc1)"
|
||||||
echo "-f Flash storage image generated with artiq_mkfs"
|
echo "-f Flash storage image generated with artiq_mkfs"
|
||||||
echo "-d Directory containing the binaries to be flashed"
|
echo "-d Directory containing the binaries to be flashed"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -129,30 +126,28 @@ fi
|
||||||
if [ "$BOARD" == "kc705" ]
|
if [ "$BOARD" == "kc705" ]
|
||||||
then
|
then
|
||||||
UDEV_RULES=99-kc705.rules
|
UDEV_RULES=99-kc705.rules
|
||||||
BITSTREAM=artiq_kc705-${MEZZANINE_BOARD}-kc705.bit
|
|
||||||
CABLE=jtaghs1_fast
|
CABLE=jtaghs1_fast
|
||||||
PROXY=bscan_spi_kc705.bit
|
PROXY=bscan_spi_kc705.bit
|
||||||
BIOS_ADDR=0xaf0000
|
BIOS_ADDR=0xaf0000
|
||||||
RUNTIME_ADDR=0xb00000
|
RUNTIME_ADDR=0xb00000
|
||||||
RUNTIME_FILE=runtime.fbi
|
|
||||||
FS_ADDR=0xb40000
|
FS_ADDR=0xb40000
|
||||||
if [ -z "$BIN_PREFIX" ]
|
if [ -z "$BIN_PREFIX" ]
|
||||||
then
|
then
|
||||||
RUNTIME_FILE=${MEZZANINE_BOARD}/runtime.fbi
|
BIN_PREFIX=$ARTIQ_PREFIX/binaries/kc705-$HARDWARE_ADAPTER
|
||||||
BIN_PREFIX=$ARTIQ_PREFIX/binaries/kc705
|
|
||||||
fi
|
fi
|
||||||
search_for_proxy $PROXY
|
search_for_proxy $PROXY
|
||||||
elif [ "$BOARD" == "pipistrello" ]
|
elif [ "$BOARD" == "pipistrello" ]
|
||||||
then
|
then
|
||||||
UDEV_RULES=99-papilio.rules
|
UDEV_RULES=99-papilio.rules
|
||||||
BITSTREAM=artiq_pipistrello-nist_qc1-pipistrello.bit
|
|
||||||
CABLE=papilio
|
CABLE=papilio
|
||||||
PROXY=bscan_spi_lx45_csg324.bit
|
PROXY=bscan_spi_lx45_csg324.bit
|
||||||
BIOS_ADDR=0x170000
|
BIOS_ADDR=0x170000
|
||||||
RUNTIME_ADDR=0x180000
|
RUNTIME_ADDR=0x180000
|
||||||
RUNTIME_FILE=runtime.fbi
|
|
||||||
FS_ADDR=0x1c0000
|
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
|
search_for_proxy $PROXY
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -195,7 +190,7 @@ fi
|
||||||
if [ "${FLASH_BITSTREAM}" == "1" ]
|
if [ "${FLASH_BITSTREAM}" == "1" ]
|
||||||
then
|
then
|
||||||
echo "Flashing FPGA bitstream..."
|
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
|
fi
|
||||||
|
|
||||||
if [ "${FLASH_BIOS}" == "1" ]
|
if [ "${FLASH_BIOS}" == "1" ]
|
||||||
|
@ -207,7 +202,7 @@ fi
|
||||||
if [ "${FLASH_RUNTIME}" == "1" ]
|
if [ "${FLASH_RUNTIME}" == "1" ]
|
||||||
then
|
then
|
||||||
echo "Flashing ARTIQ runtime..."
|
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
|
fi
|
||||||
echo "Done."
|
echo "Done."
|
||||||
xc3sprog -v -c $CABLE -R > /dev/null 2>&1
|
xc3sprog -v -c $CABLE -R > /dev/null 2>&1
|
||||||
|
|
|
@ -10,7 +10,7 @@ import os
|
||||||
from quamash import QEventLoop, QtGui, QtCore
|
from quamash import QEventLoop, QtGui, QtCore
|
||||||
from pyqtgraph import dockarea
|
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.protocols.pc_rpc import AsyncioClient
|
||||||
from artiq.gui.state import StateManager
|
from artiq.gui.state import StateManager
|
||||||
from artiq.gui.explorer import ExplorerDock
|
from artiq.gui.explorer import ExplorerDock
|
||||||
|
@ -21,10 +21,6 @@ from artiq.gui.log import LogDock
|
||||||
from artiq.gui.console import ConsoleDock
|
from artiq.gui.console import ConsoleDock
|
||||||
|
|
||||||
|
|
||||||
data_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
|
||||||
"..", "gui")
|
|
||||||
|
|
||||||
|
|
||||||
def get_argparser():
|
def get_argparser():
|
||||||
parser = argparse.ArgumentParser(description="ARTIQ GUI client")
|
parser = argparse.ArgumentParser(description="ARTIQ GUI client")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -46,7 +42,8 @@ def get_argparser():
|
||||||
class MainWindow(QtGui.QMainWindow):
|
class MainWindow(QtGui.QMainWindow):
|
||||||
def __init__(self, app, server):
|
def __init__(self, app, server):
|
||||||
QtGui.QMainWindow.__init__(self)
|
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.setWindowTitle("ARTIQ - {}".format(server))
|
||||||
self.exit_request = asyncio.Event()
|
self.exit_request = asyncio.Event()
|
||||||
|
|
||||||
|
@ -67,15 +64,18 @@ def main():
|
||||||
app = QtGui.QApplication([])
|
app = QtGui.QApplication([])
|
||||||
loop = QEventLoop(app)
|
loop = QEventLoop(app)
|
||||||
asyncio.set_event_loop(loop)
|
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)
|
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)
|
win = MainWindow(app, args.server)
|
||||||
area = dockarea.DockArea()
|
area = dockarea.DockArea()
|
||||||
smgr.register(area)
|
smgr.register(area)
|
||||||
|
@ -85,7 +85,9 @@ def main():
|
||||||
status_bar.showMessage("Connected to {}".format(args.server))
|
status_bar.showMessage("Connected to {}".format(args.server))
|
||||||
win.setStatusBar(status_bar)
|
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)
|
smgr.register(d_explorer)
|
||||||
loop.run_until_complete(d_explorer.sub_connect(
|
loop.run_until_complete(d_explorer.sub_connect(
|
||||||
args.server, args.port_notify))
|
args.server, args.port_notify))
|
||||||
|
@ -110,10 +112,11 @@ def main():
|
||||||
area.addDock(d_datasets, "top")
|
area.addDock(d_datasets, "top")
|
||||||
area.addDock(d_explorer, "above", d_datasets)
|
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(
|
loop.run_until_complete(d_schedule.sub_connect(
|
||||||
args.server, args.port_notify))
|
args.server, args.port_notify))
|
||||||
atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close()))
|
atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close()))
|
||||||
|
d_explorer.get_current_schedule = d_schedule.get_current_schedule
|
||||||
|
|
||||||
d_log = LogDock()
|
d_log = LogDock()
|
||||||
smgr.register(d_log)
|
smgr.register(d_log)
|
||||||
|
@ -121,14 +124,10 @@ def main():
|
||||||
args.server, args.port_notify))
|
args.server, args.port_notify))
|
||||||
atexit.register(lambda: loop.run_until_complete(d_log.sub_close()))
|
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):
|
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):
|
def _del_dataset(k):
|
||||||
asyncio.ensure_future(dataset_db.delete(k))
|
asyncio.ensure_future(rpc_clients["dataset_db"].delete(k))
|
||||||
d_console = ConsoleDock(
|
d_console = ConsoleDock(
|
||||||
d_datasets.get_dataset,
|
d_datasets.get_dataset,
|
||||||
_set_dataset,
|
_set_dataset,
|
||||||
|
|
|
@ -11,8 +11,8 @@ from artiq.tools import verbosity_args, simple_network_args, init_logger
|
||||||
def get_argparser():
|
def get_argparser():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-P", "--product", required=True,
|
parser.add_argument("-P", "--product", required=True,
|
||||||
help="type of the Thorlabs T-Cube device to control",
|
help="type of the Thorlabs T-Cube device to control: "
|
||||||
choices=["tdc001", "tpz001"])
|
"tdc001/tpz001")
|
||||||
parser.add_argument("-d", "--device", default=None,
|
parser.add_argument("-d", "--device", default=None,
|
||||||
help="serial device. See documentation for how to "
|
help="serial device. See documentation for how to "
|
||||||
"specify a USB Serial Number.")
|
"specify a USB Serial Number.")
|
||||||
|
@ -39,11 +39,19 @@ def main():
|
||||||
dev = TdcSim()
|
dev = TdcSim()
|
||||||
elif product == "tpz001":
|
elif product == "tpz001":
|
||||||
dev = TpzSim()
|
dev = TpzSim()
|
||||||
|
else:
|
||||||
|
print("Invalid product string (-P/--product), "
|
||||||
|
"choose from tdc001 or tpz001")
|
||||||
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
if product == "tdc001":
|
if product == "tdc001":
|
||||||
dev = Tdc(args.device)
|
dev = Tdc(args.device)
|
||||||
elif product == "tpz001":
|
elif product == "tpz001":
|
||||||
dev = Tpz(args.device)
|
dev = Tpz(args.device)
|
||||||
|
else:
|
||||||
|
print("Invalid product string (-P/--product), "
|
||||||
|
"choose from tdc001 or tpz001")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
simple_server_loop({product: dev}, args.bind, args.port)
|
simple_server_loop({product: dev}, args.bind, args.port)
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.genlib.fsm import *
|
from migen.genlib.fsm import *
|
||||||
from migen.genlib.misc import WaitTimer
|
from migen.genlib.misc import WaitTimer
|
||||||
from migen.bus import wishbone
|
from misoc.interconnect import wishbone
|
||||||
from migen.bus.transactions import *
|
|
||||||
from migen.sim.generic import run_simulation
|
|
||||||
|
|
||||||
|
|
||||||
class AD9xxx(Module):
|
class AD9xxx(Module):
|
||||||
"""Wishbone interface to the AD9858 and AD9914 DDS chips.
|
"""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.
|
Write to address 2**len(pads.a) to pulse the FUD signal.
|
||||||
Address 2**flen(pads.a)+1 is a GPIO register that controls the
|
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.
|
sel and reset signals. rst is mapped to bit 0, followed by sel.
|
||||||
|
|
||||||
Write timing:
|
Write timing:
|
||||||
|
@ -38,15 +36,15 @@ class AD9xxx(Module):
|
||||||
read_wait_cycles=10, hiz_wait_cycles=3,
|
read_wait_cycles=10, hiz_wait_cycles=3,
|
||||||
bus=None):
|
bus=None):
|
||||||
if bus is None:
|
if bus is None:
|
||||||
bus = wishbone.Interface(data_width=flen(pads.d))
|
bus = wishbone.Interface(data_width=len(pads.d))
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
dts = TSTriple(flen(pads.d))
|
dts = TSTriple(len(pads.d))
|
||||||
self.specials += dts.get_tristate(pads.d)
|
self.specials += dts.get_tristate(pads.d)
|
||||||
hold_address = Signal()
|
hold_address = Signal()
|
||||||
dr = Signal(flen(pads.d))
|
dr = Signal(len(pads.d))
|
||||||
rx = Signal()
|
rx = Signal()
|
||||||
self.sync += [
|
self.sync += [
|
||||||
If(~hold_address, pads.a.eq(bus.adr)),
|
If(~hold_address, pads.a.eq(bus.adr)),
|
||||||
|
@ -56,9 +54,9 @@ class AD9xxx(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
if hasattr(pads, "sel"):
|
if hasattr(pads, "sel"):
|
||||||
sel_len = flen(pads.sel)
|
sel_len = len(pads.sel)
|
||||||
else:
|
else:
|
||||||
sel_len = flen(pads.sel_n)
|
sel_len = len(pads.sel_n)
|
||||||
gpio = Signal(sel_len + 1)
|
gpio = Signal(sel_len + 1)
|
||||||
gpio_load = Signal()
|
gpio_load = Signal()
|
||||||
self.sync += If(gpio_load, gpio.eq(bus.dat_w))
|
self.sync += If(gpio_load, gpio.eq(bus.dat_w))
|
||||||
|
@ -98,7 +96,7 @@ class AD9xxx(Module):
|
||||||
|
|
||||||
fsm.act("IDLE",
|
fsm.act("IDLE",
|
||||||
If(bus.cyc & bus.stb,
|
If(bus.cyc & bus.stb,
|
||||||
If(bus.adr[flen(pads.a)],
|
If(bus.adr[len(pads.a)],
|
||||||
If(bus.adr[0],
|
If(bus.adr[0],
|
||||||
NextState("GPIO")
|
NextState("GPIO")
|
||||||
).Else(
|
).Else(
|
||||||
|
@ -157,20 +155,20 @@ class AD9xxx(Module):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _test_gen():
|
def _test_gen(bus):
|
||||||
# Test external bus writes
|
# Test external bus writes
|
||||||
yield TWrite(4, 2)
|
yield from bus.write(4, 2)
|
||||||
yield TWrite(5, 3)
|
yield from bus.write(5, 3)
|
||||||
yield
|
yield
|
||||||
# Test external bus reads
|
# Test external bus reads
|
||||||
yield TRead(14)
|
yield from bus.read(14)
|
||||||
yield TRead(15)
|
yield from bus.read(15)
|
||||||
yield
|
yield
|
||||||
# Test FUD
|
# Test FUD
|
||||||
yield TWrite(64, 0)
|
yield from bus.write(64, 0)
|
||||||
yield
|
yield
|
||||||
# Test GPIO
|
# Test GPIO
|
||||||
yield TWrite(65, 0xff)
|
yield from bus.write(65, 0xff)
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,14 +183,7 @@ class _TestPads:
|
||||||
self.rst_n = Signal()
|
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__":
|
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")
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.bank.description import *
|
from misoc.interconnect.csr import *
|
||||||
from migen.bus import wishbone
|
from misoc.interconnect import wishbone
|
||||||
|
from misoc.cores import mor1kx
|
||||||
from misoclib.cpu import mor1kx
|
from misoc.integration.soc_core import mem_decoder
|
||||||
from misoclib.soc import mem_decoder
|
|
||||||
|
|
||||||
|
|
||||||
class KernelCPU(Module):
|
class KernelCPU(Module):
|
||||||
|
@ -23,9 +22,8 @@ class KernelCPU(Module):
|
||||||
self.cd_sys_kernel.clk.eq(ClockSignal()),
|
self.cd_sys_kernel.clk.eq(ClockSignal()),
|
||||||
self.cd_sys_kernel.rst.eq(self._reset.storage)
|
self.cd_sys_kernel.rst.eq(self._reset.storage)
|
||||||
]
|
]
|
||||||
self.submodules.cpu = RenameClockDomains(
|
self.submodules.cpu = ClockDomainsRenamer("sys_kernel")(
|
||||||
mor1kx.MOR1KX(platform, exec_address),
|
mor1kx.MOR1KX(platform, exec_address))
|
||||||
"sys_kernel")
|
|
||||||
|
|
||||||
# DRAM access
|
# DRAM access
|
||||||
self.wb_sdram = wishbone.Interface()
|
self.wb_sdram = wishbone.Interface()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.bus import wishbone
|
from misoc.interconnect import wishbone
|
||||||
|
|
||||||
|
|
||||||
class Mailbox(Module):
|
class Mailbox(Module):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from mibuild.generic_platform import *
|
from migen.build.generic_platform import *
|
||||||
|
|
||||||
|
|
||||||
papilio_adapter_io = [
|
papilio_adapter_io = [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from mibuild.generic_platform import *
|
from migen.build.generic_platform import *
|
||||||
|
|
||||||
|
|
||||||
fmc_adapter_io = [
|
fmc_adapter_io = [
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from migen.fhdl.std import *
|
from functools import reduce
|
||||||
from migen.bank.description import *
|
from operator import and_
|
||||||
from migen.genlib.misc import optree
|
|
||||||
|
from migen import *
|
||||||
from migen.genlib.record import Record
|
from migen.genlib.record import Record
|
||||||
from migen.genlib.cdc import *
|
from migen.genlib.cdc import *
|
||||||
from migen.genlib.fifo import AsyncFIFO
|
from migen.genlib.fifo import AsyncFIFO
|
||||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
from misoc.interconnect.csr import *
|
||||||
|
|
||||||
from artiq.gateware.rtio import rtlink
|
from artiq.gateware.rtio import rtlink
|
||||||
|
|
||||||
|
@ -105,9 +107,15 @@ class _OutputManager(Module):
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
# FIFO
|
# FIFO
|
||||||
fifo = RenameClockDomains(AsyncFIFO(ev_layout, fifo_depth),
|
fifo = ClockDomainsRenamer({"write": "rsys", "read": "rio"})(
|
||||||
{"write": "rsys", "read": "rio"})
|
AsyncFIFO(layout_len(ev_layout), fifo_depth))
|
||||||
self.submodules += fifo
|
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
|
# Buffer
|
||||||
buf_pending = Signal()
|
buf_pending = Signal()
|
||||||
|
@ -138,13 +146,15 @@ class _OutputManager(Module):
|
||||||
if interface.suppress_nop:
|
if interface.suppress_nop:
|
||||||
# disable NOP at reset: do not suppress a first write with all 0s
|
# disable NOP at reset: do not suppress a first write with all 0s
|
||||||
nop_en = Signal(reset=0)
|
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 += [
|
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.
|
# buf now contains valid data. enable NOP.
|
||||||
If(self.we & ~any_error, nop_en.eq(1)),
|
If(self.we & ~any_error, nop_en.eq(1)),
|
||||||
# underflows cancel the write. allow it to be retried.
|
# underflows cancel the write. allow it to be retried.
|
||||||
|
@ -156,7 +166,7 @@ class _OutputManager(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
# Buffer read and FIFO write
|
# Buffer read and FIFO write
|
||||||
self.comb += fifo.din.eq(buf)
|
self.comb += fifo_in.eq(buf)
|
||||||
in_guard_time = Signal()
|
in_guard_time = Signal()
|
||||||
self.comb += in_guard_time.eq(
|
self.comb += in_guard_time.eq(
|
||||||
buf.timestamp[fine_ts_width:]
|
buf.timestamp[fine_ts_width:]
|
||||||
|
@ -195,7 +205,7 @@ class _OutputManager(Module):
|
||||||
self.sync.rio += \
|
self.sync.rio += \
|
||||||
If(fifo.re,
|
If(fifo.re,
|
||||||
dout_stb.eq(1),
|
dout_stb.eq(1),
|
||||||
dout.eq(fifo.dout)
|
dout.eq(fifo_out)
|
||||||
).Elif(dout_ack,
|
).Elif(dout_ack,
|
||||||
dout_stb.eq(0)
|
dout_stb.eq(0)
|
||||||
)
|
)
|
||||||
|
@ -235,24 +245,30 @@ class _InputManager(Module):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
fifo = RenameClockDomains(AsyncFIFO(ev_layout, fifo_depth),
|
fifo = ClockDomainsRenamer({"read": "rsys", "write": "rio"})(
|
||||||
{"read": "rsys", "write": "rio"})
|
AsyncFIFO(layout_len(ev_layout), fifo_depth))
|
||||||
self.submodules += fifo
|
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
|
# FIFO write
|
||||||
if data_width:
|
if data_width:
|
||||||
self.comb += fifo.din.data.eq(interface.data)
|
self.comb += fifo_in.data.eq(interface.data)
|
||||||
if interface.timestamped:
|
if interface.timestamped:
|
||||||
if fine_ts_width:
|
if fine_ts_width:
|
||||||
full_ts = Cat(interface.fine_ts, counter.value_rio)
|
full_ts = Cat(interface.fine_ts, counter.value_rio)
|
||||||
else:
|
else:
|
||||||
full_ts = counter.value_rio
|
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)
|
self.comb += fifo.we.eq(interface.stb)
|
||||||
|
|
||||||
# FIFO read
|
# FIFO read
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.ev.eq(fifo.dout),
|
self.ev.eq(fifo_out),
|
||||||
self.readable.eq(fifo.readable),
|
self.readable.eq(fifo.readable),
|
||||||
fifo.re.eq(self.re)
|
fifo.re.eq(self.re)
|
||||||
]
|
]
|
||||||
|
@ -376,8 +392,8 @@ class RTIO(Module):
|
||||||
if hasattr(o_manager.ev, "address"):
|
if hasattr(o_manager.ev, "address"):
|
||||||
self.comb += o_manager.ev.address.eq(
|
self.comb += o_manager.ev.address.eq(
|
||||||
self.kcsrs.o_address.storage)
|
self.kcsrs.o_address.storage)
|
||||||
ts_shift = (flen(self.kcsrs.o_timestamp.storage)
|
ts_shift = (len(self.kcsrs.o_timestamp.storage)
|
||||||
- flen(o_manager.ev.timestamp))
|
- len(o_manager.ev.timestamp))
|
||||||
self.comb += o_manager.ev.timestamp.eq(
|
self.comb += o_manager.ev.timestamp.eq(
|
||||||
self.kcsrs.o_timestamp.storage[ts_shift:])
|
self.kcsrs.o_timestamp.storage[ts_shift:])
|
||||||
|
|
||||||
|
@ -412,8 +428,8 @@ class RTIO(Module):
|
||||||
else:
|
else:
|
||||||
i_datas.append(0)
|
i_datas.append(0)
|
||||||
if channel.interface.i.timestamped:
|
if channel.interface.i.timestamped:
|
||||||
ts_shift = (flen(self.kcsrs.i_timestamp.status)
|
ts_shift = (len(self.kcsrs.i_timestamp.status)
|
||||||
- flen(i_manager.ev.timestamp))
|
- len(i_manager.ev.timestamp))
|
||||||
i_timestamps.append(i_manager.ev.timestamp << ts_shift)
|
i_timestamps.append(i_manager.ev.timestamp << ts_shift)
|
||||||
else:
|
else:
|
||||||
i_timestamps.append(0)
|
i_timestamps.append(0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.bank.description import *
|
|
||||||
from migen.genlib.cdc import BusSynchronizer, MultiReg
|
from migen.genlib.cdc import BusSynchronizer, MultiReg
|
||||||
|
from misoc.interconnect.csr import *
|
||||||
|
|
||||||
|
|
||||||
class Monitor(Module, AutoCSR):
|
class Monitor(Module, AutoCSR):
|
||||||
|
@ -8,7 +8,7 @@ class Monitor(Module, AutoCSR):
|
||||||
chan_probes = [c.probes for c in channels]
|
chan_probes = [c.probes for c in channels]
|
||||||
|
|
||||||
max_chan_probes = max(len(cp) for cp in chan_probes)
|
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.chan_sel = CSRStorage(bits_for(len(chan_probes)-1))
|
||||||
self.probe_sel = CSRStorage(bits_for(max_chan_probes-1))
|
self.probe_sel = CSRStorage(bits_for(max_chan_probes-1))
|
||||||
self.value_update = CSR()
|
self.value_update = CSR()
|
||||||
|
@ -20,7 +20,7 @@ class Monitor(Module, AutoCSR):
|
||||||
for cp in chan_probes:
|
for cp in chan_probes:
|
||||||
cp_sys = []
|
cp_sys = []
|
||||||
for p in cp:
|
for p in cp:
|
||||||
vs = BusSynchronizer(flen(p), "rio", "rsys")
|
vs = BusSynchronizer(len(p), "rio", "rsys")
|
||||||
self.submodules += vs
|
self.submodules += vs
|
||||||
self.comb += vs.i.eq(p)
|
self.comb += vs.i.eq(p)
|
||||||
cp_sys.append(vs.o)
|
cp_sys.append(vs.o)
|
||||||
|
@ -36,7 +36,7 @@ class Injector(Module, AutoCSR):
|
||||||
chan_overrides = [c.overrides for c in channels]
|
chan_overrides = [c.overrides for c in channels]
|
||||||
|
|
||||||
max_chan_overrides = max(len(co) for co in chan_overrides)
|
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.chan_sel = CSRStorage(bits_for(len(chan_overrides)-1))
|
||||||
self.override_sel = CSRStorage(bits_for(max_chan_overrides-1))
|
self.override_sel = CSRStorage(bits_for(max_chan_overrides-1))
|
||||||
self.value = CSR(max_override_len)
|
self.value = CSR(max_override_len)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
|
|
||||||
from artiq.gateware import ad9xxx
|
from artiq.gateware import ad9xxx
|
||||||
from artiq.gateware.rtio.phy.wishbone import RT2WB
|
from artiq.gateware.rtio.phy.wishbone import RT2WB
|
||||||
|
@ -6,9 +6,9 @@ from artiq.gateware.rtio.phy.wishbone import RT2WB
|
||||||
|
|
||||||
class _AD9xxx(Module):
|
class _AD9xxx(Module):
|
||||||
def __init__(self, ftw_base, pads, nchannels, onehot=False, **kwargs):
|
def __init__(self, ftw_base, pads, nchannels, onehot=False, **kwargs):
|
||||||
self.submodules._ll = RenameClockDomains(
|
self.submodules._ll = ClockDomainsRenamer("rio")(
|
||||||
ad9xxx.AD9xxx(pads, **kwargs), "rio")
|
ad9xxx.AD9xxx(pads, **kwargs))
|
||||||
self.submodules._rt2wb = RT2WB(flen(pads.a)+1, self._ll.bus)
|
self.submodules._rt2wb = RT2WB(len(pads.a)+1, self._ll.bus)
|
||||||
self.rtlink = self._rt2wb.rtlink
|
self.rtlink = self._rt2wb.rtlink
|
||||||
self.probes = [Signal(32) for i in range(nchannels)]
|
self.probes = [Signal(32) for i in range(nchannels)]
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ class _AD9xxx(Module):
|
||||||
current_data.eq(self.rtlink.o.data))
|
current_data.eq(self.rtlink.o.data))
|
||||||
|
|
||||||
# keep track of the currently selected channel(s)
|
# keep track of the currently selected channel(s)
|
||||||
current_sel = Signal(flen(current_data)-1)
|
current_sel = Signal(len(current_data)-1)
|
||||||
self.sync.rio += If(current_address == 2**flen(pads.a) + 1,
|
self.sync.rio += If(current_address == 2**len(pads.a) + 1,
|
||||||
current_sel.eq(current_data[1:])) # strip reset
|
current_sel.eq(current_data[1:])) # strip reset
|
||||||
|
|
||||||
def selected(c):
|
def selected(c):
|
||||||
|
@ -35,13 +35,13 @@ class _AD9xxx(Module):
|
||||||
# keep track of frequency tuning words, before they are FUDed
|
# keep track of frequency tuning words, before they are FUDed
|
||||||
ftws = [Signal(32) for i in range(nchannels)]
|
ftws = [Signal(32) for i in range(nchannels)]
|
||||||
for c, ftw in enumerate(ftws):
|
for c, ftw in enumerate(ftws):
|
||||||
if flen(pads.d) == 8:
|
if len(pads.d) == 8:
|
||||||
self.sync.rio_phy += \
|
self.sync.rio_phy += \
|
||||||
If(selected(c), [
|
If(selected(c), [
|
||||||
If(current_address == ftw_base+i,
|
If(current_address == ftw_base+i,
|
||||||
ftw[i*8:(i+1)*8].eq(current_data))
|
ftw[i*8:(i+1)*8].eq(current_data))
|
||||||
for i in range(4)])
|
for i in range(4)])
|
||||||
elif flen(pads.d) == 16:
|
elif len(pads.d) == 16:
|
||||||
self.sync.rio_phy += \
|
self.sync.rio_phy += \
|
||||||
If(selected(c), [
|
If(selected(c), [
|
||||||
If(current_address == ftw_base+2*i,
|
If(current_address == ftw_base+2*i,
|
||||||
|
@ -51,7 +51,7 @@ class _AD9xxx(Module):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
# FTW to probe on FUD
|
# 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))
|
If(selected(c), probe.eq(ftw))
|
||||||
for c, (probe, ftw) in enumerate(zip(self.probes, ftws))])
|
for c, (probe, ftw) in enumerate(zip(self.probes, ftws))])
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
|
|
||||||
from artiq.gateware.rtio.phy import ttl_serdes_generic
|
from artiq.gateware.rtio.phy import ttl_serdes_generic
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.genlib.coding import PriorityEncoder
|
from migen.genlib.coding import PriorityEncoder
|
||||||
|
|
||||||
from artiq.gateware.rtio import rtlink
|
from artiq.gateware.rtio import rtlink
|
||||||
|
@ -18,7 +18,7 @@ def _mk_edges(w, direction):
|
||||||
class _SerdesDriver(Module):
|
class _SerdesDriver(Module):
|
||||||
def __init__(self, serdes_o, stb, data, fine_ts, override_en, override_o):
|
def __init__(self, serdes_o, stb, data, fine_ts, override_en, override_o):
|
||||||
previous_data = Signal()
|
previous_data = Signal()
|
||||||
serdes_width = flen(serdes_o)
|
serdes_width = len(serdes_o)
|
||||||
edges = Array(_mk_edges(serdes_width, "rising"))
|
edges = Array(_mk_edges(serdes_width, "rising"))
|
||||||
edges_n = Array(_mk_edges(serdes_width, "falling"))
|
edges_n = Array(_mk_edges(serdes_width, "falling"))
|
||||||
self.sync.rio_phy += [
|
self.sync.rio_phy += [
|
||||||
|
@ -40,7 +40,7 @@ class _SerdesDriver(Module):
|
||||||
class Output(Module):
|
class Output(Module):
|
||||||
def __init__(self, serdes):
|
def __init__(self, serdes):
|
||||||
self.rtlink = rtlink.Interface(
|
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]]
|
self.probes = [serdes.o[-1]]
|
||||||
override_en = Signal()
|
override_en = Signal()
|
||||||
override_o = Signal()
|
override_o = Signal()
|
||||||
|
@ -56,8 +56,8 @@ class Output(Module):
|
||||||
|
|
||||||
class Inout(Module):
|
class Inout(Module):
|
||||||
def __init__(self, serdes):
|
def __init__(self, serdes):
|
||||||
serdes_width = flen(serdes.o)
|
serdes_width = len(serdes.o)
|
||||||
assert flen(serdes.i) == serdes_width
|
assert len(serdes.i) == serdes_width
|
||||||
self.rtlink = rtlink.Interface(
|
self.rtlink = rtlink.Interface(
|
||||||
rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)),
|
rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)),
|
||||||
rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width)))
|
rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width)))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
# 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
|
from artiq.gateware.rtio.phy import ttl_serdes_generic
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.genlib.cdc import MultiReg
|
from migen.genlib.cdc import MultiReg
|
||||||
|
|
||||||
from artiq.gateware.rtio import rtlink
|
from artiq.gateware.rtio import rtlink
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.bus import wishbone
|
from misoc.interconnect import wishbone
|
||||||
|
|
||||||
from artiq.gateware.rtio import rtlink
|
from artiq.gateware.rtio import rtlink
|
||||||
|
|
||||||
|
@ -11,11 +11,11 @@ class RT2WB(Module):
|
||||||
self.wb = wb
|
self.wb = wb
|
||||||
self.rtlink = rtlink.Interface(
|
self.rtlink = rtlink.Interface(
|
||||||
rtlink.OInterface(
|
rtlink.OInterface(
|
||||||
flen(wb.dat_w),
|
len(wb.dat_w),
|
||||||
address_width + 1,
|
address_width + 1,
|
||||||
suppress_nop=False),
|
suppress_nop=False),
|
||||||
rtlink.IInterface(
|
rtlink.IInterface(
|
||||||
flen(wb.dat_r),
|
len(wb.dat_r),
|
||||||
timestamped=False)
|
timestamped=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class RT2WB(Module):
|
||||||
wb.adr.eq(self.rtlink.o.address[:address_width]),
|
wb.adr.eq(self.rtlink.o.address[:address_width]),
|
||||||
wb.we.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.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,
|
If(wb.ack,
|
||||||
active.eq(0)
|
active.eq(0)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
|
|
||||||
|
|
||||||
class OInterface:
|
class OInterface:
|
||||||
|
@ -64,7 +64,7 @@ def _get_or_zero(interface, attr):
|
||||||
_get_or_zero(interface.o, attr))
|
_get_or_zero(interface.o, attr))
|
||||||
else:
|
else:
|
||||||
if hasattr(interface, attr):
|
if hasattr(interface, attr):
|
||||||
return flen(getattr(interface, attr))
|
return len(getattr(interface, attr))
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from misoclib.soc import mem_decoder
|
from misoc.integration.soc_core import mem_decoder
|
||||||
from misoclib.cpu import timer
|
from misoc.cores import timer
|
||||||
|
|
||||||
from artiq.gateware import amp
|
from artiq.gateware import amp
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class AMPSoC:
|
||||||
a "mailbox" entry in the memory map.
|
a "mailbox" entry in the memory map.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if not hasattr(self, "cpu_or_bridge"):
|
if not hasattr(self, "cpu"):
|
||||||
raise ValueError("Platform SoC must be initialized first")
|
raise ValueError("Platform SoC must be initialized first")
|
||||||
if hasattr(self, "timer0"):
|
if hasattr(self, "timer0"):
|
||||||
raise ValueError("Timer already exists. "
|
raise ValueError("Timer already exists. "
|
||||||
|
|
|
@ -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.resetsync import AsyncResetSynchronizer
|
||||||
from migen.genlib.cdc import MultiReg
|
from migen.genlib.cdc import MultiReg
|
||||||
from migen.bank.description import *
|
from migen.build.generic_platform import *
|
||||||
from migen.bank import wbgen
|
from migen.build.xilinx.vivado import XilinxVivadoToolchain
|
||||||
from mibuild.generic_platform import *
|
from migen.build.xilinx.ise import XilinxISEToolchain
|
||||||
from mibuild.xilinx.vivado import XilinxVivadoToolchain
|
|
||||||
from mibuild.xilinx.ise import XilinxISEToolchain
|
|
||||||
|
|
||||||
from misoclib.com import gpio
|
from misoc.interconnect.csr import *
|
||||||
from misoclib.soc import mem_decoder
|
from misoc.interconnect import wishbone
|
||||||
from misoclib.mem.sdram.core.minicon import MiniconSettings
|
from misoc.cores import gpio
|
||||||
from targets.kc705 import MiniSoC
|
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.soc import AMPSoC
|
||||||
from artiq.gateware import rtio, nist_qc1, nist_qc2
|
from artiq.gateware import rtio, nist_qc1, nist_qc2
|
||||||
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds
|
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds
|
||||||
|
from artiq.tools import artiq_dir
|
||||||
|
|
||||||
|
|
||||||
class _RTIOCRG(Module, AutoCSR):
|
class _RTIOCRG(Module, AutoCSR):
|
||||||
|
@ -87,15 +93,17 @@ class _NIST_QCx(MiniSoC, AMPSoC):
|
||||||
}
|
}
|
||||||
mem_map.update(MiniSoC.mem_map)
|
mem_map.update(MiniSoC.mem_map)
|
||||||
|
|
||||||
def __init__(self, platform, cpu_type="or1k", **kwargs):
|
def __init__(self, cpu_type="or1k", **kwargs):
|
||||||
MiniSoC.__init__(self, platform,
|
MiniSoC.__init__(self,
|
||||||
cpu_type=cpu_type,
|
cpu_type=cpu_type,
|
||||||
sdram_controller_settings=MiniconSettings(l2_size=128*1024),
|
sdram_controller_type="minicon",
|
||||||
|
l2_size=128*1024,
|
||||||
with_timer=False, **kwargs)
|
with_timer=False, **kwargs)
|
||||||
AMPSoC.__init__(self)
|
AMPSoC.__init__(self)
|
||||||
|
|
||||||
self.submodules.leds = gpio.GPIOOut(Cat(
|
self.submodules.leds = gpio.GPIOOut(Cat(
|
||||||
platform.request("user_led", 0),
|
self.platform.request("user_led", 0),
|
||||||
platform.request("user_led", 1)))
|
self.platform.request("user_led", 1)))
|
||||||
|
|
||||||
def add_rtio(self, rtio_channels):
|
def add_rtio(self, rtio_channels):
|
||||||
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
|
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)
|
""", rio_clk=self.rtio_crg.cd_rtio.clk)
|
||||||
|
|
||||||
rtio_csrs = self.rtio.get_csrs()
|
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.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
|
||||||
self.rtiowb.bus)
|
self.rtiowb.bus)
|
||||||
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
|
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):
|
class NIST_QC1(_NIST_QCx):
|
||||||
def __init__(self, platform, cpu_type="or1k", **kwargs):
|
def __init__(self, cpu_type="or1k", **kwargs):
|
||||||
_NIST_QCx.__init__(self, platform, cpu_type, **kwargs)
|
_NIST_QCx.__init__(self, cpu_type, **kwargs)
|
||||||
|
|
||||||
|
platform = self.platform
|
||||||
platform.add_extension(nist_qc1.fmc_adapter_io)
|
platform.add_extension(nist_qc1.fmc_adapter_io)
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
|
@ -172,8 +182,10 @@ class NIST_QC1(_NIST_QCx):
|
||||||
|
|
||||||
|
|
||||||
class NIST_QC2(_NIST_QCx):
|
class NIST_QC2(_NIST_QCx):
|
||||||
def __init__(self, platform, cpu_type="or1k", **kwargs):
|
def __init__(self, cpu_type="or1k", **kwargs):
|
||||||
_NIST_QCx.__init__(self, platform, cpu_type, **kwargs)
|
_NIST_QCx.__init__(self, cpu_type, **kwargs)
|
||||||
|
|
||||||
|
platform = self.platform
|
||||||
platform.add_extension(nist_qc2.fmc_adapter_io)
|
platform.add_extension(nist_qc2.fmc_adapter_io)
|
||||||
|
|
||||||
rtio_channels = []
|
rtio_channels = []
|
||||||
|
@ -214,4 +226,34 @@ class NIST_QC2(_NIST_QCx):
|
||||||
self.add_rtio(rtio_channels)
|
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()
|
48
soc/targets/artiq_pipistrello.py → artiq/gateware/targets/pipistrello.py
Normal file → Executable file
48
soc/targets/artiq_pipistrello.py → artiq/gateware/targets/pipistrello.py
Normal file → Executable file
|
@ -1,22 +1,26 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
||||||
# Copyright (C) 2014, 2015 M-Labs Limited
|
# Copyright (C) 2014, 2015 M-Labs Limited
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
|
|
||||||
from migen.fhdl.std import *
|
from migen import *
|
||||||
from migen.bank.description import *
|
|
||||||
from migen.bank import wbgen
|
|
||||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
from migen.genlib.cdc import MultiReg
|
from migen.genlib.cdc import MultiReg
|
||||||
|
|
||||||
from misoclib.com import gpio
|
from misoc.interconnect.csr import *
|
||||||
from misoclib.soc import mem_decoder
|
from misoc.interconnect import wishbone
|
||||||
from misoclib.mem.sdram.core.minicon import MiniconSettings
|
from misoc.cores import gpio
|
||||||
from targets.pipistrello import BaseSoC
|
from misoc.integration.soc_core import mem_decoder
|
||||||
|
from misoc.targets.pipistrello import *
|
||||||
|
|
||||||
from artiq.gateware.soc import AMPSoC
|
from artiq.gateware.soc import AMPSoC
|
||||||
from artiq.gateware import rtio, nist_qc1
|
from artiq.gateware import rtio, nist_qc1
|
||||||
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_spartan6, dds
|
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_spartan6, dds
|
||||||
|
from artiq.tools import artiq_dir
|
||||||
|
|
||||||
|
|
||||||
class _RTIOCRG(Module, AutoCSR):
|
class _RTIOCRG(Module, AutoCSR):
|
||||||
|
@ -110,12 +114,15 @@ class NIST_QC1(BaseSoC, AMPSoC):
|
||||||
}
|
}
|
||||||
mem_map.update(BaseSoC.mem_map)
|
mem_map.update(BaseSoC.mem_map)
|
||||||
|
|
||||||
def __init__(self, platform, cpu_type="or1k", **kwargs):
|
def __init__(self, cpu_type="or1k", **kwargs):
|
||||||
BaseSoC.__init__(self, platform,
|
BaseSoC.__init__(self,
|
||||||
cpu_type=cpu_type,
|
cpu_type=cpu_type,
|
||||||
sdram_controller_settings=MiniconSettings(l2_size=64*1024),
|
l2_size=64*1024,
|
||||||
with_timer=False, **kwargs)
|
with_timer=False, **kwargs)
|
||||||
AMPSoC.__init__(self)
|
AMPSoC.__init__(self)
|
||||||
|
|
||||||
|
platform = self.platform
|
||||||
|
|
||||||
platform.toolchain.ise_commands += """
|
platform.toolchain.ise_commands += """
|
||||||
trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf
|
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
|
# CPU connections
|
||||||
rtio_csrs = self.rtio.get_csrs()
|
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.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
|
||||||
self.rtiowb.bus)
|
self.rtiowb.bus)
|
||||||
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
|
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
|
||||||
rtio_csrs)
|
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()
|
|
@ -216,7 +216,7 @@ class _ArgumentEditor(QtGui.QTreeWidget):
|
||||||
|
|
||||||
|
|
||||||
class ExplorerDock(dockarea.Dock):
|
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))
|
dockarea.Dock.__init__(self, "Explorer", size=(1500, 500))
|
||||||
|
|
||||||
self.main_window = main_window
|
self.main_window = main_window
|
||||||
|
@ -263,8 +263,7 @@ class ExplorerDock(dockarea.Dock):
|
||||||
grid.addWidget(self.log_level, 3, 3)
|
grid.addWidget(self.log_level, 3, 3)
|
||||||
|
|
||||||
submit = QtGui.QPushButton("Submit")
|
submit = QtGui.QPushButton("Submit")
|
||||||
submit.setShortcut("CTRL+RETURN")
|
submit.setToolTip("Schedule the selected experiment (Ctrl+Return)")
|
||||||
submit.setToolTip("Schedule the selected experiment (CTRL+ENTER)")
|
|
||||||
grid.addWidget(submit, 4, 0, colspan=4)
|
grid.addWidget(submit, 4, 0, colspan=4)
|
||||||
submit.clicked.connect(self.submit_clicked)
|
submit.clicked.connect(self.submit_clicked)
|
||||||
|
|
||||||
|
@ -276,9 +275,29 @@ class ExplorerDock(dockarea.Dock):
|
||||||
self.shortcuts = ShortcutManager(self.main_window, self)
|
self.shortcuts = ShortcutManager(self.main_window, self)
|
||||||
|
|
||||||
self.el.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
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 = QtGui.QAction("Edit shortcuts", self.el)
|
||||||
edit_shortcuts_action.triggered.connect(self.edit_shortcuts)
|
edit_shortcuts_action.triggered.connect(self.edit_shortcuts)
|
||||||
self.el.addAction(edit_shortcuts_action)
|
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):
|
def update_selection(self, selected, deselected):
|
||||||
if deselected:
|
if deselected:
|
||||||
|
@ -385,6 +404,28 @@ class ExplorerDock(dockarea.Dock):
|
||||||
due_date,
|
due_date,
|
||||||
self.flush.isChecked())
|
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):
|
def edit_shortcuts(self):
|
||||||
experiments = sorted(self.explist_model.backing_store.keys())
|
experiments = sorted(self.explist_model.backing_store.keys())
|
||||||
self.shortcuts.edit(experiments)
|
self.shortcuts.edit(experiments)
|
||||||
|
|
|
@ -191,10 +191,14 @@ class LogDock(dockarea.Dock):
|
||||||
await self.subscriber.close()
|
await self.subscriber.close()
|
||||||
|
|
||||||
def filter_level_changed(self):
|
def filter_level_changed(self):
|
||||||
|
if not hasattr(self, "table_model_filter"):
|
||||||
|
return
|
||||||
self.table_model_filter.set_min_level(
|
self.table_model_filter.set_min_level(
|
||||||
getattr(logging, self.filter_level.currentText()))
|
getattr(logging, self.filter_level.currentText()))
|
||||||
|
|
||||||
def filter_freetext_changed(self):
|
def filter_freetext_changed(self):
|
||||||
|
if not hasattr(self, "table_model_filter"):
|
||||||
|
return
|
||||||
self.table_model_filter.set_freetext(self.filter_freetext.text())
|
self.table_model_filter.set_freetext(self.filter_freetext.text())
|
||||||
|
|
||||||
def rows_inserted_before(self):
|
def rows_inserted_before(self):
|
||||||
|
|
|
@ -82,7 +82,6 @@ class ScheduleDock(dockarea.Dock):
|
||||||
delete_action.setShortcut("SHIFT+DELETE")
|
delete_action.setShortcut("SHIFT+DELETE")
|
||||||
self.table.addAction(delete_action)
|
self.table.addAction(delete_action)
|
||||||
|
|
||||||
|
|
||||||
async def sub_connect(self, host, port):
|
async def sub_connect(self, host, port):
|
||||||
self.subscriber = Subscriber("schedule", self.init_schedule_model)
|
self.subscriber = Subscriber("schedule", self.init_schedule_model)
|
||||||
await self.subscriber.connect(host, port)
|
await self.subscriber.connect(host, port)
|
||||||
|
@ -90,6 +89,13 @@ class ScheduleDock(dockarea.Dock):
|
||||||
async def sub_close(self):
|
async def sub_close(self):
|
||||||
await self.subscriber.close()
|
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):
|
def init_schedule_model(self, init):
|
||||||
self.table_model = _ScheduleModel(self.table, init)
|
self.table_model = _ScheduleModel(self.table, init)
|
||||||
self.table.setModel(self.table_model)
|
self.table.setModel(self.table_model)
|
||||||
|
|
|
@ -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
|
|
@ -92,7 +92,7 @@ static int kloader_start_flash_kernel(char *key)
|
||||||
{
|
{
|
||||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||||
char buffer[32*1024];
|
char buffer[32*1024];
|
||||||
int length, remain;
|
unsigned int length, remain;
|
||||||
|
|
||||||
length = fs_read(key, buffer, sizeof(buffer), &remain);
|
length = fs_read(key, buffer, sizeof(buffer), &remain);
|
||||||
if(length <= 0)
|
if(length <= 0)
|
|
@ -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)
|
|
@ -10,7 +10,7 @@
|
||||||
#include <lwip/mem.h>
|
#include <lwip/mem.h>
|
||||||
|
|
||||||
#include <netif/etharp.h>
|
#include <netif/etharp.h>
|
||||||
#include "netif/liteethif.h"
|
#include "liteethif.h"
|
||||||
|
|
||||||
#include <hw/flags.h>
|
#include <hw/flags.h>
|
||||||
#include <hw/ethmac_mem.h>
|
#include <hw/ethmac_mem.h>
|
|
@ -8,8 +8,6 @@
|
||||||
#include <hw/flags.h>
|
#include <hw/flags.h>
|
||||||
|
|
||||||
#ifdef CSR_ETHMAC_BASE
|
#ifdef CSR_ETHMAC_BASE
|
||||||
#include <netif/etharp.h>
|
|
||||||
#include <netif/liteethif.h>
|
|
||||||
#include <lwip/init.h>
|
#include <lwip/init.h>
|
||||||
#include <lwip/memp.h>
|
#include <lwip/memp.h>
|
||||||
#include <lwip/ip4_addr.h>
|
#include <lwip/ip4_addr.h>
|
||||||
|
@ -18,6 +16,8 @@
|
||||||
#include <lwip/sys.h>
|
#include <lwip/sys.h>
|
||||||
#include <lwip/tcp.h>
|
#include <lwip/tcp.h>
|
||||||
#include <lwip/timers.h>
|
#include <lwip/timers.h>
|
||||||
|
#include <netif/etharp.h>
|
||||||
|
#include <liteethif.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "bridge_ctl.h"
|
#include "bridge_ctl.h"
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
#ifdef CSR_ETHMAC_BASE
|
#ifdef CSR_ETHMAC_BASE
|
||||||
|
|
||||||
#include <netif/etharp.h>
|
|
||||||
#include <netif/liteethif.h>
|
|
||||||
#include <lwip/init.h>
|
#include <lwip/init.h>
|
||||||
#include <lwip/memp.h>
|
#include <lwip/memp.h>
|
||||||
#include <lwip/ip4_addr.h>
|
#include <lwip/ip4_addr.h>
|
||||||
|
@ -12,6 +10,8 @@
|
||||||
#include <lwip/sys.h>
|
#include <lwip/sys.h>
|
||||||
#include <lwip/tcp.h>
|
#include <lwip/tcp.h>
|
||||||
#include <lwip/timers.h>
|
#include <lwip/timers.h>
|
||||||
|
#include <netif/etharp.h>
|
||||||
|
#include <liteethif.h>
|
||||||
|
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "net_server.h"
|
#include "net_server.h"
|
|
@ -1,6 +1,5 @@
|
||||||
#include <generated/csr.h>
|
#include <generated/csr.h>
|
||||||
|
|
||||||
#include "exceptions.h"
|
|
||||||
#include "rtio.h"
|
#include "rtio.h"
|
||||||
|
|
||||||
void rtio_init(void)
|
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);
|
while(rtio_o_status_read() & RTIO_O_STATUS_FULL);
|
||||||
if(status & RTIO_O_STATUS_UNDERFLOW) {
|
if(status & RTIO_O_STATUS_UNDERFLOW) {
|
||||||
rtio_o_underflow_reset_write(1);
|
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());
|
timestamp, channel, rtio_get_counter());
|
||||||
}
|
}
|
||||||
if(status & RTIO_O_STATUS_SEQUENCE_ERROR) {
|
if(status & RTIO_O_STATUS_SEQUENCE_ERROR) {
|
||||||
rtio_o_sequence_error_reset_write(1);
|
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);
|
timestamp, channel, 0);
|
||||||
}
|
}
|
||||||
if(status & RTIO_O_STATUS_COLLISION_ERROR) {
|
if(status & RTIO_O_STATUS_COLLISION_ERROR) {
|
||||||
rtio_o_collision_error_reset_write(1);
|
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);
|
timestamp, channel, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -299,6 +299,7 @@ void session_startup_kernel(void)
|
||||||
if(!kloader_start_startup_kernel())
|
if(!kloader_start_startup_kernel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
log("Startup kernel started");
|
||||||
while(1) {
|
while(1) {
|
||||||
kloader_service_essential_kmsg();
|
kloader_service_essential_kmsg();
|
||||||
|
|
|
@ -6,7 +6,7 @@ import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
import collections
|
import collections
|
||||||
import os.path
|
import os
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ from artiq.protocols import pyon
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
artiq_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)))
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments(arguments):
|
def parse_arguments(arguments):
|
||||||
d = {}
|
d = {}
|
||||||
|
|
|
@ -3,24 +3,13 @@
|
||||||
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
|
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
|
||||||
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
|
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
|
||||||
|
|
||||||
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705
|
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-qc1
|
||||||
mkdir -p $SOC_PREFIX/nist_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
|
wget http://sionneau.net/artiq/binaries/kc705/flash_proxy/bscan_spi_kc705.bit
|
||||||
mv bscan_spi_kc705.bit $SOC_PREFIX/
|
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/
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ requirements:
|
||||||
build:
|
build:
|
||||||
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
|
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
|
||||||
- artiq 0.0
|
- artiq 0.0
|
||||||
- migen 0.0
|
- migen 0.2
|
||||||
|
- misoc 0.1
|
||||||
- llvm-or1k
|
- llvm-or1k
|
||||||
- binutils-or1k-linux
|
- binutils-or1k-linux
|
||||||
run:
|
run:
|
||||||
|
|
|
@ -3,24 +3,13 @@
|
||||||
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
|
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
|
||||||
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
|
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
|
||||||
|
|
||||||
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705
|
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-qc2
|
||||||
mkdir -p $SOC_PREFIX/nist_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
|
wget http://sionneau.net/artiq/binaries/kc705/flash_proxy/bscan_spi_kc705.bit
|
||||||
mv bscan_spi_kc705.bit $SOC_PREFIX/
|
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/
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ requirements:
|
||||||
build:
|
build:
|
||||||
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
|
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
|
||||||
- artiq 0.0
|
- artiq 0.0
|
||||||
- migen 0.0
|
- migen 0.2
|
||||||
|
- misoc 0.1
|
||||||
- llvm-or1k
|
- llvm-or1k
|
||||||
- binutils-or1k-linux
|
- binutils-or1k-linux
|
||||||
run:
|
run:
|
||||||
|
|
|
@ -3,24 +3,13 @@
|
||||||
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
|
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
|
||||||
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
|
[ -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
|
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
|
wget https://people.phys.ethz.ch/~robertjo/bscan_spi_lx45_csg324.bit
|
||||||
mv bscan_spi_lx45_csg324.bit $SOC_PREFIX/
|
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/
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ requirements:
|
||||||
build:
|
build:
|
||||||
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
|
# We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies.
|
||||||
- artiq 0.0
|
- artiq 0.0
|
||||||
- migen 0.0
|
- migen 0.2
|
||||||
|
- misoc 0.1
|
||||||
- llvm-or1k
|
- llvm-or1k
|
||||||
- binutils-or1k-linux
|
- binutils-or1k-linux
|
||||||
run:
|
run:
|
||||||
|
|
|
@ -33,7 +33,6 @@ requirements:
|
||||||
- python >=3.5.0
|
- python >=3.5.0
|
||||||
- setuptools
|
- setuptools
|
||||||
- numpy
|
- numpy
|
||||||
- migen 0.0
|
|
||||||
- pyelftools
|
- pyelftools
|
||||||
- binutils-or1k-linux
|
- binutils-or1k-linux
|
||||||
run:
|
run:
|
||||||
|
|
|
@ -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``.
|
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
|
$ cd ~/artiq-dev
|
||||||
$ git clone --recursive https://github.com/m-labs/misoc
|
$ 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: ::
|
* Download and install ARTIQ: ::
|
||||||
|
|
||||||
$ cd ~/artiq-dev
|
$ cd ~/artiq-dev
|
||||||
$ git clone --recursive https://github.com/m-labs/artiq
|
$ git clone --recursive https://github.com/m-labs/artiq
|
||||||
|
$ cd artiq
|
||||||
$ python3 setup.py develop --user
|
$ python3 setup.py develop --user
|
||||||
|
|
||||||
.. note::
|
.. 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>`.
|
: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
|
$ 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.
|
.. 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::
|
* For Pipistrello::
|
||||||
|
|
||||||
$ ./make.py -X ~/artiq-dev/artiq/soc -t artiq_pipistrello all
|
$ python3 -m artiq.gateware.targets.pipistrello
|
||||||
|
|
||||||
* For KC705::
|
* 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
|
$ mkdir binaries
|
||||||
$ ~/artiq-dev/artiq/artiq/frontend/artiq_flash.sh -t pipistrello -d $PWD -r
|
$ 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``.
|
.. 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
|
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:
|
.. _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.
|
.. 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.
|
.. 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>`.
|
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:
|
* 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).
|
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
|
$ 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.
|
.. 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
|
Ubuntu 14.04 specific instructions
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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`;
|
* as well as read, write and remove key-value records from the :ref:`core-device-flash-storage`;
|
||||||
* erase the entire flash storage area.
|
* 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``::
|
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
|
$ artiq_coretool cfg-read my_key
|
||||||
b'test_value'
|
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-write -f idle_kernel idle.elf
|
||||||
$ artiq_coretool cfg-read idle_kernel | head -c9
|
$ artiq_coretool cfg-read idle_kernel | head -c9
|
||||||
|
|
|
@ -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": {
|
"comm": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
|
|
|
@ -6,6 +6,8 @@ from artiq import *
|
||||||
class DDSSetter(EnvExperiment):
|
class DDSSetter(EnvExperiment):
|
||||||
"""DDS Setter"""
|
"""DDS Setter"""
|
||||||
def build(self):
|
def build(self):
|
||||||
|
self.setattr_device("core")
|
||||||
|
|
||||||
self.dds = dict()
|
self.dds = dict()
|
||||||
|
|
||||||
device_db = self.get_device_db()
|
device_db = self.get_device_db()
|
||||||
|
@ -16,10 +18,16 @@ class DDSSetter(EnvExperiment):
|
||||||
and v["class"] in {"AD9858", "AD9914"}):
|
and v["class"] in {"AD9858", "AD9914"}):
|
||||||
self.dds[k] = {
|
self.dds[k] = {
|
||||||
"driver": self.get_device(k),
|
"driver": self.get_device(k),
|
||||||
"frequency": self.get_argument("{}_frequency".format(k),
|
"frequency": self.get_argument(
|
||||||
NumberValue())
|
"{}_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):
|
def run(self):
|
||||||
for k, v in self.dds.items():
|
for k, v in self.dds.items():
|
||||||
v["driver"].set(v["frequency"])
|
self.set_dds(v["driver"], v["frequency"])
|
||||||
|
|
|
@ -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
|
|
|
@ -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)
|
|
Loading…
Reference in New Issue