USB · Module 8
Attached State
The state where a device exists but the protocol does not: why USB needs explicit device state, the five distinct state domains a controller contains, and why the expensive bugs live in the disagreements between them.
Module 7 established what a device claims to be. Every descriptor was a contract: this configuration exists, this interface has these endpoints, this endpoint carries packets of this size.
This module is about something the descriptors never say.
A descriptor is a claim about capability. It says nothing about when that capability may be exercised. An addressed device and a configured device have byte-identical descriptors and are permitted entirely different things.
That gap is what device state fills, and this chapter starts at the one state where a device is unambiguously present and almost nothing is permitted.
1. Why Explicit Device State Is Necessary
Derive the requirement rather than accepting it, because the derivation is what makes the rest of the module predictable.
A USB device is subject to events it does not control. It can be plugged in and unplugged. It can be powered and unpowered. The host can reset it, address it, configure it, deconfigure it, or stop talking to it entirely. Any of these can happen at any time.
After any of them, the device must answer three questions:
- What operations are legal now? A request that is perfectly valid in one condition is meaningless in another.
- What information is still true? An address assigned before a reset is not an address afterwards.
- What must change, and what must not?
Consider what happens without explicit state. The device would have to infer its situation from the last thing that happened to it — and that fails immediately, because the same event means different things depending on what preceded it. A configuration selection means one thing to an addressed device and is meaningless to one that has never been addressed. An event's meaning depends on the condition it arrives in, which is precisely what a state is.
So the device carries explicit protocol state, and every legality question is answered by it.
2. Five Different Things Called "State"
Here is the chapter's most important contribution, and the discipline the rest of the module depends on.
A real device controller contains at least five distinct notions of state, and they are routinely confused. Confusing them is not a vocabulary problem — it is the origin of a whole class of bug that is hard to find precisely because every individual block is correct.
Physical state. Is the connector actually mated? Is bus power present? This is the domain Chapter 6.1 worked in, where a mechanical connector bounces and debounce is a correctness requirement.
PHY and link condition. What speed was established, is the line idle, is an extended idle a reset? Chapter 3.7 owns the decoding; what matters here is that these are electrical conditions interpreted, not protocol state.
USB protocol state. The six canonical states this module is about. This is an abstraction defined by the specification, not a register — a point §3 develops, because it is where most RTL engineers go wrong.
Controller RTL state. The actual flip-flops. A state register, an address register, a configuration register, enable signals. This represents the protocol state and is not identical to it.
Firmware state. What software believes. Firmware learns about transitions through status registers and interrupts, which means it learns late and can miss things entirely.
3. Protocol State Is Not One Big FSM
A specific warning for RTL engineers, because the intuitive implementation is wrong in an instructive way.
The temptation is to read "USB devices have six states" and write:
always_comb begin
unique case (usb_state)
ST_ATTACHED: /* ... everything the device does here ... */
ST_POWERED: /* ... everything the device does here ... */
ST_DEFAULT: /* ... and so on ... */
endcase
endThis does not scale and does not reflect how controllers are built. A real device controller contains a control-transfer engine, per-endpoint state machines, a packet engine, a PHY interface, buffer and DMA management, and a firmware register interface. Each has its own state, its own clock relationships, and its own reset behaviour.
The protocol state is not the union of those. It is a small, separate, authoritative abstraction that gates them.
The architecture that works looks like this:
protocol state (a few bits, registered, one owner)
│
├──→ derived enable: may function endpoints operate?
├──→ derived gate: is this request legal right now?
├──→ derived value: which address do I answer to?
└──→ status: what does firmware get told?Protocol state is an input to everything and the implementation of nothing. The endpoint block does not contain a copy of it; it consumes an enable derived from it. The control engine does not re-implement it; it asks whether a request is legal.
That is the architectural lesson of this module, and Chapter 8.5 measures what happens when a block keeps its own copy instead.
4. The Attached State
Now the state itself — and it is the one where the least is permitted.
A device is Attached when it is physically connected to the bus but the protocol has not begun. The connector is mated. Nothing else is true.
What is legal? Essentially nothing. The device is not required to respond to anything, because it may not even be powered — §5 is about that distinction.
What is guaranteed to be true? Only that something is physically present. The device has no address, no configuration, no speed established, and no protocol identity of any kind.
How is it entered? By physical connection — Chapter 6.1's attach detection, debounce included.
How is it left? By becoming powered, which is Chapter 8.2.
5. Attached Is Not Powered
The distinction that makes Attached a separate state rather than a formality.
Connection and power are independent facts. A device can be plugged into a port that is not supplying power — a port the host has not yet enabled, a hub port that is off, a port whose power was cut. It is connected and it cannot do anything.
So the two conditions are separated: Attached says the connector is mated, Powered says operating power is available.
Why does the protocol care? Because the transition between them is a real event with real consequences. A device that becomes powered has to bring itself up, present its pull-up (Chapter 3.5) so the host notices it, and be ready for what follows. A device that is merely attached does none of that.
And because the reverse transition matters too. Power can be removed from a still-connected device — and a device that loses power loses everything, including any protocol state it had accumulated. That is a different event from being unplugged, and a controller that treats them identically will get one of them wrong.
6. Observing the Domains — a Verification Model
§2 claimed the expensive bugs live between domains. That claim is worth building an instrument for, and doing it now gives the rest of the module something to reuse.
// ─────────────────────────────────────────────────────────────────────────
// usb_state_domain_observer
//
// Classification: VERIFICATION MODEL. Not synthesizable, not part of any
// device, and deliberately not connected to anything the design depends on.
//
// WHAT IT MODELS. Section 2's five domains, as five independent inputs, and
// the CONSISTENCY RELATIONSHIPS between them. It exists because no block in
// a controller can see more than one or two of these at once, so no block
// can detect a disagreement -- which is exactly the class of bug this module
// is about.
//
// WHAT IT DOES NOT MODEL. Any transition logic (Chapter 8.3 owns the FSM),
// any decoding (Module 3 owns electrical interpretation), endpoints
// (Module 9), transfers (Modules 11-13), or firmware behaviour. It only
// WATCHES; it never drives.
//
// WHY A MODEL AND NOT ASSERTIONS INSIDE THE DESIGN. Assertions inside a
// block see that block's signals. These relationships span four blocks and
// a software interface, so the checker has to sit outside all of them. That
// is not a limitation of the technique -- it is the whole point.
// ─────────────────────────────────────────────────────────────────────────
package usb_state_pkg;
// The canonical device states. Chapter 8.3 develops the transitions; this
// package exists from 8.1 so every later chapter shares one definition
// rather than each declaring its own (which is how enums drift apart).
typedef enum logic [2:0] {
DEV_NOTATTACHED = 3'd0, // NOT a specification state -- see section 4
DEV_ATTACHED = 3'd1,
DEV_POWERED = 3'd2,
DEV_DEFAULT = 3'd3,
DEV_ADDRESS = 3'd4,
DEV_CONFIGURED = 3'd5
} usb_dev_state_e;
localparam logic [6:0] USB_DEFAULT_ADDR = 7'd0;
localparam logic [7:0] USB_NO_CONFIG = 8'd0;
endpackage
module usb_state_domain_observer
import usb_state_pkg::*;
(
input logic clk,
input logic rst_n,
// ── Domain 1: physical ────────────────────────────────────────────────
input logic phys_connected, // debounced (Chapter 6.1)
input logic phys_powered, // operating power present
// ── Domain 2: PHY / link ──────────────────────────────────────────────
input logic phy_speed_known, // Chapter 3.7 completed
// ── Domain 3: protocol state (the abstraction) ────────────────────────
input usb_dev_state_e proto_state,
// ── Domain 4: controller registers ────────────────────────────────────
input logic [6:0] active_addr,
input logic [7:0] active_config,
input logic function_eps_enabled,
// ── Domain 5: firmware's belief ───────────────────────────────────────
input usb_dev_state_e fw_believed_state,
input logic fw_status_stale_ok, // a transition is in flight,
// so a lag is expected
output logic domains_disagree
);
logic d1, d2, d3, d4, d5;
// ── D1: a device cannot be in a protocol state above Attached without
// actually being connected. This catches a controller that retained its
// protocol state across a physical removal.
assign d1 = (proto_state > DEV_ATTACHED) && !phys_connected;
// ── D2: nor without power. Distinct from D1 -- section 5's point is that
// connection and power are independent, so they need separate checks.
assign d2 = (proto_state > DEV_ATTACHED) && !phys_powered;
// ── D3: COMPOSITION. Being in the Address state and holding the default
// address are contradictory. Chapter 8.4 develops this; it lives here
// because the observer is the thing that can see both.
assign d3 = (proto_state == DEV_ADDRESS && active_addr == USB_DEFAULT_ADDR)
|| (proto_state == DEV_CONFIGURED && active_addr == USB_DEFAULT_ADDR);
// ── D4: COMPOSITION. Configured must agree with a selected configuration,
// and function endpoints must be enabled only when Configured.
// Chapter 8.5 develops both halves.
assign d4 = (proto_state == DEV_CONFIGURED && active_config == USB_NO_CONFIG)
|| (function_eps_enabled && proto_state != DEV_CONFIGURED);
// ── D5: firmware may LAG hardware -- that is normal and unavoidable,
// because firmware learns through status and interrupts. What it must not
// do is lag INDEFINITELY, so this is only a disagreement when nothing
// explains it. Chapter 8.5 returns to why the exemption is necessary
// rather than a weakening.
assign d5 = (fw_believed_state != proto_state) && !fw_status_stale_ok;
assign domains_disagree = d1 | d2 | d3 | d4 | d5;
// Reporting each relationship separately is deliberate: "the domains
// disagree" sends an engineer to read five signals, while naming the
// relationship points at one.
always_ff @(posedge clk) begin
if (rst_n) begin
if (d1) $error("DOMAIN: protocol state %0s with nothing connected",
proto_state.name());
if (d2) $error("DOMAIN: protocol state %0s with no power",
proto_state.name());
if (d3) $error("DOMAIN: state %0s but active_addr is the default",
proto_state.name());
if (d4) $error("DOMAIN: state %0s, config %0d, function EPs %0b",
proto_state.name(), active_config, function_eps_enabled);
if (d5) $error("DOMAIN: firmware believes %0s, hardware is %0s",
fw_believed_state.name(), proto_state.name());
end
end
endmoduleClassification. Verification model — it watches and never drives.
What it models. The consistency relationships between §2's five domains.
Why it exists. Because no block in a controller can see more than one or two domains, so no block can detect a disagreement between them. The checker has to sit outside all of them.
Inputs. One or more signals from each domain. State retained. None — every relationship is combinational. Outputs. A single disagreement flag, plus per-relationship reporting.
Reset behaviour. Reporting is suppressed while the local reset is asserted, because during reset the domains are legitimately in flux.
Hardware implied. None. This is not hardware.
Assumptions. That phys_connected is already debounced; that the firmware-belief input is available to the testbench (in a real environment it is read from the status register the firmware reads); and that fw_status_stale_ok is asserted by the environment while a transition is genuinely in flight.
Deliberately omits. All transition logic, all decoding, endpoints, transfers, and firmware behaviour.
What DV should verify with it. That it fires on each of its five relationships when the corresponding defect is injected — a checker nobody has ever seen fail is a checker nobody knows works.
Two decisions carry the teaching:
- The five relationships are reported separately. The domains disagree sends an engineer to read five signals; state is Address but the address register holds the default points at one.
- Firmware lag is exempted rather than forbidden. Firmware genuinely cannot track hardware instantaneously, so a checker that forbade any difference would fire constantly and be disabled within a day. §5 of Chapter 8.5 returns to why this exemption has to exist and what it costs.
7. Mutation Test
A checker nobody has watched fail is a checker nobody knows works. §6's model was therefore driven with eleven scenarios — five defects, one per relationship, plus six consistent cases that must stay silent — and then mutated to confirm each relationship is doing work.
The correct model is measured silent on every consistent case and fires on every defect: a configured device with nothing connected, a configured device with no power, both Address and Configured holding the default address, a Configured device with no configuration, function endpoints enabled outside Configured, and firmware disagreeing without an explanation. An Attached device with no power, no address and no configuration is correctly silent — §5's case, which is consistent rather than defective.
Three mutations, each removing part of one relationship:
mutation defect that becomes invisible
────────────────────────────────────────────────────────────────────────
D1 removed entirely configured while disconnected
D3's Configured half removed Configured holding the default
address (the Address half
still caught)
D5's exemption removed nothing — instead it FIRES on a
legitimate in-flight transitionThe third is the interesting one, because it fails in the opposite direction from the others. Removing the exemption does not create a blind spot; it creates a false positive on a device behaving correctly, because firmware genuinely lags hardware.
8. Verification
This chapter's contribution to the plan is the framework the rest of the module uses, not a transition to test.
The state × event method, which every later chapter applies:
current state × incoming event
↓
is this event legal in this state?
↓
expected next state
↓
expected architectural side effects
↓
compare against the DUT — all of it, not just the stateStimulus for this chapter. Physical connection and disconnection; power applied and removed while connected; both in each order; and connection events during reset.
Observation. All five domains together. §6's model exists to make that practical — and the point of building it in the module's first chapter is that every later chapter can inject a defect and watch it fire.
Negative cases with defined outcomes: removing power from a connected device must not leave protocol state above Attached; a physical disconnection must not leave protocol state claiming otherwise; and reconnection must not restore anything from before.
The verification habit this chapter establishes: never check the state enum alone. Chapter 8.4 measures a defect that a correct state enum actively hides.
9. Common Misconceptions
10. Reason It Through
A device is unplugged while it is operating normally. Some time later it is plugged back in. It fails to enumerate. Power-cycling the host fixes it.
What does power-cycling fixes it tell you? That something survived the disconnection which should not have. A logic error would fail every time; this is state that outlived the event that should have cleared it.
Which domain is the survivor most likely in? Not the physical one — that one changed correctly, or the host would not have noticed the removal. The candidates are protocol state and the controller registers beneath it.
What relationship would catch it? §6's D1: a protocol state above Attached while nothing is connected. If the controller kept its Configured state through the removal, D1 fires on the first cycle after the disconnection.
Why would per-block checking miss it? Because no block did anything wrong. The FSM was never told to change — it was not reset, and a disconnection is not one of its events unless someone made it one. The address register held the address it was correctly given. Every block preserved exactly what it was designed to preserve.
What is the design question underneath? Which events invalidate protocol state, and is physical removal one of them? It is easy to build a controller whose state changes only on protocol events and which therefore has no opinion about being unplugged.
And the transferable lesson? Fails on the second attempt, fixed by a power cycle is a stale-state signature — the same one Chapter 6.6 §9 identified for a partial reset. It says something was not cleared, and it directs the search at whatever was supposed to do the clearing rather than at whatever failed.
11. Understanding Check
12. Summary
Descriptors say what a device can do; state says when it may do it. An addressed device and a configured device have identical descriptors and entirely different permissions, and that gap is what this module fills.
Explicit protocol state is necessary because an event's meaning depends on the condition it arrives in. A device cannot infer its situation from the last event alone, so it carries state, and every legality question is answered by it. A state is the answer to what is legal now — not a label.
The module's foundational discipline is that five different things are called state: physical, PHY/link, protocol, controller registers, and firmware. Each is derived from the one below, every derivation can silently stop agreeing, and when they disagree every individual block is still locally correct — which is what makes the resulting bugs expensive and why §6's checker has to sit outside all of them.
For RTL, the architectural point is that protocol state is not one big FSM. A real controller has control-transfer, endpoint, packet, PHY and DMA state of its own. The protocol state is a small authoritative abstraction those blocks consume — through derived enables, legality gates and status — rather than live inside. It is an input to everything and the implementation of nothing.
Attached is the state where the device is physically present and almost nothing is permitted: no address, no configuration, no speed, no identity. It is separate from Powered because connection and power are independent, and because losing power is a different event from being unplugged — one a controller that conflates them will get wrong.
And implementations commonly add a not-attached state the specification does not define, which is legitimate: a specification describes the states a device passes through while it exists, and an implementation also needs to describe the boundaries of that existence.
13. What Comes Next
A device that is Attached is present and inert. Nothing it might want to do is possible, because it may have no power to do it with.
Chapter 8.2 is the state where that changes — and it turns out to be the state in which the device makes its first and only unilateral decision. Everything after it is the host acting on the device. Becoming powered is the one moment where the device chooses to be noticed, by presenting the pull-up Chapter 3.5 described, and the timing of that choice is a design decision with consequences the device controller owns alone.
Browse the full path on the USB tutorials index.
Continue learning
Related tutorials
- Related topic
SuperSpeed (SS)
A mode that does not compete for the conductors the others use — it has its own. What active mode means when two modes run concurrently on one connection, why that makes mode a per-path property, and the verification model that must observe rather than assume.
- Related topic
USB Reset
Reset as an assertion rather than a question: what a bus reset clears, what it deliberately does not, and why a protocol bus reset and an RTL reset are different mechanisms with different scopes.
- Related topic
Configuration Selection
Addressed is not configured. What selecting a configuration switches on, why configuration zero is an un-select rather than a choice, and the RTL consequence of a state entered and left by the same request.
- Related topic
Endpoint Descriptor
Seven bytes that promise hardware: address and direction, transfer type, packet size and interval — the length limiter that bounds every response, and the consistency checker that catches a descriptor the silicon cannot keep.
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.
