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 ? ""}:
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; };
fetchcargo = import ./fetchcargo.nix {
inherit (pkgs) stdenv cacert git cargo cargo-vendor;
@ -45,53 +48,115 @@ let
vivado = import ./vivado.nix { inherit pkgs; };
artiqpkgs = import ./default.nix { inherit pkgs; };
# Board packages are Python modules so that they get added to the ARTIQ Python
# environment, and artiq_flash finds them.
in pkgs.python3Packages.toPythonModule (pkgs.stdenv.mkDerivation rec {
name = "artiq-board-${target}-${variant}-${version}";
version = import ./pkgs/artiq-version.nix (with pkgs; { inherit stdenv fetchgit git; });
phases = [ "buildPhase" "installCheckPhase" "installPhase" ];
buildInputs = [
vivado
pkgs.gnumake
(pkgs.python3.withPackages(ps: with ps; [ jinja2 numpy artiqpkgs.migen artiqpkgs.microscope artiqpkgs.misoc artiqpkgs.jesd204b artiqpkgs.artiq ]))
pkgs.cargo
artiqpkgs.rustc
artiqpkgs.binutils-or1k
artiqpkgs.llvm-or1k
];
buildPhase =
''
export CARGO_HOME=${cargoVendored}
export TARGET_AR=or1k-linux-ar
${buildCommand}
'';
checkPhase = ''
# Search for PCREs in the Vivado output to check for errors
check_log() {
set +e
grep -Pe "$1" artiq_${target}/${variant}/gateware/vivado.log
FOUND=$?
set -e
if [ $FOUND != 1 ]; then
exit 1
# Board packages are Python modules so that they get added to the ARTIQ Python
# environment, and artiq_flash finds them.
boardModule = pkgs.python3Packages.toPythonModule (pkgs.stdenv.mkDerivation {
name = "${name}-firmware";
inherit version;
phases = [ "buildPhase" "installCheckPhase" "installPhase" ];
buildInputs = [
vivado
pkgs.gnumake pkgs.which
(pkgs.python3.withPackages(ps: with ps; [ jinja2 numpy artiqpkgs.migen artiqpkgs.microscope artiqpkgs.misoc artiqpkgs.jesd204b artiqpkgs.artiq ]))
pkgs.cargo
artiqpkgs.rustc
artiqpkgs.binutils-or1k
artiqpkgs.llvm-or1k
];
buildPhase =
''
export CARGO_HOME=${cargoVendored}
export TARGET_AR=or1k-linux-ar
${buildCommand} --no-compile-gateware
'';
installPhase =
''
TARGET_DIR=$out/${installPath}
mkdir -p $TARGET_DIR $out/src
cp -ar artiq_${target}/${variant}/gateware $out/src/
pushd $out/src/gateware
LIB_PATH=$(dirname $(dirname $(which python)))/${pkgs.python3Packages.python.sitePackages}
(
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
}
check_log "\d+ constraint not met\."
check_log "Timing constraints are not met\."
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}
'';
});
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 =
''
TARGET_DIR=$out/${pkgs.python3Packages.python.sitePackages}/artiq/board-support/${target}-${variant}
mkdir -p $TARGET_DIR
cp artiq_${target}/${variant}/gateware/top.bit $TARGET_DIR
if [ -e artiq_${target}/${variant}/software/bootloader/bootloader.bin ]
then cp artiq_${target}/${variant}/software/bootloader/bootloader.bin $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}
installPhase = ''
TARGET_DIR=$out/${builtins.unsafeDiscardStringContext installPath}
mkdir -p $TARGET_DIR
chmod a+r top.bit
cp top.bit $TARGET_DIR
'';
})
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}" ];
}