Skip to content
VLSI Mentor

USB · Module 10

Interrupt Transfers

Nothing interrupts anything — the host polls. What the endpoint really buys is a bound on the gap between questions, and the device owes a sticky flag whose collision rule decides whether events survive.

Chapter 10.3 was a type promised nothing. This one is promised something very specific, and the specific thing is not bandwidth.

It is also the type with the most misleading name in the entire protocol, so the chapter begins by taking the name apart.

1. Nothing Interrupts Anything

A USB device cannot interrupt the host. There is no mechanism by which it could.

Chapter 10.1 §1 established the bootstrap fact the whole protocol rests on: the host initiates every transaction. A device transmits when it is asked to and at no other time. Nothing about an interrupt endpoint changes that — it is not a back channel, not a signalling line, and not an exception to host control.

So what does the name refer to? The use case. An interrupt endpoint is how you build the thing an interrupt line would have given you on a parallel bus — a mouse movement reaching software promptly — and the name records the intent rather than the mechanism.

The mechanism is polling. The host asks, repeatedly, on a schedule. The Linux kernel is blunt about it in the comment on usb_fill_int_urb, which describes the interval as saying how often to poll for transfers.

2. What an Interrupt Endpoint Actually Buys

Not bandwidth. Not priority. A bound on the gap between questions.

An interrupt endpoint's descriptor declares a service intervalChapter 7.4's bInterval — and in exchange for a reservation the host undertakes not to let more than that interval pass without asking.

Which makes the guarantee one about opportunity, not about data. The host promises to ask. It promises nothing about whether there will be an answer, because whether there is an answer is the device's business.

And that is exactly why a mouse needs a reservation despite producing almost no data. Chapter 10.3 §2's grid places Interrupt in the low-throughput-with-guarantee cell, and the mouse is the reason the cell exists: a few bytes, but they must arrive soon, and soon is a latency property that no amount of bandwidth supplies.

The worst-case latency a device engineer should quote is therefore approximately one service interval plus whatever the device itself takes to have the answer ready — and §5 is about that second term, which is the only one the device controls.

3. The Interval Is a Ceiling, Not a Period

A distinction that changes how you write the device side.

bInterval is an upper bound on the gap between service opportunities, not a promise of exactly that gap. The kernel states it directly in the documentation for the URB interval field: “The polling interval may be more frequent than requested.”

Three consequences, all of which show up in real firmware:

  • A device may be asked sooner than it expects, and must have a defined answer — including nothing new — at every opportunity rather than only at the ones it anticipated.
  • A device may be asked far more often than it produces data, so nothing to report is the common case, not an error, and must be cheap.
  • Nothing accumulates on the host's behalf. The host is not counting how many opportunities it used; the device cannot infer from the poll rate anything about how its data is being consumed.

4. The Device's Side of the Bargain

The host promises to ask. What does the device promise?

That an answer exists whenever it is asked. Not that the answer is interesting — that there is one, immediately, without the host waiting.

There are exactly two answers, and both are normal:

  • Data — something has happened since the last report.
  • Nothing new — nothing has happened. This is not an error, it is not a failure, and on a typical interrupt endpoint it is the overwhelming majority of responses.

Which means the device needs one thing: a record of whether something has happened that has not yet been reported. That record is a flag, and the flag is where the design gets interesting, because two things touch it from different directions:

  • the device side sets it when the event occurs, on the device's own timing;
  • the host side clears it when a report is collected, on the host's timing.

Those two timings are unrelated, so they will eventually coincide. What the design does in the cycle where they coincide decides whether events survive — and that decision is the subject of §5 and the whole of §6.

A sequence diagram of six service opportunities on an interrupt endpoint. In the first opportunity the host asks and the device answers that it has nothing new. In the second the host asks again and again gets nothing new. Between the second and third, a device-side event occurs and sets the pending flag. In the third opportunity the host asks and the device delivers the report, clearing the flag. In the fourth the host asks and gets nothing new. Before the fifth, two events occur in quick succession, and the second sets a coalesced indication because the first has not yet been reported. In the fifth opportunity a single report is delivered covering both events, and in the same instant a further event occurs; because set takes precedence over clear, the flag remains asserted. In the sixth opportunity that final event is delivered its own report. An annotation notes that the device never initiates anything in this diagram.Polling, with the device answeringHostInterrupt endpointDevice logicopportunity 1 —anything?nothing newopportunity 2 —anything?nothing newevent — pending := 1opportunity 3 —anything?report · pending :=0opportunity 4 —anything?nothing newevent, then a secondbefore any pollcoalesced := 1 — onereport will covertwoopportunity 5 —anything?…and an event landsin the same instantreport · SET WINS ·pending stays 1opportunity 6 —anything?report — thecollided eventsurvivedthe device initiatednothing here
Figure 1 — six consecutive service opportunities on an interrupt endpoint. Most of them return nothing, which is the normal case rather than a fault. Note the fifth opportunity: an event occurs in the same instant the report is taken, and whether that event survives is decided by one line of RTL.

5. The Pending Flag, as RTL

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// usb_intr_pending
//
// Classification: SIMPLIFIED SYNTHESIZABLE TEACHING RTL. It models section
// 4's record -- has something happened that has not yet been reported? --
// and the collision rule that decides whether events survive.
//
// WHAT IT MODELS. A sticky event flag with two writers on unrelated
// timebases, and a second flag that makes COALESCING visible rather than
// silent.
//
// WHAT IT DOES NOT MODEL. The payload (this block says THAT something
// happened, never WHAT); the transaction that carries the report (Module
// 12); the handshake by which "nothing new" is expressed on the wire
// (Module 12 -- on a real bus it is a NAK); the service schedule that
// decides WHEN `collected` pulses (the host's, and Chapter 10.3's arbiter
// is the nearest model of it); and bInterval itself, which is a
// configuration-time number this block never sees.
//
// ── THE COLLISION RULE, AND WHY IT IS THIS WAY ──────────────────────────
// `event_set` and `collected` come from unrelated timebases (section 4), so
// they WILL coincide. The rule here is SET WINS:
//
//   the collected report carried the state as of the moment it was taken;
//   an event arriving in that same cycle is NOT in that report, so the flag
//   must remain asserted for it.
//
// The alternative -- clear wins -- silently destroys that event. The
// asymmetry is the whole argument: an event reported twice is recoverable
// by anything idempotent downstream, and an event reported zero times is
// recoverable by nothing. Section 6 measures the cost.
// ─────────────────────────────────────────────────────────────────────────
module usb_intr_pending (
  input  logic clk,
  input  logic rst_n,

  // Chapter 8.3: a bus reset abandons what was in flight. An event that was
  // never reported does not survive one.
  input  logic bus_reset,

  // Chapter 9.3: an endpoint that is not enabled by the active configuration
  // has nothing to report and no one to report it to.
  input  logic ep_enabled,

  // The device-side condition became true. Device timing -- unrelated to
  // anything the host is doing.
  input  logic event_set,

  // A report was taken. Host timing.
  input  logic collected,

  output logic pending,     // there is something to report
  output logic coalesced    // at least one report stood for more than one event
);

  logic pending_q, coalesced_q;
  assign pending   = pending_q;
  assign coalesced = coalesced_q;

  // An event only counts while the endpoint is enabled.
  logic accept_event;
  assign accept_event = event_set && ep_enabled;

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      pending_q   <= 1'b0;
      coalesced_q <= 1'b0;
    end else if (bus_reset || !ep_enabled) begin
      // Both conditions mean the same thing here: there is no longer an
      // agreement under which this report would be meaningful.
      pending_q   <= 1'b0;
      coalesced_q <= 1'b0;
    end else begin
      // SET WINS -- this ordering is the whole contract. See the header.
      if      (accept_event) pending_q <= 1'b1;
      else if (collected)    pending_q <= 1'b0;

      // COALESCING MADE VISIBLE. A new event arriving while the previous one
      // is still uncollected means one report will stand for two events.
      // Without this flag, that merge is completely silent -- and section 6
      // measures that no functional check notices its absence.
      if (accept_event && pending_q && !collected) coalesced_q <= 1'b1;
    end
  end

endmodule

What it models. Whether an unreported event exists, and whether any report has stood for more than one event.

Engineering reason. Because §4's two writers are on unrelated timebases, and the cycle in which they coincide is where events are silently destroyed.

Inputs. Clock and reset; bus reset; the endpoint's enable; the device-side event; the host-side collection.

