Skip to content
VLSI Mentor

USB · Module 11

USB Packet Structure

Four packet types turn out to be one structure — and the PID check field, measured, catches 100% of single-bit errors and 85.7% of two-bit ones.

Four chapters, four packet types, four sets of rules. They are one structure.

Every packet in USB is a PID, an optional body, and an optional check — and the differences between a token, a data packet, a handshake and an SOF are entirely in what fills those last two slots.

1. One Shape

PacketPIDBodyCheckTotal beyond the PID
Token (OUT/IN/SETUP)1 byte11 bits: ADDR + ENDPCRC52 bytes
SOF1 byte11 bits: frame numberCRC52 bytes
Data (DATA0/DATA1/DATA2/MDATA)1 byte0 – 1024 bytes of payloadCRC16variable
Handshake (ACK/NAK/STALL/NYET)1 bytenonenone0

A handshake is a packet consisting entirely of its own identity — and that is the cleanest illustration of the structure, because it shows the body and the check are genuinely optional rather than merely sometimes empty.

Two things frame every one of them and belong to a different layer: a SYNC pattern before and an end-of-packet after. Both are signalling rather than structure — they are how a receiver finds the packet's boundaries, and Module 14 owns them. Everything in this chapter sits between them.

2. The PID Is Two Nibbles

The low nibble is the PID. The high nibble is its bitwise complement.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   bit  7   6   5   4   3   2   1   0
       ┌───────────────┬───────────────┐
       │   ~PID[3:0]   │    PID[3:0]   │
       └───────────────┴───────────────┘
            check            value

Which halves the information and doubles the confidence, and the trade is worth quantifying rather than asserting. Computed over all sixteen legal PID bytes:

PropertyMeasured
Bytes satisfying the check, out of 25616 — exactly the legal PIDs
Single-bit corruptions tested128 (16 PIDs × 8 positions)
Single-bit corruptions undetected0
Two-bit corruptions tested448
Two-bit corruptions undetected64 — 14.3%
Probability a random byte passes1 in 16

Three readings, and the third is the one that matters for RTL:

  • Every single-bit error is caught, with certainty. Flipping any one bit breaks the complement, because a bit appears in exactly one nibble.
  • The guarantee stops there. Two-bit errors slip through 14.3% of the time — specifically when the two flips are the same position in the two nibbles. The check field is a single-bit detector, not a general one.
  • A random byte passes one time in sixteen, which is why nothing downstream may treat passed the check field as is a real packet.

3. Sixteen PIDs, Four Groups of Four

The two least significant bits of the PID name its group, and the assignment is complete and exact:

PID[1:0]GroupMembers
00SpecialEXT 0xF0 · PING 0xB4 · SPLIT 0x78 · PRE/ERR 0x3C
01TokenOUT 0xE1 · SOF 0xA5 · IN 0x69 · SETUP 0x2D
10HandshakeACK 0xD2 · NYET 0x96 · NAK 0x5A · STALL 0x1E
11DataDATA0 0xC3 · DATA2 0x87 · DATA1 0x4B · MDATA 0x0F

Sixteen PIDs, four groups, four members each — with no gaps and no exceptions. Verified against the values in linux/usb/hcd.h, and the check-field property holds for all sixteen.

Which makes a receiver's first decision two bits wide. Before identifying the packet, a receiver needs to know what shape it is — how long the body is and which check to run — and that is exactly what the group tells it:

GroupBodyCheck
Token11 bitsCRC5
DatapayloadCRC16
Handshakenonenone
Specialvariesvaries

So PID[1:0] is not a convenience. It is the field that tells the receiver how many more bits to expect — which is why §7's mutation that reads the wrong two bits is more damaging than its size suggests.

