Skip to content
VLSI Mentor

Verilog · Chapter 4.4 · Lexical Conventions

Number Representation in Verilog

A number in software is just a value. A number in Verilog usually carries a width as well, because the hardware it meets is built from a fixed number of wires. This lesson teaches you to read a Verilog literal properly: the width that says how many bits it occupies, the base that says how the digits are written, the value itself, and the optional marker that says whether those bits should be read as signed. You will also see what underscores do, what x and z mean in a literal, and what happens when a value and its destination are different widths. The deeper rules about how width and signedness govern a whole expression belong to later chapters; the goal here is that no literal you read is a mystery.

Foundation17 min readVerilogLiteralsNumbersSyntax

Chapter 4 · Page 4.4 · Lexical Conventions

1. Why a Number in RTL Carries More Than a Value

In software, 10 is a value and that is the end of it. The language finds somewhere to put it.

In Verilog you are describing hardware, and hardware is made of a fixed number of wires. A signal declared as

Azvya Education Pvt. Ltd.VLSI Mentor
an eight-bit register
reg [7:0] count_q;

is eight flip-flops. Not "a number" — eight bits, physically. So when you write a value that is going to meet those eight bits, it is useful to be able to say how wide the value is, not only what it equals.

That is why Verilog literals look the way they do:

Azvya Education Pvt. Ltd.VLSI Mentor
the same value, said two ways
8'd10      // ten, written as an eight-bit value
10         // ten, with no width stated

Both are legal. The first says something the second does not.

2. The Three Things to Read — Width, Base, Value

Whenever you meet a Verilog literal, read it as up to three separate questions:

  • Width — how many bits is this value?
  • Base — what notation are the digits written in?
  • Value — what are the digits?

Take 8'hA5:

  • width — 8 bits
  • base — hexadecimal
  • value — A5, which is 1010_0101

Once you can split any literal into those three, nothing on the page is opaque any more.

3. Anatomy of a Based Literal

The form with an apostrophe in it is called a based literal, because it names its base explicitly.

Azvya Education Pvt. Ltd.VLSI Mentor
8'hA5, part by part
8'hA5
│ ││
│ │└── value — the digits, written in the chosen base
│ └─── base  — b, o, d or h
└───── size  — how many bits wide

Written out in order, the parts are:

PartExampleNotes
size8A plain decimal count of bits. Optional.
apostrophe'Separates the size from the base.
signed markersOptional, written just before the base — 8'shA5. See §10.
basehb, o, d or h. Required in a based literal.
valueA5The digits, in that base. Underscores allowed between them.

The size is a count of bits, never of digits. 8'hA5 is eight bits that happen to need two hex digits; 8'b1010_0101 is the same eight bits written in binary.

Letters are not case-sensitive anywhere in a literal: 8'hA5, 8'ha5 and 8'HA5 are the same value. That is one of the few places Verilog ignores case — identifiers do not (Chapter 4.6).

4. The Four Bases

BaseLetterExampleBinary
Binaryb4'b10101010
Octalo6'o52101_010
Decimald8'd420010_1010
Hexadecimalh8'h2A0010_1010

Each base digit covers a fixed number of bits: one for binary, three for octal, four for hexadecimal. That is the whole reason hexadecimal is so common in RTL — one hex digit is exactly one nibble, so a 32-bit value reads as eight tidy digits:

Azvya Education Pvt. Ltd.VLSI Mentor
bases.v — same 32-bit value, three notations
32'h1234_5678
32'd305_419_896
32'b0001_0010_0011_0100_0101_0110_0111_1000

Decimal is the right choice when the number is what matters — a count, a threshold, a divider ratio. Binary and hexadecimal are right when the bit pattern is what matters — a mask, an opcode, a reset value.

5. Same Value, Different Width

This is the idea that separates HDL from ordinary programming, so it gets its own section.

Azvya Education Pvt. Ltd.VLSI Mentor
same-value-different-width.v
4'b1010            // four bits  — the number ten
8'b0000_1010       // eight bits — the number ten

Both are ten. They are not the same literal, because they are not the same width. One is four wires, the other is eight.

Value and width are two different properties. Two literals can agree on one and differ on the other.

Hold on to that. Almost everything in this lesson that surprises people comes from reading only the value and not the width.

6. Sized Literals

A sized literal states its width, so there is nothing left to work out:

Azvya Education Pvt. Ltd.VLSI Mentor
sized.v
reg [7:0] count_q;

initial count_q = 8'd0;      // an eight-bit zero for an eight-bit register

