Posted March 9, 2026
Guest Article

Programming hardware is hard business…

This guest contribution was written by:

Programming hardware is a hard business. The domains you have to work in - PCIe, low-level network protocols - are hard. The constraints - minimal latency, near-total reliability, and maximum throughput - are also hard. HDL is hard to write well, and hard to manage as a project. Testing HDL: is hard.

What I've done in the previous paragraph, though, is to bundle together two sources of hardness: domain problems, and tooling problems. PCIe is a domain problem; as a protocol, it is what it is, and it's not going away. HDL, though, is a tooling problem. Here I'll argue why it's not a good tool, and how you can use it less, so your job is at least no harder than it needs to be.

Verilog and VHDL - who will be the chief boogeymen of this article - were developed in the 80s. The software languages that were popular in the 80s - Turbo Pascal, BASIC, Fortran, and (if you were riding the AI boom of the time), Lisp - are not in very widespread use. If you confidently sauntered into your morning stand-up meeting in the Bay Area and asserted that the company's next project be implemented in Turbo Pascal, it would be assumed that your microdosing had got out of hand. And this illustrates the problem for us: there have been a hundred major new software languages since the 80s. In hardware, there have been fewer than ten.

The new ones that we do have, though, generally have a few characteristics in common:

  • They're tools for generating verilog and VHDL, so not new HDLs
  • They're based on existing software languages
  • These software languages that they're based on are taken from quite a narrow niche: functional, typed, languages. Because they are used to generate verilog and VHDL, they've been referred to as HCLs: Hardware Construction Languages. Bluespec, Chisel, Clash, Dahlia, Lava, and SpinalHDL are examples of HCLs.

HCLs bring with them many of the best practices that you'd expect from a modern language. One of these is what's called, in other spheres, "defensive design". The spirit of defensive design is simple - humans are somewhat prone to making mistakes, and it's the job of the designer to save us from ourselves. Defensive design is why it's impossible to put your sim card into your phone's sim cradle the wrong way up. There's a notch cut out of one corner, and that notch has to fit with an indent in the sim cradle.

In the field of programming language design, defensive design means crafting the language in such a way that the user's power is sensibly constrained, and his or her errors revealed at the earliest possible stage.

Older languages are entirely different in spirit - they give you all the power in the world, and will happily sit back and watch while you load up your shotgun then point it at your foot. In Mr Verilog's mind, if you want to connect a 16-bit wire to an 8-bit wire in verilog, no problem at all! I guess the boss didn't really need those other 8 bits. In fact, we don't even really need to mention this to him. He's a grown adult and I'm sure he wouldn't have done it by mistake.

Let's look at this with actual code, starting with the verilog:

module silent_truncation (
    input  [15:0] wide_bus,
    output [7:0]  narrow_bus
);
    assign narrow_bus = wide_bus;  // the upper 8 bits make a French exit here
endmodule

And here's the same idea in Clash - this is what we use, other HCLs are available -

silentTruncation :: Signal dom (BitVector 16) -> Signal dom (BitVector 8)
silentTruncation wide = wide  

This doesn't compile - Clash immediately raises an error. Of course, we can still truncate - we just have to be explicit about it:

-- Option A: explicitly take the lower 8 bits
truncated :: Signal dom (BitVector 16) -> Signal dom (BitVector 8)
truncated wide = truncateB <$> wide

-- Option B: explicitly take the upper 8 bits
upperByte :: Signal dom (BitVector 16) -> Signal dom (BitVector 8)
upperByte wide = slice d15 d8 <$> wide

The Verilog philosophy might have been entirely appropriate on the far, far less complex hardware of the time, but writing a modern-scale project with these paradigms is much harder and riskier than it needs to be. Modern HCLs are based on languages which have highly advanced, highly robust type systems. Many large categories of bug are, in one fell swoop, rendered un-codeable. The price you pay for this is that it's harder to write hacky but effective code. In a large-, or even a medium-, or arguably even a small-scale project, this is a trade that you most certainly want to take.

There's another enormous advantage of the HCLs. Projects in Verilog/VHDL (and again, this is reflective of their vintage) - generally built and tested ad-hoc. You might use GNU make to construct your project. For your test runner, you might use python. The point is that these tools don't come with the language itself. You end up DIY-ing your own Devops set-up, which costs time and is often far from best practice. When you hire new employees, they have to learn your idiosyncratic set-up before they can contribute.

With the HCLs, you get the ecosystem that comes with the language - including, very likely, a build system, a test framework, a package manager, and some kind of standard library, for free. These things were developed in the software realm, where there's much more of an open source culture, and so enthusiastic minds immeasurably greater than our own have already invested tens of thousands of man-hours into these things. You are steered towards a development cycle which, it has already been established, works well. You get off the ground much quicker, and you're more likely to be flying in the correct direction when you do.

I'll finish with some futurology. I'll set the date far enough out that nobody will remember this article by then apart from me, so it can be swept safely under the rug if I'm wrong. But by 2035:

  • HCLs will have caught on
  • nobody will be directly writing verilog or VHDL. They'll be like assembly code; still essential, but hidden away beneath the surface.
  • software engineers, who can already write Rust, or Scala, or Haskell - the languages that these HCLs are based on - will be increasingly attracted to the hardware world
  • hardware will be easier to write, and much more robust.
Sign up to
our newsletter