Verilog describes hardware. Period.
This is one of the hardest habits to break if you already know how to program a microcontroller. While Verilog may look like sequential code, it has more in common with 74-series logic gates than C programming.
Understanding Verilog Parallelism Using Gate Primitives
Let’s start with a sum-of-products example from your digital logic class (Listing 1 and Figure 1). In this example, we use Verilog gate primitives to perform Y = \sum m(2, 4, 5).
TheseVerilog gate primitives stylistically look like C functions with the gate type followed by parameters for Boolean output and then the input(s). For example, and (Out, in_1, in_2, in_3).
They look like functions. They are not. They never run. The hardware just exists.
module sop3_prims (
input wire C, // LSB
input wire B,
input wire A,
output wire Y
);
wire nA, nB, nC; // inverter wires
wire m2, m4, m5; // minterm wires
not (nA, A);
not (nB, B);
not (nC, C);
and (m2, nA, B, nC); // minterm 2 (010)
and (m4, A, nB, nC); // minterm 4 (100)
and (m5, A, nB, C); // minterm 5 (101)
or (Y, m2, m4, m5); // Sum-of-products
endmodule
Listing 1: Verilog sum-of-products hardware constructed using gate primitives.
Figure 1: Classic 3-bit sum-of-products sensitive to 2, 4, and 5 (https://circuitverse.org/).
Tech Tip: Listing 1 and Figure 1 are for illustration purposes. Nobody writes code this way. It takes too much time and there are too many opportunities for mistakes. See Listing 2 for a better solution.
This is pure combinational circuitry described by Verilog. Everything exists at once; there is no clock and there are no registers. This is nearly identical to building the circuit using a 74HC04 hex inverter, a triple 3-input 74HC11 AND, and a triple 3-input 74HC4075 OR gate.
Standard Verilog Description of the Sum-of-Products Hardware
Listing 2 presents the preferred Verilog code for our sum-of-products hardware. This is more compact than listing 1 and less prone to errors. However, we expect the FPGA synthesis tools to produce the near identical netlists for the given FPGA. In all cases, the synthesis tools distill the logic into fabric and timing-efficient FPGA configuration bits for the smallest footprint and minimal propagation delays.
Tech Tip: If you’re still thinking about the FPGA using a microcontroller lens, the FPGA’s bit file is a giant table to configure peripherals.
module sop3_standard (
input wire C, B, A, // LSB to MSB
output wire Y
);
assign Y = (~A & B & ~C) | // minterm 2 (010)
( A & ~B & ~C) | // minterm 4 (100)
( A & ~B & C); // minterm 5 (101)
endmodule
Listing 2: Preferred code for the sum-of-products circuit.
FPGA LUT Misconceptions and Impact on Timing
The FPGA is not a collection of logic gates. Instead, the core building block is a Look Up Table (LUT). The sum-of-products description featured in this article is mapped to a single LUT. In fact, there will be room to spare as modern LUTs are wider than 3-bits. For example, the Altera Agilex 3 A3CZ135BB18AE7S on the Terasic DE23-Lite features an 8-input LUT as shown in Figure 2
Referring back to Figure 1 we see classic glitch hazards as the inverters have a longer propagation delay. This is minimized by the LUT as the entire sum-of-products collapses into a single LUT. This does not mean that timing glitches are eliminated. However, in this case they are significantly reduced. Larger designs that encompass multiple LUTs are better implemented if we use registers.
Figure 2: Block diagram of the adaptive Logic Module for the Agilex 3 FPGA.
Registers and Clock Signals Discipline the FPGA Hardware
Up until now, we have assumed everything happens in the FPGA at the same time. We now transition from combinational logic to sequential logic with the introduction of clocks and flip-flops otherwise known as registers or simply synchronous memory.
This distinction is visible in Figure 2. As a simple example, we see the topmost output signal is taken directly from the LUT while the next output signal is taken from the top flip flop (Reg). These represent combinational and synchronous outputs (respectively).
-
The combinational output updates continually.
-
The register is updated on the rising edge of a clock signal.
For example, the Terasic board uses a programmable Texas Instruments LMK3C0105A05RERR to provide three clock signals to the FPGA.
Listing 3 presents synchronous Verilog code. The most significant change is the non-blocking assignment operator “<=” and the sensitivity to posedge clk. With regards to Figure 2, the LUT is still used to perform the SOP operation but now we add the reg. The value in the reg is synchronous with the clock signal.
module sop3_registered (
input wire clk, C, B, A,
output reg Y
);
always @(posedge clk) begin
Y <= (~A & B & ~C) |
( A & ~B & ~C) |
( A & ~B & C);
end
endmodule
Listing 3: Registered sum-of-products hardware description.
Simulation Comfort Fallacy: When Verilog Stops Being Hardware
We have focused exclusively on synthesized logic which converts to a bit file that configures an FPGA. This is not the only use of Verilog. Very soon you will be introduced to Verilog based test benches. The test bench does not live on the FPGA. Instead, it lives on your PC. Consequently the compiled Verilog test bench performs functions that the FPGA cannot. The primary differences are time control and the ability to loop. For example, a Verilog testbench could be developed to generate N clock cycles.
If Verilog starts to smell like programming, it will not synthesize.
Distinguish Between Hardware and Testbench
We can see some of the telltale sign in Listing 4. This includes the simulation timescale, the tb (testbench) prefix, and the #5 which indicates a delay of 5 time units.
THIS WILL NOT SYNTHESIZE INTO AN FPGA BITFILE.
`timescale 1ns/1ps
initial begin
clk = 0;
{A, B, C} = 3'b010; // Apply minterm 2
for (i = 0; i < 10; i = i + 1) begin
#5 clk = ~clk; // Rising edge - Y updates here!
#5 clk = ~clk; // Falling edge
end
// Add code to test all minterms.
$stop;
end
Listing 4: Snippet from a Verilog test bench. This will not synthesize.
Tech Tip: On another day we can talk about Verilog generators. They look like programming but are actually iterative hardware generators. They provide an convenient way of instantiation N modules.
Best wishes,
APDahlen
Related Articles by this Author
If you enjoyed this article, you may also find these related articles helpful:
- Implementing a Clock Boundary Synchronizer in Verilog
- How to Implement a PNT derived Pulse Per Second (PPS) External Trigger for an ADC and FPGA
- Implementing a Robust Microcontroller to FPGA SPI Interface: Part 1 - FPGA Challenges
About This Author
Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET-accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians.
Dahlen has returned to his Northern Minnesota home, completing a decades-long journey that began as a search for capacitors. Read his story here.

