Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Clash: A Functional Hardware Description Language (clash-lang.org)
80 points by r3ndr on Dec 28, 2023 | hide | past | favorite | 10 comments


There was an article on the front page of HN yesterday about Chisel, which was described as a HDL (or a HDL-generating language) based on Scala. I looked at the docs for Chisel and have just looked at the Pong sample chapter for Clash. These seem wildly different to me, but I think maybe I’m just very much more familiar with Haskell syntax and so I feel like I grok Clash, but don’t get Chisel.

So if anyone knows, do both of these languages do the same thing or is there another angle I need to evaluate them through?


As described in my other comment, Clash is not like Chisel in that Clash compiles Haskell source code directly, while Chisel is an EDSL (in Scala)

Since you’re more familiar with Haskell, perhaps have a look at Blarney: https://github.com/blarney-lang/blarney/blob/master/Doc/ByEx... It’s an actively maintained EDSL for circuit design using Haskell as its host language.


Okay, at first, I was amused with the acronym's similarity to a certain Ford model that... didn't last too long on the market. I've snarked on things like this before, and been downvoted, likely for adding little else to the conversation, so I was going to give this one a miss.

Still, I was curious, so I fed it to the Duck, and got links like:

https://www.edsl.net/

https://www.insystechinc.com/edsl/

Not what was meant, I suspected, which is when I started this reply, and then remembered that other search site everyone seems to like. A search there finally brought up this:

https://wiki.c2.com/?EmbeddedDomainSpecificLanguage

which provided the answer I'm pretty sure I was seeking.

So, for all the rest of us less-enlightened visitors who might not actually know, I believe that EDSL (in this case) means:

Embedded Domain Specific Language


Why not just Haskell / What does Clash do that Haskell doesn't?

(I got downvoted, I was asking this question genuinely, am I missing something obvious?)


One of the original authors of Clash here.

I was always torn on how to describe Clash to an audience whose background I don’t know up front: is it a hardware description ‘language’, or, is it a set of tools, libraries and scaffolding to use Haskell as a method for circuit description?

So yes, Clash is just Haskell. Although it is Haskell with certain GHC language extensions enabled by default plus a type-checking plugin for reasoning about type-level natural numbers.

That’s because the Clash compiler can only translate a semantic subset of Haskell to circuits. We use types to determine how big the circuit will become (fixed-length lists, fixed-depth trees, fixed-width numerics, etc.). So the semantic subset part means that Clash will not translate Haskell programs where the recursion depth is unknown at compile time, nor things like mutation (whether it’s ST or IO) or other I/O like actions.

Finally, why we’ve kept the “Clash is a functional hardware description language” is that unlike approaches such as nMigen, Chisel, Spinal, the Clash compiler translates the actual Haskell source code to VHDL/(System)Verilog. It uses the GHC Haskell compiler to do all the parsing, type-checking and “desugaring”. This means that with Clash you can use all of Haskell’s syntax to describe how the circuit operates, including if-expressions, case-expressions, etc. In the other approaches I mentioned you usually have to use some sort of ‘when’-function to describe run-time choice. So those approaches to me feel more like a “use-language-X-as-a-tool-for-circuit-description”, while Clash, again to me, does really feel more like a hardware description ‘language’.


I posted a comment on the main article, not realizing I’d left this tab open for 8 hours, so since you commented here I’ll ask the same question more briefly:

Does Clash compile to Verilog, as Chisel does, (your comment makes me think it does not)? Or is it that it goes directly to a net-list of transistors (I think that’s the right terminology).


Clash compiles to Verilog or VHDL, just like most higher-level hardware description languages (Bluespec is another interesting one which has a Haskell-like dialect and the compiler is written in Haskell).

It's impractical for most new/independent hardware languages to go to some kind of netlist, because the components/modules you will have available will vary greatly depending on your final target. Depending on if you are going to target a specific Intel FPGA, Xilinx FPGA or even a custom ASIC with a specific cell library, the netlist will look very different, and even the tools translating from Verilog will look different.

