Designing field-programmable gate arrays

How to Design FPGAs

Several parts of the design flow of modern ICs, including FPGAs, closely resemble those of complex software like the Linux kernel or LibreOffice: First, you partition the system into sub-modules, specifying exactly how each of them should behave internally and how it communicates with all the others and the outside world; that is the board that will host the chip. As with software, you can "instantiate" (i.e., include in your design) many already existing modules from third parties or some previous project.

Second – and this is where the real differences start – you must write a precise model of how each new module works in a format suitable both for testing and for generating the physical layout of the final gate array. This happens by using some more or less sophisticated hardware description language (HDL; Figure 3), which I explain later in this article.

Third, you write "test benches," which have extra HDL code whose only purpose is to feed one or more of the modules that go into the FPGA with exactly the same digital waveforms their silicon implementations would receive as inputs. Then, you load everything into an HDL simulator and check, visually or by parsing the logfiles with a script, whether those modules produce the right outputs at the register-transfer level (RTL, more on this below).

Because this "RTL simulation" is for several reasons the most critical part of many projects, I will cover it in detail in a separate article, together with more explanations about writing HDL code.

Once you are satisfied with the simulation, it's time to "synthesize" the circuit – that is, to pass the HDL files, together with the FPGA equivalent of software makefiles, to special compilers that check whether your design can fit in the target chip and work at the desired clock speed.

Those checks can fail for several reasons, the simpler being that your HDL code needs more transistors than the FPGA contains. If that happens, you have to rewrite the HDL code more efficiently or use a bigger FPGA. If the checks succeed, the compilers proceed with the conversion of the HDL code to layout. The two most important results of this phase, called synthesis, will be a netlist and a bitstream.

The netlist is an HDL or equivalent model of the layout that you can load with your test benches in the simulator to check that the layout does work like its original model. This step, called gate-level simulation, is necessary because, although your HDL might be functionally correct, it requires too many levels of cascaded logic gates at some point to work at the desired clock speed. I will show how these problems can happen and how to fix them in a later article. The bitstream is the file you download in the board after you are sure that everything works to tell your FPGA how to connect its gates.

In practice, the real flow contains some other steps, but because they are more dependent on the vendor, or usually less critical than those I just described, I will skip them here. The next step is to install on Linux the FPGA tools by Xilinx and Altera and see how they work.

Quartus Prime and Vivado

The official development platforms for state-of-the-art Altera and Xilinx chips, called Quartus Prime and Vivado, are supported on the Linux distributions traditionally closer to the corporate world (i.e., Red Hat Enterprise, CentOS, SUSE Enterprise, and Ubuntu LTS; Altera also supports Amazon Linux). To understand which versions of each distribution is compatible with each platform, please check the download pages mentioned in the discussion of each tool.

Professional use of full installations of both Vivado and Quartus requires expensive licenses. The free-of-charge, limited versions shown here, however, are more than any beginner FPGA designer might ever need to learn all the tricks of the craft.

To install Quartus, visit the Intel FPGA Software Development Center [7] and download the current Linux version of the Intel Quartus Prime Lite Edition Design Software. Once its TAR archive is on your computer, expand it in a temporary folder and launch the script to start the graphical installation program.

Besides accepting the license agreement, you will only have to provide the absolute path of a folder with enough disk space to host the whole suite (I chose /fpga/quartus) and wait until everything is ready. Once the installation is complete, taking up about 17GB of disk space, you will find the quartus executable and all its auxiliary commands in the subfolder $INSTALLDIR/intelFPGA_lite/$QUARTUS_VERSION_NUMBER/quartus/bin.

Figure 4 shows the Quartus graphical interface in its default configuration. If it seems intimidating, don't worry! You can rearrange it in several ways. In the long run, you will likely end up using the command-line versions of all those components anyway, because it's a much more efficient way to work, at least for certain phases of the design. As an environment for beginners, though, I think it's great.

Figure 4: The Quartus Prime interface for FPGA development puts all the most important functions in plain sight.

The central blue area of the window is where you write your HDL code or run simulations. At the beginning of a project, however, the most important parts would be the Compilation Hierarchy (top left), IP Catalog (top right), and Tasks (center left) panels. The first shows how all the modules of your design are nested into each other; the other two areas deserve more attention.

Quartus divides the FPGA design flow I already outlined in five phases. Two tools are the RTL Simulation and Gate Level Simulation I already mentioned: the others are called Full Design, Rapid Recompile, and Compilation. Full Design is used in the initial configuration and general high-level management of a project where, among other things, you may add other libraries of standard, reusable components to those already provided by Quartus (partially shown in Figure 5). Rapid Recompile is used, as its name suggests, to run and verify small, incremental changes to an already synthesized design.

Figure 5: The IP Catalog panel shows one of the many libraries shipped with Quartus, providing many math functions.

The Compilation steps, shown in Figure 6, perform all the checks described above: They place all the modules in the gate array, route all their connections, and generate both the bitstream to load into the FPGA and the netlist for gate-level simulation.

Figure 6: The Quartus Tasks panel gives quick access to all the phases of FPGA compilation.

The bottom panel of the Quartus interface is a Tcl Console where you can launch scripts for Quartus tools and see logfiles or error reports.


The current version of Vivado at the time of writing was ML Edition 2022.2. Like Quartus for Altera products, Vivado supports all phases of Xilinx FPGA development. To install it, you must first create a free AMD account by following the link on the download page [8]. Then, you can download the current Linux version of the Xilinx Unified Installer, which for version 2022.2 is an executable BIN file of 271MB. To proceed with the download, you must also provide your address; this step is necessary according to the AMD website to get export approval from the U.S. government.

