Write In PipelineC For FPGAs

The best thing about field-programmable gate arrays (FPGAs), when you have a massively parallel application, is that everything runs in parallel. The worst thing about FPGAs, when you need a lot of stuff to happen in sequence, is that everything runs in parallel. If you have a multi-step computation, for example, you need to break it up into chunks, figure out the timing between them, and make sure that each chunk clears before it is fed new data. This is pipelining, and taking care of all the low-level details yourself is one of the things that can sometimes make FPGA a four-letter word beginning with “F”.

[Julian Kemmerer]’s PipelineC is a C-like language that compiles down into VHDL so that you can use it in an FPGA, and it does the pipelining for you. He has examples of how you’d use it to construct a simple state machine, and after you’ve written a few hundred state machines the long way, you’ll know why this is a good idea.

PipelineC isn’t the only high level synthesis language out there, but it sits in an interesting place. It doesn’t take care of memory or define interfaces. It just takes care of pipelining. We haven’t tried it out yet, but it looks like it would be interesting for moderately complex projects, where the mechanics of pipeline signalling is a hassle, but you don’t require the deluxe treatment. Check it out, and if you like it, let us (and [Julian], natch) know.

If you want to dive head-first into pipelining, give [Al Williams]’ two-part mini-series a look.

Pipeline graphic CC BY-SA 3.0 by CBurnett

15 thoughts on “Write In PipelineC For FPGAs

  1. Historical comment. Originally, they were called Programmable Gate Arrays (PGA). However. They were also offered in pin grid array (PGA) packages, which was confusing. Adding the F made them a 4 letter word. In summary, pin grid arrays are the reason FPGA is a 4 letter word!

    1. To a degree no.

      The “field” part of FPGA is about the fact that the device can be reprogrammed out in the field. A fairly useful feature for some markets. (And yes, a lot of FPGAs use external EEPROMs, but the FPGA can reprogram these via JTAG. (And this is usually how the ROM gets programmed to start with.))

      A lot of early PGAs weren’t re-programmable, and sometimes even masked. And these types of devices are still on the market. (Some PGAs were though UV erasable, and could be reprogrammed in the field. While others were OTP.)

      Some PGAs were though also called Programmable Logic Arrays (PLA) instead, but this can be confused with certain 3D printer filament….

      1. The earliest were GALs, gate array logic and were just a maskable template for effectively ASIC. Not programmable at all.

        Next were PALs, programmable array logic and these were OTP one time programmable with fuses.

        Next were PLDs programmable logic device and these were mostly OTP and later erasable and reprogrammable.

        Next were CPLDs which were also OTP of reprogrammable.

        Then FPGA field programmable gate array.

        There is not as much destination between CPLD and FPGA now as you can get instant on FPGA where the program is imbeded and doesn’t need to read from a serial flash. Generally though FPGA has a larger gate count than CPLD.

        1. Um, no. You’re thinking of the PLA/ULA, which was factory masked. The PAL chip (which was one time programable or UV erasable) was improved into the GAL (which was higher capacity and electrically erasable). CPLDs came next, followed by FPGAs.

        2. Oh, and though there is crossover between low end FPGAs and high end CPLDs, the differentiating factor is the number and amount of hard blocks (CPLDs MAY have memory blocks, but they don’t have DSP blocks, high speed SERDES, external memory controllers etc.)

  2. My brain is just broken with the dissonance of compiling C into an Ada-like language (VHDL) instead of a C-like language (Verilog).

    Not arguing merits or anything, my brain just would have super issues comparing the input to output due to all of the small syntax differences (operators, array accesses, etc.).

    1. My thoughts to. I chose VHDL over Veralog just avoid this confusion in the first place. Any HDL is NOT a programming language and shouldn’t look like one in my opinion.

      I don’t have any piping or clock domain problems in VHDL though I would imagine these things to be less clear in Veralog.

      So I could easily see a bennifit to this for Veralog but not so much for VHDL.

      Brain twister.

      1. By that logic VHDL is pretty bad as it still looks too much like a sequential programming language. An HDL that was based on Lisp or something else functional would probably for the metaphor better.

        1. There were HDLs before VHDL and Veralog like CUPL and PALASM but they could never scale to the level of abstraction we need to support modern devices.

          I agree with your comment and I would like to see new HDLs but we only have current contenders.

          Modern HDLs seem more focused on the fact that we think sequentially rather than holding strong relevance between code and hardware at a human conceptual level.

      2. I’ve been working on FPGAs for decades, and I can say with absolute certainty that choice of language has absolutely zero effect on ability to pipeline or handle clock domain crossings. You have to deal with both explicitly in both languages, there are no language support mechanisms for either.

        1. It’s probably different for different people. For me, starting with very early programmable logic and using 74xx like logic symbols and logic equations, VHDL is easier for me to visualise at a simpler level.

          1. I’m fluent in both VHDL and Verilog, although I write mostly in Verilog because it’s less verbose and the syntax is C-based so there’s less cost to flipping back and forth between Python/C/Verilog. In fact with bitvectors in Python it’s actually easy to construct a shared header file between the firmware and code, because the syntax is identical. The number of times I’ve accidentally used “!=” or “[3:0]” in VHDL…

            Both VHDL and Verilog map almost identically to logic. However Verilog (on its own, not SystemVerilog) is in some sense *closer* because it’s not typed at all (well, essentially not typed, the simulation portion of it is moreso) – everything’s a bit vector.

            For instance, consider signed/unsigned issues. Suppose you’ve got an 8-bit number, and you need to expand it to 16 bits for some reason. If it’s signed, you need to sign-extend the top bit, if it’s unsigned, you need to zero-pad. In Verilog you need to explicitly do one or the other, exactly like you would have to physically do in hardware.

            In VHDL it’s “std_logic_vector(resize(signed(slv_8), slv_16’length));” (or the ‘unsigned’ equivalent). In Verilog you can easily make it dynamic whether or not it’s a signed or unsigned extension, and it’s obvious what’s going on at a logic-level: pass in a “signed_op” bit, and it with the top bit and extend upwards. In VHDL you’d have to do it in an “if/else” block. The VHDL version may be *clearer* to some readers, but the Verilog’s more representative of what’s going on. Not making any arguments about better, mind you. They both synthesize to the same thing.

            Verilog also has unary reductive operators, which are obvious circuit analogs (as in, “and all the bits together”) whereas that doesn’t exist until VHDL-2008. VHDL-2008’s far more approachable in terms of usability, but sadly there are often vendor issues there.

            However there’s really very little difference between the two: it’s really just a vi/emacs flamewar all over again. VHDL’s advantages (strong typing) mostly go away if you need to use IP modules that you only have port-level access to, because you need to adapt them to bit vectors anyway, and then you have the exact same problem as Verilog in ensuring that you’re using those unspecified bit vectors properly.

            I will say that unfortunately the flamewar’s bad enough that if you *don’t* learn both VHDL and Verilog (and at some level SystemVerilog), you’re making a Huge Mistake at this point, because you’ll be limited in what IP modules you can use. There are plenty of vendor IP modules that have SystemVerilog interfaces to control them in a testbench, for instance, and you’re just screwed if you don’t know it.

            So, for the tl;dr crowd: learn both, use one. It sucks, but that’s life.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.