# Clash is a Haskell embedded in an FPGA toolchain, and the GHC version you pick decides whether it starts

> Clash compiles Haskell to synthesizable VHDL, Verilog or SystemVerilog, with a REPL for testing designs without a test bench and a compatibility table that spends more space warning about GHC start-up times than listing features. It is aimed at FPGA and ASIC work.

**clash-lang/clash-compiler** — Haskell to VHDL/Verilog/SystemVerilog compiler

- Repository: https://github.com/clash-lang/clash-compiler
- Website: https://clash-lang.org/
- Stars: 1,626 · Forks: 172
- Language: Haskell
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/clash-lang-clash-compiler

## Higher-order functions become parameterised hardware

Clash is described as a functional hardware description language that borrows both its syntax and its semantics from Haskell, and the compiler transforms those high-level descriptions into low-level synthesizable VHDL, Verilog or SystemVerilog.

Three output languages from one source is the practical point. A team that has to target three vendors does not write three descriptions, and the choice becomes a build flag rather than a fork.

The features list explains what makes this possible. Higher-order functions, with type inference, result in designs that are fully parametric by default. A filter that takes a coefficient list does not instantiate it at compile time with Haskell-style partial application, it emits hardware whose parameters are set when it is instantiated in the surrounding design. That single property is the reason to use Clash rather than write a generator script.

The type system is described as strongly typed with a very high degree of type inference, which the README frames as enabling safe and fast prototyping using concise descriptions. For hardware, a type error caught before synthesis is worth a great deal, because the synthesis step is where iteration is slowest.

The topics on the repository name the field: asic, fpga, hardware-description-language, haskell, systemverilog, verilog, vhdl. This is not a general-purpose Haskell tool with a hardware backend. It is a hardware tool that chose Haskell as its surface language.

## Signal is a stream, and that is how feedback loops get written

The core abstraction is stated in one line: synchronous sequential circuit design based on streams of values, called `Signal`s, leads to natural descriptions of feedback loops.

`Signal a` is a stream of `a`, one value per clock cycle. That single type does a lot of work. A register becomes a function from `Signal a` to `Signal a`. A combinational circuit becomes a plain function. A feedback loop, the thing that is awkward in Verilog because it involves non-blocking assignment and simulation ordering, becomes an ordinary recursive function over a stream, where the recursion is unrolled in time rather than in space.

The other structural feature listed is support for multiple clock domains, with type safe clock domain crossing. Type safe is the operative phrase. Crossing clock domains in Verilog is a discipline the tools do not enforce. In Clash, if the crossing is expressed with the clock types in the signature, a crossing that mixes incompatible domains is a type error rather than metastability you find on a bench.

The practical consequence is that the compiler can reject a class of bugs before any code reaches a synthesiser. Whether it catches enough in practice depends on how you write the signals, but the mechanism exists.

## The REPL is the feature that changes the inner loop

The interactive REPL is listed as a headline feature: load your designs in an interpreter and easily test all your components without needing to setup a test bench.

That deserves unpacking, because a test bench in conventional HDL workflow is not a small cost. You write or generate one, you simulate, you inspect waveforms, you iterate. For a design with many small components, most of your time goes into the harness rather than the design.

Clash's REPL can load designs into an interpreter for testing without a test bench. The example files at the top of the `examples/` directory are ordinary Haskell modules: `ALU.hs`, `Blinker.hs`, `Fifo.hs`, `FIR.hs`, `MAC.hs`, `MatrixVect.hs`, `Sprockell.hs`, plus `crc32/` and `i2c/` directories and larger designs such as `CHIP8.hs`, `CochleaPlus.hs`, `Reducer.hs` and `Queens.hs`. `Sprockell.hs` and `CochleaPlus.hs` are recognisably the kind of thing you would write to prove the workflow on a real project rather than a counter.

The same mechanism that gives you type inference gives you executable specifications. A description that evaluates to a concrete result in a REPL is a description whose behaviour you have checked before asking a synthesiser to spend an hour on it.

There is a `clashi` binary as well, which the README's Nix section names alongside `clash`. That is the image-based interactive variant, and it is what makes loading a design into a session with sample inputs practical.

## Pick your GHC version before you pick anything else

The GHC compatibility table in the README is the most operationally important content in the document, and it is unusually candid.

Clash is a compiler that has to be compiled. It is built against a specific GHC, and the table tracks which GHC versions work on which platforms for released and development versions. The rows run from GHC 8.6 through 9.14.

Released versions support older compilers: GHC 8.6 supports Clash 1.0 through 1.8, 8.8 does the same, 8.10 supports 1.2 through 1.8, and 9.0 through 9.2 are also limited to 1.8. Support for the current line, 1.10, begins at GHC 9.12, and 1.10.3 specifically pairs with 9.14.

The footnotes are where the real information is. GHC 9.2 contains a regression that renders Clash error messages indecipherable, and the README says the change was reverted in 9.4, which means 9.2 is a compiler you should avoid entirely rather than a compiler with a rough edge. GHC 9.0.2 on Windows fails to compile `clash-cores`, so the Clash test suite does not run in CI for that combination. GHC 9.12.1 through 9.12.3 contain bugs affecting Clash, with 9.12.4 or newer recommended.

And two footnotes are about start-up time. Clash starts extremely slowly when compiled with 9.4.8 up to and including 9.6.2, with the advice to downgrade to 9.4.7 or upgrade to 9.6.3 and up. On Windows, the same problem appears from GHC 9.6 through 9.12, where the advice is to consider downgrading to 9.4.7.

Platform coverage is uneven too. GHC 9.14 is tested on Linux, and Windows and macOS are not yet covered by the CI matrix. On macOS, 8.10 and 9.2 are marked unsupported.

