USB · Module 3
USB Signalling Overview
The four named conditions of the classic USB pair — J, K, SE0 and SE1 — and the receiver structure that produces them. Why a USB receiver observes the pair both differentially and single-endedly, what each observation can and cannot see, and where the analog/digital boundary actually falls.
Module 2 ended at a boundary it never crossed. Every chapter said the PHY handles signalling and moved on — Chapter 2.5 drew the line explicitly, giving the controller protocol state and the PHY electrical behaviour, and then stopped at the interface between them.
Module 3 is what is on the other side of that line.
The question it answers is the one Module 2 deferred: how does a decision become a voltage, and how does a voltage become an event a controller can act on? That transformation happens in stages, and the single most valuable thing this module can give you is the discipline to keep those stages apart. An engineer who can say this is a protocol intention, this is a logical line state, this is a voltage on a conductor, and this is what my RTL actually receives can debug a physical-layer problem. An engineer who has fused them into “the signals” cannot.
1. Two Conductors, Four Named Conditions
The classic USB signalling pair is two conductors, D+ and D-. Chapters 3.3 and 3.4 take each one individually; this chapter is about what the pair can be in, taken together.
At any instant the pair is in one of four named conditions. Three are normal and one is a fault.
J and K are the two signalling states. They are the conditions in which the pair is carrying information, and they are names for a relationship between the conductors, not names for a voltage on either one. That distinction is the whole of §3 and most of Chapter 3.4.
SE0 — single-ended zero — is the condition in which both conductors are in their low state simultaneously. Note immediately that this is not a value of the differential relationship at all: differentially, both-low is neither J nor K, which is exactly why it needs a separate name and why a receiver needs a separate way to see it. SE0 is used for real purposes, including marking the end of a packet and, held long enough, signalling a bus reset — Chapter 3.7 develops the duration question.
SE1 — both conductors high simultaneously — is the fourth condition, and it is illegal. Nothing in USB signalling uses it. A conforming transmitter never produces it, so observing it means something is wrong: contention between drivers, a fault in a driver, or a wiring problem. A receiver design that treats SE1 as merely another code is throwing away the most direct evidence of a hardware fault that the interface provides.
2. What the Receiver Actually Looks At
Here is the structural fact that explains everything above, and it surprises people who assume a differential interface has a differential receiver and nothing else.
A classic USB receiver observes the pair two ways at once.
The differential receiver answers one question: which conductor is higher than the other? That question has two useful answers, and they are what distinguish J from K. It is also the observation that buys the noise rejection Chapter 3.2 is about.
The single-ended receivers answer a different question, one per conductor: is this conductor above or below a threshold, measured against the local ground reference? That is what makes SE0 and SE1 observable at all — because when both conductors are low there is nothing for the differential receiver to report, and its output in that condition is not meaningful information.
This is the reason USB's line states are not simply “a differential bit.” The interface deliberately carries conditions that are outside the differential alphabet, and it therefore requires receivers that can see outside it. An engineer who models a USB receiver as a single differential comparator has built something that cannot detect the end of a packet or a bus reset.
3. The Four Conditions, Together
Line states over time — logical view
7 cyclesRead the third row carefully. During the SE0 interval the differential receiver has nothing to say — not “zero”, not a valid state, simply no meaningful output. The condition is recognised by the single-ended observations, exactly as §2 requires.
Read the fourth row as the conclusion the decoder reaches, not as something present on the wire. There is no conductor carrying “J”. J is a name for a relationship that a receiver computes.
4. Where the Digital Boundary Really Falls
A question that matters enormously for RTL engineers and is almost always answered wrongly in tutorials: does controller logic sample D+ and D- directly?
Generally, no. In a typical implementation the analog receiving is done in the PHY, and what crosses into the digital controller domain is a already-decoded line-state indication plus other status — commonly a small encoded bus reporting which of the conditions is present, alongside the received data path.
That has three consequences worth fixing now, because the rest of Module 3 depends on them.
Thresholds are not an RTL concern. Deciding whether a conductor is above or below a threshold is an analog comparison. RTL does not do it and should not model it. Code that compares a “voltage” variable against a number is describing something that does not happen in the digital domain.
The decoder in §2 usually lives on the PHY side of the boundary. The teaching model below is therefore a model of PHY-side behaviour. It is written to make the four conditions inspectable, not because controller RTL performs this decode.
And the line-state indication crosses a clock-domain boundary. The PHY's timing derives from signalling; the controller runs on its own clock. Any indication passing between them needs the treatment Chapter 1.5 established — with an important refinement §7 returns to, because a multi-bit encoded value is not safe to synchronise bit by bit.
5. The Decode, as a Teaching Model
// ─────────────────────────────────────────────────────────────────────────
// line_state_decode
//
// Classification: CONCEPTUAL RTL — a model of PHY-SIDE decode behaviour.
// Synthesizable as written, but in a typical implementation this decision
// is made inside the PHY and the CONTROLLER receives the result. Do not
// read this as controller logic sampling the wires.
//
// WHAT IT MODELS. How the three receiver observations of section 2 combine
// into one named condition, and why an illegal condition deserves its own
// output rather than being folded into a "don't care".
//
// WHAT IT DOES NOT MODEL. Anything analog: thresholds, hysteresis,
// comparator delay, rise and fall times, noise, or signal integrity. The
// inputs here are the DIGITAL OUTPUTS of receivers that have already made
// those decisions. It also models no encoding, no packet structure, and no
// clock recovery.
//
// AND IT ASSUMES FULL SPEED. The J/K naming below is the full-speed
// convention; at low speed the mapping inverts. Chapter 3.4 generalises
// this block. Using it unmodified on a low-speed port reports J and K
// exactly backwards.
// ─────────────────────────────────────────────────────────────────────────
package usb_ls_pkg;
typedef enum logic [1:0] {
LS_SE0 = 2'b00, // both conductors low -- legal, and meaningful
LS_J = 2'b01, // signalling state -- polarity depends on SPEED (3.4)
LS_K = 2'b10, // the other signalling state
LS_SE1 = 2'b11 // both conductors high -- ILLEGAL, never transmitted
} line_state_e;
endpackage
module line_state_decode
import usb_ls_pkg::*;
(
input logic clk,
input logic rst_n,
// Digital outputs of the receivers in Figure 1. These have ALREADY been
// through analog comparison; nothing below is an analog decision.
input logic se_dp, // single-ended: D+ above threshold
input logic se_dm, // single-ended: D- above threshold
input logic diff_dp_hi, // differential: D+ is the higher conductor
output line_state_e line_state,
output logic illegal_se1 // sticky-free flag: SE1 observed this cycle
);
line_state_e ls_c;
always_comb begin
// Default assignment first, so every path is covered and no latch can
// be inferred from a missed branch.
ls_c = LS_SE0;
unique case ({se_dp, se_dm})
2'b00: ls_c = LS_SE0; // both low
2'b11: ls_c = LS_SE1; // both high -- illegal
// Exactly one conductor high: the pair is signalling, and WHICH
// signalling state it is comes from the differential receiver rather
// than from either single-ended output.
//
// ASSUMPTION MADE EXPLICIT: naming "D+ higher" as J is the FULL-SPEED
// convention. It is written that way here because this chapter has not
// yet introduced speed, and Chapter 3.4 shows the mapping INVERTS at
// low speed and generalises this block accordingly. Left unstated, this
// line is the single most common latent bug in a hand-written USB
// line-state decoder.
default: begin
if (diff_dp_hi) ls_c = LS_J; // full-speed convention -- see 3.4
else ls_c = LS_K;
end
endcase
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
line_state <= LS_SE0; // the bus idles at SE0 with nothing attached
illegal_se1 <= 1'b0; // -- see Chapter 3.6
end else begin
line_state <= ls_c;
illegal_se1 <= (ls_c == LS_SE1);
end
end
endmoduleWhat it models. The combination of §2's three observations into one reported condition.
Why the structure exists. The case is on the single-ended pair, because that is what distinguishes the four conditions — both-low and both-high are exactly the cases a differential receiver cannot report. Only in the one-high-one-low case is the differential output consulted, and it is consulted rather than inferred from se_dp because the J/K polarity assignment is speed-dependent, which Chapter 3.4 makes concrete. illegal_se1 is a separate output because an illegal condition is evidence of a hardware fault and folding it into a default discards that evidence.
Hardware implied. A small combinational decode and two flops of registered output. Nothing more.
State retained. Only the registered output. There is deliberately no history here — Chapter 3.7 adds the duration qualification that turns a condition into an event, and keeping that out of this block is what keeps each concept separable.
Inputs assumed. Already-thresholded digital receiver outputs, already in this clock domain. If they are not, see §7.
Reset value. LS_SE0, because a downstream port with nothing attached genuinely sits at SE0 — Chapter 3.6 explains why. Resetting to LS_J would manufacture a false idle and make reset release look like a bus event.
What DV should verify. That all four conditions are reachable; that LS_SE1 is reported rather than absorbed; that the differential input is what selects between J and K, so a change of polarity convention does not silently break the decode; and that reset yields SE0.
What it deliberately omits. Everything analog, all duration qualification, all encoding and all packet structure — and, importantly, it assumes full speed. The J/K naming above is the full-speed convention, and Chapter 3.4 shows why a decoder that hard-codes it is correct for only half the devices it will meet.
6. The Invariants Worth Asserting
The decoder is a truth table, which makes its useful properties few and sharp. Two are worth writing.
// ─────────────────────────────────────────────────────────────────────────
// Assertions for line_state_decode.
//
// Classification: TEACHING ASSERTIONS at the PHY-interface abstraction.
// They constrain this decode's semantics; they are not USB compliance
// checks and say nothing about any analog behaviour.
// ─────────────────────────────────────────────────────────────────────────
// L1 -- ILLEGAL MEANS REPORTED. Both conductors high must surface as SE1
// rather than being folded into a default. This is the chapter's central
// claim as a property: SE1 is the most direct evidence of a hardware fault
// the interface provides -- driver contention, a broken driver, a wiring
// problem -- and a decoder that absorbs it discards that evidence silently.
property p_se1_is_reported;
@(posedge clk) disable iff (!rst_n)
(se_dp && se_dm) |=> (line_state == LS_SE1) && illegal_se1;
endproperty
assert property (p_se1_is_reported);
// L2 -- THE SIGNALLING STATES FOLLOW THE DIFFERENTIAL RECEIVER, not either
// single-ended output. Written as a relation so it stays true whichever
// polarity convention is in force, which matters because Chapter 3.4 shows
// the convention is speed-dependent. It fails immediately against a decoder
// that decides J or K from se_dp -- a plausible-looking simplification,
// since in the one-high-one-low case se_dp appears to carry the same
// information, and one that becomes wrong the moment a fault or a speed
// change makes the two disagree.
property p_jk_follows_differential;
@(posedge clk) disable iff (!rst_n)
(se_dp ^ se_dm) |=> ((line_state == LS_J) == $past(diff_dp_hi));
endproperty
assert property (p_jk_follows_differential);L1 is the one the chapter exists to justify. An illegal condition that is reported is a diagnosis; one that is absorbed into a default is a silence indistinguishable from health — and §10's scenario depends entirely on SE1 being visible in order to be investigated at all.
L2 protects against a simplification that looks free. When exactly one conductor is high, se_dp and diff_dp_hi normally agree, so deciding J from se_dp appears to work and is one gate cheaper. It stops working precisely when the two disagree — which is what a receiver fault or a marginal signal produces, and exactly when you most want the decode to be following the receiver that was designed to make the decision.
7. Crossing Into the Controller Domain — a Warning
§4 noted that a line-state indication crosses from PHY timing into controller timing. There is a trap here that is worth naming precisely, because it is a genuine and common CDC mistake.
line_state above is a two-bit encoded value. Passing it through a two-flop synchroniser per bit is not safe in general. The two bits may resolve on different clock edges, so the receiving domain can observe a combination that never existed — a transition from LS_J (01) to LS_SE0 (00) is fine, but a transition from LS_J (01) to LS_K (10) changes both bits, and independent resolution can produce a transient 00 or 11. The second of those is LS_SE1: a synchroniser built the wrong way can manufacture an illegal-condition report out of a perfectly legal transition.
The standard remedies are the usual ones — Gray-coded encodings in which only one bit changes per legal transition, a handshake, or transferring the value through a small asynchronous FIFO — and choosing among them is an implementation decision this module does not make for you. What Module 3 asserts is only that bit-wise synchronisation of a multi-bit line-state bus is a bug, and that a design review should ask how the crossing is handled rather than assume two flops settled it.
8. Verification at This Boundary
Stimulus is the four conditions and, more importantly, the transitions between them — including the both-bits-change transition of §7 and the illegal condition itself, which no conforming transmitter produces and which therefore only ever appears in a test if the environment injects it deliberately.
The reference model is trivial, which is a feature: given the three receiver observations, the expected condition is a two-line truth table. When a reference model is this simple and the DUT still disagrees, the bug is nearly always in the plumbing — synchronisation, sampling, enables — rather than in the logic, which is a useful prior.
Representative coverage dimensions — not a verification plan:
- each of the four conditions reached at least once, SE1 included
- every ordered transition pair between conditions, so that the both-bits-change case is not skipped
- SE0 entered from J and from K
- reset asserted while in each condition
The error injections worth building: SE1 driven deliberately, to confirm it is reported and not absorbed; a receiver output stuck, so that one observation disagrees with the others; and — if the environment models the crossing — a transient combination during a both-bits-change transition, which is §7's failure made visible.
And the monitoring point matters. A monitor on the PHY's reported line state sees conditions; a monitor on the conductors sees voltages; a monitor on the controller's packet interface sees neither. A disagreement between the first two is an analog or threshold problem; a disagreement between the first and third is a digital problem in decode, synchronisation or control. That triangulation is the method the rest of this module keeps using.
9. Common Misconceptions
10. Reason It Through
A receive path reports occasional SE1 conditions. An oscilloscope on the conductors shows clean signalling with no instance of both lines high. The reports correlate with heavy traffic.
What does the contradiction tell you? That the condition is being created somewhere between the conductors and the report, rather than observed. If both lines are never simultaneously high, no receiver looking at them can legitimately conclude SE1.
Where can a condition be manufactured? §7's crossing. LS_J is 01 and LS_K is 10; a J-to-K transition changes both bits, and if they are synchronised independently the receiving domain can sample one bit new and the other old, yielding 11 — which decodes as SE1.
Why does it correlate with traffic? Because J-to-K transitions are what signalling is. Idle traffic holds one state and changes nothing; heavy traffic produces the both-bits-change transition constantly, so the opportunity for an unlucky sample scales with activity.
How would you confirm it cheaply? Check whether the reported SE1 events are single-cycle and always adjacent to a J/K transition. A genuine electrical SE1 has no reason to be exactly one cycle long or to appear only next to transitions; a synchronisation artefact has every reason to be both.
What is the fix, and what is the general lesson? Cross the value safely — a Gray-coded encoding in which legal transitions change one bit, a handshake, or an asynchronous FIFO. The general lesson is that a fault report is itself a signal that can be wrong, and when an observation at one abstraction level contradicts an observation at another, the discrepancy is evidence about the path between them rather than about either endpoint.
11. Understanding Check
12. Summary
The classic USB pair has four named conditions. J and K are signalling states naming a relationship between the conductors, SE0 is both conductors low and is legal and meaningful, and SE1 is both conductors high and is illegal — evidence of a fault rather than a code to decode.
A receiver therefore observes the pair two ways at once. A differential receiver answers which conductor is higher, distinguishing J from K. Single-ended receivers, one per conductor, compare against a threshold and are what make SE0 and SE1 observable, because neither has any differential meaning. A design with only a differential comparator cannot detect the end of a packet or a bus reset.
Controller RTL does not generally sample the conductors. The analog decisions happen in the PHY and the controller receives an already-decoded indication, so thresholds are not an RTL concern and code comparing voltages is modelling something that does not occur in the digital domain.
Because that indication crosses from PHY timing into controller timing, it is a clock-domain crossing — and a multi-bit encoded line state is not safe to synchronise bit by bit, since a both-bits-change transition can be observed as a combination that never existed. One of those combinations is SE1, which means a badly built crossing can fabricate fault reports out of legal traffic.
The transferable habit: keep the levels apart. What the conductors are doing, what the pair means, what the PHY reports, and what the controller received are four different statements — and nearly every physical-layer diagnosis proceeds by finding the boundary where they stop agreeing.
13. What Comes Next
This chapter used the differential receiver without justifying it. J and K were distinguished by which conductor is higher, and that phrasing was doing quiet work: it means the receiver's decision depends on the difference between the conductors rather than on either one's absolute level.
Chapter 3.2 asks why an interface would be built that way. The usual answer — noise immunity — is correct and almost always stated too strongly, in a form that implies noise disappears. It does not. What a differential pair actually buys is narrower, conditional on how the pair is built and routed, and worth understanding precisely, because the conditions under which the benefit holds are exactly the conditions a board designer can violate.
Browse the full path on the USB tutorials index.
Continue learning
Related tutorials
- Related topic
PS/2 Keyboard / Mouse
The dedicated input port where the device supplies the clock and the host receives on someone else's timing. The two-wire open-drain bus, the framed byte, why sampling a foreign clock directly is a real hardware bug, and a synthesizable teaching receiver with its synchroniser, recovery timeout and assertions.
- Related topic
The Root Hub
Where the tree begins: a hub that is architecturally ordinary and structurally unique, living inside the host controller and managed through its registers rather than addressed on the bus. The place bus events first become software-visible, with a teaching register block covering synchronisation, sticky status and clear semantics.
- Related topic
PCIe vs USB — Who Is Allowed to Start a Transfer
A device that must wait to be asked is a different machine from one that may speak. At a 128-step service interval the polled model completed 3,124 of 7,967 transfers.
- Related topic
The Parallel Port
Why presenting eight data lines at once forces an explicit data/strobe/acknowledge handshake, what that costs in timing discipline, a synthesizable teaching FSM that implements it with the assertions that protect it, and why an interface shaped around one peripheral's operational model cannot generalise.
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.