State retained. Two flip-flops — one for pending, one for coalesced.

Outputs. The two flags, both registered.

Hardware implied. Two flip-flops with a small amount of set/clear priority logic. Nothing else.

Reset behaviour. Both flags clear on hard reset, on bus reset, and whenever the endpoint is not enabled. An event that was never reported does not survive any of the three.

Assumptions. That event_set is already synchronised into this clock domain — crossing that boundary is not modelled here and is a real design obligation; that collected pulses for exactly one cycle per report taken; and that a report taken while pending is low carries nothing new rather than stale data.

Omissions. The payload, the transaction, the wire-level handshake, the schedule and bInterval — all listed in the header, because a block called pending invites being read as the whole endpoint.

What DV should verify. That an event is never lost while the endpoint stays enabled with no bus reset; that pending survives a same-cycle collision; that a collection with nothing pending reports nothing; that events while disabled do not accumulate; that a bus reset clears a pending event; and that coalesced asserts exactly when a report stands for more than one event.

Sticky pending — collision and coalescing

10 cycles
A waveform of the interrupt pending flag over ten cycles with the endpoint enabled throughout. In the first cycle a device event occurs and the pending flag sets. In the second the host collects the report and the flag clears. In the third the host collects again with nothing pending, so nothing is reported, which is the normal case. In the fourth and fifth cycles two events occur before any collection, and the coalesced flag sets because one report will now stand for both. In the sixth the report is collected and pending clears while coalesced remains asserted. In the seventh another event sets pending. In the eighth an event and a collection occur in the same cycle; because set takes precedence over clear, pending remains asserted afterwards rather than being destroyed. In the tenth cycle a bus reset clears both flags, abandoning that unreported event.poll, nothing to report — normalpoll, nothing to report —normalsecond event before any pollsecond event before anypollCOLLISION — set wins, pending survivesCOLLISION — set wins,pending survivesbus reset abandons it anywaybus reset abandons itanywayep_enabledevent_setcollectedpendingcoalescedbus_resett0t1t2t3t4t5t6t7t8t9
Figure 2 — ten cycles of the flag, every column taken from a simulation of the block above rather than drawn by hand. Cycle 2 is a poll with nothing to report, which is the common case. Cycles 3 and 4 are two events sharing one report. Cycle 7 is the collision, and pending is still asserted afterwards — until cycle 9's bus reset abandons it regardless. Controller-domain decoded events, not USB bus signalling; no real durations are depicted.

6. Mutation Test

Five mutations, run against the block in §5. The bench evaluates 1,024 cycles across eight stimulus phases, the last of which is a clean window — no bus reset, endpoint enabled throughout — in which an event-conservation law must hold:

events raised = reports delivered + events merged into an earlier report

Over that window the unmutated block raised 219 events, delivered 101 reports, and merged 118 — and 101 + 118 = 219 exactly. Nothing was lost.

pending vs modelcoalesced vs modelreports deliveredconservation
golden00101holds
I1 clear wins1893181FAILS
I2 level, not sticky3265164FAILS
I3 coalescing removed0791101holds
I4 reset/disable ignored35220102FAILS
I5 enable guard removed00101holds

I1 — clear wins on a collision

Swap the priority so collected beats event_set.

Measured. 81 reports where the correct design delivered 101 — 20 of 219 events reached the host through no report at all. Conservation fails, and pending diverges from the model on 189 cycles.

And the events lost are not random. They are precisely the ones that arrived in the same cycle a report was taken — which is to say, the ones that arrived while the endpoint was busiest. The failure rate scales with the event rate, which is the worst possible property for a bug: it is invisible in light testing and worsens exactly where it hurts.

I2 — a level, not a sticky flag

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
pending_q <= accept_event;   // MUTANT I2: reflects the event, remembers nothing

Measured. 64 reports out of a correct 101 — 37 of 219 events lost. The worst of the five by raw count, and the easiest to write by accident.

The mechanism is the one §1's misconception produces. A flag that merely reflects the event assumes the host is watching. It is not watching; it is asking, occasionally, on a schedule unrelated to the device's events. An event is then observed only when a poll happens to land in the one cycle the level was high.

This is what the misconception costs in silicon. Write the device side as though the device controls the timing of its reports, and this is the flag you write.

I3 — remove the coalescing indication

