So far we have seen what an FPGA is and what pieces it has inside (LUTs and Flip-Flops). Now it’s time to tackle the part that usually scares newcomers: The Toolchain (or workflow).
In the programming world, we are used to a “Compile and Upload” button. Behind the scenes, a compiler (avr-gcc) translates C++ into machine code.
In the FPGA world, the process is radically different. We are not generating instructions for a CPU; we are designing a physical chip. This requires a series of complex steps that transform our abstract description into a real electrical configuration.
We call this process FPGA Implementation Flow, and understanding it is important to know what is happening when your computer stays “thinking” for minutes (or hours for large designs).
Design Entry
Everything starts with us writing code. As we saw, we use an HDL (Hardware Description Language) such as Verilog or VHDL.
It is also possible to use graphical design tools (Schema Entry) by connecting blocks with the mouse, but in the professional world and in this course, we will focus on code, which is much more powerful and maintainable.
// Our abstract description
module blinky(input clk, output led);
// ... counter logic ...
endmoduleSynthesis
The first “heavy” step is Synthesis.
Here, the tool takes our Verilog code (which is human-readable) and translates it into a list of basic logic components. It is equivalent to when a C compiler translates to assembly, but instead of instructions, it generates logic gates and registers.
The synthesizer performs three key tasks:
Syntax Checking: Looks for errors in the code.
Inference: Detects what we want to do. If it sees a +, it infers an adder. If it sees an if, it infers a multiplexer.
Technology Mapping: Translates those generic elements into the real resources of our specific FPGA.
The result of synthesis is a Netlist.
Imagine the Netlist as a giant electrical schematic in text that says: “The output of LUT A connects to the input of Flip-Flop B”.
Place and Route (Implementation)
This is one of the most delicate parts of the flow, and where the software works its hardest. We have a Netlist (a list of logical connections), but now we have to place it physically on the chip.
This step is divided into two phases that usually go hand in hand:
The tool decides which exact physical resource of the FPGA will perform each function.
- “We will put the counter’s logic function in the LUT at row 3, column 12”.
- “The input buffer will be at Pin 45”.
It’s like playing a giant Tetris with millions of pieces, trying to keep interconnected pieces close together to reduce delays.
Once the pieces have a fixed location, they need to be connected. The tool searches for paths through the Interconnection Matrix (those “wires” and switches we saw in the previous article).
The router must find free paths for thousands of signals without them crossing incorrectly and, most importantly, meeting timing constraints.
Place & Route is an NP-Complete mathematical problem. That is why, on very large FPGAs, this step can take hours. Fortunately, on the small FPGAs we will use (like the iCE40), it only takes a few seconds.
Timing Analysis
This is not a step that generates a file, but rather a critical report. In a digital circuit, signals take a physical time to travel from one Flip-Flop to another (going through wires and LUTs). If the signal takes too long, it won’t arrive in time for the next clock cycle, and the system will fail.
The timing analyzer checks if, with the current placement and routing, our design can run at the speed we requested (e.g., 100 MHz).
- If it meets the requirements, we have Timing Closure.
- If it doesn’t, the tool will warn us of critical paths that violate the constraints.
Bitstream Generation
If everything has gone well, the last step is to generate the final file. Depending on the vendor, it will have an extension like .bit, .bin, .sof, etc.
This Bitstream file is not an executable. It is a bitstream that defines the state of all configuration switches on the FPGA.
It is literally the map that says:
- “Switch 1024: ON”
- “LUT 50 Content: 10110010”
- “Pin 3 Voltage Standard: 3.3V”
Configuration and Loading
Finally, we send the Bitstream to the chip. Here there is an important distinction compared to microcontrollers.
Most FPGAs (like those from Xilinx or the iCE40 family) are based on SRAM. This means they are volatile.
- When the board powers up, the FPGA is “empty” and dumb.
- The FPGA reads the bitstream from an external Flash memory (or we send it via USB).
- It configures itself and starts running.
If you remove power, the FPGA loses its configuration. That is why, when we “program” our board, we are usually programming the external Flash memory that accompanies the FPGA.
The Complete Flow
To make the mental map clear for us:
Code (Verilog/VHDL): What we write.
Synthesis: Logical translation to primitives (Netlist).
Place & Route: Physical placement and wiring on the chip.
Bitstream: Configuration binary file.
Loading: Send to FPGA/Flash.