As an aside though, Verilog is quite versatile, so you can actually represent a netlist in Verilog itself with custom cell libraries. Instead you refer to Verilog you normally write in as a register transfer level (RTL) description.


Thanks, I find hardware design interesting (despite a very small level of knowledge), so I’ll probably spend some of my lunch break chasing down links using RTL as a starting point.


Clash isn't really a separate language, it's more of a library+scaffolding+tooling for Haskell.


Excellent question! The reason has to do with the fundamental differences between software and hardware. Think of software as fundamentally sequential and hardware as fundamentally parallel:

Software source code can't run directly on hardware and has to be either interpreted by an interpreter, or compiled by a compiler. In both cases the source code is transformed into machine instructions. As the term implies these are instructions to the hardware, more specifically a processor, or a processing unit.

Hardware is the physical manifestation of the computer. Most components of a modern computer - CPU, GPU, RAM, SSD drive, USB controller - consist of vast networks of interconnected transistors. By connecting a few transistors together the right way they can express the electrical equivalent of a boolean logic gate (AND, OR, XOR, NOT etc). By connecting logic gates together they can express logic blocks of various types (multiplexers, adders etc). "Zoom out" a few more levels of abstraction and we call the logic blocks "CPU", "RAM", "USB controller" etc.

Many different types of physical objects have been invented that all behave functionally equivalent to a transistor. The first computers were mechanical. For practical and performance reasons, essentially all modern computers use electrical transistors that express boolean logic where logical 0 and logical 1 are represented by different voltage levels.

Going back to machine instructions, these are interpreted by the hardware / boolean logic network / transistors one at a time through the fetch-decode-execute instruction cycle. We call this fundamental interface between hardware and software the Instruction Set Architecture. Some ISAs have variable-length instructions, such as x86, others have only one length, such as RISC-V RV32I. In RV32I all instructions are 32-bit wide. An RV32I CPU fetches one instruction at a time. Each of the instruction's 32 bits are transmitted on a separate wire from memory to the CPU decoder logic block. The decoder logic block in turn is connected to other wires that constitute control signals to other parts of the CPU.

From this perspective let's rephrase your question a few different ways:

Why not use machine instructions to express transistors?

Why not use a sequence of instructions to express the behavior of a billion parts that all move at the same time?

Haskell's syntax and interpreter/compiler tool chain, or any other programming language for that matter is designed to be transformed into machine intructions. Why not use the same syntax and tools to design the hardware that executes those instructions?

Because software design is an abstraction of something inherently sequential, and hardware design is an abstraction of something inherently parallel, massively parallel. Software is "simply" varying voltage levels that represent 0s and 1s, flowing through a labyrinth of billions of transistors in rhythm, all at the same time. The rhythm they are flowing to is the clock frequency. The massively parallel labyrinth is the hardware.

This answer is getting a bit long, but it doesn't even begin to uncover the complexities of hardware. Hardware designers of state-of-the-art chips have to consider things like running different parts of a chip at different clock frequencies, turning parts of for microseconds at a time when they are not used so the chip doesn't burn up, account for the fact that 0s and 1s won't arrive at the intended destination at the same time due to wire length and how "deep" the logic gate network is, and taking these things into consideration when they decide where to physically place parts of a chip.

Nah, you didn't miss anything obvious. To miss something obvious is either subjective, a contradiction in terms or context-dependent. The differences between a programming language and a hardware description language wasn't obvious to you. It is to me.

Does the context of HN assume knowledge of this difference? I sure hope the answer is No! Don't apologize for asking "dumb" questions. I do it frequently, because I learned long ago that I'll likely learn something. More often than not it also turns out that I wasn't the only one confused. The others just didn't know it, or were too afraid to admit it.

Embrace your inner n00b. Ask "dumb" questions. :)

(note: You may very well know some of this already, but it wasn't obvious to me. I seized the opportunity to write an extensive explanation that I hope will help others as well.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: