Introduction to Verilog HDL
Verilog is a hardware description language. It can look like C because it uses familiar punctuation, but synthesizable Verilog does not describe instructions running on a processor. It describes hardware that synthesis maps into LUTs, flip-flops, routing, memory blocks, DSP blocks, and I/O cells.
Learning Objectives
By the end of this lesson, you should be able to:
- explain what an HDL describes;
- separate synthesizable RTL from simulation-only code;
- recognize modules, ports, nets, registers, and assignments;
- read simple combinational and clocked Verilog;
- avoid the beginner mistake of treating Verilog as sequential software.
Verilog Describes Circuits
This module describes a two-input AND gate:
module and_gate (
input wire a,
input wire b,
output wire y
);
assign y = a & b;
endmodule
There is no CPU loop and no instruction pointer. The output y is continuously driven by logic formed from a and b. If either input changes, the combinational path changes after propagation delay.
RTL, Simulation, and Synthesis
Register-transfer level, or RTL, describes how signals move through combinational logic and registers on clock edges. A simulator executes the Verilog model so you can inspect behavior. A synthesis tool accepts the synthesizable subset and builds hardware.
checks behavior"] SRC --> SYN["Synthesis
builds RTL hardware"] SYN --> PNR["Place and route"] PNR --> BIT["Bitstream"] BIT --> FPGA["FPGA fabric"]
| Code type | Purpose | Goes into FPGA fabric? |
|---|---|---|
| Synthesizable RTL | real logic, registers, memories, interfaces | yes |
| Testbench | drives inputs and checks outputs | no |
Delays such as #10 |
simulation timing stimulus | no |
$display, $finish |
simulation messages and control | no |
| Assertions | verification checks | usually no, unless deliberately synthesized |
Beginner rule: if the code waits for nanoseconds, prints text, opens files, or ends the simulation, it is probably testbench code.
Important Verilog Words
| Word | Meaning |
|---|---|
module |
reusable hardware block with ports |
input, output, inout |
external connections |
wire |
net driven by continuous assignment or a module output |
reg |
procedural variable in older Verilog syntax |
logic |
SystemVerilog signal type often used instead of reg |
assign |
continuous combinational assignment |
always @* |
combinational procedural block |
always @(posedge clk) |
clocked procedural block |
The word reg is a syntax category, not a guarantee that a physical register exists. A reg assigned in combinational logic can synthesize to LUTs. A signal assigned on posedge clk normally synthesizes to flip-flops.
Combinational vs Clocked Hardware
Combinational logic responds to current inputs:
assign y = (a & b) | c;
Clocked logic stores state on a clock edge:
always @(posedge clk) begin
if (rst)
q <= 1'b0;
else
q <= d;
end
The assignment to q updates only on the rising edge of clk. This is how flip-flops, counters, shift registers, and state machines are described.
Worked Example: Active-Low Button
Many FPGA boards wire buttons as active-low: released reads 1, pressed reads 0. A direct LED indicator needs an inverter.
module button_led (
input wire button_n,
output wire led
);
assign led = ~button_n;
endmodule
Expected behavior:
button_n |
Button state | led |
|---|---|---|
1 |
released | 0 |
0 |
pressed | 1 |
This design is combinational. Real push buttons also bounce, so a production design usually adds synchronization and debouncing before using the signal inside a clocked system.
Tiny Testbench
A testbench can check the AND gate without going into the FPGA:
module tb_and_gate;
reg a;
reg b;
wire y;
and_gate dut (
.a(a),
.b(b),
.y(y)
);
initial begin
a = 0; b = 0; #1;
a = 0; b = 1; #1;
a = 1; b = 0; #1;
a = 1; b = 1; #1;
$finish;
end
endmodule
The #1 delays and $finish are simulation-only. They should not appear in synthesizable design modules.
Exercise
Write a synthesizable Verilog module named two_switch_led:
- inputs:
sw0,sw1; - output:
led; - behavior:
ledturns on only when both switches are on.
Expected design:
module two_switch_led (
input wire sw0,
input wire sw1,
output wire led
);
assign led = sw0 & sw1;
endmodule
Expected hardware: one two-input AND function, likely implemented inside one LUT.
Common Mistakes
- Thinking each Verilog line executes once from top to bottom like C.
- Putting
#10,$display, or$finishin RTL intended for synthesis. - Forgetting that signal width affects arithmetic and comparisons.
- Using a button or external input without synchronization.
- Copying SystemVerilog examples into tools configured for older Verilog.
- Ignoring synthesis warnings because simulation appeared to pass.
Summary
Verilog describes hardware. Simulators run the model for verification, while synthesis tools map the synthesizable subset into FPGA resources. Start with a hardware mental model: combinational logic responds to inputs, registers update on clock edges, and testbench code is not the circuit.
Next: Modules, Ports, Wires, and Regs.
Further Reading
- IEEE 1364 Verilog standard overview
- Yosys manual: Verilog frontend and synthesis subset
- Verilator documentation: language support and warnings
- FPGA vendor HDL coding guidelines for synthesis