Hardware description languages
How VHDL, Verilog and SystemVerilog describe synthesisable hardware, where Chisel, SpinalHDL, Amaranth, Hardcaml and Clash fit, and how to choose between them.
Overview
A hardware description language describes a circuit, not a program. The text looks like software, with modules, signals and conditionals, but every statement in the synthesisable subset turns into gates, registers and wires that all exist at once. This hub is for engineers choosing a language for FPGA work, and for programmers who already know one and want to understand what the tools will and will not accept.
Two languages dominate synthesis: VHDL and Verilog (with its superset SystemVerilog). Both are IEEE standards and both are supported by every vendor tool. A second group of languages, often called hardware construction languages or generators, run as ordinary programs in Scala, Python, OCaml or Haskell and emit Verilog or VHDL for the vendor tool to consume. They do not replace the synthesiser. They replace the typing.
Key ideas
Register-transfer level and the synthesisable subset
Whatever the language, synthesisable code is written at register-transfer level: a description of registers, of the combinational logic between them, and of which clock edge loads each register. Each language is far larger than its synthesisable subset. Delays, file I/O, dynamic memory, class objects and most of the verification features exist for simulation only. A synthesis tool reads the subset, infers flip-flops from clocked processes, infers multiplexers from conditionals, and maps everything to the device’s cells. Code that simulates correctly but falls outside the subset will either be rejected or, worse, silently produce different hardware. Knowing the boundary is the core skill.
VHDL versus Verilog and SystemVerilog
VHDL is strongly typed, verbose and explicit. Signals carry types such as std_logic_vector, unsigned and signed, and mixing them without a conversion is an error. That rigidity catches width and sign mistakes at compile time. VHDL-2008 relaxed much of the ceremony and VHDL-2019 added more, though vendor support for 2019 is still partial at the time of writing. VHDL is common in European industry, defence, aerospace and anywhere a long maintenance life matters.
Verilog is terse and permissive. Widths extend implicitly, undeclared wires appear with a warning, and a missing else creates a latch. SystemVerilog adds packed structs, enumerated types, always_ff and always_comb blocks, interfaces and a large verification layer. For synthesis, SystemVerilog’s typed subset removes most of plain Verilog’s traps while keeping its brevity. It is the default in North American industry and in most open-source cores. Vendor synthesis support for SystemVerilog is good on AMD and Altera, adequate on Lattice and Microchip, and limited in open-source Yosys without a frontend such as Slang or the commercial Verific plugin.
Generators: Chisel, SpinalHDL, Amaranth, Hardcaml and Clash
A generator is a library in a general-purpose language whose objects represent wires and registers. Running the program builds a circuit graph and writes it out as Verilog. Chisel (Scala, from Berkeley) is the best known and underlies Rocket Chip and many RISC-V cores. SpinalHDL (also Scala) was built by an FPGA engineer and is pragmatic about things like clock domains and bus interfaces, and VexRiscv is written in it. Amaranth (Python, formerly nMigen) is popular with the open-source toolchain community and ships its own simulator. Hardcaml (OCaml, from Jane Street) emphasises type safety and testing. Clash compiles a subset of Haskell directly to hardware, treating a circuit as a pure function over streams.
The gain is in parameterisation and reuse: a Chisel generator can produce a 4-port or a 64-port crossbar from one source. The cost is a second toolchain, a generated netlist that is hard to read in the vendor’s schematic viewer, and debugging that passes through two layers of names. Teams that already live in Scala or Python find the trade worthwhile. Teams that must hand code to a certifying authority usually do not.
How to choose
Pick the language your colleagues, your IP and your tool chain already use, in that order. If you are starting alone, VHDL or SystemVerilog are the safe choices because every tool, every job advert and every vendor example supports them. Learn one of them properly before adopting a generator, because the generator’s output is still RTL and you will have to read it when something fails.
Where to start
- /learn/beginner/05-your-first-hdl-module/ writes a first module in both VHDL and Verilog.
- /learn/beginner/06-simulation-and-testbenches/ shows how to run it before touching a board.
- /learn/beginner/07-finite-state-machines/ and /learn/beginner/08-counters-timers-and-debouncing/ cover the patterns you will write most often.
- /learn/beginner/10-from-rtl-to-board/ takes a module through synthesis to hardware.
Intermediate lessons on SystemVerilog for synthesis, VHDL-2008 and a first Amaranth design are coming.
Tools and vendors
| Language | Standard | Synthesis support | Open-source path |
|---|---|---|---|
| VHDL | IEEE 1076-2008, 1076-2019 | All vendors (2019 partial) | GHDL with the ghdl-yosys-plugin |
| Verilog | IEEE 1364-2005 | All vendors | Yosys, Icarus Verilog, Verilator |
| SystemVerilog | IEEE 1800-2023 | AMD and Altera good, others partial | Yosys with Slang frontend, Verilator |
| Chisel | Scala library | Via emitted Verilog | CIRCT, firtool |
| SpinalHDL | Scala library | Via emitted Verilog or VHDL | Built-in simulator wrappers for Verilator |
| Amaranth | Python library | Via emitted Verilog | Yosys integration, own simulator |
| Hardcaml | OCaml library | Via emitted Verilog | Own simulator and test harness |
| Clash | Haskell compiler | Via emitted Verilog or VHDL | GHC-based toolchain |
Vendor-specific notes live at /vendors/amd/, /vendors/altera/, /vendors/lattice/ and /vendors/opensource/.
Common mistakes
- Writing sequential software in an HDL and expecting it to run in order. Every process runs at once.
- Incomplete assignments in combinational blocks, which infer latches rather than logic.
- Mixing blocking and non-blocking assignments in one Verilog always block.
- Using a signal before it is assigned in a VHDL process and misunderstanding the delta cycle that results.
- Trusting a simulator to flag non-synthesisable code. It will not. Only synthesis does.
- Adopting a generator to avoid learning RTL, then being unable to read the output when timing fails.
Going deeper
- IEEE 1076-2019, VHDL Language Reference Manual: the current VHDL standard.
- IEEE 1800-2023, SystemVerilog: the current SystemVerilog standard, which also covers plain Verilog.
- Chisel documentation: language guide and the generator philosophy.
- SpinalHDL documentation: includes a good explanation of clock domains in a generator.
- Amaranth documentation: language guide and simulator.
- Cummings, “Nonblocking Assignments in Verilog Synthesis” (SNUG 2000): the paper that settled the blocking versus non-blocking question.