A block diagram of the universal USB packet structure. A synchronisation pattern, owned by the signalling layer, precedes every packet. Then comes the packet identifier byte, whose high nibble is the complement of its low nibble and is checked immediately. The low nibble's two least significant bits select the group, which determines the packet's shape. A token or start-of-frame group leads to an eleven-bit body checked by a five-bit cyclic redundancy code. A data group leads to a payload of zero to one thousand and twenty-four bytes checked by a sixteen-bit code. A handshake group leads to no body and no check at all. An end-of-packet marker, also owned by the signalling layer, follows every packet.SYNCModule 14 — framingPID byte~PID[3:0] | PID[3:0]Check fieldevery 1-bit errorPID[1:0]what shape follows11 bits + CRC5token · SOFpayload + CRC160–1024 bytesnothinghandshakeEOPModule 14 — framingverifydecode01111012
Figure 1 — the universal packet, and where each chapter's subject sits in it. The PID's two least significant bits are what tell the receiver how much more packet there is, which is why they are decoded before anything else.

4. What Is Protected, and What Is Not

Worth assembling, because the coverage is less uniform than it looks.

FieldProtected byStrength
PIDits own check nibbleall single-bit errors; 85.7% of two-bit
ADDR + ENDPCRC55 bits over 11
Frame numberCRC55 bits over 11
PayloadCRC1616 bits over up to 8192
Handshake meaningthe PID check alonesee below

The last row is the one to notice. A handshake packet has no CRC because it has no body — so ACK, NAK, STALL and NYET are protected by four bits of complement and nothing else.

Which is a defensible choice and not a free one. Chapter 11.3 established that these four carry a device's entire error model, and §2 measured the residual: a two-bit error in matching nibble positions converts one into another undetectably.

The mitigation is not in the packet. It is in the protocol. A corrupted handshake is usually indistinguishable from a lost handshake, and Chapter 11.2's toggle already handles that case — the host retransmits, and the retransmission is absorbed. The packet layer's weakness is covered by the transaction layer's redundancy, which is a pattern worth recognising because it recurs: a layer can be thin when the layer above it is already handling the failure.

5. The PID Decoder, as RTL

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// usb_pid_pkg + usb_pid_decode
//
// Classification: SIMPLIFIED SYNTHESIZABLE TEACHING RTL, plus a CONCEPTUAL
// package. This is the block every other chapter in Module 11 assumed had
// already run: Chapters 11.1 to 11.4 all take `pid` as a validated low
// nibble, and this is where that validation happens.
//
// WHAT IT MODELS. Section 2's check field and section 3's group decode --
// the two decisions a receiver makes before it knows how much more packet
// to expect.
//
// WHAT IT DOES NOT MODEL. The SYNC pattern and end-of-packet that frame the
// byte (Module 14); the reception of the body; either CRC (Chapter 11.6);
// and everything a decoded packet then means, which is Chapters 11.1 to
// 11.4 and Module 12.
//
// ── WHY THIS BLOCK IS FIRST AND SMALL ───────────────────────────────────
// Its outputs gate the receiver's length and check selection, so it sits on
// the critical path of every packet on the bus. It is written as pure
// combinational decode of one byte for that reason: a registered stage here
// would cost a cycle on literally every packet.
// ─────────────────────────────────────────────────────────────────────────
package usb_pid_pkg;

  // Section 3. The group is PID[1:0], and it is what tells a receiver the
  // packet's SHAPE before it knows the packet's identity.
  typedef enum logic [1:0] {
    PGRP_SPECIAL   = 2'b00,
    PGRP_TOKEN     = 2'b01,
    PGRP_HANDSHAKE = 2'b10,
    PGRP_DATA      = 2'b11
  } pid_group_e;

  // The LOW NIBBLE is the PID; the high nibble is derived. Storing four bits
  // rather than eight is not a saving -- it is a statement that the check
  // field is not part of the identity, and it makes a whole class of
  // confusion impossible.
  localparam logic [3:0] PID_EXT   = 4'b0000, PID_PING  = 4'b0100,
                         PID_SPLIT = 4'b1000, PID_PRE   = 4'b1100,
                         PID_OUT   = 4'b0001, PID_SOF   = 4'b0101,
                         PID_IN    = 4'b1001, PID_SETUP = 4'b1101,
                         PID_ACK   = 4'b0010, PID_NYET  = 4'b0110,
                         PID_NAK   = 4'b1010, PID_STALL = 4'b1110,
                         PID_DATA0 = 4'b0011, PID_DATA2 = 4'b0111,
                         PID_DATA1 = 4'b1011, PID_MDATA = 4'b1111;

  // The transmitted byte, DERIVED from the PID rather than tabulated. A
  // table of sixteen bytes would be sixteen chances to typo a check nibble;
  // this is one expression that is right or wrong exactly once.
  function automatic logic [7:0] pid_byte(input logic [3:0] p);
    return {~p, p};
  endfunction

