I come from a programming background and have not messed around too much with hardware or firmware (at most a bit of electronics and Arduino).

What is the motivation in using hardware description languages (HDL) such as Verilog and VHDL over a programming language like C or Assembly language?

Is this a matter of choice?

I read that hardware, which has its firmware written in an HDL, has a clear advantage in running instructions in parallel. However, I was surprised to see discussions expressing doubts whether to write firmware in C or Assembly (how is Assembly appropriate if you don't necessarily have a CPU?) but I concluded it's also an option.

Therefore, I have a few questions (don't hesitate to explain anything):

  1. Can a firmware really be written either in HDL or in a software programming language, or is it just another way to accomplish the same mission? I'd love to have some real-world examples. What constraints result from each option?

  2. I know that a common use of firmware over software is in hardware accelerators (such as GPUs, network adapters, SSL accelerators, etc). As I understand it, this acceleration is not always necessary, but only recommended (for example, in the case of SSL and acceleration of complex algorithms). Can one choose between firmware and software in all cases? If not, I'd be happy to know the cases in which firmware is clearly and unequivocally appropriate.

  3. I've read that the firmware is mostly burned on ROM or flash. How it is represented in there? In bits, like software? If so, what's the profound difference? Is it the availability of adapted circuits in the case of firmware?

I guess I made a mistake here and there in some assumptions, please forgive me. Thank you!

  • 24
    \$\begingroup\$ Programming languages are for describing software, hardware description languages are for describing hardware. \$\endgroup\$ Commented Oct 9, 2014 at 23:07
  • 2
    \$\begingroup\$ You don't write firmware with Verilog or VHDL - you use Verilog or VHDL to design chips, program FPGA and design motherboards. You use C or assembly to write firmware. You can also use C/C++ to design motherboards - there is a library called SystemC that can be compiled by a C compiler to create a program that simulates your design but can also be compiled by a SystemC compiler into circuits. \$\endgroup\$
    – slebetman
    Commented Oct 10, 2014 at 13:56
  • \$\begingroup\$ FWIW, since you have Arduino experience, writing software for an Arduino is called writing firmware. Firmware can be complete operating systems - linux for example is used in the firmware of most routers and Windows is used in the firmware of most ATMs \$\endgroup\$
    – slebetman
    Commented Oct 10, 2014 at 13:57
  • \$\begingroup\$ Why do we write books in English and not C? Why do we write programs in C and not nglish? Why didn't telegraphs use English instead of morse code? \$\endgroup\$ Commented Sep 27, 2020 at 23:07
  • \$\begingroup\$ The synthesizable part (what's actually implemented) of VHDL/Verilog/Systemverilog is nothing more then an abstract way to "draw" digital logic circuits using language. You DO NOT program! You draw circuits - with words. \$\endgroup\$
    – shaiko
    Commented Apr 3, 2021 at 12:41

7 Answers 7


What is the motivation in using hardware description languages (HDL) such as Verilog and VHDL over programming languages like C or some Assembly?

C and assembly are good languages for telling a CPU what to do. They describe actions to be done sequentially by a single state machine.

HDLs are good languages for describing or defining an arbitrary collection of digital circuits. They can express operations done in parallel in ways that programming languages can't. They can also describe timing limitations for the interfaces between blocks in ways that programming languages can't.

I was surprised to see discussions expressing doubts whether to write firmware in C or Assembly (how is Assembly appropriate if you don't necessarily have a CPU?)

In that question, what's asked is, "If you are writing code for a microcontroller is there a real difference if you write in assembly or C or some other high level language?".

Since he's specifically asking about systems with a microcontroller (a CPU with peripherals), C or assembly are both reasonable choices for firwmare development, and HDL's are not.

A firmware really can be written either in HDL or in a software programming language, or it's just another way to perform the same mission?

It depends what kind of hardware you have. If you have a CPU, use a programming language. If you have an FPGA or you're designing an ASIC, use an HDL. If you are designing a very large amount of digital logic, you can look to one of the in-between languages like SystemVerilog.

I've read that the firmware mostly burned on ROM or flash. How it is represented in there? In bits, like software? If so, what's the profound difference? Is it the availability of adapted circuits in the case of firmware?

I think you are getting hung up on the term "firmware". This word originally meant code to be run on an embedded system, that wasn't accessible for the end user to change. If you sold somebody a PC, there's a very high chance that the user would change what software is run on it. If you sold them an oscilloscope, you wouldn't want them to change the code that's run on the internal microprocessor, so you called it firmware.

FPGA users appropriated the word "firmware" for the output of their designs, because it is more changeable than hardware (stuff that's soldered together). But really the "firmware" that configures an FPGA is different from the "firmware" that runs on a uC. uC firmware directs the uC through a series of states to perform it's function. FPGA firmware defines a set of interconnections between logic elements, and values to be stored in look-up tables.

In either case, the firmware is typically stored as bits on an eeprom (or on disk on a host machine that will donwload it whenever the embedded system is re-started). But that doesn't make them similar to each other.

  • \$\begingroup\$ When you write in VHDL/Verilog it is alot easier to visualise the logic that will be implemented and thus optimise. The same cannot be said for C. Even SystemC is still divorced enough from actual physical implementation that unexpected synthesis results can occur \$\endgroup\$
    – user16222
    Commented Oct 9, 2014 at 23:15
  • 1
    \$\begingroup\$ @JonRB, If you're coding for a uC or uP, I'm not actually aware of any way to do that with an HDL. I agree that when coding logic, SystemVerilog or SystemC are for systems that are so big that its just not practical to try to design everything at the individual gate level. \$\endgroup\$
    – The Photon
    Commented Oct 9, 2014 at 23:18
  • 2
    \$\begingroup\$ Note that VHDL and Verilog are also used when you have no hardware at all. They can be compiled directly to circuits instead of FPGA bitstream. Apple for example used to design their motherboards using Verilog instead of GUI schematic capture since there is better support for version control, grepping and simply parsing using scripts when your design is plain text instead of proprietary binary drawings. \$\endgroup\$
    – slebetman
    Commented Oct 10, 2014 at 13:53
  • \$\begingroup\$ @slebetman, motherboards are usually PCBs where the dimension of the components matter. I cannot see how an HDL can capture these dimensions. \$\endgroup\$ Commented Sep 27, 2020 at 17:43
  • 1
    \$\begingroup\$ They are captured the normal way your CAD programs do it. At the board layout level or when selecting component form the component library. Only, instead of a GUI selection box the component selection is just writing the right text. With a good IDE you can get autocompletion help when selecting components just like doing it in GUI only it inserts text instead of graphics. For IC designs, where these languages originate from, dimensions of the n-layer, p-layer and metal traces are even more important than simple component dimensions in PCB design or the intended transistor will not even work \$\endgroup\$
    – slebetman
    Commented Sep 27, 2020 at 18:09

For the first part of your question, about the motivations of using one or the other: there is a fundamental difference between C and HDLs (VHDL/Verilog). C is a software programming language (as assembly is), VHDL/Verilog are hardware description languages. They are not meant for the same purpose.

C is translated into assembly code (in its binary form, i.e., machine language) when compiled. This code is a series of instructions that tell the CPU to do a series of basic operations (change a register value, perform an addition, etc.).

On the other hand, a HDL is synthesized to hardware. In VHDL you could for example write something like:

output <= input1 + input2;

(see also a more complete example here). This would be synthesized to an (hardware) adder. If the code is synthesized for an FPGA, this would mean a bitstream that can configure the specific FPGA to implement an adder (as combinational logic).

Actually, you could design a CPU in VHDL (see Soft core Processors VS Hard core Processors), and write the software for it in C...

About the firmware: it actually all depends on how you define the word. A firmware can be a program (software) that runs in a microcontroller (thus written for example in C or assembler), or it can be a bitstream to configure a programmable (hardware) logic device (CPLD or FPGA). Sometimes it can be a package containing both: if you take the firmware for some models of FritzBox (an ADSL modem), they actually contain a whole Linux system (written in assembler, C, and many other programming languages), and a bitstream to configure an FPGA (likely synthesized from VHDL or Verilog).


VHDL and Verilog are more suitable to describe hardware concurrency

Electrons can flow at the same time in parallel wires, so we want to take that into account when designing hardware.

In VHDL, if you write something like:

x <= a or b;
y <= a and b;
z <= x xor y;

(outside of a process or function, which explicitly mark it as sequential), then you have encoded the fact that:

  • x, y, z, a and b are wires
  • a and b are input signals
  • x is connected to the output of a or circuit, which takes a and b as input
  • and so on for the other lines

It is easy to see how that will be synthesized into actual hardware, and that x and y are evaluated at the same time.

A--+----+     |  X
   |    | OR  +-----+
B----+--+     |     |  +-----+
   | |  +-----+     +--+     |
   | |                 | XOR +-- Z
   | |  +-----+     +--+     |
   | +--+     |  Y  |  +-----+
   |    | AND +-----+
   +----+     |

Then, when it is time so simulate the circuit, the simulator (which is usually a sequential program) has so simulate the physics of the circuit something like this:

  • has a or b changed? Yes? Hey, x depends on a. Let's update x.
  • y also depends on a. Update that as well.
  • z depends on x. Update it because x was updated.
  • has anything that x depends on (a or b) been updated? No? Same for y and z. OK, we are done with this step.

This leads to "interesting" possible outcomes which have no sequential analogue, but which represent possible physical situations:

  • x <= not x would lead to an infinite recursion of the simulation. Simulators can just cut off after a certain depth.
  • x <= 0; x <= 1 leads to an error (short circuit). This is one of the reasons whystd_logic exists.

Still, even though VHDL models hardware more closely than C, it is not itself a perfectly detailed description of it:

In the end VHDL provides a nice balance between higher level human understandable circuit functionality, and lower level synthesizability.

C on the other hand, is more focused on talking to the CPU sequentially.

You could of course encode a circuit with C structs, enums and arrays, and then simulate it just like VHDL does (this looks more or less like what System C does, but I have never tried it).

But you would be essentially re-implementing a VHDL simulator, and with a more verbose language. Right tool for the right job I guess.

There are also tools that convert C to VHDL https://stackoverflow.com/questions/8988629/can-you-program-fpgas-in-c-like-languages but expect lower performance since those are hard higher level conversions.

  1. It depends on your architecture. If you have a CPU (or, typically, a Microcontroller), you need to write firmware in a regular programming language (including assembly). If you have something like an FPGA, your firmware needs to be written in a HDL. HDLs cannot (to my knowledge) generate programs that can be efficiently executed by a conventional CPU, and an FPGA does not execute conventional programs out of the box. You could, however, configure your FPGA as a CPU and then execute a conventional program with that. This would require two layers of firmware, the lower layer written in a HDL to build the CPU, and the higher layer written in a conventional programming language to execute on that CPU.
  2. There is no hard distinction between firmware and software. On many devices, firmware would be stored in e.g. flash memory, but on a modern phone, almost everything is stored in flash memory, and the distinction between firmware and software is unclear (most people would probably consider the code to program the baseband processor firmware, and most people would consider application programs software, but where is the exact boundary?).
  3. As I said in 2, there is no clear cut distinction, other than the idea that firmware is a bit more permanent.

HDLs are used to describe(synthesize) hardware where as programming language is used to program the already synthesized hardware i.e cpu.

You can get soft core versions of cpus as VHDL or bitstream to synthesize that cpu on an FPGA.


It's worth mentioning a bit of history. Back in the 1970s-1980s, microcontrollers were still somewhat rare and a lot of digital systems were designed with digital logic (74HC etc) integrated circuits. To save space and cost, HDL languages were evolved. You'd come up with a logic function and hack it down in VHDL, then burn a "PLD" with some manner of PROM on-board. With this you could replace all them integrated circuits with a single one.

Then in the 1990s EPROM microcontrollers became more common and much more affordable, starting to make the use of digital logic PLDs increasingly obsolete. In the 2000s, MCUs came with on-chip flash memories that could be easily re-programmed (electronically erasable) and this mostly put an end to the use of PLDs.

The use of HDL languages remained, but moved to projects with specialized FPGAs, mostly used when you had high volume production or very tight real-time or current consumption requirements, for example in telecommunication devices. It remains like that today, you'll use a FPGA when you have specialized requirements and don't expect the product functionality to change over time.

Today, microcontrollers are ridiculously cheap and more powerful than ever, so the real-time arguments for using FPGA are becoming increasingly irrelevant. Also SoC/ASIC that combine programmable CPU core(s) with digital logic in the same chip are somewhat common too, so you can cherry-pick whatever you like from both worlds.

Also notably, programming in the relatively "high level" C language is much more complex than assembler or VHDL, so this takes a whole lot more programmer education and experience. This is one reason why many companies stayed clear of C in the 1990s - it was simply hard to find C programmers who knew what they were doing and C compilers were of very diverse quality.

  • 2
    \$\begingroup\$ Disagree with the last paragraph - while the concepts of the synthesisable subset of HDLs are simple as it's dealing with primitive functions, to build anything of significant complexity is very difficult and highly specialised. Abstraction, and all that... \$\endgroup\$
    – awjlogan
    Commented Mar 4, 2021 at 9:52
  • \$\begingroup\$ @awjlogan Well, yes... similarly, it is very difficult to make large and complex programs in assembler. C is simply more suitable when you need to introduce layers of abstraction to deal with complexity and/or portability. Intermediate-level C classes usually address abstraction, program design and portability at some extent. \$\endgroup\$
    – Lundin
    Commented Mar 4, 2021 at 9:57
  • \$\begingroup\$ Performance used to be a major argument for sticking with assembler or VHDL though. And that was mostly because of the poor quality of C compilers in the 1990s. \$\endgroup\$
    – Lundin
    Commented Mar 4, 2021 at 9:59
  • 2
    \$\begingroup\$ Yes, agreed on abstraction and quality of compiler (also a factor when writing HDL, incidentally). Specifically, I disagree with the statement that there is more education and experience required to write in C - anecdotally, I would say it takes a lot longer to become "skilled" enough to make useful things in HDL, and even longer to make really useful things :) \$\endgroup\$
    – awjlogan
    Commented Mar 4, 2021 at 10:01

A processor uses a modest amount of circuitry to perform a large number of operations, sequentially, by allowing most of the components to be used to perform different operations at different times.

An FPGA contains a number of circuits that cannot--at least individually--perform particularly sophisticated operations, but are all capable of acting simultaneously and independently.

Suppose one wants to have a chip that performs a number of tasks, among which is monitoring 15 inputs and:

  • Setting an output high any time all inputs have been stable for at least 21ms and the number of inputs that are high is a multiple of three
  • Setting the output low any time all inputs have been stable for at least 21ms and the number of inputs that are high is not a multiple of three
  • Changing the output in arbitrary fashion between the time any input changes and the time all inputs have been stable for at least 20ms.

If one has a microcontroller which is doing other things, but can spare a few microseconds every 20ms to examine those inputs and set the output, then most of the circuitry that the microcontroller uses to perform other tasks will also be usable to perform the task indicated above, so very little circuitry (other than some ROM and maybe RAM) will need to be devoted to that task. On the other hand, it may take awhile between the time an input changes and the time the output properly reflects it.

Using Verilog or VHDL, one could construct a hardware circuit which could continually monitor the 15 inputs and perform the indicated computation. Such a device would probably be able to have the output produce a correct indication within 100ns--orders of magnitude faster than the microcontroller--but the amount of circuitry dedicated to that task and unusable for any other purpose would be much greater.

  • \$\begingroup\$ This does not seem like a particularly clear cut example to illustrate a distinction with - there are enough debatable points in its details that it may not really help familiarize anyone not already familiar. Someone realistically faced with this problem would probably choose a modern MCU with a wide data word and good pin-change interrupts. Deciding which solution is consuming more logic would then require deciding if you count the numerous unused peripherals on the MCU or the untouched slices on the FPGA. The former will be quite a bit cheaper. \$\endgroup\$ Commented Jun 20, 2016 at 23:43
  • \$\begingroup\$ @ChrisStratton: Perhaps I should have suggested that things may change if timing requirements get tighter? Requiring that a CPU have a few microseconds available every 20ms may not require any change to an underlying system, but if the response time needed to be 200us, such a requirement might necessitate a faster CPU than would otherwise be needed, if it needed to be under 20us, it may be necessary to add an extra CPU just to handle it, and if under 200ns it may be impossible to accomplish at all with a CPU. \$\endgroup\$
    – supercat
    Commented Jun 21, 2016 at 0:24
  • \$\begingroup\$ That's because you're not leveraging the MCU's capabilities. On the pin change interrupt, start a hardware timer block that will set the output 20 ms later. Then decide, at leisure if that is actually warranted, and if not, cancel it. It's not really a great example to make your FPGA point because there's so much interdependence - the only part that really runs in parallel is the event detection, and a modern MCU already gives you that in largely parallel hardware. Meanwhile the rest is effectively sequential, so you build a ultra fast state machine that watches a very slow clock? \$\endgroup\$ Commented Jun 21, 2016 at 4:02
  • \$\begingroup\$ @ChrisStratton: If a suitable pin-change interrupt feature exists and isn't already being used for something else, that may avoid the need for constant polling, but if many things happen at once they'll need to be processed sequentially at whatever rate the CPU can handle them. \$\endgroup\$
    – supercat
    Commented Jun 21, 2016 at 14:53
  • \$\begingroup\$ Sequential processing is a non-issue given the huge delay your problem statement imposes between input and response. And even if the current MCU were too busy, adding one for this purpose would be a fraction of the cost of adding an FPGA. Realistically the only way this problem gets solved in an FPGA is either because there already is one with spare slices and the signals routed to it, or as an artificial project in an educational or hobby context. \$\endgroup\$ Commented Jun 27, 2016 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.