So the honest summary is that most of the GHC versions people would reach for first are either degraded, unsupported or slow to start, and the project has documented which ones to avoid.

## Four ways to build it, and what each one assumes

The README documents four build routes, and picking the wrong one costs you an afternoon.

For a normal user, it points at clash-lang.org/install for the latest stable release or for setting up a Clash project. That is the route to take unless you are contributing.

For development from source, you clone and check out a version. The two commands that matter are `git checkout v1.2.3` for a released version and `git checkout 1.2` for a release branch, with an explicit warning that release branches might contain non-released patches. That warning matters if you are pinning a dependency.

Cabal requires both Cabal and GHC installed, and the README recommends installing them with ghcup. The command is `cabal v2-run -- clash`, and if it fails the README's advice is to run `cabal update` to refresh the package index. Stack needs Stack installed and is `stack run -- clash`.

Nix is the most elaborate and the most reproducible. It needs Nix 2.4 or newer with the new-style `nix` command and flakes, and those must still be enabled manually in `nix.conf`:

```
experimental-features = nix-command flakes
```

Then the dev shell is `nix develop .` for the default, or `nix develop .#ghc9103` for a specific GHC version. The flake points at the clash-lang Cachix binary cache, so the first run asks whether to allow and trust it, and accepting avoids building Clash from source. For automatic entry and exit, a `.envrc` in the repository root containing `use flake` and `watch_file nix/*` works with direnv and nix-direnv.

That specificity matters. A specific-GHC dev shell such as `nix develop .#ghc9103` is the mechanism for reproducing the compatibility table above, which is how you test a version rather than discovering its behaviour by surprise.

## Repository layout, community and where this is the wrong tool

The tree shows a project with clear internal separation. `clash-ghc/` is the compiler driver, `clash-lib/` the compiler proper, `clash-prelude/` the user-facing prelude of types and primitives, and `clash-term/` the terminal and REPL. Two directories carry the suffix `-hedgehog`, `clash-lib-hedgehog/` and `clash-prelude-hedgehog/`, which is the property-based testing framework applied to the compiler and the prelude respectively. So the generated hardware is tested as a property, not only by example.

There is `benchmark/` for performance work, `tests/` for the suite, `examples/` for the design samples, and `changelog/` alongside CHANGELOG.md. `clash-dev` and `clash-dev.ps1` are development scripts. `ARCHITECTURE.md`, `HACKING.md`, `RELEASING.md` and `AUTHORS.md` are there, which is the documentation set you want before contributing. `cabal.project`, `stack.yaml`, `default.nix`, `shell.nix`, `flake.nix` and `flake.lock` cover the four build systems. `.gitlab-ci.yml` sits alongside `.github/` and `.mergify.yml`, so there is CI on GitLab as well as GitHub.

The community channels are five and split by purpose: a Discourse forum for long-form questions, Discord and Bluesky and Fosstodon for short-form chat, and GitHub issues for bug reports.

Where is this the wrong tool? If your hardware is mostly structural wiring, clock domain crossing glue and memory-mapped register banks, a functional HDL gives you little and costs you a synthesis toolchain to debug. If your team does not know Haskell, the learning cost is not the language but the reorientation from thinking about hardware as concurrent processes to thinking about it as functions on streams. And if your simulator or vendor flow is deeply tied to vendor-specific primitives, generated Verilog that calls into them needs care, because the guarantees Clash gives you are about types, not about how your particular toolchain handles the output.

One licensing point to settle before use. GitHub cannot classify the licence this repository ships, and the LICENSE file is the only source. For a compiler in a hardware toolchain, that needs reading rather than assuming.

## Conclusion

Clash suits a hardware team that already thinks in functional programming and wants to describe DSP, filters or protocol logic at Haskell abstraction level, since polymorphic functions become parameterised hardware and the REPL removes the test bench from the inner loop. It is the wrong choice if your team is Verilog-native and your design is mostly structural wiring, because the generated output is yours to debug after every compile. Before installing, pick your GHC version from the compatibility table rather than accepting the newest one, because Clash starts extremely slowly when compiled with GHC 9.4.8 up to and including 9.6.2 and the README suggests downgrading to 9.4.7 or upgrading to 9.6.3 or later; then check whether your platform is actually covered by CI for that row, since GHC 9.14 is tested on Linux only.

## FAQ

### What does Clash compile to?

Clash transforms Haskell descriptions into low-level synthesizable VHDL, Verilog or SystemVerilog. It is a functional hardware description language that borrows syntax and semantics from Haskell.

### Which GHC version should I use with Clash?

The README's compatibility table shows released Clash 1.10.3 pairing with GHC 9.14, tested on Linux. It also warns that Clash starts extremely slowly with GHC 9.4.8 through 9.6.2, and that GHC 9.12.1 to 9.12.3 contain bugs affecting Clash.

### How do I run Clash without installing it?

The Nix flake provides a dev shell. Run `nix develop .` for the default or `nix develop .#ghc9103` for a specific GHC version, which needs Nix 2.4 or newer with flakes enabled in nix.conf.

### What is a Signal in Clash?

A Signal is a stream of values, one per clock cycle, used for synchronous sequential circuit design. The README says this leads to natural descriptions of feedback loops.

### Can I test Clash components without a test bench?

Yes. Clash has an interactive REPL, described as letting you load designs in an interpreter and test components without setting up a test bench, and a companion clashi binary for image-based interaction.

## Sources

- [clash-lang/clash-compiler on GitHub](https://github.com/clash-lang/clash-compiler)
- [Issues](https://github.com/clash-lang/clash-compiler/issues)
- [Project website](https://clash-lang.org/)
- [README](https://github.com/clash-lang/clash-compiler/blob/master/README.md)
- [Releases](https://github.com/clash-lang/clash-compiler/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/clash-lang-clash-compiler