endpackage

module usb_pid_decode
  import usb_pid_pkg::*;
(
  input  logic       clk,
  input  logic       rst_n,

  input  logic       pid_valid,      // a PID byte has been framed (Module 14)
  input  logic [7:0] pid_byte_in,

  output logic       pid_ok,         // the check field holds
  output logic [3:0] pid,            // what Chapters 11.1 to 11.4 consume
  output pid_group_e group,
  output logic       has_body,       // section 1: a handshake has none
  output logic       has_crc16       // section 4: only data carries one
);

  logic [3:0] lo, hi;
  assign lo = pid_byte_in[3:0];
  assign hi = pid_byte_in[7:4];

  // SECTION 2. The complement, not merely a difference -- section 7's P2 is
  // what "merely a difference" costs, and it is the mutation that passes
  // every positive test.
  assign pid_ok = pid_valid && (hi == ~lo);

  assign pid   = lo;
  assign group = pid_group_e'(lo[1:0]);

  // Shape, derived from the group. Everything downstream -- how many bits to
  // shift in, which CRC to run -- follows from these two lines, which is why
  // section 7's P3 does more damage than its size suggests.
  assign has_body  = pid_ok && (group != PGRP_HANDSHAKE);
  assign has_crc16 = pid_ok && (group == PGRP_DATA);

endmodule

What it models. Validation of the PID byte and extraction of the packet's shape.

Engineering reason. Because a receiver must know how many more bits are coming before it can receive them, and the answer is two bits of the first byte.

Inputs. A framed PID byte and its validity.

State retained. None, deliberately — see the header. This sits on the critical path of every packet on the bus.

Outputs. A validity verdict, the four-bit identity, the group, and two shape indications.

Hardware implied. A four-bit comparator against an inversion, a two-bit decode, and two equality tests. Under twenty gates.

Reset behaviour. Nothing to reset.

Assumptions. That pid_valid means the byte was correctly framed — a misframed byte is not this block's problem and cannot be made so; and that the bit order has already been normalised, since USB transmits least-significant-bit first and this block sees a byte.

Omissions. Framing, the body, both CRCs, and every packet's meaning — in the header.

What DV should verify. That every byte failing the complement is rejected — not merely the plausible ones; that all sixteen legal PIDs are accepted; that the group comes from PID[1:0]; that a handshake reports no body and no CRC16; that only the data group reports CRC16; and that nothing is accepted while pid_valid is low.

6. Mutation Test

Four mutations over 416 PID bytes, in three exhaustive phases: all 16 legal PIDs, all 128 single-bit corruptions of them, and all 256 possible bytes — plus 16 with pid_valid low.

The unmutated block: 32 bytes accepted (the 16 legal PIDs, encountered in two phases) and 0 errors of any kind. All 128 single-bit corruptions were rejected.

acceptedinvalid byte acceptedvalid byte rejectedwrong groupwrong has_body
golden320000
P1 no check field at all32368000
P2 hi != lo instead of hi == ~lo32352000
P3 group from PID[3:2]32002412
P4 handshakes have a body320008

P1 — remove the check entirely

Measured: 368 invalid bytes accepted.

Every corruption becomes a packet. The receiver then reads a body length and a check type from bits that are noise — and §3's point bites: the group decides how many more bits to receive, so a corrupted PID desynchronises the receiver from the bus, not merely the packet.