Measured. Conservation holds. pending matches the model on every one of 1,024 cycles. Every report is delivered. No data is lost.

The only check that fires is the comparison of coalesced against a model that bothers to track coalescing.

And that is the honest reading: this is not a data-loss defect. The stream of reports is identical. What is lost is knowledge — the device can no longer tell the difference between one thing happened and several things happened and you are seeing the last of them.

Whether that matters is a specification question, not an RTL question. If reports carry current state, coalescing is harmless and the flag is genuinely optional. If reports carry events — keystrokes, counts, edges — then a merged report is a lost keystroke, and the flag is the only thing that would ever tell you.

§8 is about the consequence for verification: a check can only catch what somebody decided to model.

I4 — bus reset and disable ignored

Measured. 102 reports — one more than the correct design — and conservation fails on the excess.

An extra report is not a harmless surplus. It is an event raised under one agreement being delivered under a different one: the host reset the bus, rebuilt its understanding of the device from scratch (Chapter 8.3), and then received a report describing something that happened before all of that. The report is not wrong about the past; it is unrelated to the present.

I5 — remove the enable guard

Let event_set be accepted regardless of ep_enabled.

Measured: nothing. Zero divergences on both flags, conservation holds, report count unchanged. It survives every check in the bench.

And it survives because it is genuinely unobservable, not merely unobserved — which §7 takes apart, because the reason is more useful than the result.

7. The Assertions

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// Classification: TEACHING ASSERTIONS about the pending flag.
// N-properties are the NEGATIVE space -- what must never happen. C is the
// COLLISION contract. K is the coalescing contract.
// ─────────────────────────────────────────────────────────────────────────

// N1 -- AN EVENT IS NEVER LOST. If an event is accepted, pending is asserted
// on the next cycle, whatever else is happening. This is the property that
// catches section 6's I1 and I2, and it is stated over the NEXT cycle rather
// than as an eventuality because the flag is registered and the obligation
// is immediate.
property p_event_never_lost;
  @(posedge clk) disable iff (!rst_n)
    (event_set && ep_enabled && !bus_reset) |=> pending;
endproperty
assert property (p_event_never_lost);

// C1 -- SET WINS. The collision contract, stated on its own so that a
// failure names the rule rather than a symptom. Note this is a SPECIAL CASE
// of N1: N1 already covers it. It is written separately anyway, because a
// failing assertion is a diagnostic message, and "the collision rule broke"
// is a far better message than "an event was lost".
property p_set_beats_clear;
  @(posedge clk) disable iff (!rst_n)
    (event_set && collected && ep_enabled && !bus_reset) |=> pending;
endproperty
assert property (p_set_beats_clear);

// N2 -- NO SPONTANEOUS PENDING. pending only rises because of an accepted
// event. Catches a flag that asserts itself for any other reason.
property p_no_spontaneous_pending;
  @(posedge clk) disable iff (!rst_n)
    ($rose(pending)) |-> $past(event_set && ep_enabled);
endproperty
assert property (p_no_spontaneous_pending);

// N3 -- A DISABLED OR RESET ENDPOINT HAS NOTHING PENDING. Catches section
// 6's I4.
property p_reset_clears;
  @(posedge clk) disable iff (!rst_n)
    (bus_reset || !ep_enabled) |=> (!pending && !coalesced);
endproperty
assert property (p_reset_clears);

// N4 -- CLEARING HAS A CAUSE. pending only falls because a report was taken,
// or because the agreement went away. Without the last two terms this
// property would be FALSE on the golden design, which is the kind of
// over-tight property that gets weakened under pressure until it means
// nothing -- so the exclusions are written once, deliberately, and justified.
property p_clear_has_a_cause;
  @(posedge clk) disable iff (!rst_n)
    ($fell(pending)) |-> $past(collected || bus_reset || !ep_enabled);
endproperty
assert property (p_clear_has_a_cause);

// K1 -- COALESCING IS REPORTED. If a second event arrives while the first is
// still uncollected, the coalesced flag asserts. The ONLY property that
// catches section 6's I3 -- and it exists only because somebody decided
// coalescing was worth modelling.
property p_coalescing_visible;
  @(posedge clk) disable iff (!rst_n)
    (event_set && ep_enabled && pending && !collected && !bus_reset) |=> coalesced;
