Two Names, One Job
Every signal in Verilog has a type. The two types you'll meet first are wire and reg. Both can hold a value. Both can be single-bit or multi-bit. The difference isn't about what the signal is - it's about who drives it.
wiresignals are driven outside procedural blocks - byassignstatements, by the outputs of sub-modules, or by module input ports.regsignals are driven inside procedural blocks -initialoralways.
That's the entire rule. The keyword names are awkward because they predate the modern way of writing Verilog. reg doesn't always become a register in hardware. Read on for why.
Wire: The Continuous Connection
A wire is an electrical wire. It carries whatever its driver is producing, continuously. Two ways a wire gets driven:
Three things to notice:
yandzare declaredwirein the module andwireagain in the testbench.- They're driven by
assign- that's the continuous-assignment form. The right-hand side of the=is recomputed whenever any signal in it changes. - We can't write
y = a & binside analwaysblock while keepingyaswire. The compiler would reject it.
If you forget the wire keyword, Verilog will implicitly declare the signal as a single-bit wire for you - which is sometimes convenient and sometimes a silent bug. Most teams enable a tool option that errors on implicit wires. Be explicit and avoid the trap.
Reg: Storage Inside a Procedural Block
A reg is a signal you assign to inside initial or always. The name is a relic of the language's early days when "reg" sounded like "register"; in modern usage a reg is just the type of any signal procedural code writes to.
count is reg inside the module (because the always block writes to it) and wire in the testbench (because the DUT's output port drives it). Same signal, different roles, different types in each scope.
Why "Reg" Doesn't Always Mean "Register"
Here's the most common beginner trap. This module declares y as reg - but the synthesized hardware doesn't contain a flip-flop:
The always @(*) block is sensitive to any input change. It's combinational. A synthesis tool sees that pattern and produces an AND gate - no flip-flop, no clock, just logic. The reg keyword is purely a syntactic requirement because y is assigned inside an always.
To get an actual flip-flop, the always block has to be sensitive to a clock edge:
always @(posedge clk) begin
q <= d;
end
That's the synthesis-tool-please-make-a-flip-flop pattern: clocked sensitivity list, non-blocking assignment. Same reg keyword, completely different hardware. We cover the distinction in Always Block and Blocking vs Non-blocking.
The Decision in Practice
Every time you declare a signal, ask: how will I drive it?
- Driving with
assign? →wire. - Connecting to a sub-module's output port? →
wire. - Module input port? →
wire. (Inputs are always wire.) - Driving from
initialoralways? →reg. - Module output port driven by procedural code? →
output reg. - Module output port driven by
assign? →output wire. (Or justoutput- direction alone defaults to wire.)
That decision tree covers every situation you'll meet in plain Verilog.
Driver Conflicts
wire signals can have multiple drivers in theory - that's how tri-state buses work, where several modules can drive the same wire and the inactive ones go high-impedance (z). For ordinary logic, two assign statements writing the same wire produce undefined behavior:
assign y = a;
assign y = b; // BAD - y has two drivers
The simulator might pick one, might X-out the signal, depends on the tool. Either way it's a bug. One driver per wire unless you're explicitly building a bus.
reg signals can only be driven from one procedural block. Two always blocks both assigning the same reg is a synthesis error and bizarre in simulation. Same rule: one driver.
The SystemVerilog Update: logic
SystemVerilog (the superset Verilog evolved into) adds a single keyword that replaces both: logic. A logic signal can be driven by assign or by a procedural block - but not both - and the compiler stops you from accidentally setting up a multi-driver bug.
module modern(input logic a, input logic b, output logic y);
assign y = a ^ b;
endmodule
If you're starting a project from scratch and your tool supports SystemVerilog (which the editor on this page does, with -g2012), using logic everywhere simplifies the rules. Plain .v files still need the wire/reg split, and you'll see both styles in the wild forever.
What Comes Next
The next doc - Vectors and Arrays - takes the same two types and shows how to make them multi-bit. Bus widths, ranges, packed dimensions, the difference between a vector of bits and an array of vectors. All the things you need before you can build anything bigger than a one-bit adder.
Frequently Asked Questions
What is the difference between wire and reg in Verilog?
wire and reg both hold a signal value at every moment in simulation, but you choose between them based on who drives the signal. A wire is driven from outside a procedural block - by an assign or a sub-module output. A reg is driven from inside an initial or always block. The names are historical and misleading; reg does not always mean 'register'.
Does reg in Verilog mean a flip-flop?
Not necessarily. A reg only synthesizes to a flip-flop when its always block is sensitive to a clock edge and uses non-blocking assignment. A reg assigned inside a combinational always @(*) block synthesizes to plain combinational logic. The keyword chooses the Verilog data type, not the hardware.
When should I use wire vs reg?
Rule of thumb: if you'll drive the signal with assign or connect it to a sub-module output port, use wire. If you'll assign to it inside an always or initial block, use reg. Inputs to a module are always wire. Outputs are wire if driven by assign and reg if driven by a procedural block.
Can you assign to a wire inside an always block?
No - that's a syntax error. wire signals can only be driven by continuous assignments (assign) or by being connected as an output of a sub-module instance. Anything inside initial or always has to target a reg (or in SystemVerilog, a logic). The compiler will catch this and complain about a 'left-hand side type mismatch'.
What is logic in SystemVerilog?
logic is SystemVerilog's unification of wire and reg. It can be driven by either a continuous assignment or a procedural block (but not both at the same time). Modern code increasingly uses logic everywhere and forgets the wire/reg distinction. Plain Verilog files still need to choose.