P2 — test for inequality rather than complement

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign pid_ok = pid_valid && (hi != lo);   // MUTANT P2

Measured: 352 invalid bytes accepted — and zero valid bytes rejected.

This is the mutation to study. For every legal PID, hi is ~lo, and ~lo != lo is true for all four-bit values. So the mutant accepts all sixteen legal PIDs, correctly, every time.

A bench that tests only that legal PIDs are accepted passes it completely. The defect lives entirely in what it also accepts: 352 of the 384 invalid bytes presented, including every single-bit corruption the check field exists to catch.

It is also a plausible edit. The two nibbles must not be the same is a sentence somebody could write down believing it captures the rule, and it captures exactly one sixteenth of it.

P3 — take the group from the wrong two bits

Measured: 24 wrong groups out of 32 accepted bytes, and 12 wrong has_body.

PID[3:2] instead of PID[1:0] — an off-by-two in a slice, the same class as Chapter 11.1 §6's endpoint mutation.

The damage is disproportionate to the edit because the group selects the packet's shape. A DATA0 classified as a token means the receiver expects 11 bits and a CRC5 where 64 bytes and a CRC16 are arriving, so it stops being aligned to the bus — and the next several packets are garbage regardless of their own integrity.

P4 — give handshakes a body

Measured: 8 wrong.

Exactly the eight handshake PIDs across the two phases that present them. The receiver waits for a body that never comes on every ACK, NAK, STALL and NYET — which is a hang on the most common packets on the bus, and the most immediately visible of the four.

7. The Assertions

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// Classification: TEACHING ASSERTIONS about the PID decoder.
// V-properties concern VALIDATION; G-properties the group; S the shape.
// Note how many are equivalences: for a pure decode, an implication is
// almost always the weaker half of what you meant.
// ─────────────────────────────────────────────────────────────────────────

// V1 -- VALIDITY IS EXACTLY THE COMPLEMENT. An EQUIVALENCE, and section 6's
// P2 is precisely why: the implication form (pid_ok |-> something) is
// satisfied by a check that accepts far too much, and the reverse form by
// one that accepts too little. Only the equality pins both directions.
property p_ok_iff_complement;
  @(posedge clk) disable iff (!rst_n)
    pid_ok == (pid_valid && (pid_byte_in[7:4] == ~pid_byte_in[3:0]));
endproperty
assert property (p_ok_iff_complement);

// V2 -- EVERY SINGLE-BIT ERROR IS REJECTED. Section 2's measured property,
// written as an assertion rather than trusted. It needs a reference to the
// byte that WAS sent, so it is a bind against a transmit monitor -- and the
// inconvenience is the point: this is the only statement here that knows
// what the truth was, rather than merely what arrived.
property p_single_bit_rejected;
  @(posedge clk) disable iff (!rst_n)
    (pid_valid && ($countones(pid_byte_in ^ tx_pid_byte) == 1)) |-> !pid_ok;
endproperty
assert property (p_single_bit_rejected);   // via bind

