artiq-fast: build gateware from a self-contained separate source derivation

Addresses item 2. of Gitea issue #1.
This commit is contained in:
Astro 2020-01-09 00:33:52 +01:00
parent 2ba53bff9c
commit 7d4e022784

View File

@ -8,6 +8,9 @@
, extraInstallCommands ? ""}: , extraInstallCommands ? ""}:
let let
name = "artiq-board-${target}-${variant}-${version}";
version = import ./pkgs/artiq-version.nix (with pkgs; { inherit stdenv fetchgit git; });
installPath = "${pkgs.python3Packages.python.sitePackages}/artiq/board-support/${target}-${variant}";
artiqSrc = import ./pkgs/artiq-src.nix { fetchgit = pkgs.fetchgit; }; artiqSrc = import ./pkgs/artiq-src.nix { fetchgit = pkgs.fetchgit; };
fetchcargo = import ./fetchcargo.nix { fetchcargo = import ./fetchcargo.nix {
inherit (pkgs) stdenv cacert git cargo cargo-vendor; inherit (pkgs) stdenv cacert git cargo cargo-vendor;
@ -45,53 +48,115 @@ let
vivado = import ./vivado.nix { inherit pkgs; }; vivado = import ./vivado.nix { inherit pkgs; };
artiqpkgs = import ./default.nix { inherit pkgs; }; artiqpkgs = import ./default.nix { inherit pkgs; };
# Board packages are Python modules so that they get added to the ARTIQ Python # Board packages are Python modules so that they get added to the ARTIQ Python
# environment, and artiq_flash finds them. # environment, and artiq_flash finds them.
in pkgs.python3Packages.toPythonModule (pkgs.stdenv.mkDerivation rec { boardModule = pkgs.python3Packages.toPythonModule (pkgs.stdenv.mkDerivation {
name = "artiq-board-${target}-${variant}-${version}"; name = "${name}-firmware";
version = import ./pkgs/artiq-version.nix (with pkgs; { inherit stdenv fetchgit git; }); inherit version;
phases = [ "buildPhase" "installCheckPhase" "installPhase" ]; phases = [ "buildPhase" "installCheckPhase" "installPhase" ];
buildInputs = [ buildInputs = [
vivado vivado
pkgs.gnumake pkgs.gnumake pkgs.which
(pkgs.python3.withPackages(ps: with ps; [ jinja2 numpy artiqpkgs.migen artiqpkgs.microscope artiqpkgs.misoc artiqpkgs.jesd204b artiqpkgs.artiq ])) (pkgs.python3.withPackages(ps: with ps; [ jinja2 numpy artiqpkgs.migen artiqpkgs.microscope artiqpkgs.misoc artiqpkgs.jesd204b artiqpkgs.artiq ]))
pkgs.cargo pkgs.cargo
artiqpkgs.rustc artiqpkgs.rustc
artiqpkgs.binutils-or1k artiqpkgs.binutils-or1k
artiqpkgs.llvm-or1k artiqpkgs.llvm-or1k
]; ];
buildPhase = buildPhase =
'' ''
export CARGO_HOME=${cargoVendored} export CARGO_HOME=${cargoVendored}
export TARGET_AR=or1k-linux-ar export TARGET_AR=or1k-linux-ar
${buildCommand} ${buildCommand} --no-compile-gateware
''; '';
checkPhase = '' installPhase =
# Search for PCREs in the Vivado output to check for errors ''
check_log() { TARGET_DIR=$out/${installPath}
set +e mkdir -p $TARGET_DIR $out/src
grep -Pe "$1" artiq_${target}/${variant}/gateware/vivado.log
FOUND=$? cp -ar artiq_${target}/${variant}/gateware $out/src/
set -e pushd $out/src/gateware
if [ $FOUND != 1 ]; then LIB_PATH=$(dirname $(dirname $(which python)))/${pkgs.python3Packages.python.sitePackages}
exit 1 (
set -e
cd $LIB_PATH
for EXT in v vh
do
find misoc/ -name "*.$EXT" -type f
done
) | while read V
do
SRC=$LIB_PATH/$V
mkdir -p $(dirname $V)
cp $SRC $V
substituteInPlace top.tcl --replace $SRC $V \
2> /dev/null
done
popd
if [ -e artiq_${target}/${variant}/software/bootloader/bootloader.bin ]
then cp artiq_${target}/${variant}/software/bootloader/bootloader.bin $TARGET_DIR
fi fi
} if [ -e artiq_${target}/${variant}/software/runtime ]
check_log "\d+ constraint not met\." then cp artiq_${target}/${variant}/software/runtime/runtime.{elf,fbi} $TARGET_DIR
check_log "Timing constraints are not met\." else cp artiq_${target}/${variant}/software/satman/satman.{elf,fbi} $TARGET_DIR
fi
${extraInstallCommands}
'';
});
gatewareSourceArchive = pkgs.stdenv.mkDerivation {
name = "${name}-gateware-source.nar.base64";
buildInputs = [ pkgs.nix ];
phases = [ "installPhase" ];
installPhase = "nix-store --dump ${boardModule}/src/gateware | base64 -w0 > $out";
};
# Funnelling the source code through a Nix string allows dropping
# all dependencies via `unsafeDiscardStringContext`. The gateware
# will then be rebuilt only when these contents have changed.
pureGatewareSourceArchive = builtins.toFile "${name}-gateware-source.nar.base64" (
builtins.unsafeDiscardStringContext (
builtins.readFile gatewareSourceArchive
));
# Depends on just Vivado and the generated Bitstream source
gateware = pkgs.stdenvNoCC.mkDerivation {
name = builtins.unsafeDiscardStringContext "${name}-gateware";
unpackPhase = "base64 -d < ${pureGatewareSourceArchive} | nix-store --restore gateware";
buildInputs = [ vivado pkgs.nix ];
buildPhase = ''
cd gateware
vivado -mode batch -source top.tcl
''; '';
installPhase =
'' installPhase = ''
TARGET_DIR=$out/${pkgs.python3Packages.python.sitePackages}/artiq/board-support/${target}-${variant} TARGET_DIR=$out/${builtins.unsafeDiscardStringContext installPath}
mkdir -p $TARGET_DIR mkdir -p $TARGET_DIR
cp artiq_${target}/${variant}/gateware/top.bit $TARGET_DIR
if [ -e artiq_${target}/${variant}/software/bootloader/bootloader.bin ] chmod a+r top.bit
then cp artiq_${target}/${variant}/software/bootloader/bootloader.bin $TARGET_DIR cp top.bit $TARGET_DIR
fi
if [ -e artiq_${target}/${variant}/software/runtime ]
then cp artiq_${target}/${variant}/software/runtime/runtime.{elf,fbi} $TARGET_DIR
else cp artiq_${target}/${variant}/software/satman/satman.{elf,fbi} $TARGET_DIR
fi
${extraInstallCommands}
''; '';
})
doCheck = true;
checkPhase = ''
# Search for PCREs in the Vivado output to check for errors
check_log() {
set +e
grep -Pe "$1" vivado.log
FOUND=$?
set -e
if [ $FOUND != 1 ]; then
exit 1
fi
}
check_log "\d+ constraint not met\."
check_log "Timing constraints are not met\."
'';
};
in pkgs.buildEnv rec {
inherit name;
paths = [ boardModule gateware ];
pathsToLink = [ "/${installPath}" ];
}