endproperty
assert property (p_coalescing_visible);

// K2 -- COALESCED IS STICKY WITHIN AN AGREEMENT. It is a "this happened at
// least once" flag, not a per-report status, so it must not clear on a
// collection.
property p_coalesced_sticky;
  @(posedge clk) disable iff (!rst_n)
    (coalesced && !bus_reset && ep_enabled) |=> coalesced;
endproperty
assert property (p_coalesced_sticky);

Two things about this set are worth extracting.

C1 is deliberately redundant with N1, and it earns its place on diagnostic grounds alone: both fire on §6's I1, but only one of them tells you which rule broke. A property set optimised for minimality is optimised for the wrong thing — it will be read by somebody at 2am looking at a failure, and the message is the product.

N4's exclusion list is the kind that goes wrong. Chapter 8.5 §6 removed an invariant whose exclusions had grown to excuse every case it was meant to catch. This one is bounded and justified: pending may fall for exactly three reasons, all three are in the antecedent, and there is no fourth. The test for whether an exclusion list is honest is whether you can enumerate it and stop — if you cannot, the property has become a description of the implementation rather than a constraint on it.

8. Verification

This chapter's commit point is the device had an answer, and the right one, at every opportunity.

Stimulus. An event then a poll; a poll with nothing pending; two events before any poll; an event and a collection in the same cycle, with a report actually pending — the case §6's I1 needs and the one a directed test omits because it reads like an unlikely coincidence; events while disabled; a bus reset over a pending event; and a long randomised phase.

And one stimulus property matters more than the list. Because §6's I1 fails only on the collision cycle, its detection probability is proportional to how often the bench creates one. The randomised phase in the bench drives event_set and collected independently at roughly one-in-three and one-in-four, which produces collisions constantly. Directed stimulus that advances one event at a time, politely, produces none of them — and would have passed I1 completely.

Observation. Both flags every cycle, plus the count of reports delivered. §6's I4 changes the report count by exactly one across 1,024 cycles; nothing but a count would have noticed.

Reference model. A four-line next-state function written from §4's rules. And the conservation law is the more valuable check of the two, because it is not a restatement of the model:

events raised = reports delivered + events merged into an earlier report

That law is an accounting identity over the whole run. It does not know how the design works, and it caught I1, I2 and I4 without referring to any internal signal.

Coverage — crosses:

  • event_set × collected × pendingall eight combinations, the collision cell included
  • ep_enabled × event_set × pending
  • bus_reset × pending × coalesced
  • coalesced × a subsequent collection — confirming it does not clear
  • back-to-back events at every spacing from zero to the poll interval

Negative cases with defined outcomes: an accepted event never fails to raise pending; pending never rises without one; nothing is pending while disabled or reset; and a collection with nothing pending delivers nothing rather than repeating the last report.

9. Debugging: the Device That Misses Events Only When Busy

A HID device reports correctly under light use. Under rapid input some events never reach software. No error is reported, the device does not stall, and the loss rate rises with the input rate.

What does rises with the input rate tell you? That the failure depends on coincidence, not on volume. Something goes wrong when two things happen close together, and rapid input simply makes that more frequent. That single observation eliminates most candidate causes.

Which coincidence? The one §4 identified: an event on the device's timing landing in the same window as a collection on the host's. Look at the collision rule before anything else.

What would a protocol analyser show? Correct traffic. Well-formed reports, at the right interval, carrying valid data. The missing events were never transmitted, so they are not absent from the trace — they were never in it. This is a device-side defect that a bus trace is almost entirely blind to.

How do you distinguish a lost event from a coalesced one? By whether the count of reports matches the count of events. And on a design without §5's coalesced flag, you generally cannot — which is §6's I3 arriving as a debugging cost rather than as a verification finding. The flag pays for itself the first time this question is asked.

What if the loss rate is high even under light use? Then it is not a collision — it is §6's I2, a flag that does not stick, and the loss is governed by the poll rate rather than the event rate. The two defects are distinguished by what the loss rate scales with, which is why measuring it is the first thing to do rather than the last.

The signature to keep: a loss rate that scales with the event rate is a collision; one that scales with the poll interval is a missing sticky.

10. Common Misconceptions

11. Reason It Through

