What is a Hardware Description Language?

A hardware description language (HDL) is a computer language used to describe the structure and behavior of digital (and sometimes analog) electronic circuits. A HDL may look quite similar to a traditional programming language and indeed will behave similar as well in some aspects, however in other aspects there are important differences that one must be aware of when writing HDL code.

This article is meant to give an extremely brief overview of HDLs, their origins, what’s so special about them and what state of the art HDLs of today can offer.

Where do HDLs originate from?

The origins of HDLs go back as far as the early 1970s when the complexity of digital integrated circuits was increasing dramatically and quickly became too much for traditional engineering workflows to handle. At that time the forefathers of todays HDLs stepped into play. These first HDLs were designed under the intention to allow circuit designers to create register-transfer level (RTL) descriptions from a high level perspective (for the time), independent of the technology (e.g. CMOS) used for production later on.

The big players: VHDL and Verilog

It was during the mid to late 1980s that the main players of today emerged in the industry: VHDL and Verilog. Even though both languages had been around in some form for a while then, it was the standardization by the IEEE which solidified their overall acceptance in the industries.

Since then numerous revisions of both standards where published, the latest being VHDL-2008 and SystemVerilog-2012.

What’s an HDL good for?

A HDL is a domain specific language, specifically designed to support the description of digital logic circuits and clock driven sequential logic. As such a HDL contains special constructs to enable the description of digital hardware and RTL elements.

One example of a hardware related language construct is the description of the rising edge of a clock signal, which is used to model the behavior of sequential circuits.

A D-Flipflop in VHDL would be described like the following:

process (clk) is
begin
    if rising_edge(clk) then
        q <= d;
    end if;
end process;

In Verilog on the other hand the very same D-Flipflop description looks like this:

always @ (posedge clk)
begin
    q <= d;
end

What does an HDL lack?

Usually a HDL alone is not sufficient to specify all aspects of a digital design, e.g. for an FPGA implementation (even more so for ASICs). A lot of meta information is required to turn HDL code into hardware. Some of this meta information can be presented in form of constraints which define physical or timing requirements the resulting hardware must fulfill. To describe these constraints special description languages exist outside the scope of HDLs. Some constraints can be embedded into the HDL code as well, but many engineers (including myself) like to keep the two things apart.

For a simple example, one constraint which practically all digital designs contain is the timing constraint for a clock signal. Such a clock constraint may look like the following (using XDC syntax, a Xilinx flavor of Synopsys SDC syntax):

create_clock -name "system_clock" -period 10.0 -waveform {5.0 5.0} [get_ports "sys_clk_i"]

Or using the older UCF syntax (hmm yes, 100% Xilinx proprietary non-portability):

NET "sys_clk_i" TNM_NET = system_clock;
TIMESPEC TS_system_clock = PERIOD "system_clock" 10 ns HIGH 50%;

Another area where HDLs have not reached their full potential yet is the huge field of verification. During simulation and verification a designer needs to create abstracted models and command sequences to see if the written HDL code behaves as expected. Writing such abstracted code can be very hard in traditional HDLs. Among the reasons for this are a lack of native support for highly abstracted code in HDLs and a lack of standard libraries (like in C or Python).

A lot of specialized verification languages contest to fill this gap, including e, OpenVera, SystemC and SystemVerilog.

Especially SystemVerilog tries to be a jack of all trades, trying to handle RTL coding, supporting various advanced forms of verification and offering a lot of high level constructs. However all these constructs have made SystemVerilog very complex, which in turn caused a lot of best practices to evolve, which constrict the allowed language subset to proven features and coding styles. Ironic.

The future of HDLs

Maybe HDLs may become obsolete in the next decade. HDLs do not offer the same high productivity known from high level programming languages. This is partly due to the very limited support for abstraction and little code reuse and portability issues.

One approach to this problem is the idea of high level synthesis (HLS). Instead of extending and improving HDL languages to support more abstract constructs, why not use existing high level languages like C and adapt the implementation tools? A HLS tool will not gobble up HDL code, but instead accept C code written by a COTS programmer. The HLS tool will then do its best to create a hardware implementation which performs the same task as the program code.

In my opinion this approach sounds a lot better in theory than it works in practice (this may change). There are too many unsupported constructs and a lot of constraints must be tossed at the tools to get the result you want. Since the resulting hardware is not the most optimized, HLS may be seen as a trade of productivity vs. efficiency.

HLS languages include: SystemC (based on C++), Bluespec (based on Haskell), Chisel (based on Scala) and MyHDL (based on Python), among others.

A likely development could be that HLS is added as an additional layer on top of HDL code, similar to high level programming languages added as a top layer onto assembler code. If you want productivity write HLS code, if you need performance and efficiency write HDL code. Since most (all?) existing HLS tools do not directly output a netlist, but synthesizable HDL code, this forecast seems not all that wrong.

[references]