The short answer: Verilog has two families of data types. Nets (mainly wire) represent connections and must be driven continuously, by an assign or a module output. Variables (mainly reg, plus integer, time and real) hold the last value assigned to them in an always or initial block. A reg is not necessarily a flip-flop: it becomes a flop only if it’s assigned on a clock edge. Both can be vectors, and variables can form arrays used as memories.
“Should this be a wire or a reg?” is the question every Verilog beginner asks. The answer isn’t about hardware at all; it’s about how the signal is assigned in your code. Once that clicks, data types are easy.
- The four values
- Nets vs variables
- Vectors and part selects
- Signed types
- integer, time and real
- Arrays and memories
- Implicit nets: a trap
Table of Contents
Part 1: The four values
Every bit in Verilog can be 0, 1, x (unknown) or z (high impedance, nobody driving). In simulation, nets start as z when nothing drives them and variables start as x until they’re assigned. Seeing x in a waveform usually means a missing reset or a missing assignment.
Part 2: Nets vs variables

wire y; // net: driven by a continuous assignment
assign y = a & b;
reg q; // variable: assigned in a procedural block
always @(posedge clk) q <= d; // this reg becomes a flip-flop
reg z;
always @(*) z = a | b; // this reg is combinational logic!
The rule I follow: if a signal is assigned with assign or connected to a module output, it’s a wire. If it’s assigned inside an always or initial block, it’s a reg. In SystemVerilog, logic works in both places, which removes the confusion.
Part 3: Vectors and part selects
wire [7:0] data; // 8-bit vector, bit 7 is the MSB
reg [31:0] word;
assign msb = data[7]; // bit select
assign nib = data[3:0]; // part select
assign byte1 = word[8 +: 8]; // indexed part select: bits 15:8
assign top = word[31 -: 8]; // bits 31:24
Indexed part selects (+: and -:) are very useful when the start position is a variable, because the width stays constant.
Part 4: Signed types
By default vectors are unsigned. Declare reg signed [7:0] or use $signed() for two’s complement arithmetic. If you mix signed and unsigned operands in one expression, Verilog treats the whole expression as unsigned, which is a classic bug in DSP code. My operators post covers this in more detail.
Part 5: integer, time and real
| Type | Size | Typical use |
|---|---|---|
| integer | 32-bit signed variable | Loop counters, testbench calculations |
| time | 64-bit unsigned | Storing $time in testbenches |
| real | Double-precision floating point | Testbench models, not synthesisable |
| realtime | Like real, for time values | $realtime in testbenches |
Part 6: Arrays and memories
reg [7:0] mem [0:255]; // 256 words, 8 bits each
reg [7:0] grid [0:3][0:3]; // 2-D array (Verilog-2001)
always @(posedge clk)
if (we) mem[addr] <= wdata;
assign rdata = mem[raddr]; // one word per access
You can only access one element of a Verilog array at a time; there’s no way to assign a whole array in one statement (SystemVerilog adds that). Synthesis tools turn small arrays into flops and larger ones, written in the right style, into RAM.
Part 7: Implicit nets: a trap
If you use an undeclared name in a port connection or on the left of an assign, Verilog silently creates a 1-bit wire. A typo then compiles fine and you get a floating signal. I put this at the top of every file:
`default_nettype none
Now any undeclared name is an error. (Some third-party code expects the default, so set it back to wire at the end of your files if you mix code.)
Practise this on VLSI Forge
I built VLSI Forge so you can write RTL in your browser, run it on a real simulator and check every signal in the waveform. Free, nothing to install.
Previous in my Verilog series: Verilog syntax, comments and numbers. Next: Verilog operators.
FAQ
Is a reg always a flip-flop?
No. A reg assigned in a clocked always block becomes a flip-flop; one assigned in always @(*) becomes combinational logic; one assigned incompletely in a combinational block becomes a latch.
What is the difference between wire and reg?
A wire must be driven continuously by an assign or a module output. A reg holds the value last assigned to it in a procedural block.
What is the default value of a reg?
x (unknown) in simulation, until it’s assigned. Real hardware powers up to 0 or 1, which is why you need a reset.
What is logic in SystemVerilog?
A 4-state type that can be used wherever Verilog needed wire or reg, as long as it has only one driver.
