π 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.