Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
    • Digital Logic for RTL Engineers
    • Number Systems for RTL Engineers
    • Verilog Fundamentals
      • Modules and Ports
      • Wire vs reg
      • assign vs always
      • The Two Process Templates
      • Blocking vs Non-blocking
      • From Code to Hardware
    • Verilog Operators and Types
    • SystemVerilog for RTL
    • Simulation and Testbenches
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Verilog Fundamentals
  1. Topics
  2. RTL Design
  3. RTL Foundations
  4. Verilog Fundamentals
  5. Wire vs reg

Part 1 · Foundations · Beginner

Wire vs reg

Nets carry driven values, variables hold procedural values, and SystemVerilog logic covers both cases.

On this page

    Why this matters

    Declaring a signal reg does not make a register. Two outputs both declared reg can be a flip-flop and a plain AND gate, depending only on how they are assigned.

    After this lesson you can: choose wire or reg from where a signal is assigned, and say what hardware an always block describes.

    Nets and variables

    wire (net)

    reg (variable)

    Driven by

    assign, a module output, a gate

    Procedural assignment in an always or initial block

    Holds a value?

    No: it carries whatever drives it

    Yes, in simulation, until assigned again

    Multiple drivers

    Allowed (resolved), as for a bus

    Only one process should assign it

    Becomes hardware as

    A wire (or the output of a gate)

    A flip-flop or plain combinational logic, depending on the code

    Warning

    reg is a legacy name for “a variable that a procedural block can assign”. It says nothing about whether a flip-flop is created. The hardware depends on how you assign it, not on the keyword.

    reg_is_not_a_flop.v
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    module reg_is_not_a_flop (
      input  wire a, b,
      output reg  y_comb      // declared 'reg' ...
    );
      always @(*) y_comb = a & b;     // ... but this is pure combinational logic (an AND gate)
    endmodule
    
    module reg_is_a_flop (
      input  wire clk, d,
      output reg  q           // same keyword ...
    );
      always @(posedge clk) q <= d;   // ... but here it IS a flip-flop (edge-triggered)
    endmodule

    Both outputs are declared reg, but only the second is a flip-flop. The first is pure combinational logic, an AND gate.

    Three code shapes and the hardware each one describes: the keyword reg appears in two of them, but only the clocked block makes a flip-flop

    Read each row from the code on the left to the hardware on the right; the orange reg marks the keyword that does not decide anything.

    • Rows one and two build the same AND gate. Only the declaration changes, because assign needs a net and always needs a variable.

    • Row three is the only one with an edge in its event control, so it is the only one with storage.

    The sensitivity list decides when the block runs, but only full assignment cover keeps it combinational. @(*) with every output assigned on every path describes logic, while @(posedge clk) describes a clocked element. An incomplete @(*) block infers a latch.

    Which type to use

    • Signals assigned with assign or driven by instance outputs: declare as wire.

    • Signals assigned inside an always or initial block: declare as reg.

    • Never mix the two on one signal (no assign plus an always assignment).

    SystemVerilog logic

    SystemVerilog adds logic, a 4-state data type for nearly every RTL variable. Such a variable accepts one continuous assignment or port, or procedural assignments. The type alone does not limit ordinary procedural writers to one process.

    Keep one writer per RTL variable. always_ff and always_comb impose writer restrictions, and lint checks ownership; two plain always blocks can otherwise write the same variable and race. Reserve a resolved net such as wire for shared buses.

    logic_demo.sv
    1
    2
    3
    4
    5
    6
    7
    8
    module logic_demo (
      input  logic clk, a, b,
      output logic y_comb,
      output logic q
    );
      assign     y_comb = a & b;          // driven continuously: fine for logic
      always_ff @(posedge clk) q <= a;    // driven procedurally: also fine
    endmodule

    Tip

    If you are working in a Verilog-2001 code base, the wire/reg split is mechanical: look at where the signal is assigned. If the compiler says “illegal left-hand side” or “reg is not a valid net”, you used the wrong kind for that assignment.

    Check yourself A signal is declared reg [3:0] count; and assigned on every path inside always @(*) with a full case statement. Is it a register in the hardware?

    No. A combinational always @(*) that assigns the variable on every path produces pure combinational logic. Only an edge-triggered block (or an incomplete combinational block that infers a latch) creates storage.

    Remember

    • reg only means a variable that a procedural block can assign.

    • An always @(*) block that assigns on every path is combinational, an incomplete one infers a latch, and @(posedge clk) describes a flop.

    • Keep one writer per RTL variable. Reserve a resolved net such as wire for shared buses.

    Rule of thumb: the hardware comes from how you assign, not from the keyword.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • assign vs always

    Previous

    14 / 350

    Next: assign vs always

    Up next

    Up nextassign vs always

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • The Two Process Templates
    • Blocking vs Non-blocking
    • From Code to Hardware