{
description = "A very basic flake";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
};
runScriptPrefix = package: required: ''
# Search for an imperative declaration of the installation directory of ${package}
error=0
if [[ -f ~/.config/${package}/nix.sh ]]; then
source ~/.config/${package}/nix.sh
else
echo "nix-${package}-error: Did not find ~/.config/${package}/nix.sh" >&2
error=1
fi
if [[ ! -d "$INSTALL_DIR" ]]; then
echo "nix-${package}-error: INSTALL_DIR $INSTALL_DIR isn't a directory" >&2
error=2
'' + ''
fi
if [[ $error -ne 0 ]]; then
exit $error
fi
'';
# pkgs for Xilinx tools
xilinxTargetPkgs = pkgs: with pkgs; [
gnumake
coreutils
stdenv.cc.cc
ncurses5
ncurses
zlib
xorg.libX11
xorg.libXrender
xorg.libxcb
xorg.libXext
xorg.libXtst
xorg.libXi
freetype
gtk2
glib
libxcrypt-legacy
gperftools
glibc.dev
fontconfig
liberation_ttf
# Xilinx ISE
glib
iproute2
libstdcxx5
libusb-compat-0_1
libuuid
motif
# motif3-compat
xorg.libXcursor
xorg.libXft
xorg.libXmu
xorg.libXp
xorg.libXt
xorg.libXrandr
xorg.libSM
xorg.libICE
];
diamondTargetPkgs = pkgs: with pkgs; [
fontconfig
libgcc
glibc
stdenv.cc.cc.lib
xorg.libXext
xorg.libXft
xorg.libX11
xorg.libXrender
];
quartusTargetPkgs = pkgs: with pkgs; [
stdenv.cc.cc.lib
zlib
glib
libxcrypt-legacy
libpng12
freetype
fontconfig.lib
xorg.libSM
xorg.libICE
xorg.libXrender
xorg.libXext
xorg.libX11
xorg.libXtst
xorg.libXi
xorg.libXft
xorg.libxcb.out
xorg.xcbutilrenderutil.out
xorg.libXau
xorg.libXdmcp
gtk2
libelf
expat
dbus.lib
brotli.lib
libpng
bzip2.out
];
questaFhsEnv = pkgs.buildFHSEnv {
targetPkgs = quartusTargetPkgs;
name = "questasim-env";
runScript = pkgs.writeScript "questasim-env" ''
${runScriptPrefix "questa" true}
if [[ ! -z $INSTALL_DIR ]]; then
export PATH=$INSTALL_DIR/bin:$PATH
fi
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
exec "$@"
'';
};
questaFiles = [
"crd2bin" "dumplog64" "flps_util" "hdloffice" "hm_entity" "jobspy" "mc2com"
"mc2perfanalyze" "mc2_util" "qhcvt" "qhdel" "qhdir" "qhgencomp" "qhlib" "qhmake" "qhmap"
"qhsim" "qrun" "qverilog" "qvhcom" "qvlcom" "qwave2vcd" "qwaveman" "qwaveutils"
"sccom" "scgenmod" "sdfcom" "sm_entity" "triage" "vcd2qwave" "vcd2wlf" "vcom" "vcover"
"vdbg" "vdel" "vdir" "vencrypt" "verror" "vgencomp" "vhencrypt" "vis" "visualizer"
"vlib" "vlog" "vmake" "vmap" "vopt" "vovl" "vrun"
"vsim" "wlf2log" "wlf2vcd" "wlfman" "wlfrecover" "xml2ucdb"
];
wrappedQuestaScripts = map (x: pkgs.writeScriptBin x ''
exec ${questaFhsEnv}/bin/questasim-env ${x} "$@"
'') questaFiles;
in {
packages.${system} = {
diamond-shell = pkgs.buildFHSEnv {
multiPkgs = diamondTargetPkgs;
name = "diamond-shell";
multiArch = true;
runScript = pkgs.writeScript "diamond-shell" ''
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
exec bash
'';
};
quartus-shell = pkgs.buildFHSEnv {
targetPkgs = quartusTargetPkgs;
name = "quartus-shell";
runScript = pkgs.writeScript "quartus-shell" ''
${runScriptPrefix "quartus" false}
if [[ ! -z $INSTALL_DIR ]]; then
export PATH=$INSTALL_DIR/quartus/bin:$INSTALL_DIR/questa_fse/bin:$PATH
fi
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
exec bash
'';
};
quartus = pkgs.buildFHSEnv {
targetPkgs = quartusTargetPkgs;
name = "quartus";
runScript = pkgs.writeScript "quartus" ''
${runScriptPrefix "quartus" true}
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
exec $INSTALL_DIR/quartus/bin/quartus
'';
};
questa = pkgs.buildEnv {
name = "questa";
paths = wrappedQuestaScripts ++ [
(pkgs.writeTextFile {
name = "modelsim.ini";
text = ''
Dummy ini
# For VUnit to find ModelSim.
'';
destination = "/modelsim.ini";
})
];
meta = {
description = "Environment containing QuestaSim/ModelSim executable files.";
mainProgram = "vsim";
};
};
quartus-udev-rules = pkgs.writeTextFile {
name = "quartus-usbblaster";
destination = "/etc/udev/rules.d/51-usbblaster.rules";
text = ''
# Intel FPGA Download Cable
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6001", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6002", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6003", MODE="0666"
# Intel FPGA Download Cable II
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6010", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6810", MODE="0666"
'';
};
vivado-shell = pkgs.buildFHSEnv {
targetPkgs = xilinxTargetPkgs;
name = "vivado-shell";
runScript = pkgs.writeScript "vivado-shell" ''
${runScriptPrefix "ise" false}
if [[ ! -z $INSTALL_DIR ]]; then
source $INSTALL_DIR/Vivado/2023.1/settings64.sh
fi
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
exec bash
'';
};
vivado = pkgs.buildFHSEnv {
targetPkgs = xilinxTargetPkgs;
name = "vivado-runner";
runScript = pkgs.writeScript "vivado-runner" ''
${runScriptPrefix "vivado" true}
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
exec $INSTALL_DIR/Vivado/2023.1/bin/vivado "$@"
'';
};
ise-shell = pkgs.buildFHSEnv {
targetPkgs = pkgs: xilinxTargetPkgs pkgs ++ [
self.packages.${system}.ise-fw
];
name = "ise-shell";
runScript = pkgs.writeScript "ise-shell" ''
${runScriptPrefix "ise" false}
if [[ ! -z $INSTALL_DIR ]]; then
source $INSTALL_DIR/14.7/ISE_DS/settings64.sh $INSTALL_DIR/14.7/ISE_DS
fi
exec bash
'';
};
ise = pkgs.buildFHSEnv {
targetPkgs = xilinxTargetPkgs;
name = "xilinx-runner";
runScript = ''
${runScriptPrefix "ise" true}
source $INSTALL_DIR/14.7/ISE_DS/settings64.sh $INSTALL_DIR/14.7/ISE_DS
$INSTALL_DIR/14.7/ISE_DS/ISE/bin/lin64/ise
'';
};
ise-fw = pkgs.stdenv.mkDerivation {
name = "xilinx-jtag-fw";
phases = ["unpackPhase" "installPhase"];
src = ./xilinx/ise/fw;
installPhase = ''
mkdir -p $out/share
cp * $out/share/
'';
};
ise-udev-rules = pkgs.writeTextFile (let
ise-fw = self.packages.${system}.ise-fw;
in {
name = "ise-udev-rules";
destination = "/etc/udev/rules.d/05-xilinx-ise.rules";
text = ''
# version 0003
SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0008", MODE="666"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0007", RUN+="${pkgs.fxload} -v -t fx2 -I ${ise-fw}/share/xusbdfwu.hex -D $tempnode"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0009", RUN+="${pkgs.fxload} -v -t fx2 -I ${ise-fw}/share/xusb_xup.hex -D $tempnode"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="000d", RUN+="${pkgs.fxload} -v -t fx2 -I ${ise-fw}/share/xusb_emb.hex -D $tempnode"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="000f", RUN+="${pkgs.fxload} -v -t fx2 -I ${ise-fw}/share/xusb_xlp.hex -D $tempnode"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0013", RUN+="${pkgs.fxload} -v -t fx2 -I ${ise-fw}/share/xusb_xp2.hex -D $tempnode"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0015", RUN+="${pkgs.fxload} -v -t fx2 -I ${ise-fw}/share/xusb_xse.hex -D $tempnode"
'';
});
vivado-udev-rules = pkgs.writeTextFile {
name = "vivado-udev-rules";
destination = "/etc/udev/rules.d/10-xilinx-vivado.rules";
text = ''
# xilinx-ftdi-usb.rules
ACTION=="add", ATTR{idVendor}=="0403", ATTR{manufacturer}=="Xilinx", MODE:="666"
# xilinx-digilent-usb.rules
ATTR{idVendor}=="1443", MODE:="666"
ACTION=="add", ATTR{idVendor}=="0403", ATTR{manufacturer}=="Digilent", MODE:="666"
# xilinx-pcusb.rules
ATTR{idVendor}=="03fd", ATTR{idProduct}=="0008", MODE="666"
ATTR{idVendor}=="03fd", ATTR{idProduct}=="0007", MODE="666"
ATTR{idVendor}=="03fd", ATTR{idProduct}=="0009", MODE="666"
ATTR{idVendor}=="03fd", ATTR{idProduct}=="000d", MODE="666"
ATTR{idVendor}=="03fd", ATTR{idProduct}=="000f", MODE="666"
ATTR{idVendor}=="03fd", ATTR{idProduct}=="0013", MODE="666"
ATTR{idVendor}=="03fd", ATTR{idProduct}=="0015", MODE="666"
'';
};
};
};
}