Skip to content
VLSI Mentor

Verilog · Chapter 4.6 · Lexical Conventions

Identifier Declaration in Verilog

Every wire, register, module, port, parameter and instance in Verilog has a name you chose, and those names follow a small set of rules. This lesson covers what makes a name legal, why Verilog treats capitalisation as meaningful, what the escaped form with a backslash is for and where you will actually meet it, and how dotted hierarchical names are built from ordinary identifiers. It finishes with the naming conventions experienced RTL engineers use — the active-low suffix, the registered-and-next pair, the instance prefix — which are not language rules at all but do more for readability than any of them.

Foundation15 min readVerilogIdentifiersNamingSyntax

Chapter 4 · Page 4.6 · Lexical Conventions

1. Every Name in Verilog Is an Identifier

Look at a line of RTL and separate what the language owns from what you chose:

Azvya Education Pvt. Ltd.VLSI Mentor
mux2.v
module mux2 (input wire sel, input wire a, input wire b, output wire y);

Two kinds of word are on that line:

  • Keywords — the language owns them. module, input, wire, output. They mean the same thing in every Verilog file ever written.
  • Identifiers — names you invented. mux2, sel, a, b, y. They mean whatever this design makes them mean.

Verilog attaches no meaning to the name itself. rst_n is a reset because of what the code does with it, not because of its spelling. That is why this page has two halves: the rules the language actually enforces, and the conventions that carry meaning to the next human.

The everyday form is the simple identifier. Four rules cover it:

RuleAllowedNot allowed
First charactera letter or _a digit, or $
Later charactersletters, digits, _, $anything else — - . / + space
Casemeaningful — see §4—
Collisionsmust not be a Verilog keywordwire, reg, module, …
Azvya Education Pvt. Ltd.VLSI Mentor
legal.v
reg        data_q;          // fine
reg [3:0]  count_4b;        // digits after the first character
wire       rst_n;           // fine
parameter  WIDTH = 8;       // fine
reg        _internal;       // a leading underscore is allowed
Azvya Education Pvt. Ltd.VLSI Mentor
illegal.v
// reg  8th_bit;            // starts with a digit
// reg  data-q;             // '-' is not a legal identifier character
// reg  $myname;            // '$' cannot start a name — see §7
// reg  wire;               // 'wire' is a keyword

$ is legal inside a name — clk$gated parses — but almost nobody writes it, because readers expect $ to mean a system task. Treat it as allowed-but-avoided.

3. Why the First Character Matters

The first character is what separates a name from a number. Identifiers begin with a letter or an underscore; numeric literals begin with a digit. That is the entire reason for the rule.

So 8th_bit is simply not a legal identifier — the language has no way to read it as a name. It is enough to know that; you do not need a theory about what the tool does with the text instead.

4. Verilog Is Case-Sensitive

Azvya Education Pvt. Ltd.VLSI Mentor
three names, not one
reg rst;
reg Rst;
reg RST;

Those are three different identifiers. Capitalisation is part of the name, not decoration.

This catches people coming from VHDL, which is case-insensitive — there, rst and Rst are the same signal, and RTL ported across can carry the wrong assumption with it.