The first thing to do after the download is to create a dedicated folder for Vivado. Consider that the complete suite of Xilinx tools needs about 250GB of disk space, but 60GB are enough to get an environment more than adequate for a beginner. Once that folder is ready, type the commands

#> sudo apt-get install libtinfo5
#> chmod 777 Xilinx_Unified_2022.2_1014_8888_Lin64.bin
#> ./Xilinx_Unified_2022.2_1014_8888_Lin64.bin

at the prompt in the download folder of the installer, being sure to replace the version number with the version you downloaded.

The first command is necessary only on Ubuntu LTS, as explained in the Xilinx online documentation [9]. Otherwise, the install process is similar to that for Quartus, but keep in mind that the installer needs to download a lot of stuff from the Xilinx website, so you'll need to be online with a stable, relatively fast connection. Once the installation is complete, you can start Vivado from your desktop environment or from the command line:

#> cd /z/fpga/Vivado/2022.2/
#> ./bin/vivado

The Vivado graphical interface (Figure 7) has a different style and different layout choices than Quartus. A closer look, however, will reveal that many of the panels have similar content, which is not surprising, because both products are design platforms for the same type of integrated circuits. Two Vivado panels, however, deserve your immediate attention, always keeping in mind that equivalent functions are present also in Quartus.

Figure 7: Vivado might seem different from Quartus, but by recognizing the same functions, it's easier than you might expect.

Figure 8 illustrates a crucial part of the beginning of every FPGA project – that is, choosing the right chip. As the screenshot shows, you may choose between two packages, with different numbers of I/O pins, I/O buffers (IOBs), preconfigured RAM modules, and other elements.

Figure 8: Templates for ready-to-use models of very complex circuits are easily available in Vivado (and Quartus, too).

The Template Selector shown in Figure 9 gives an idea of the support for design of FPGAs with embedded microprocessors: If you need a custom IC with a MicroBlaze or even a generic RISC CPU, you don't have to build it from scratch, because both the core and several peripherals are available as configurable macros.

Figure 9: Every FPGA vendor produces a number of chips grouped in several families: Choosing the right chip is the first critical decision to make in a project.

Besides complex components, designers can also use many other turnkey components at lower levels, like the arithmetic blocks (Figure 10, left).

Figure 10: Besides high-level modules for CPUs and similar systems, Vivado and Quartus contain plenty of components at the RTL level.

The language shown in Figures 3 and 10 is Verilog, which shares the crown for most used HDL with very high speed integrated circuit (VHSIC) hardware description language (VHDL). Both languages were developed in the 1980s but are still doing well, in spite of the arrival of much more sophisticated languages. Don't ask which is better, though, unless you are ready for endless HDL versions of the vi vs. Emacs or KDE vs. Gnome wars.

I will analyze HDL in more detail in the article to come on simulation. For now, the first thing you really need to know about HDL languages is that they are made for concurrency. Each "block" in an HDL module represents one separate blob of logic gates that work simultaneously with all the others, always in the same way, regardless of the order in which those blocks are written in the module, or even scattered in multiple files.

The second thing to recognize is the different levels of HDL. The highest, which is the quickest to write but might be not translatable to silicon, is behavioral: Basically, you describe what a circuit does as synthetically as possible, without worrying about its physical feasibility or performance. This step is very useful, if not mandatory, for both quick modeling and simulation purposes.

Below the behavioral level is RTL, wherein every single register that must exist in the hardware is explicitly declared and is updated according to the current values of other registers or input signals. Synchronous updates, which you must declare explicitly, happen only at clock edges. A well-written RTL can always be synthesized, meaning the tools will be able to translate it into a set of silicon gates that work in the expected way with the expected timing.

The right side of Figure 10 shows the beginning of every well-written HDL module: After a header (not entirely shown) that contains version number, authors, and a synthetic description, you have the so-called instantiations and port list.

These declarations give modules unique names (e.g., COUNTER_TC_MACRO), so other parts of the design can load it, and lists first the values of every configurable parameter it may have (e.g., a 48-bit-wide counter output bus) and then all the input and output ports. Albeit not mandatory, it is a common and extremely recommended good practice to list one signal per line, followed by a brief description of its purpose.

Internally, HDL modules look like that in Figure 3: After the port list is almost all the content, either declarations of internal registers (in the lower part of the figure) or instantiations of synchronous blocks (i.e., register assignments that happen only on each positive or negative edge of some clock signal) or the statement:

Figure 3: A basic sample of the Verilog HDL.
always @(posedge...

Figure 11 is the HDL simulator in Vivado and anticipates what you will learn in the next article: To know whether your design is right, you have to feed it with realistic waveforms and check that all its outputs always look exactly as they should, according to the design specification. Quote often; you can have the software do lots of checking by giving it instructions like "print an error message if the value of output signal X does not change one clock cycle after input signal Y stays low for 10 cycles." Sooner or later, you will have to look very closely at waveforms if you want to know what caused a problem.

Figure 11: A crucial part of every FPGA design is simulating the physical behavior of the hardware circuit, pin by pin.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • 26C3: Milkymist Visual Synthesizer Soon with Ethernet and USB

    Initiator and main developer of the Milkymist project, Sébastien Bourdeauducq, showed a prototype of his visual synthesizer at the latest Chaos Congress and builds his own board for it.

  • Digital IC Simulation on Linux

    Designing field-programmable gate arrays is only half the job: The hardest part is the simulation, but Linux is the best place to tackle certain challenges.

  • News
  • Kernel News

    Chronicler Zack Brown reports on the latest news, views, dilemmas, and developments within the Linux kernel community.

  • Sustainability by Design

    Sustainability studies for the IT industry often ignore the contributions of software. This article explores what developers and admins can do to create and maintain more energy-efficient systems.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More