8'd0 is exactly eight bits wide. count_q is exactly eight bits wide. The widths agree, and a reader can see that they agree without knowing anything about the rest of the file.

That readability is the real argument for sizing a literal — the width you meant is visible at the point of use, and it stays visible through review and refactoring.

6.1 When fewer digits are written than the size needs

You can write a size larger than the digits you supply. The value is then extended on the left:

Azvya Education Pvt. Ltd.VLSI Mentor
left-extension.v
8'h1        // -> 8'h01        extended with zeros
8'hF        // -> 8'h0F        extended with zeros, NOT 8'hFF
8'hx        // -> 8'bxxxx_xxxx extended with x
8'hz        // -> 8'bzzzz_zzzz extended with z

The rule is: extend with 0, unless the leftmost digit you wrote is x or z, in which case extend with that instead. It is a common mistake to assume 8'hF fills with ones — it does not.

In practice you rarely want to rely on this. Writing 8'h0F and 8'h00 says the same thing with nothing left to remember.

7. Unsized Literals — Read Them Carefully

You may leave the size off. There are two different-looking forms, and it is worth seeing them as distinct rather than lumping them together.

Azvya Education Pvt. Ltd.VLSI Mentor
unsized.v — two forms, neither one sized
42          // no apostrophe at all — a plain decimal number
'h2A        // based, but no size in front of the apostrophe

42 is a perfectly valid Verilog literal. It needs no apostrophe. A number written this way is decimal by default, and it is treated as signed.

'h2A is also valid. It names its base but not its width, and a based literal is treated as unsigned unless you add the s marker.

So the first thing to say about unsized literals is that they are not one category.

What about their width? Neither form states one in the source text. Verilog settles the width when the value is actually used — from the language's sizing rules and from the context the value appears in — and which rules apply depends on the form of the literal. The practical consequence:

An unsized literal does not tell you its width. You cannot read one off the source text, so do not reason about it as though an explicit width had been written.

That is deliberately narrower than any fixed-number rule you may have seen quoted for unsized literals — and it is all this chapter needs. Where the width actually comes from, and how an expression with operands and operators in it arrives at a width and a signedness, belongs to Verilog Operators and Operands — Chapter 10, §8 — alongside the operators those rules govern.

7.1 So when should you write the width?

Not as a ritual. The useful rule is about intent:

When a literal's width affects the hardware you mean or the way the expression behaves, write the width down. When it does not, a plain number is fine and often clearer.

Worth writing explicitly — the width is part of the meaning:

Azvya Education Pvt. Ltd.VLSI Mentor
width-carries-meaning.v
count_q  <= 8'd0;          // an eight-bit register being cleared
mask     =  8'hA5;         // a specific eight-bit pattern
opcode   =  4'b1010;       // a four-bit encoding

Perfectly fine unsized — the width is not the point:

Azvya Education Pvt. Ltd.VLSI Mentor
width-is-not-the-point.v
parameter DEPTH = 16;          // a count, used to size other things
for (i = 0; i < 8; i = i + 1)  // a loop bound in a testbench or generate
    ...

A bare 0 or 16 is not bad style on its own. What matters is whether a reader needs to know the width to understand what you meant.

8. Underscores for Readability

Underscores may appear between the digits of a value. They are separators for human eyes and contribute nothing to the number.

Azvya Education Pvt. Ltd.VLSI Mentor
underscores.v
32'b1010_1100_0011_0101       // grouped by nibbles
16'd12_345                    // grouped like thousands
8'hA5                         // short enough not to need any

32'b1010_1100_0011_0101 and 32'b1010110000110101 are the same value with the same bits. Group hexadecimal and binary by nibbles and long decimals by thousands, and long constants stop being a counting exercise.

One limit: an underscore cannot be the first character of the value, and it does not belong in the size or the base specifier.

9. Unknown (x) and High-Impedance (z)

Verilog models a signal with four values, not two: 0, 1, x and z. Literals can carry the last two.

Azvya Education Pvt. Ltd.VLSI Mentor
xz.v
4'bxxxx        // four unknown bits
8'hxx          // eight unknown bits
1'bz           // one high-impedance bit
4'b10xz        // a mix — every bit is independent
  • x means unknown — the model does not know what this bit is. A reg that has never been assigned reads as x, which is useful precisely because it is visible: an x propagating through a simulation is the model telling you something was never driven.
  • z means high-impedance — nothing is actively driving the signal, as when a tri-state driver has been released.

Be careful about what these are:

x and z are values in Verilog's logic model, not physical voltages. An x in a waveform means "this is not determined in the model" — it is not a third voltage level sitting between 0 and 1 on real silicon, and it does not map one-to-one onto what a manufactured chip would do.

In binary, octal and hexadecimal you can mix x and z freely with the ordinary digits — and remember one hex x digit covers four unknown bits, which is why 8'hxx is eight unknowns rather than two. A decimal literal cannot mix them with digits, so write 8'bx or 8'hx when you want unknown bits.

The four-state model itself — where x comes from, how it propagates, what it means for a wire versus a reg — is Variables & Data Types, Chapter 5.

10. Signed Literals — Same Bits, Different Interpretation

An s written just before the base marks the literal as signed.

The single most important thing to understand is what the s does not do:

Azvya Education Pvt. Ltd.VLSI Mentor
signed-bits.v — identical bits
8'b1111_1111       // eight bits: 1111_1111
8'sb1111_1111      // the same eight bits: 1111_1111

The stored bits are identical. The s does not change a single one of them. What it changes is how those bits are read when the value takes part in something.

Azvya Education Pvt. Ltd.VLSI Mentor
the mental model
BITS                          1111_1111
        +
INTERPRETATION       unsigned  ->  255
                     signed    ->   -1   (two's complement)

Same pattern, two readings. Which one applies is decided by signedness, not by the bits.

Azvya Education Pvt. Ltd.VLSI Mentor
signed-forms.v
8'hAA          // unsigned eight-bit — bits 1010_1010, reads as 170
8'shAA         // signed   eight-bit — the same bits, reads as -86

Where does that matter? Wherever the value participates in something that has to know which reading you meant — a comparison, arithmetic, a shift, or a change of width. That is the connection to keep:

Signedness does not live in the bits. It is a statement about how to interpret them, and it starts to matter the moment the value is used.

That is as far as Chapter 4 goes. How signedness governs a whole expression — what happens when a signed and an unsigned operand meet, how a signed comparison differs from an unsigned one, what $signed() is for — is Verilog Operators and Operands, Chapter 10, alongside the operators that do the interpreting. Declaring a signal signed in the first place (reg signed [7:0]) is Variables & Data Types, Chapter 5.

10.1 A note on negative numbers

A minus sign in front of a literal is the arithmetic negation operator applied to the literal — it is not part of the literal itself.

Azvya Education Pvt. Ltd.VLSI Mentor
negative.v
-8'd5      // negate the eight-bit value 5 -> bits 1111_1011

Those bits read as −5 signed, or 251 unsigned. Which one you get depends on the signedness of where the value ends up, which is again Chapter 10's subject. For now: notice that the minus sign and the s marker are two different things, doing two different jobs.

11. What Happens When Widths Do Not Match

A value and its destination do not always agree on width. Two things can happen.

The value is wider than the destination. It cannot fit, so the extra bits are dropped — the least significant bits are the ones kept:

Azvya Education Pvt. Ltd.VLSI Mentor
truncation.v
reg [3:0] small;

initial small = 8'b1010_1100;   // eight bits into four
                                // small ends up as 4'b1100

Nothing is flagged; the assignment is legal and the value that arrives is simply not the value that was written. This is worth noticing in review, because the source line still reads like it is carrying all eight bits.

The value is narrower than the destination. It is extended on the left to fill the space — and how it is extended depends on whether the value is signed:

Azvya Education Pvt. Ltd.VLSI Mentor
extension.v
wire        [7:0]  a_u = 8'hFF;      // unsigned
wire signed [7:0]  a_s = 8'shFF;     // signed — same bits as a_u

wire        [15:0] wide_u = a_u;     // zero-extended -> 16'h00FF   (255)
wire signed [15:0] wide_s = a_s;     // sign-extended -> 16'hFFFF   (-1)
  • Zero extension — fill the new upper bits with 0. This is what an unsigned value gets.
  • Sign extension — copy the value's most significant bit into the new upper bits. This is what a signed value gets, and it is what preserves a negative number's meaning as it gets wider.

In these simple assignments, it is the signedness of the value on the right that decides which of the two happens, while the destination width decides how far it extends. Once operators enter the expression the full context rules apply, and those are Chapter 10's subject rather than this page's.

What Chapter 4.4 asks you to take away is narrower and entirely reliable:

Width mismatches change the value that arrives. Reading a literal means reading its width too, and comparing it to where it is going.

12. Real Literals — Simulation Only

Verilog also has floating-point literals. They exist for testbenches and behavioural models, not for hardware.

Azvya Education Pvt. Ltd.VLSI Mentor
reals.v
real period = 10.0;      // a '.' makes it a real
real freq   = 100e6;     // so does an exponent

10 is an integer literal; 10.0 is a real one. In the synthesisable RTL style this course teaches, real is not used to describe ordinary hardware signals — it belongs to simulation and behavioural modelling, so keep it to testbench and model code. Note what that does not say: it is a statement about the Verilog real type, not about floating-point hardware, which is built from ordinary bit-vector RTL like anything else. Chapter 5 covers the real type properly.

13. Common Reading Mistakes

Assuming a missing apostrophe is fine. 8h2A is not valid based-number syntax; the based form needs the apostrophe, as 8'h2A. But do not over-correct in the other direction either — 42 on its own is a perfectly valid literal, because a number with no apostrophe is simply decimal.

Reading the base too fast. 8'd10 and 8'h10 share their digits and are different numbers — ten and sixteen. d and h are one keystroke apart.

Expecting short literals to fill with ones. 8'hF is 8'h0F, not 8'hFF. Left-extension uses 0 unless the leftmost digit written is x or z (§6.1).

Reading the value and skipping the width. 4'b1010 and 8'b0000_1010 are both ten, and putting either one where the other belongs is a width change, not a no-op.

Thinking s changes the bits. It does not. 8'hAA and 8'shAA hold the same eight bits; only the interpretation differs.

14. Exercises

Work each one out before reading the answers.

Exercise 1 — Decode a literal

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-1.v
8'hA5

What is its width? Its base? Its value in binary?

Exercise 2 — Compare two literals

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-2.v
4'b1010
8'b0000_1010

Do they represent the same numerical value? Are they the same width?

Exercise 3 — Which of these are valid?

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-3.v
42
8'd42
8h2A
8'h2A

Say which are valid Verilog literals and why.

Exercise 4 — Width reasoning

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-4.v
reg [3:0] data_q;

initial data_q = 8'b1010_1100;

Before worrying about any detailed expression rule — what should you notice here?

Exercise 5 — Signed interpretation

Azvya Education Pvt. Ltd.VLSI Mentor
exercise-5.v
8'b1111_1111
8'sb1111_1111

Are the stored bits the same? What differs?

Answers

Exercise 1. Width 8 bits; base hexadecimal; value A5 = 1010_0101. Each hex digit is four bits, so two digits fill the eight bits exactly.

Exercise 2. Yes to the value — both are ten. No to the width — one is four bits, the other eight. This is the §5 point: value and width are separate properties, and two literals can agree on one while differing on the other.

Exercise 3.

LiteralValid?Why
42✅A number with no apostrophe is a plain decimal literal. Unsized and signed.
8'd42✅A based literal: size 8, base decimal, value 42.
8h2A❌The based form requires the apostrophe between the size and the base — 8'h2A.
8'h2A✅Size 8, base hexadecimal, value 2A = 0010_1010.

The one to be careful with is 42. It is easy to over-learn "numbers need an apostrophe" from seeing 8'd42 everywhere — but the apostrophe's job is to separate the size from the base inside a based literal, and a plain decimal number has neither.

Exercise 4. The widths do not match: an eight-bit value is being assigned to a four-bit register. That alone is worth pausing on, regardless of what the detailed rules say happens next. (They say the four least significant bits are kept, so data_q becomes 4'b1100 — but noticing the mismatch is the skill, and it is the part that transfers to every case.)

Exercise 5. The bits are identical — 1111_1111 in both. What differs is the interpretation: unsigned, those bits read as 255; signed, they read as −1 in two's complement. The s marker makes a statement about how to read the bits, and changes none of them.

15. Summary

A Verilog literal is read as up to three things, plus one optional marker:

  • Width — how many bits. 8'hA5 is eight bits.
  • Base — b, o, d or h, after the apostrophe.
  • Value — the digits, with underscores allowed between them purely for readability.
  • Signed marker — an s before the base, saying how to interpret the bits. It never changes them.

And four things to carry forward:

  • Value and width are different properties. 4'b1010 and 8'b0000_1010 are the same number at different widths.
  • A number with no apostrophe is still a literal. 42 is valid; the apostrophe separates size from base inside a based literal.
  • Unsized is not the same as explicitly 32-bit. A literal with no size does not state its width at all; Verilog settles that when the value is used. Write the width when the width is part of what you mean, and do not bother when it is not.
  • x and z are model values, not voltages. They describe what the simulation does not know or is not driving.

Next, String Handling covers Verilog's other literal form — characters between double quotes — and how they are actually stored.

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.