The practical protection is the one from Chapter 3: put `default_nettype none at the top of every design file. A mistyped Data_Ready then becomes an error you see immediately, rather than a silently invented one-bit wire that nothing drives.

Pick one convention per project — lowercase with underscores for signals is the common one — and stay inside it.

5. How Long Can a Name Be?

Longer than you will ever want. The standard requires tools to support identifiers of at least 1024 characters, and most allow more.

So length is never the constraint that matters. Readability is: a name long enough to need scrolling costs the reader more than it explains. Descriptive and short beats exhaustive.

6. Names You Cannot Use

A name that matches a Verilog keyword cannot be a simple identifier — the language already knows what that word means.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// reg wire;        // 'wire' is a keyword
// reg time;        // so is 'time'
// reg output;      // and 'output'

The words that catch people out are the ones that are also ordinary engineering vocabulary: time, output, input, signed, force, and, or, not. The fix is always the same — say what you actually mean:

Azvya Education Pvt. Ltd.VLSI Mentor
renaming around a keyword
reg [31:0] time_q;        // not 'time'
reg [7:0]  input_data;    // not 'input'
reg        and_result;    // not 'and'

The full keyword list, how it grew across the standard's revisions, and the porting traps around it are the very next lesson — Keyword Usage, Chapter 4.7. You do not need to memorise it; descriptive names like data_valid and count_q were never going to collide.

7. The $ Prefix

A name cannot begin with $, because that prefix is reserved for system tasks and functions:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$display("...");     // a system task
$time                // a system function
$finish              // a system task

Keeping $ reserved at the start is what makes the two namespaces unambiguous: if a token starts with $, it is the simulator's, not yours. What those tasks do is System Tasks & Functions, Chapter 8.

8. Escaped Identifiers

Occasionally a name has to contain characters the simple form does not allow. Verilog's answer is the escaped identifier: start with a backslash, and end at the next whitespace.

Azvya Education Pvt. Ltd.VLSI Mentor
escaped.v
wire \data[7] = some_signal;     // the name is  data[7]
wire \net.7   = x;               // the name is  net.7
wire \1st_bit = sig;             // the name is  1st_bit

Everything between the backslash and the terminating whitespace is part of the name — brackets, dots, a leading digit, characters that would otherwise be operators. Three points to hold:

  • The backslash and the terminating space are not part of the name. They are delimiters.
  • The terminating whitespace is required. Without it the tool keeps reading, and the next token gets swallowed into the name.
  • A name that needs escaping needs it everywhere. Declare \rst-n and every reference must be written \rst-n too, because there is no simple-form spelling of that name.

You will rarely write one by hand. Where you will see them is tool output — a post-synthesis netlist that has split a vector into individual bits needs a legal name for each one, and \data[7] is how it gets one. Recognising the form when you open such a file is the whole skill here.

One thing not to do: the escaped form will technically let you name something \reg or \time . It parses, and every reader after you will stop and wonder why. If a keyword collides with the word you want, rename as in §6.

9. Hierarchical Names

A dotted path names something inside an instance:

Azvya Education Pvt. Ltd.VLSI Mentor
hierarchical.v — testbench only
initial begin
    $display("r0 = %h", tb.dut.regfile.r0);
end

Each segment between the dots — tb, dut, regfile, r0 — is an ordinary identifier following the rules above. That is the lexical point, and it is the only one this chapter needs.

Beyond that: hierarchical references are a simulation and debug tool. Synthesis tools generally do not accept them, so keep them in testbench code. Module hierarchy itself is covered in Design & Testbench Creation, Chapter 9.

10. Naming Conventions That Make RTL Readable

None of this is enforced by the language. All of it is what experienced RTL reads like, and adopting it will make your code legible to anyone who has worked on a chip.

PatternUsed forExample
snake_casesignals, ports, modulesaddr_valid, axi_master
ALL_CAPSparameters and localparamDATA_WIDTH, FIFO_DEPTH
_n suffixactive-low signalsrst_n, cs_n
_q suffixa registered value — a flip-flop outputdata_q, count_q
_d suffixthe value heading into that flip-flopdata_d, count_d
u_ prefixan instance nameu_fifo, u_alu
tb_ prefixtestbench codetb_top

The _d / _q pair is the one worth internalising first, because it names the central fact of sequential RTL: _d is what the flip-flop will take at the next clock edge, _q is what it is holding now. Seeing both in a module tells you where the state is before you read a line of logic.

Here is a small module where the names do the explaining:

Azvya Education Pvt. Ltd.VLSI Mentor
pipe_register.v — the conventions applied
module pipe_register #(
    parameter DATA_WIDTH = 32            // ALL_CAPS — a parameter
) (
    input  wire                  clk,
    input  wire                  rst_n,  // _n — active low
    input  wire [DATA_WIDTH-1:0] data_d, // _d — heading into the flop
    output reg  [DATA_WIDTH-1:0] data_q  // _q — held by the flop
);

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            data_q <= {DATA_WIDTH{1'b0}};
        else
            data_q <= data_d;
    end

endmodule

Read the port list alone and you already know: there is a clock, an active-low reset, one value going into a register and one coming out. That is what naming discipline buys — and it costs nothing.

Azvya Education Pvt. Ltd.VLSI Mentor
instantiation.v — the u_ prefix
pipe_register #(.DATA_WIDTH(32)) u_pipe (
    .clk    (clk),
    .rst_n  (rst_n),
    .data_d (payload_d),
    .data_q (payload_q)
);

Whichever set you adopt matters less than applying it consistently. Mixed conventions inside one project cost more than any single choice among them.

11. Common Mistakes

A case mismatch. data_ready and Data_Ready are different names. With `default_nettype none this is an error you see; without it, it can pass quietly.

