Skip to content
 

I can’t imagine designing hardware in C …

I recently had a conversation with an old friend from my graduate school days who, when I told him about Forte and high-level synthesis, said, “I can’t imagine designing hardware in C, or any other programming language.” This guy is one of the best programmers I know — he wrote the user interface code for the Apollo workstation in 1981, one of the first graphical user interfaces — so I take his opinions seriously.

He went on to say that good hardware had such a high level of parallelism, he didn’t see how a compiler could produce that from inherently sequential code like what is written in a standard, general-purpose programming language. In his words, “though I wouldn’t write in assembly language any more, the output of gcc is crap. If it can’t do a good job with sequential code, why should I believe that a compiler can do a good job producing parallel code?”

My answer to him was along the lines of, “well, it really isn’t all that hard, and our customers have produced lots of real designs using Cynthesizer,” but that wasn’t a very satisfying answer. Here is the answer that I didn’t have time to give my friend:

  1. You’re right, you can’t use C. We need to define what we mean by a programming language. Verilog (and VHDL) is a hardware description language, not a “hardware programming language.” However, it is also a simulation language, with a lot of similarities to Simula (one of the groundbreaking early simulation languages). We’ve been designing hardware in a simulation language for 20 years, so the basic idea is not all that radical.
  2. Though Verilog (and VHDL) is a simulation language, it is not a particularly rich one. It is object-oriented (modules are classes, and instantiations are objects), but it lacks a lot of features that object-oriented programming languages provide. What it does have, however, are bit-wise operators and data types, and a standard module class which has ports, threads, and submodules.
  3. Actually, Verilog (and VHDL) is capable of representing hardware at a higher level of abstraction than RTL, but it has one big drawback: it isn’t used for algorithm development, implementation or publication. Really, the only language that doesn’t have that drawback is C (or C++). Java is a distant second, and the other popular languages aren’t really candidates (M?, Fortran?, Perl?, Python?, Ruby on Rails?, …).
  4. This is where SystemC comes in. C++ is a rich object-oriented language which is nearly universal and, since it is a superset of C, the vast majority of algorithms which are published are in C++. Being an object-oriented language, C++ has the ability to support a hierarchy of layers of abstraction, implemented by libraries of classes. SystemC is a library of classes which implements a “hardware abstraction layer” in C++. You can write the same code in SystemC/C++ as you would write in Verilog, at the netlist level or at RTL. That’s not particularly interesting — algorithms aren’t written at RTL in any language. What’s important is that you can also write code at a higher level than RTL, using C++ constructs. And, you can take a C algorithm, stick it unchanged in a SystemC module (that is, make it a method in an SC_MODULE class), and you have a starting point for hardware implementation.
  5. Now that we have a structure for describing concurrent processes (a hierarchy of modules is a collection of concurrent processes), we’ve got something that a compiler (or high-level synthesis tool) can work with. Extracting fine-grain parallelism from a sequential process is easy (at least conceptually) — compilers have been doing that for years. Managing concurrency between processes requires a bit more work, but there is enough information in the source code for the compiler to do a good job.
  6. Finally, the world of parallel vector supercomputers spawned a rich set of code transformations in the compiler world which could expose possible parallelism in sequential loops. Many of these can be applied to hardware synthesis. The end result is that a great deal of parallelism can be realized from a hardware description in SystemC.
  7. So, implementing parallel hardware from a SystemC description can be done effectively. Generally, this part of the problem falls into the category of scheduling. That is, creating an optimal (by some definition) state machine, or set of state machines, to implement the described functions. Scheduling is a critical part of the high-level synthesis process. But that is only part of the problem. The other part is to implement the desired schedule in the smallest amount of hardware possible. That generally is called allocation, and that is the subject for another article.

The conclusion is that you not only can imagine creating hardware automatically from a C-related programming language, it is being done successfully by today’s high-level synthesis programs. At least, we can say it is being done successfully by Cynthesizer. It has taken quite a bit of time and effort to develop the synthesis technology to the point we are at today, where the vast majority of hardware designs can be done successfully with high-level synthesis. This will have a profound effect on how people do hardware design in the coming years.

Leave a Reply