This repository contains a basic skeleton for doing FPGA development and testing, using Clash, Yosys, IceStorm, and more tools. These are all wrapped up and provided using the Nix package manager, meaning this setup should work on any Linux distribution.
It gives you a fairly painless and one-shot way of setting up an environment for Clash development, along with a lot of other helpful tools.
The Nix environment used here installs several tools for FPGA and Haskell development in general:
- Synthesis tools:
- Clash 0.99 (soon-to-be 1.0.0)
- Yosys
- Haskell libraries and tools:
- lens
- shake
- tasty, hedgehog, hunit
- ghcid
- Chip/hardware tools:
- IceStorm and arachne-pnr
- Verification & testing tools:
- Icarus Verilog and GHDL (LLVM version)
- SymbiYosys, a tool for driving
yosys-smtbmc
based verification flows in an automated manner. - A few SMT solvers including Yices (now GPLv3!) and Z3 (MIT) to go with SymbiYosys.
- A neat-o binary cache, so you don’t have to compile anything!
NOTE: This repository has only been tested on Linux! While Nix supports macOS systems, and in theory this repository should work, macOS High Sierra seems to have several issues with Nix at this time of writing, and I CAN NOT provide any support for High Sierra users (as I do not have a Mac).
If you are a Nix-on-macOS user who is brave and would like to try supporting this repository, please submit any patches if they are necessary. In the future I would like to support macOS users, using a binary cache.
First off, you must…
The first thing you must do no matter what Linux distribution you are running is to install the Nix package manager. However, it’s luckily very easy to do this. A bash script on the provided https://nixos.org homepage can do it for you.
When this installation is complete, you should have a /nix
directory on the
root /
dir of your machine, and you should be able to execute:
$ nix-env --version nix-env (Nix) 1.11.14
After this is done, you can clone the Git repository:
$ git clone https://github.com/thoughtpolice/clash-playground $ cd clash-playground
At this point, you normally would just run nix-shell
, however, this normally
implies going and hanging out for a while, because you must compile a bunch of
stuff that may not be in the upstream Nixpkgs repository.
However, I have set up a binary cache for this repository, making it possible to streamline the work to a few extra downloads.
The binary cache’s public address is https://hydra.inner-haven.net, with a
public key of VqumEYPdXW7X7eamcVvvrJaqbCV9LToxKyUPZUv++/A=
, which you should
verify on the public website before using!
The convention is to normally specify this as a single string,
hydra.inner-haven.net-1:VqumEYPdXW7X7eamcVvvrJaqbCV9LToxKyUPZUv++/A=
If you are running on NixOS, or using multi-user NixOS, the best place to do
this is to put it inside your nix.conf
file (see man 5 nix.conf
). If you
are not doing that, just skip over this part and go to the next one. This is
the following specification I use, which allow me to opt-into my server:
binary-caches = https://cache.nixos.org trusted-binary-caches = https://hydra.inner-haven.net signed-binary-caches = * binary-cache-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.inner-haven.net-1:VqumEYPdXW7X7eamcVvvrJaqbCV9LToxKyUPZUv++/A= verify-https-binary-caches = true
This does not enable the cache by default on your machine, but does enable and trust it, so any user may enable it. You can now run `nix-shell` like this:
$ nix-shell --option binary-caches "https://cache.nixos.org https://hydra.inner-haven.net"
NOTE: if you have a bunch of spare cores available, you can speed this up! For
example, using the ncpus
utility, available in most systems already:
$ nix-shell -j$(ncpus) --option binary-caches "https://cache.nixos.org https://hydra.inner-haven.net"
This will download in parallel, but it will also compile many things in parallel, so use it with as many cores as you can spare to help speed it up.
Now…
Once this is complete, you will be dropped into a new Bash shell environment,
with a green PS1
prompt, that looks like the following:
[nix-shell:~/src/clash-playground]$
In order to make sure everything works – try invoking clashi
and testing it:
[nix-shell:~/src/clash-playground]$ clashi CLaSHi, version 0.99 (using clash-lib, version 0.99): http://www.clash-lang.org/ :? for help Clash.Prelude> let x = register (0 :: Unsigned 32) (x + 1) Clash.Prelude> sampleN 32 x [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31] Clash.Prelude>
Hurrah! And with that done, you can now…
Go ahead and look under src/
for more Clash examples and some notes there!
release.nix
– a file describing all of the necessary dependencies and build tools for this project.shell.nix
– a file that is used fornix-shell
, so it knows what environment to put the user inside of.. It simply exports theshell
environment fromrelease.nix
and is otherwise empty.nix/
: contains Nix-related expressions and package code. It mainly provides a customized set of Haskell/Clash packages that are very recent versions.src/
: All Clash and Verilog source code.
The Haskell packages are automatically indexed into a Hoogle database, and the
hoogle
commands are available to you. But it’s easier and even nicer to use
them with ghci
. Simply put the following in your $HOME/.ghc/ghci.conf
:
:def hoogle \s -> return $ ":! hoogle search -l --count=15 \"" ++ s ++ "\"" :def doc \s -> return $ ":! hoogle search -l --info \"" ++ s ++ "\""
Now, you can do things like search for module documentation, for example, for
Clash.Prelude
:
[nix-shell:~/src/clash-playground/nix/haskell]$ ghci GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/austin/.ghc/ghci.conf Prelude> :hoogle Clash.Prelude module Clash.Explicit.Prelude -- file:///nix/store/dkwx3sy2wlc9lgz77gj49pcdgz87i13q-clash-prelude-0.99-doc/share/doc/html/Clash-Explicit-Prelude.html module Clash.Prelude -- file:///nix/store/dkwx3sy2wlc9lgz77gj49pcdgz87i13q-clash-prelude-0.99-doc/share/doc/html/Clash-Prelude.html Prelude>
Note that any new packages you install will automatically get indexed, but every addition means the index must be rebuilt! So it adds a little build time on top of whatever packages you need.
What you need to hack this repository is two things, mostly: nix-prefetch-git
and cabal2nix
. Both of these tools are available in the nix-shell
environment for you.
The two most common things to do are “upgrade Haskell packages” and “upgrade Nixpkgs”.
This is easy: simply get the revision you want to update to (from GitHub, git
rev-parse HEAD
in your local git clone, where-ever) and use the
./update-nixpkgs.sh
script inside ./nix/
, like so:
[nix-shell:~/src/clash-playground]$ cd nix [nix-shell:~/src/clash-playground/nix]$ ./update-nixpkgs.sh <REVISION>
If you want to point the revision to a custom version of Nixpkgs (e.g. in your GitHub) fork, you can do that too:
[nix-shell:~/src/clash-playground/nix]$ ./update-nixpkgs.sh <REPOSITORY> <REVISION>
This is really just a simple wrapper around nix-prefetch-url
.
All of the customized Haskell packages are under the nix/haskell
directory,
each file being generated by cabal2nix
. Thus, updating these packages is also
easy: just use cabal2nix
to point them to a new version.
For example, here is how we might upgrade the clash-prelude
package to the
latest Git version:
[nix-shell:~/src/clash-playground]$ cd nix/haskell [nix-shell:~/src/clash-playground/nix/haskell]$ cabal2nix https://github.com/clash-lang/clash-prelude > clash-prelude.nix
Be sure to read the contributing guidelines. File bugs in the GitHub issue tracker.
Primary git repository:
git clone https://github.com/thoughtpolice/clash-playground
See AUTHORS.txt.
MIT. See LICENSE.txt for more information.