📘 Verilog Syntax Overview#
Verilog syntax is C-like and consists of modules, ports, data types, assignments, and procedural blocks.
📑 Key Verilog Syntax Rules and Concepts#
Concept | Syntax Example | Description |
---|---|---|
Module | module adder(...); ... endmodule | Basic unit of design |
Ports | input , output , inout | Module interface signals |
Data Types | wire , reg , integer , real | Used for signals and variables |
Assignment | assign y = a & b; | Continuous assignment for combinational logic |
Procedural Block | always , initial | Used for sequential or simulation-only code |
Delay | #10 | Time delay (simulation only) |
Display | $display , $monitor , $finish | Used in testbenches for output |
Comments | // single-line , /* multi-line */ | Same as in C/C++ |
✅ Essential Coding Rules for Beginners#
- Every design must be inside a
module
and end withendmodule
. - Use
wire
for combinational outputs,reg
for values assigned insidealways
blocks. - Use
assign
for continuous logic, not insidealways
. always @(*)
oralways @(posedge clk)
are used to model logic — use the correct sensitivity list.- Simulation-only constructs like
initial
,#delay
,$display
are NOT synthesizable. - Indent code and comment generously for readability.
- Bit widths matter:
reg [3:0] a;
means a 4-bit register.
✨ Example (Combinational & Sequential)#
Sequential#
module example(input clk, input a, b, output reg y);
// Sequential process
always @(posedge clk) begin
y <= a & b; // Non-blocking assignment
end
endmodule
Combinational#
module example(input a, b, output reg y);
// combinational process
always @(*) begin
y = a & b; // Blocking assignment
end
endmodule
🔢 Sized vs Unsized Constants in Verilog#
In Verilog, numeric constants (literals) can be either sized or unsized. Understanding the difference is essential for predictable simulation and synthesis.
📐 Sized Constants#
Format: size'basevalue
Explicitly define the number of bits used.
Common bases:
b
= binaryo
= octald
= decimalh
= hexadecimal
Examples:
4'b1010 // 4-bit binary: 1010
8'hA9 // 8-bit hexadecimal: A9
-16'sd5 // 16-bit signed decimal: -5
The
s
prefix (e.g.16'sd
) marks the value as signed.
🧩 Unsized Constants#
- Do not specify a bit-width.
- Interpreted as at least 32 bits, and signed by default.
- May cause unexpected sign extension or truncation.
Examples:
12 // Unsized decimal, treated as 32-bit signed
'd7 // Unsized base-specified decimal
⚠️ Special Values#
Symbol | Meaning | Example |
---|---|---|
x | Unknown (undefined) | 4'b10x1 |
z | High-impedance | 8'bzzzzzzzz |
? | Alias for z | 4'b??0? |
🔧 Padding Behavior#
If a value has fewer bits than the specified size, it is left-padded:
- With
0
,x
, orz
, depending on the literal
- With
Example:
4'b1 // Interpreted as 4'b0001
8'hx // Interpreted as 8'hxx (i.e. xxxxxxxx)
❌ Invalid Syntax Warning#
This is invalid:
8'd -6 // ❌ Will produce an error
Instead, write:
-8'd6 // ✅ Signed negative literal
-(8'd6) // ✅ Parenthesized version
🧠 Tip: Use Sized Constants in RTL#
Always prefer sized constants in RTL design for clarity and tool consistency. Avoid surprises in bit-width inference and sign-extension.
⚙️ Operators in Verilog#
Verilog includes several categories of operators:
Type | Example | Description | ||
---|---|---|---|---|
Arithmetic | + , - , * , / , % | Basic math | ||
Logical | && , || , ! | True/false evaluation | ||
Bitwise | & , | , ^ , ~ | Operate on individual bits | ||
Shift | << , >> | Left/right logical shift | ||
Comparison | == , != , < , >= | Comparisons (return 1-bit result) | ||
Reduction | ~& , | , ~| , ^ , ~^ | Operate across all bits of a vector | ||
Concatenation | {a, b} | Combine signals | ||
Replication | {3{a}} | Repeat a signal | ||
Equality | === , !== | Case equality (X/Z sensitive) | ||
Conditional | cond ? true_val : false_val | Ternary (if-else in one line) |
🧵 String Data Type#
Verilog supports the
string
system task style for printing/logging.There is no native
string
variable type like in C.Use:
$display("Hello = %s", "World");
For storing characters, use a
reg [8*LEN-1:0] my_string;
Example:
reg [79:0] message; // 10 characters
initial message = "Verilog!";
🆔 Identifiers in Verilog#
Identifiers are names for modules, variables, ports, etc.
- Must start with a letter (
a–z
,A–Z
) or underscore (_
) - Can contain letters, digits, underscores, and dollar signs
- Cannot be the same as Verilog keywords
- Are case-sensitive (
data
≠Data
)
Valid Examples:
wire data_1;
reg _temp;
reg $value;
Invalid:
reg 2data; // ❌ starts with digit
reg module; // ❌ keyword
🗂 Verilog Reserved Keywords#
Here’s a compact list of Verilog-2005 keywords:
always, and, assign, automatic, begin, buf, bufif0, bufif1,
case, casex, casez, cell, cmos, config, deassign, default,
defparam, design, disable, edge, else, end, endcase, endconfig,
endfunction, endgenerate, endif, endmodule, endprimitive,
endspecify, endtable, endtask, event, for, force, forever,
fork, function, generate, genvar, if, ifnone, incdir, include,
initial, inout, input, instance, integer, join, large, liblist,
library, localparam, macromodule, medium, module, nand, negedge,
nmos, nor, not, notif0, notif1, or, output, parameter, pmos,
posedge, primitive, pull0, pull1, pulldown, pullup, rcmos,
real, realtime, reg, release, repeat, rnmos, rpmos, rtran,
rtranif0, rtranif1, scalared, small, specify, specparam,
strong0, strong1, supply0, supply1, table, task, time, tran,
tranif0, tranif1, tri, tri0, tri1, triand, trior, trireg,
unsigned, use, vectored, wait, wand, weak0, weak1, while, wire,
wor, xnor, xor
✅ You cannot use any of these as identifiers in your code.