A device declares an interrupt endpoint with a 10 ms interval. Its firmware reports at most one event per report. A user complains that fast double-clicks are sometimes registered as single clicks.

Is this a bus problem? No. The bus delivered every report it was given, on schedule. The reports are correct and the analyser will show them as such.

So where did the second click go? Into a report that had already been written and not yet collected. Two events arrived inside one 10 ms window, and the device's record of something happened could only hold one of them.

Is that a defect? It depends entirely on what the report means, which is §6's I3 arriving as a product question:

  • If the report carries current statethe button is down — coalescing is harmless and correct. The last state is the true state.
  • If the report carries an eventthe button was pressed — then merging two presses into one destroys one of them, and the design is wrong.

And this device carries events, because a double-click is two presses and one press is not the same thing.

What are the fixes, and what does each cost?

  • Shorten the interval. Narrows the window without closing it. Costs a larger reservation, which Chapter 10.3 §11 established is taken from everybody else on the bus whether used or not.
  • Report state instead of events. Makes coalescing correct by construction, at the cost of requiring the host to infer transitions — and it will miss any pair of transitions faster than the interval, which is the same problem wearing different clothes.
  • Queue events in the device and drain one per report. Actually solves it, up to the queue depth, and converts an unbounded silent loss into a bounded, detectable overflow.
  • Count events and report the count. Solves it with one counter instead of a queue, at the cost of losing ordering and per-event detail.

And the point the four options share: every one of them moves the loss rather than eliminating it — into bandwidth, into inference, into queue depth, into detail. A finite device observing an unbounded event rate will lose something. The engineering decision is what it loses and whether it can tell — and §5's coalesced flag is the minimum version of the second half of that sentence.

12. Understanding Check

13. Summary

The name is the misconception. Nothing interrupts anything: the host initiates every transaction, and an interrupt endpoint is polled. Substitute “the host asks often enough that the device never waits long to be heard” and every consequence follows correctly.

What the endpoint buys is a bound on the gap between questions — a guarantee about opportunity, not about data, which is why a mouse producing a handful of bytes per second still needs a reservation. And the interval is a ceiling, not a period: the kernel says the polling interval may be more frequent than requested, and its encoding differs by speed — linear 1 ms frames at full and low speed, logarithmic 125 µs microframes at high speed and above, computed as 1 << (bInterval - 1). The same byte, two meanings, failing silently when they are confused.

The device's side of the bargain is that an answer always exists — data, or nothing new, and the second is the common case. Which reduces to one record: has something happened that has not yet been reported? Two writers on unrelated timebases touch that record, so they will coincide, and the cycle in which they coincide decides whether events survive.

§6 measured five mutations over 1,024 cycles against a conservation law — events raised = reports delivered + events merged, which held exactly at 219 = 101 + 118 on the unmutated block:

  • Clear winning the collision destroyed 20 of 219 events, and destroyed precisely the ones arriving while the endpoint was busiest — a failure rate that scales with the event rate.
  • A level instead of a sticky flag lost 37 of 219, which is what §1's misconception costs when it reaches silicon: it assumes the host is watching, and the host is only asking.
  • Removing the coalescing flag lost no data at all and was caught by exactly one check. Whether it is a defect depends on what a report means — state, or events.
  • Ignoring bus reset delivered one report too many, an event raised under one agreement arriving under another.
  • Removing the enable guard survived everything — and was shown to be covered rather than dead, going from 0 divergences to 7 the moment the clause dominating it was removed.

Two lessons generalise past this block. First: a bench catches what somebody decided to model, so the useful question is what you chose not to model and whether you would know if it broke. Second: “redundant” describes the current code, not the design — a covered guard costs a gate and buys independence from an argument living elsewhere in the file.

14. What Comes Next

Interrupt buys a bound on when. The last type buys a bound on how much, and pays for it by giving up something no type has given up yet.

Chapter 10.5 is Isochronous, and it is the only transfer type with no retry. Not retry is discouraged — there is no mechanism. A corrupted isochronous packet is simply gone.

That sounds like a weakness and is a deliberate design: for a stream with a deadline, late data is worse than absent data, and a retry that arrives after its moment has passed has spent bandwidth to deliver something useless. The chapter turns on freshness, which is the axis the other three types never had to consider — and it closes the module with the service-property matrix that places all four types against one another.

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.