USB · Module 8
Configured State
The state whose consequences leave the state machine: derived enables versus stored copies, distributed state drift across four holders, and why firmware may disagree with hardware while endpoints may not.
Chapter 8.4 established that a state is a claim about a register, and measured what happens when the claim stops being true.
Configured takes that one step further, and the step is the hard one:
Configured is the first state whose consequences leave the state machine entirely. Address affects one register. Configured brings hardware to life — endpoint logic, buffers, enables — none of which the state machine contains.
Which introduces a failure mode Address does not have. Not two things disagreeing, but many — each locally correct.
1. What Configured Means
A device is Configured after a configuration commit carrying a non-zero value. It holds an address, it holds a configuration, and the endpoints belonging to that configuration operate.
What is legal? Everything the device is for. Data transfers on its function endpoints, plus the control communication that was already legal.
What is guaranteed? That the device holds a non-default address and a non-zero configuration and that the endpoints that configuration declares are operating. Three claims, which is one more than any earlier state, and §3 is about the third.
How is it entered? From Address by a configuration commit with a non-zero value. From Configured itself by re-selecting.
How is it left? To Address by an un-select (Chapter 6.5). To Default by a bus reset. To Attached by power loss or disconnection.
2. The Third Claim Is Different
Compare what the states claim.
| State | Claims | Held where |
|---|---|---|
| Default | address is the default | one register |
| Address | address is assigned | one register |
| Configured | address is assigned, and a configuration is selected, and its endpoints operate | one register, another register, and hardware elsewhere |
The first two claims are about registers the state machine owns. Chapter 8.4's composition invariants work because both sides of each invariant are visible from one place.
The third is not. Endpoint hardware lives in its own block, with its own state, its own buffers, and — critically — its own opinion about whether it is enabled.
So the question this chapter has to answer is: where does that opinion come from?
3. Derived or Stored
Two architectures, and choosing between them is the chapter's central design decision.
Derived
assign function_eps_enabled = (dev_state == DEV_CONFIGURED);The enable is a function of the state. It has no memory. It cannot be wrong unless the state is wrong, and it cannot be forgotten on any transition because there is nothing to forget.
Stored
always_ff @(posedge clk) begin
if (config_commit && config_value != 0) function_eps_enabled <= 1'b1;
if (bus_reset) function_eps_enabled <= 1'b0;
// ... and every other transition that should clear it
endThe enable is its own state, updated by events. It can be set, and it can be forgotten.
The rule worth carrying:
A derived signal cannot disagree with its source. A stored copy can, and will, at whichever transition nobody thought about.
And the transition nobody thinks about is reliably the same one: the downward one. Setting an enable when a configuration is selected is the obvious half. Clearing it on un-select, on bus reset, on power loss and on disconnection is four separate obligations, and §5 measures what missing one costs.
4. Distributed State Drift
Now the failure mode that is specific to this state.
Four places can hold an opinion about whether the device is configured:
Each is updated by its own events. The state machine by commits and resets. The configuration register by commits and resets. The endpoint block by whatever the designer wired to it. Firmware by status reads and interrupts.
Each can be individually correct and the set can still be wrong, which is Chapter 8.1 §2's point in its most concrete form.
Strategies that work — and none is universally right:
- One authoritative holder, everything else derived. Strongest guarantee, and constrained by the timing and clock-domain realities of §3.
- Explicit commit events with a single owner. If several blocks must hold state, one block emits the event and the others consume it — never each deciding independently from the same raw inputs.
- Clear ownership of reset. Every holder must respond to a bus reset, and the list of holders must be written down somewhere, because the failure is always the one that was not on the list.
- Cross-block assertions. Chapter 8.4 §4's technique, extended — §6 does exactly that.
What does not work is each block deriving its own opinion from the raw events. That produces four state machines that agree most of the time, which is the hardest failure to find.
5. Firmware Is Allowed to Disagree
An exception that is not a weakening, and a place where the rule genuinely changes.
Hardware holders must agree instantly. The state register, the configuration register and the endpoint enables are all in the same clock domain and all updated by the same events. There is no reason for them to differ on any cycle, and Chapter 8.4's invariants forbid it.
Firmware cannot. It learns about transitions by reading a status register or taking an interrupt, both of which take time. A bus reset can return a device to Default while firmware is midway through a routine that believes it is Configured, and firmware will not find out until it next looks.
So the invariant has to be different in kind. Not firmware agrees with hardware, which is unachievable, but something like firmware's belief is never more than one notification behind — and the notification must be reliable, which is the real requirement hiding underneath.
6. The Configuration Composition Checker
Chapter 8.4's technique, extended to cover the third claim.
// ─────────────────────────────────────────────────────────────────────────
// usb_config_composition_check
//
// Classification: VERIFICATION MODEL. Bound alongside the design; never
// drives it.
//
// WHAT IT MODELS. The invariants relating the protocol state, the
// configuration register, and the ENDPOINT ENABLES -- the third of which
// lives in a different block, which is what makes this chapter's checking
// harder than Chapter 8.4's.
//
// WHAT IT DOES NOT MODEL. Endpoint behaviour (Module 9 owns it -- the
// enable arrives here as one abstract bit), transfers (Modules 11-13),
// descriptors (Module 7), the commit decision (Chapter 6.5), or firmware
// timing (section 5 explains why firmware needs a different kind of
// invariant, and this checker deliberately does not attempt it).
//
// ON THE ENABLE INPUT. `eps_enabled` must be sampled from the ENDPOINT
// BLOCK, not from the state machine's derived output. A checker fed the
// state machine's own derivation is checking that a signal equals itself.
// ─────────────────────────────────────────────────────────────────────────
module usb_config_composition_check
import usb_state_pkg::*;
(
input logic clk,
input logic rst_n,
input usb_dev_state_e dev_state,
input logic [7:0] active_config,
// From the ENDPOINT BLOCK -- see the note above.
input logic eps_enabled,
input logic bus_reset,
input logic config_commit,
input logic phys_connected,
input logic phys_powered,
output logic config_error
);
logic c1, c2, c3, c4;
usb_dev_state_e p_state, ds_v;
logic [7:0] p_config;
logic p_enabled, p_reset, p_commit;
always @* ds_v = dev_state;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
p_state <= DEV_NOTATTACHED;
p_config <= USB_NO_CONFIG;
p_enabled <= 1'b0;
p_reset <= 1'b0;
p_commit <= 1'b0;
end else begin
p_state <= dev_state;
p_config <= active_config;
p_enabled <= eps_enabled;
p_reset <= bus_reset;
p_commit <= config_commit;
end
end
// ── C1: Configured means actually holding a configuration ──────────────
assign c1 = (dev_state == DEV_CONFIGURED) && (active_config == USB_NO_CONFIG);
// ── C2: the other direction -- holding a configuration means Configured.
// Chapter 8.4 section 5 measured a set that had only one direction of an
// invariant letting two mutations through; this is that lesson applied
// before rather than after.
assign c2 = (active_config != USB_NO_CONFIG) && (dev_state != DEV_CONFIGURED);
// ── C3: THE ONE THIS CHAPTER IS ABOUT. Endpoints operate exactly when
// the device is Configured. Written as an equality rather than two
// implications, deliberately: enabled-without-Configured and
// Configured-without-enabled are both defects, and an equality is the
// only form that forbids both without needing two properties.
assign c3 = (eps_enabled != (dev_state == DEV_CONFIGURED));
// ── C4: a bus reset takes everything down TOGETHER. The conjunction is
// the requirement (Chapter 8.4's I4, extended by one term).
assign c4 = p_reset && phys_connected && phys_powered
&& !((dev_state == DEV_DEFAULT)
&& (active_config == USB_NO_CONFIG)
&& !eps_enabled);
// ── There is deliberately NO provenance invariant here, although Chapter
// 8.4's I3 is exactly that for the address register. Section 7 explains
// why: the enable is a single bit fully determined by the state, so C3's
// equality already constrains it completely and a provenance check adds
// nothing but a near-vacuous exclusion list.
assign config_error = c1 | c2 | c3 | c4;
always_ff @(posedge clk) begin
if (rst_n) begin
if (c1) $error("C1: CONFIGURED with no configuration selected");
if (c2) $error("C2: configuration %0d held while in state %0s",
active_config, ds_v.name());
if (c3) $error("C3: endpoints %0s while state is %0s",
eps_enabled ? "ENABLED" : "disabled", ds_v.name());
if (c4) $error("C4: after reset state=%0s config=%0d eps=%0b",
ds_v.name(), active_config, eps_enabled);
end
end
endmoduleClassification. Verification model.
What it models. Four invariants relating state, configuration and endpoint enables.
Why it exists. Because the third claim lives in another block, so no property inside either block can relate them.
Inputs. State, configuration register, the endpoint block's own enable, and the events permitted to change any of them.
State retained. One cycle of history, for the two change-based invariants.
Outputs. An error flag and per-invariant reporting.
Reset behaviour. History clears; reporting suppressed during local reset.
Hardware implied. None.
Assumptions. That eps_enabled is sampled from the endpoint block — the header is emphatic because a checker fed the state machine's derived output verifies nothing; and that firmware is deliberately out of scope, per §5.
Deliberately omits. Endpoint behaviour, transfers, descriptors, the commit decision, and firmware timing.
What DV should verify with it. That each invariant fires on its specific defect — §7 measures exactly that.
Two decisions carry the teaching:
- C3 is an equality, not an implication. Enabled without Configured and Configured without enabled are both defects, and an equality forbids both in one property. Two implications would do the same job and give a reader two chances to write only one — which is Chapter 8.4 §5's measured hole, avoided by construction.
- C2 exists before a mutation demanded it. §7 does not measure a defect that only C2 catches. It is there because Chapter 8.4 §5 measured a one-directional set letting two mutations through, and applying that lesson before being forced to is the point of having learned it.
And one invariant was removed rather than added. §7 explains why a provenance check belongs in Chapter 8.4's checker and not in this one — the difference being whether the state determines the value.
7. Mutation Test
Five configurations measured, and one of them removed an invariant from §6.
design / mutation C1 C2 C3 C4
─────────────────────────────────────────────────────────────────
derived enable (correct) · · · ·
stored enable, all four clearing paths · · · ·
G1 stored, un-select clearing missing · · 3 ·
G2 stored, physical-loss clearing missing · · 7 ·
G3 configuration register forced to zero 17 · · ·
G4 stored, spurious change to the enable · · 6 ·The second row matters as much as the others. A stored enable with all four clearing paths present is measured clean — §3's honesty made concrete. Storing is not wrong; storing incompletely is.
G1 — store the enable, forget to clear it on un-select
Result. C3 fires from the un-select onward. The device reports Address, holds no configuration, and its endpoints are still running.
And the consequence is worse than a reporting error. The host un-configured the device precisely because it wants the endpoints to stop — releasing bandwidth, entering a low-power mode, handing the device to another driver. Endpoints that keep operating are consuming resources the host has already reallocated.
G2 — store the enable, forget to clear it on physical loss
Result. C3 fires on disconnection, and for longer than G1 — the state drops to not-attached while the enable stays high.
Why this is the one most likely to survive review. Un-select is a protocol event that appears in the state diagram. Disconnection is not — it arrives from outside the protocol, and a designer enumerating "the transitions that leave Configured" by reading the state machine will list the un-select and the bus reset and stop.
G3 — clear the configuration register without leaving Configured
Result. C1 fires, and C3 does not — the enable follows the state, which did not change.
That is worth noticing rather than passing over. A naive check of the form enabled implies a non-zero configuration would have caught this and the derived architecture does not, because the derived enable is insensitive to the configuration register by construction. The derived architecture is not uniformly stronger; it is stronger against forgotten transitions and blind to a corrupted register, which is precisely why C1 exists.
G4 — a spurious change to a stored enable
Result. C3 fires. The provenance invariant did not — and investigating why removed it from §6.
8. Verification
This chapter's commit point is the device is usable — and usable is a claim about hardware outside the state machine.
Stimulus. Configuration selection and re-selection; un-select from Configured; bus reset from Configured; power loss and disconnection from Configured; a configuration commit in states where it is illegal; and re-configuration after each way of leaving.
The stimulus requirement §7 makes non-negotiable: exercise every exit from Configured, not just the protocol ones. G2 is invisible without a disconnection from Configured, and disconnection is the exit that does not appear in the state diagram.
Observation. The state, the configuration register, and the endpoint block's own enable — the last sampled from the endpoint block, per §6's header.
Reference model. Three fields compared as a set: expected state, expected configuration, expected enable. Comparing them separately reports G3 as two passes and one unrelated failure.
Representative coverage — crosses:
- exits from Configured: un-select × bus reset × power loss × disconnection — all four
- configuration value: zero × non-zero × a value the device does not offer
- state × endpoint-enable, both polarities, for every state
- re-configuration after each of the four exits
- configuration commit attempted in Default and Powered
Negative cases with defined outcomes: endpoints must not operate in any state but Configured; an un-select must take the enable down in the same cycle it changes the state; a disconnection must clear everything; and a configuration commit outside Address or Configured must change nothing.
9. Debugging: the Device That Keeps Transmitting
A host un-configures a device to release bandwidth for another device. The bandwidth is not released, and the second device fails to start. The first device's status register reports the Address state.
What is the contradiction? An Address-state device has no operating function endpoints. Something is still using bandwidth.
Which evidence wins? The bandwidth. The status register is the device's claim; the bus is the observation. This is Chapter 8.4 §2's rule again, one layer out: the enable that reaches the endpoint hardware is the fact.
So what do you inspect? The endpoint block's enable, not the state machine's. If the two differ, the enable is stored rather than derived and a clearing path was missed.
Which path? Trace how the device left Configured. §7's G1 misses the un-select; G2 misses disconnection. Here the exit was an un-select, so G1.
Why did no state-machine test catch it? Because the state machine is correct and its test observed the state machine. The enable is in another block, and the endpoint block's own tests exercise endpoints — with the enable asserted, because that is how endpoints are tested.
And the signature? A device that reports a state it is not behaving as is Chapter 8.4's signature, and here it points one block further out. The rule generalises: when a device's report and its behaviour disagree, find the holder of the fact that produces the behaviour, and ask what is supposed to update it.
10. Common Misconceptions
11. Reason It Through
A controller runs its endpoint logic in a different clock domain from its protocol state machine. A reviewer objects that the endpoint enable therefore cannot be derived, and that §3's argument does not apply.
Is the reviewer right about the constraint? Yes. A combinational function of a register in another clock domain cannot be consumed directly; it has to be synchronised, which means registering it, which makes it state.
So does §3's argument fail? No — it relocates. The enable is now stored in the endpoint domain, and the four clearing obligations still exist. They have simply moved from remembering to clear a register to making sure four different events all propagate across the domain crossing.
Which is harder or easier? Harder in one way and easier in another. Harder because a crossing can drop or reorder events, and a disconnection is exactly the kind of event that arrives asynchronously. Easier because the obligation is now visible: a crossing is a thing a reviewer looks at, whereas a missing branch in a case is not.
What is the design that discharges it? Synchronise the state, not the events. If the endpoint domain receives the protocol state — or a single bit derived from it — through a synchroniser, then the enable is still derived, just from a synchronised copy. All four exits change the state, so all four propagate automatically, and no event can be missed because no event is being counted.
And the general principle? Synchronise facts, not events. A fact that crosses a domain carries its own consistency; an event that crosses a domain has to be counted, acknowledged, and reasoned about individually. Where a choice exists, crossing the state is safer than crossing the transitions — and it preserves the derived architecture rather than forcing a stored one.
12. Understanding Check
13. Summary
Configured is the first state whose consequences leave the state machine. Address affects one register; Configured brings hardware to life that the state machine does not contain. It claims three things — an address, a configuration, and operating endpoints — and the third is held somewhere else.
That makes the central design decision derived or stored. A derived enable is a function of the state and cannot disagree with it; a stored enable is its own state and creates one maintenance obligation per exit. Configured has four exits — un-select, bus reset, power loss, disconnection — of which only two appear in the state diagram, and §7 measured the disconnection case as the one most likely to survive review for exactly that reason.
Storing is not wrong, and §3 is honest about why real designs do it: timing paths, clock domains, and fan-out. What storing costs is a structural guarantee converted into a maintenance obligation, and the right response is to write the obligations down and let a cross-block checker enforce them — with §11's better answer available when a domain crossing is the reason: synchronise the state, not the transitions, and the enable stays derived.
Four holders can disagree: the state machine, the configuration register, the endpoint block and firmware. Each is updated by its own events, each can be locally correct, and nothing in the design is responsible for their agreement unless somebody is told to be.
Firmware is the one permitted exception, because it learns through status and interrupts and therefore learns late. The achievable requirement is not agreement but reliable notification — which forces transitions that matter to be sticky rather than polled levels, and forces a bus-reset event register to survive the reset it reports.
14. What Comes Next
Five states, one state machine, and a set of invariants that hold across blocks. The model is complete.
Except that it is not, because one state remains — and it does not fit.
Chapter 8.6 is Suspended, and it breaks the assumption every chapter so far has relied on: that a state is defined by what is true and not by how you got there. A suspended device must remember which state it was suspended from, because resuming returns it there. Suspend is not a sixth peer state at all; it is a modifier on the other five, and implementations that model it as a peer discover the problem at the moment of resume — when the device has to go back somewhere and no longer knows where.
Browse the full path on the USB tutorials index.
Continue learning
Related tutorials
- 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
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.
- Related topic
Powered State
The only state in which a device acts on its own initiative: when to present the pull-up, why a self-powered device must watch bus power to avoid back-powering a bus, and why Powered cannot become Default alone.
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.