Forgetting the space after an escaped identifier. \rst_n with no trailing space does not end — the tool keeps reading, and whatever follows becomes part of the name. Always write the space.

Using the escaped form to reuse a keyword. \reg is a legal name spelled reg. It parses; it also guarantees every future reader stops to work out what you meant.

Starting a name with $. $mysig is not a legal identifier — that prefix belongs to system tasks.

Hierarchical references in synthesisable RTL. They belong in testbench code. Synthesis tools generally reject them.

12. Exercises

Work each one out before reading the answers.

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-1.v
data_q
8th_bit
_internal
$myname
data-q
wire

Which are legal simple identifiers, and why do the others fail?

Exercise 2 — Count the names

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-2.v
reg rst;
reg Rst;
reg RST;

How many distinct identifiers is this?

Exercise 3 — Read an escaped identifier

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-3.v
wire \data[7] = sig;

What is the name being declared? What are the backslash and the space doing?

Exercise 4 — Why the $ rule?

Why can a Verilog identifier contain $ in the middle but never begin with one?

Exercise 5 — Read the names

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-5.v
module counter (
    input  wire       clk,
    input  wire       rst_n,
    input  wire       en,
    output reg  [3:0] count_q
);

Without reading any logic, what do these names tell you about the module?

Answers

Exercise 1.

NameLegal?Why
data_q✅starts with a letter; letters, underscore, letter
8th_bit❌starts with a digit
_internal✅a leading underscore is allowed
$myname❌$ cannot start a name — reserved for system tasks
data-q❌- is not a legal identifier character
wire❌it is a Verilog keyword

Exercise 2. Three. Verilog is case-sensitive, so rst, Rst and RST are three unrelated signals that merely look similar. This is exactly the shape of the bug in §4.

Exercise 3. The name is data[7] — square brackets included, as literal characters in the name rather than a bit-select. The backslash opens the escaped form and the space closes it; neither is part of the name. You would meet this in a post-synthesis netlist where a vector has been split into individual bits.

Exercise 4. Because a leading $ is how the language marks the system-task and system-function namespace — $display, $time, $finish. Reserving it at the start keeps that namespace unambiguous: a token beginning with $ is the simulator's. In the middle of a name there is no such ambiguity, so it is permitted — though convention avoids it.

Exercise 5. Quite a lot, before reading a single statement:

  • clk — the module is clocked, so it holds state.
  • rst_n — the reset is active low, so the reset condition is !rst_n.
  • en — there is an enable, so the counter does not advance every cycle.
  • count_q — the _q says this is a registered output, the value a flip-flop is currently holding, four bits wide.

None of that is enforced by Verilog. It is carried entirely by the names — which is the argument for the conventions in §10.

13. Summary

  • An identifier is a name you chose. Verilog attaches no meaning to the spelling.
  • Legal shape: start with a letter or _; continue with letters, digits, _ or $; do not use a keyword; do not start with $.
  • Case is part of the name. rst, Rst and RST are three identifiers.
  • Length is never the problem — tools support at least 1024 characters. Readability is the real limit.
  • The escaped form — a backslash, then the name, then a space — exists for names the simple form cannot spell. You will mostly read them, not write them.
  • A hierarchical name is just identifiers joined by dots, and belongs in testbench code.
  • Conventions carry the meaning the language does not. _n for active low, _d and _q for the two sides of a flip-flop, u_ for an instance.

Next, Keyword Usage covers the other half of the naming story — the words the language has already claimed.

Standards & specifications

Governing standard
IEEE Std 1364 (Verilog)(opens IEEE in a new tab)

Defines the Verilog language and its simulation semantics, including the event scheduling model. Synthesis support is defined by tools, not by this standard.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the Verilog HDL curriculum.