Topic hub

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.

Updated 13 Nov 2026 · VHDL, Verilog, SystemVerilog, Chisel, SpinalHDL, Amaranth, synthesisable subset, RTL

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.

GeneratorsChisel, SpinalHDLAmaranth, HardcamlClashHand-written RTLVHDLVerilog, SystemVerilogElaborationparameters resolvedgenerate unrolledSynthesisinfer FFs, muxesmap to LUTsNetlistto placeand routeemitSimulation reads the same sources, but also the non-synthesisable parts
Where each language enters the flow. Generators emit Verilog or VHDL and then share the same synthesis path.

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

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