Fhs env for installing xilinx

I just wanted to drop this shell.nix for installing xilinx vitis in case someone needs it:

{ pkgs ? import <nixpkgs> {} }:

let
  xrt = pkgs.callPackage ./xrt.nix {};

  fhs = pkgs.buildFHSUserEnv {
    name = "xilinx-env";
    targetPkgs = pkgs: with pkgs; [
      bash
      xrt
      coreutils
      zlib
      stdenv.cc.cc
      ncurses
      xorg.libXext
      xorg.libX11
      xorg.libXrender
      xorg.libXtst
      xorg.libXi
      xorg.libXft
      xorg.libxcb
      xorg.libxcb
      # common requirements
      freetype
      fontconfig
      glib
      gtk2
      gtk3

      # from installLibs.sh
      graphviz
      gcc
      unzip
      nettools
    ];
    multiPkgs = null;
    profile = ''
      vitis_dir=$(echo /opt/xilinx/Vitis/*/bin)
      export PATH=$vitis_dir:$PATH
      export XILINX_XRT="${xrt}"
    '';
  };
in fhs.env

and this xrt.nix

{ stdenv
, fetchFromGitHub
, linuxPackages_5_4
, cmake
, mesa
, libdrm
, pkg-config
, opencl-headers
, ocl-icd
, git
, boost
, ncurses
, openssl
, protobuf
, util-linux
, doxygen
, protobuf3_6
, valgrind
, python3Packages
, curl
, opencl-clhpp
, fetchurl
, libyaml
, udev
, dpkg
}:
let
  inherit (linuxPackages_5_4) kernel;
  suffix = "2.9.317";
  version = "202020.${suffix}";
  xrtBin = fetchurl {
    url = "https://www.xilinx.com/bin/public/openDownload?filename=xrt_${version}_20.04-amd64-xrt.deb";
    sha256 = "sha256-NTKjhOtTCFsjNweHOkH8CrM1ZloLM/+36NfM0w14l2Y=";
  };
  kernelMod = "$(pwd)/usr/src/xrt-${suffix}/driver/xocl";
  KERNELDIR = "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build";

in stdenv.mkDerivation rec {
  pname = "xrt";
  inherit version;
  src = fetchFromGitHub {
    owner = "Xilinx";
    repo = "XRT";
    rev = version;
    sha256 = "sha256-h9zpNHpm9Ys99wG2xdiXPHkzLkRgmM3Qk1PmQwiQv4c=";
  };

  enableParallelBuilding = true;

  # we take the matter in our own hand
  dontFixCmake = true;

  buildInputs = [
    libdrm
    opencl-clhpp
    opencl-headers
    ocl-icd
    boost
    ncurses
    openssl
    protobuf3_6
    util-linux
    doxygen
    curl
    valgrind
    python3Packages.sphinx
    libyaml
    udev
  ];

  nativeBuildInputs = [
    cmake
    pkg-config
    git
    dpkg
  ];


  NIX_CFLAGS_COMPILE = [ "-Wno-error" ];

  preConfigure = ''
    dpkg-deb -x ${xrtBin} root
    export XRT_FIRMWARE_DIR=$(pwd)/root/lib/firmware/xilinx
    if [ ! -d $XRT_FIRMWARE_DIR ]; then
      echo "NO xrt firmware found in binary release"
      false
    fi
    cd src

    find . -type f -print0 | \
      xargs -0 sed -i -e "s!/opt/xilinx!$out/opt/xilinx!;s!/lib/firmware!$out/lib/firmware!"

    substituteInPlace CMakeLists.txt \
      --replace "/usr" "$out/opt/xilinx"

    find . -type f -iname "*.cmake" -print0 | \
      xargs -0 sed -i -e "s!/usr/src/!$out/src/!;s!/etc/OpenCL!$out/etc/OpenCL!;s!/usr/share/pkgconfig!$out/lib/pkgconfig!"
  '';

  postInstall = ''
    export INSTALL_MOD_PATH="$out"
    modDir=$(echo $out/src/xrt-*/driver/xocl)

    pushd $modDir/mgmtpf
    make -C "${KERNELDIR}" -j$NIX_BUILD_CORES M=$(pwd)
    make -C "${KERNELDIR}" -j$NIX_BUILD_CORES M=$(pwd) modules_install
    popd
    pushd $modDir/userpf
    make -C "${KERNELDIR}" -j$NIX_BUILD_CORES M=$(pwd)
    make -C "${KERNELDIR}" -j$NIX_BUILD_CORES M=$(pwd) modules_install
    popd

    ln -s $out/opt/xilinx/xrt/include $out/include
    ln -s $out/opt/xilinx/xrt $out/include/xrt
    ln -s $out/opt/xilinx/xrt/lib/* $out/lib
  '';

  meta = with stdenv.lib; {
    description = "xilinx runtime library";
    homepage = "https://www.xilinx.com/products/boards-and-kits/alveo/u50.html#gettingStarted";
    license = licenses.mit;
    maintainers = with maintainers; [ mic92 ];
    platforms = [ "x86_64-linux" ];
  };
}

Open a shell with it:

$ nix-shell shell.nix

and run the web installer downloaded from the xilinx website.

5 Likes

The code now lives in this repository:

For vivado users there is also a way of building derivations with it:

1 Like

This is amazing. Currently Xilinx stuff is the only reason I have Docker on my laptop. (Because someone else told me that Docker works and I’m too lazy to try anything else.) I will hopefully try this out in a while when I get some time.

1 Like

I also add some module code to update xilinx firmware.
@dramforever Maybe consider moving out the code to a repo if you are an FPGA user yourself.
I only maintain this setup for post-docs in university and therefore cannot fully review changes to it.

I just got confirmation that with the NixOS module, flashing fpga firmware and the opencl drivers from xrt are functional.

I just tried this out. I used Xilinx_Unified_2020.2_1118_1232, and nixos-unstable channel version nixos-21.05pre281538.9e377a6ce42.

I had to make the following changes for Vivado to work:

  1. Replace ncurses with ncurses5, otherwise Vivado complains about missing libtinfo.so.5 on start.
  2. Replace gcc with (lib.hiPrio gcc). Otherwise the gcc ends up taken from stdenv.cc.cc and it’s unwrapped, which cannot compile executables. Vivado simulation needs gcc to work.

After making these changes I was able to try out the usual simulate, synthesize, implement, program, debug (with ILA) on a simple design and it worked great. Thank you so much for putting this together, @Mic92.

I do not use Vitis so I don’t know whether it was okay.

I am still hoping someone can set up an repository in nix community or so with this code. Personally I cannot maintain this as I would require on a colleague to test every change.