Verilog Cheat Sheet
Last updated
Module structure & ports
A module is the basic building block - it has a name and a port list.
| Syntax | Meaning |
|---|---|
module adder(...); ... endmodule | Define a module and its body |
input clk; | An input port |
output q; | An output port |
output reg q; | An output that is driven from an always block |
input [7:0] data; | An 8-bit input bus (vector) |
inout sda; | A bidirectional port |
adder u1 (.a(x), .b(y), .sum(s)); | Instantiate a module by named ports |
Data types
wire models a connection; reg holds a value that procedural code assigns.
| Element | What it does |
|---|---|
wire w; | A net driven by assign or a module output |
reg r; | Holds a value assigned inside an always/initial block |
wire [3:0] bus; | A 4-bit vector (bits 3 down to 0) |
reg [7:0] count; | An 8-bit register |
bus[2] | Select a single bit |
bus[3:1] | Select a slice of bits (part-select) |
reg mem [0:255]; | A memory: an array of registers |
parameter WIDTH = 8; | A named constant for the module |
Number literals
Format is <size>'<base><value> - size in bits, base as b/o/d/h.
| Syntax | Meaning |
|---|---|
4'b1010 | 4-bit binary, value 10 |
8'hFF | 8-bit hex, value 255 |
8'hff | Same - hex digits are case-insensitive |
16'd255 | 16-bit decimal, value 255 |
3'o7 | 3-bit octal, value 7 |
8'b1010_1100 | Underscores group digits for readability |
1'bx | An unknown (x) bit value |
1'bz | A high-impedance (z) bit value |
Operators
Bitwise, logical, comparison, and reduction operators.
| Operator | What it does |
|---|---|
& | ^ ~ | Bitwise AND, OR, XOR, NOT |
&& || ! | Logical AND, OR, NOT (return 1 bit) |
== != < > <= >= | Comparison operators |
<< >> | Left and right shift |
+ - * / % | Arithmetic operators |
&bus | Reduction AND (AND of all bits) |
|bus | Reduction OR (OR of all bits) |
^bus | Reduction XOR (parity of all bits) |
{a, b} | Concatenation; {4{1'b1}} replicates to 4'b1111 |
Continuous assignment
assign drives a wire continuously - use it for combinational logic.
| Syntax | Meaning |
|---|---|
assign y = a & b; | Drive y with the AND of a and b |
assign sum = a + b; | Continuously compute a sum |
assign y = sel ? a : b; | Ternary - a 2-to-1 multiplexer |
assign {c, s} = a + b; | Capture carry and sum together |
assign y = ~en; | Drive a wire from an inverted signal |
Procedural blocks
always and initial run statements; the sensitivity list controls when.
| Syntax | Meaning |
|---|---|
always @(*) begin ... end | Combinational logic (any input change) |
always @(posedge clk) | Run on each rising clock edge (sequential) |
always @(negedge clk) | Run on each falling clock edge |
always @(posedge clk or posedge rst) | Clocked block with async reset |
initial begin ... end | Run once at time 0 (testbenches, sim only) |
begin ... end | Group multiple statements |
#10 | Delay 10 time units (simulation only) |
Blocking vs non-blocking
Use = for combinational logic, <= for clocked sequential logic.
| Syntax | Meaning |
|---|---|
a = b; | Blocking - executes in order, immediately |
a <= b; | Non-blocking - all RHS read first, then assigned |
always @(*) y = a & b; | Combinational: use blocking = |
always @(posedge clk) q <= d; | A flip-flop: use non-blocking <= |
Mixing = and <= in one block | Avoid it - a common source of bugs |
Control flow
Conditionals and multi-way branches inside procedural blocks.
| Syntax | Meaning |
|---|---|
if (cond) ... else ... | Conditional statement |
if (a) x = 1; else x = 0; | Single-line if/else |
case (sel) ... endcase | Multi-way branch on a value |
2'b00: y = a; | A case item |
default: y = 0; | Fallback case item |
for (i = 0; i < 8; i = i + 1) | Loop (often inside generate or sim) |
repeat (4) @(posedge clk); | Repeat a statement N times |
Common patterns
Building blocks you write again and again, plus testbench tasks.
| Pattern | Syntax |
|---|---|
| D flip-flop | always @(posedge clk) q <= d; |
| Register with reset | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| Counter | always @(posedge clk) count <= count + 1; |
| FSM state register | always @(posedge clk) state <= next_state; |
| FSM next-state logic | always @(*) case (state) ... endcase |
| Print a value | $display("q = %b", q); |
| Print on change | $monitor("t=%0t q=%b", $time, q); |
| End the simulation | $finish; |
Every piece of Verilog syntax you reach for, on one page. This Verilog cheat sheet is a quick reference for the hardware description language - declaring modules and ports, choosing data types, writing combinational and sequential logic, and the always-block patterns that describe real circuits.
The syntax here is standard Verilog (IEEE 1364) and works in common simulators like Icarus Verilog and Verilator. Copy what you need, or try it live in the Verilog playground - write a module, simulate it, and see the output in your browser.
Verilog cheat sheet FAQ
Is this Verilog cheat sheet free?
What is the difference between wire and reg?
wire models a physical connection and must be driven continuously - by an assign statement or a module output - so you use it for combinational nets. A reg holds its value until procedural code changes it, so you use it for anything assigned inside an always or initial block. Despite the name, a reg does not always become a hardware register; it just means the value is set procedurally.What is the difference between blocking and non-blocking assignment?
=) executes immediately and in order, like a normal programming statement, so use it for combinational logic in always @(*) blocks. Non-blocking assignment (<=) evaluates all right-hand sides first and then updates the left-hand sides together, which correctly models flip-flops - so use it in clocked always @(posedge clk) blocks. Mixing the two in one block is a classic source of simulation bugs.