1{ stdenv
2, lib
3, abc-verifier
4, bash
5, bison
6, boost
7, fetchFromGitHub
8, flex
9, libffi
10, makeWrapper
11, pkg-config
12, python3
13, readline
14, symlinkJoin
15, tcl
16, verilog
17, zlib
18, yosys
19, yosys-bluespec
20, yosys-ghdl
21, yosys-symbiflow
22, enablePython ? true # enable python binding
23}:
24
25# NOTE: as of late 2020, yosys has switched to an automation robot that
26# automatically tags their repository Makefile with a new build number every
27# day when changes are committed. please MAKE SURE that the version number in
28# the 'version' field exactly matches the YOSYS_VER field in the Yosys
29# makefile!
30#
31# if a change in yosys isn't yet available under a build number like this (i.e.
32# it was very recently merged, within an hour), wait a few hours for the
33# automation robot to tag the new version, like so:
34#
35# https://github.com/YosysHQ/yosys/commit/71ca9a825309635511b64b3ec40e5e5e9b6ad49b
36#
37# note that while most nix packages for "unstable versions" use a date-based
38# version scheme, synchronizing the nix package version here with the unstable
39# yosys version number helps users report better bugs upstream, and is
40# ultimately less confusing than using dates.
41
42let
43
44 # Provides a wrapper for creating a yosys with the specifed plugins preloaded
45 #
46 # Example:
47 #
48 # my_yosys = yosys.withPlugins (with yosys.allPlugins; [
49 # fasm
50 # bluespec
51 # ]);
52 withPlugins = plugins:
53 let
54 paths = lib.closePropagation plugins;
55 module_flags = with builtins; concatStringsSep " "
56 (map (n: "--add-flags -m --add-flags ${n.plugin}") plugins);
57 in lib.appendToName "with-plugins" ( symlinkJoin {
58 inherit (yosys) name;
59 paths = paths ++ [ yosys ] ;
60 nativeBuildInputs = [ makeWrapper ];
61 postBuild = ''
62 wrapProgram $out/bin/yosys \
63 --set NIX_YOSYS_PLUGIN_DIRS $out/share/yosys/plugins \
64 ${module_flags}
65 '';
66 });
67
68 allPlugins = {
69 bluespec = yosys-bluespec;
70 ghdl = yosys-ghdl;
71 } // (yosys-symbiflow);
72
73 boost_python = boost.override {
74 enablePython = true;
75 python = python3;
76 };
77
78in stdenv.mkDerivation (finalAttrs: {
79 pname = "yosys";
80 version = "0.38";
81
82 src = fetchFromGitHub {
83 owner = "YosysHQ";
84 repo = "yosys";
85 rev = "refs/tags/${finalAttrs.pname}-${finalAttrs.version}";
86 hash = "sha256-mzMBhnIEgToez6mGFOvO7zBA+rNivZ9OnLQsjBBDamA=";
87 };
88
89 enableParallelBuilding = true;
90 nativeBuildInputs = [ pkg-config bison flex ];
91 propagatedBuildInputs = [
92 tcl
93 readline
94 libffi
95 zlib
96 (python3.withPackages (pp: with pp; [
97 click
98 ]))
99 ] ++ lib.optional enablePython boost_python;
100
101 makeFlags = [ "PREFIX=${placeholder "out"}"];
102
103 patches = [
104 ./plugin-search-dirs.patch
105 ./fix-clang-build.patch # see https://github.com/YosysHQ/yosys/issues/2011
106 ];
107
108 postPatch = ''
109 substituteInPlace ./Makefile \
110 --replace-fail 'echo UNKNOWN' 'echo ${builtins.substring 0 10 finalAttrs.src.rev}'
111
112 # https://github.com/YosysHQ/yosys/pull/4199
113 substituteInPlace ./tests/various/clk2fflogic_effects.sh \
114 --replace-fail 'tail +3' 'tail -n +3'
115
116 chmod +x ./misc/yosys-config.in
117 patchShebangs tests ./misc/yosys-config.in
118 '';
119
120 preBuild = let
121 shortAbcRev = builtins.substring 0 7 abc-verifier.rev;
122 in ''
123 chmod -R u+w .
124 make config-${if stdenv.cc.isClang or false then "clang" else "gcc"}
125 echo 'ABCEXTERNAL = ${abc-verifier}/bin/abc' >> Makefile.conf
126
127 if ! grep -q "ABCREV = ${shortAbcRev}" Makefile; then
128 echo "ERROR: yosys isn't compatible with the provided abc (${shortAbcRev}), failing."
129 exit 1
130 fi
131
132 if ! grep -q "YOSYS_VER := $version" Makefile; then
133 echo "ERROR: yosys version in Makefile isn't equivalent to version of the nix package (allegedly ${finalAttrs.version}), failing."
134 exit 1
135 fi
136 '' + lib.optionalString enablePython ''
137 echo "ENABLE_PYOSYS := 1" >> Makefile.conf
138 echo "PYTHON_DESTDIR := $out/${python3.sitePackages}" >> Makefile.conf
139 echo "BOOST_PYTHON_LIB := -lboost_python${lib.versions.major python3.version}${lib.versions.minor python3.version}" >> Makefile.conf
140 '';
141
142 preCheck = ''
143 # autotest.sh automatically compiles a utility during startup if it's out of date.
144 # having N check jobs race to do that creates spurious codesigning failures on macOS.
145 # run it once without asking it to do anything so that compilation is done before the jobs start.
146 tests/tools/autotest.sh
147 '';
148
149 checkTarget = "test";
150 doCheck = true;
151 nativeCheckInputs = [ verilog ];
152
153 # Internally, yosys knows to use the specified hardcoded ABCEXTERNAL binary.
154 # But other tools (like mcy or symbiyosys) can't know how yosys was built, so
155 # they just assume that 'yosys-abc' is available -- but it's not installed
156 # when using ABCEXTERNAL
157 #
158 # add a symlink to fake things so that both variants work the same way. this
159 # is also needed at build time for the test suite.
160 postBuild = "ln -sfv ${abc-verifier}/bin/abc ./yosys-abc";
161 postInstall = "ln -sfv ${abc-verifier}/bin/abc $out/bin/yosys-abc";
162
163 setupHook = ./setup-hook.sh;
164
165 passthru = {
166 inherit withPlugins allPlugins;
167 };
168
169 meta = with lib; {
170 description = "Open RTL synthesis framework and tools";
171 homepage = "https://yosyshq.net/yosys/";
172 license = licenses.isc;
173 platforms = platforms.all;
174 maintainers = with maintainers; [ shell thoughtpolice emily Luflosi ];
175 };
176})