// G1 -- THE GROUP IS PID[1:0]. Section 6's P3. A restatement of one line of
// RTL, and worth it for the same reason Chapter 11.1's endpoint-slice
// property was: it records WHICH BITS, sourced from the packet format
// rather than from the code.
property p_group_is_low_two;
  @(posedge clk) disable iff (!rst_n)
    pid_ok |-> (group == pid_group_e'(pid[1:0]));
endproperty
assert property (p_group_is_low_two);

// S1 -- A HANDSHAKE HAS NO BODY, AND EVERYTHING ELSE HAS ONE. Section 6's
// P4. Again an equivalence: `handshake |-> !has_body` alone is satisfied by
// a decoder that reports no body for anything.
property p_body_iff_not_handshake;
  @(posedge clk) disable iff (!rst_n)
    pid_ok |-> (has_body == (group != PGRP_HANDSHAKE));
endproperty
assert property (p_body_iff_not_handshake);

// S2 -- ONLY DATA CARRIES A CRC16. Section 4.
property p_crc16_iff_data;
  @(posedge clk) disable iff (!rst_n)
    pid_ok |-> (has_crc16 == (group == PGRP_DATA));
endproperty
assert property (p_crc16_iff_data);

// S3 -- NOTHING IS DECODED WITHOUT A VALID PID. Catches shape outputs that
// assert on noise between packets.
property p_nothing_without_ok;
  @(posedge clk) disable iff (!rst_n)
    !pid_ok |-> (!has_body && !has_crc16);
endproperty
assert property (p_nothing_without_ok);

Four of the six are equivalences, and that is not a stylistic habit. This block is a pure decode: for every input there is exactly one correct output, so any implication discards half of what you know. §6's P2 is the concrete demonstration — it satisfies pid_ok |-> pid_valid and every other one-directional statement about validity.

V2 is the property worth the trouble. It needs tx_pid_byte — what was actually transmitted — which is not a signal of the receiver and must come from a monitor on the other side. It is the only assertion here that can distinguish this byte is self-consistent from this byte is the one that was sent, and §2's entire measured claim is about the second.

8. Verification

This chapter's commit point is nothing was accepted that should not have been.

Stimulus. Exhaustive, in three phases, because the input is one byte and there is no excuse:

  • all 16 legal PID bytes — the positive set;
  • all 128 single-bit corruptions of them — §2's measured claim, as stimulus;
  • all 256 possible byte values — the complete negative space;
  • and 16 with pid_valid deasserted.

Observation. The verdict, the group, and both shape outputs — on every byte, against a reference that recomputes the complement independently.

Coverage. For a one-byte input, coverage is not a sampling question: every input was applied. What remains is whether the checks were right, and §6's P2 is the reminder that they can be complete on the positive set and empty on the negative one.

Negative cases with defined outcomes: every byte failing the complement is rejected — all 240 of them; nothing is decoded while pid_valid is low; and no shape output asserts without a valid PID.

9. Debugging: the Receiver That Loses Sync Under Noise

A device works on a clean bus. On an electrically noisy one it does not merely drop packets — it goes deaf for extended periods, recovering only after an idle gap. The deafness lasts far longer than any single corrupted packet.

What does longer than one packet tell you? That a single corruption is costing more than one packet. The receiver is losing alignment, not just data.

How does a packet-level corruption cost alignment? §3: the PID's group decides how many more bits to receive. A receiver that acts on a corrupted PID waits for the wrong number of bits — and then interprets the next packet's bytes as the current one's body.

So where do you look? At whether the PID check is actually rejecting. §6's P1 and P2 both produce exactly this: P1 accepts everything, P2 accepts 92% of corruptions — and both leave the receiver acting on noise.

How do you tell them apart from P4? By whether the deafness follows corruption or follows a specific packet type. P4 hangs on every handshake, which happens on a clean bus too — so a device that is fine when quiet has a check-field problem, not a shape problem.

Why does an idle gap recover it? Because Module 14's framing resynchronises on the next SYNC after sufficient idle. The receiver is not broken; it is mis-aligned, and alignment is re-established by the one thing that does not depend on packet contents.

And the confirming observation? Count accepted PIDs against transmitted ones under noise. A correct receiver rejects more as noise rises; a broken one accepts the same number and produces garbage. That ratio is the single most diagnostic number here, and it requires instrumenting the receiver rather than the bus.

The signature to keep: deafness lasting longer than the corruption that caused it means a length was taken from a damaged field — and in USB the length comes from two bits of the first byte.

10. Common Misconceptions

11. Reason It Through

An engineer proposes saving logic by dropping the PID check field on a device that will only ever be used inside a sealed product, on a short, shielded, internal cable. The bus is electrically quiet by construction.

Is the premise reasonable? Surprisingly, yes. Single-bit errors on a short shielded link in a controlled enclosure are genuinely rare, and the engineer is not wrong about the error rate.

What does the check actually cost? §5 measured it: a four-bit comparator against an inversion. Under twenty gates for the whole block, of which the check is a handful.

So the trade is a handful of gates against a rare event. Which sounds like a reasonable engineering judgement, and is not — for a reason that has nothing to do with the error rate.

What breaks if a corrupted PID is accepted? §9: the group decides how many more bits to receive, so the receiver loses alignment with the bus. The cost is not one corrupted packet; it is every packet until the next idle gap.

So how should the trade actually be evaluated? Not as probability × one packet, but as probability × unbounded recovery time. And the multiplier is what makes the arithmetic collapse: a rare event with a large and variable cost is exactly the case where removing a cheap guard is worst.

Is there a second argument? Yes, and it is stronger. The premise is a claim about the environment, and environments change. A cable gets longer in revision B; the enclosure gains a switching regulator; somebody reuses the block. The guard costs gates once; the premise must hold forever.

What would make the proposal acceptable? Essentially nothing at this price. A guard whose cost is twenty gates and whose absence is unbounded does not need a risk assessment — and recognising which decisions do not warrant analysis is itself a skill, because the analysis costs more than the gates.

And the transferable point: when the cost of a guard is negligible, the argument for removing it has to be about something other than cost — and there usually is not one. Chapter 10.4 §6 measured a redundant guard that was covered rather than dead; this is the same lesson from the other direction.

12. Understanding Check

13. Summary

Four packet types are one structure: a PID, an optional body, an optional check. A handshake is a packet consisting entirely of its own identity, which is what proves the last two slots are genuinely optional. A token and an SOF are byte-for-byte identical in shape, differing only in what the PID says their eleven bits mean.

The PID is four bits transmitted with its complement. Measured: all 16 legal bytes of the 256 possible satisfy the check; all 128 single-bit corruptions are rejected; 64 of 448 two-bit corruptions (14.3%) are not; a random byte passes one time in sixteen. It is a single-bit detector, and that is what makes it safe for Chapter 11.3's NAK and STALL to sit two bits apart.

Sixteen PIDs form four groups of four on PID[1:0], with no gaps — and the group is the field that tells a receiver how many more bits to expect, which is why misreading it costs alignment rather than a packet.

Protection is not uniform. A handshake's meaning rests on four bits of complement and nothing else — covered not by the packet layer but by the transaction layer above it, where a corrupted handshake is indistinguishable from a lost one and Chapter 11.2's toggle already handles it.

§6 measured four mutations across an exhaustive 416-byte stimulus. The one worth carrying is P2: testing that the nibbles differ rather than that one is the other's complement. It accepted all 16 legal PIDs and 352 of 384 invalid bytes — a validator with a perfect positive record and no value whatsoever.

A validator's worth is measured entirely by what it turns away.

And §8 closes Module 11's verification thread with three distinct ways a passing bench has been wrong across five chapters — an unreachable state, a shared misunderstanding, and an empty negative space. They are independent, they need different fixes, and none of the three appears in a coverage report, because all three concern the relationship between what was applied and what was checked.

14. What Comes Next

This chapter took crc5_ok and has_crc16 as given. Chapter 11.6 is where they come from.

Two polynomials, five bits and sixteen, guarding eleven bits and up to eight thousand. The chapter's centre is a property that is easy to state and easy to implement wrongly: a receiver does not compute the CRC and compare it. It feeds the received check bits through the same machine as the data and confirms the result is a fixed constant — a residue, which for USB's CRC5 is 0b01100 and for its CRC16 is 0x800D, both derivable from the polynomials rather than quoted.

Getting that distinction wrong produces a checker that works on every test vector anyone writes by hand and fails on the wire.

Browse the full path on the USB tutorials index.

Continue learning

Standards & specifications

Governing standard
USB-IF (Universal Serial Bus Specification)(opens USB Implementers Forum (USB-IF) in a new tab)

Defines the USB bus — its electrical signalling, connectors, packet and transaction model, device framework and the descriptors a device must expose — together with the device-class specifications layered on it. It does not define host-controller register interfaces (xHCI and EHCI are separate documents) nor any operating system's driver architecture.

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 USB curriculum.