DDR · Module 28
Training Failures
A pass bitmap is a projection of four independent failure domains onto one bit per setting. Eleven signatures, each consistent with several causes, and the experiment that separates them.
Module 21 built the training algorithms: the write-leveling search, read leveling, gate training, eye centering, and the sequencer that orders them. Chapter 21.5 owns the flow, and 19.5 owns the calibration lifecycle those steps report into.
This chapter starts one step later: training ran, and it reported failure.
What you have is a pass bitmap — for each setting the search tried, a bit saying whether the classifier judged it good. And the temptation, which this whole module exists to resist, is to read that bitmap as a diagnosis.
It is not a diagnosis. It is evidence. A bitmap of all zeros is consistent with a dead lane, a stuck classifier, a mis-programmed sweep range, an unfinished prerequisite step, and a genuine margin failure. Five causes, one signature, and nothing in the bitmap distinguishes them.
1. What a Pass Bitmap Actually Is
Be precise about the object, because every misreading in this chapter starts with imprecision here.
A training search applies a setting, runs a test, and asks a classifier whether the result was acceptable. Chapter 21.5 owns that loop. The bitmap is the sequence of the classifier's answers.
So a bit in the bitmap is the composition of four things:
bit[k] = classifier( observe( device( apply(setting k) ) ) )
^^^^^^^^^^ ^^^^^^^ ^^^^^^ ^^^^^
judgement capture physics controlA zero can come from any of the four, and the bitmap records only the composition. That is the entire difficulty: the signature is a projection of four independent failure domains onto one bit per setting, and projections lose information.
2. The Eleven Signatures
CURRICULUM-DERIVED from 21.5's flow, the shapes a failed or suspicious training run actually leaves. Read the third column as the strongest thing this evidence supports — never as a conclusion.
| # | Signature | What it supports | What it does not establish |
|---|---|---|---|
| 1 | No passing taps — bitmap all zero | something in the chain is broken or margin is gone | which of the four layers in §1 |
| 2 | All taps passing | the classifier is not discriminating, or the sweep range is too narrow to reach a failing setting | that margin is large |
| 3 | One passing tap | the window is at or below the search step size | that the window is truly one step wide |
| 4 | Narrow window (2–3 taps) | little margin at this setting granularity | a numeric margin in time or volts |
| 5 | Disjoint windows | the classifier saw two acceptable regions | which one is correct — §7 |
| 6 | Unstable bitmap across repeats | the measurement is not repeatable | that the device is marginal |
| 7 | Lane-local failure | the fault follows one lane's path | that the lane's channel is at fault — §9 |
| 8 | Timeout | the step never reached a decision | that the step would have failed — §10 |
| 9 | Stale result | a committed setting predates the current configuration | that the setting is wrong for it |
| 10 | Selected point near an edge | the chooser picked badly, or the window is asymmetric | which — §12 |
| 11 | Retraining changes the result | the result depends on state the step does not control | that either result is correct |
Signature 2 is the dangerous one and it is worth saying why immediately. An all-passing bitmap looks like success. It is reported as success. And it is the signature of a classifier that cannot fail — which 27.3 §9 established as the worst class of instrument defect, because it reports confidence it has not earned. §4 is about it.
3. Signature 1 — No Passing Taps
The all-zero bitmap. Four hypotheses, and they are not equally likely.
| Hypothesis | Mechanism | Evidence that would support it |
|---|---|---|
| A. Control defect | the setting never reached the hardware | the applied setting register reads back unchanged across the sweep |
| B. Observation defect | the comparison never sees real data | the captured data is constant — all zeros, all ones, or one repeated beat |
| C. Prerequisite not met | an earlier step never committed | the earlier step's own committed flag is false — §11 |
| D. Margin failure | no setting is actually good | everything above is ruled out, and the failure follows the device |
Hypothesis C is the one engineers skip, and it is the reason the module's second law exists. Chapter 21.5 establishes an ordering among the steps: gate training must be established before read leveling has a meaningful capture to judge. So a read-leveling all-zero bitmap may be a gate-training failure that reported success, and the first observed error is then the second causal error.
The discriminating experiment is cheap and it must be run first. Read back the applied setting during the sweep. If it does not change, hypothesis A is confirmed and hypotheses B, C, D are untested — and the bitmap contains no information about the device at all.
THE THREE-READBACK TEST, in order of cost
1. does the APPLIED setting change across the sweep?
no -> control defect (A). The sweep never happened.
yes -> continue.
2. does the CAPTURED data change across the sweep?
no -> observation defect (B). The classifier is judging a
constant, so every bit of the bitmap is the same bit.
yes -> continue.
3. did every PREREQUISITE step commit?
no -> ordering / prerequisite defect (C). The step under
investigation may be blameless.
yes -> margin hypothesis (D) is now the surviving one, and
§18 is where it goes.
note the order: each test is cheaper than the next and each one
invalidates the evidence the later tests depend on. Running them
out of order wastes the lab time you spent on the expensive one.4. Signature 2 — All Taps Passing
The signature that reports success. Three mechanisms.
The classifier is not discriminating. If the comparison is against a pattern the channel cannot corrupt — all zeros, a single toggling bit, a pattern shorter than the burst — then every setting passes. This is a real defect that produces a green result, and it survives review because nothing fails.
The sweep range is too narrow. If the search only tries settings inside the good region, it never finds an edge. The bitmap is then a true statement about a range nobody chose deliberately — and the window it reports is the range, not the margin.
The step is measuring the wrong thing. A read-leveling sweep that varies a setting the capture path does not depend on will pass at every value, correctly.
| Discriminating experiment | If the classifier is weak | If the range is too narrow |
|---|---|---|
| Widen the sweep range beyond the plausible window | still all pass | failing taps appear at both ends |
| Substitute a more aggressive pattern | failing taps appear | boundaries move but remain inside |
| Deliberately apply a setting known to be bad | still passes — proves the classifier | fails, as it should |
The third row is the one to run, and it is the cheapest. Apply a setting far outside any plausible window and demand a failure. A classifier that passes a setting known to be wrong has been proven non-discriminating, and every bitmap it has ever produced is now uninterpretable — including the ones that passed.
This is 27.2 §2's vacuity argument in hardware. A check that cannot fail contributes nothing, and the only way to establish that it can fail is to make it fail on purpose.
5. Signatures 3 and 4 — One Tap, and Narrow Windows
A window of one or a few taps is the signature engineers most often act on, and the action is usually wrong.
A one-tap window means the window is at or below the step size. It does not mean the window is one step wide. DERIVED from a stated model, with an ILLUSTRATIVE step size:
sweep step = 1 tap. window observed = 1 tap (index 4 passes).
what the bitmap constrains:
the good region overlaps tap 4's decision point,
and does NOT overlap tap 3's or tap 5's.
what it does NOT constrain:
the width of the good region. It may be
slightly wider than one step and badly aligned, or
far narrower than one step and centred on tap 4.
so the SAME bitmap is produced by a comfortable window that the
sweep grid samples badly and by a window on the edge of failing.
Refining the step size distinguishes them; nothing else here does.So the discriminating experiment for a narrow window is a finer sweep, not a decision. Halve the step and re-sweep the neighbourhood. If the window grows in proportion, the original was a sampling artefact. If it stays one fine step wide, the narrowness is real at this granularity — and then it is a margin question for §18.
And a narrow window must never be silently accepted by the chooser. §13's ledger records the window width precisely so a run that committed a one-tap setting is distinguishable from one that committed the centre of a wide window. Both report success.
6. Signature 5 — Disjoint Windows
Two separated passing regions. This is the signature with the most structure and therefore the most information.
Three mechanisms, and they predict different things.
| Mechanism | Why two windows appear | Prediction that distinguishes it |
|---|---|---|
| Aliasing — the sweep wrapped | the setting is cyclic and the search crossed the wrap | the two windows are adjacent modulo the range; joining them across the wrap gives one window |
| A second, worse sampling point | capture succeeds at two different alignments | the two windows have different widths, and the narrower is the alias |
| Instability | a marginal region flickered during the sweep | re-sweeping gives different window boundaries — §8 |
Row one is the common case and the cheapest to test. If the setting space is cyclic — and several training settings are — then a window at the bottom of the range and one at the top may be one window seen across the wrap. Rotating the sweep start point is the discriminating experiment: a true single window becomes contiguous, and genuinely disjoint windows stay disjoint.
Choosing the midpoint of a disjoint bitmap is the trap. §14's waveform shows it concretely: a bitmap passing at taps 2–4 and again at tap 7 has an overall span from 2 to 7, whose midpoint is 4.5 — and taps 5 and 6 both fail. A chooser that averages the extremes lands in the gap, commits a failing setting, and reports success.
7. Signature 6 — An Unstable Bitmap
The bitmap changes between identical repeats. This is the signature that most resembles a verdict and is least entitled to be one.
What instability establishes is that the measurement is not repeatable. That is all. It does not say the device is marginal, because the instability may live in any of §1's four layers.
| Where the instability could live | How it would look | Discriminating experiment |
|---|---|---|
| The pattern is not deterministic | boundaries move by one tap run to run | drive a fixed, repeatable pattern |
| The classifier threshold is marginal | the same setting flips verdicts | count repeats per setting; a 50/50 setting is at the threshold |
| Uncontrolled prior state | the first repeat differs from the rest | reset to a defined state before each repeat — §11 |
| Genuine physical marginality | boundaries move randomly, and only at the edges | everything above ruled out, then §18 |
Row three has a signature worth recognising: the first repeat differs and later repeats agree. That is not noise. It is state left behind by whatever ran before, and it means the step is not self-contained. §11 is about it.
The right instrument is repetition with counting, not a single re-run. Sweep each setting N times and record a pass count rather than a bit. A setting passing 4 of 8 times is a different finding from one passing 8 of 8, and a one-bit bitmap cannot represent the difference — which is why §13's ledger stores a count.
8. Signatures 7 and 9 — Lane-Local, and Global
Whether a failure follows one lane or all of them is the single most useful partition in training debug, and it is also the most over-interpreted.
What a lane-local failure establishes: the fault follows something specific to that lane's path. CURRICULUM-DERIVED from 19.1, that path includes the lane's per-lane delay setting, its capture logic, its share of the classifier, its package trace, its board trace, and its device pin.
So lane-local is a location result, not a domain result. It narrows where; it says nothing about what.
| Observation | Supports | Does not support |
|---|---|---|
| One lane fails, others pass | a per-lane cause | that the cause is the channel |
| The same lane fails on a different device | cause is not in that device | that it is the board |
| The failure moves with the device | cause is in the device | that it is not also marginal elsewhere |
| All lanes fail identically | a shared cause — clock, command, config, prerequisite | that no lane is individually worse |
Row four is the one that redirects the investigation. A failure on every lane is rarely a lane problem. It points at what the lanes share — the clock, the command path, the configuration, or an unmet prerequisite — and 28.7's staged order exists so those are established before per-lane steps are believed.
9. Signature 8 — Timeout Is Not Failure
A step that timed out and a step that failed are different findings, and collapsing them destroys information.
A failure means the search completed and found no acceptable setting. A timeout means the search did not complete, so the bitmap is partial and its zeros include settings that were never tried.
| Failure | Timeout | |
|---|---|---|
| Bitmap | complete | partial — untried settings read as zero |
| Supports | no good setting in the swept range | nothing about settings not reached |
| Common cause | margin, or §3's A–C | a done that never asserts, a stuck sweep, a budget too small |
So a timeout's bitmap must not be interpreted as a margin result at all — and this is why §13's ledger records a reason and a count of settings actually tried, rather than only a bitmap. A bitmap of 10 zeros where only 3 settings were tried is not an all-zero signature; §3's four hypotheses do not apply to it.
The discriminating experiment is to raise the budget and re-run. If the step then completes, the timeout was a budget or liveness problem. If it times out again at the same setting index, the sweep is stuck — and the index is the localization.
10. Signatures 9 and 11 — Stale State and Order
Two signatures with one underlying cause: the step is not self-contained.
A stale result is a committed setting that predates the configuration it is being used under. Chapter 19.5 owns the lifecycle in which a result becomes valid and can be invalidated. A setting trained at one frequency and used at another is stale, and nothing about the setting itself reveals that.
Retraining changing the result is the same defect seen from the other side. If a second identical training pass produces a different committed setting, the step depends on state it does not control — and the two candidate locations are the device's state and the controller's.
| Experiment | If the step depends on device state | If it depends on controller state |
|---|---|---|
| Retrain after a full device reset | result returns to the first value | result stays at the second |
| Retrain after re-applying configuration only | result stays at the second | result returns to the first |
| Retrain twice with no intervening change | second and third agree | second and third agree |
Row three is the control and it is the one most often omitted. If pass two and pass three agree with each other but not with pass one, then pass one ran in a state the later passes did not — which is a bring-up ordering question, not a training algorithm question.
11. The Failure-Domain Split
Everything above resolves into six domains. This table is the chapter's spine, and the right-hand column is what makes it actionable rather than a taxonomy.
| Domain | Definition | Earliest reliable evidence |
|---|---|---|
| Control | the setting never reached the hardware | applied-setting readback during the sweep |
| Observation | the classifier judged something other than real captured data | captured data constant across settings |
| Configuration | the sweep range, pattern, or threshold is wrong for this device | a known-bad setting still passes; range never reaches an edge |
| Ordering | a prerequisite step never committed | the prerequisite's own committed flag |
| Stale state | a committed result predates the current configuration | the result's provenance tag versus the active configuration |
| Physical margin | no setting is acceptable, and the five above are excluded | everything above ruled out, and the failure follows the device |
The order is not arbitrary — it is cheapest-first, and each row invalidates the evidence for the rows below it. A control defect makes every observation meaningless; an observation defect makes every configuration conclusion meaningless. So physical margin is last not because it is unlikely, but because it is the only hypothesis that cannot be tested until the other five are excluded.
And this is the module's fifth law in one sentence: localize before correcting. Raising a timing setting because training failed, without excluding the first five rows, changes a number and tests nothing.
12. The Training Flow With Its Failure Exits
Chapter 21.5 owns the sequencer. What this chapter needs from it is where the failure exits are, because each exit produces a different signature.
Two things the exits make visible.
There are three failure states, not one. NO PASS, FRAGMENTED and TIMEOUT produce different bitmaps and admit different hypotheses — and a sequencer that collapses them into a single FAILED state has destroyed the distinction §10 says is essential.
And every failure state returns to idle by recording, not by retrying. That ordering is the module's fourth law made structural: a passing retry does not explain the first attempt, so the signature is preserved before anything else is allowed to run.
13. A Fragmented Bitmap, Cycle by Cycle
The disjoint-window case from §6, as the sweep actually produces it. ILLUSTRATIVE settings and data.
A fragmented pass bitmap, and the midpoint that lands in the gap
10 cyclesThe arithmetic that makes this a trap. DERIVED, recomputed: first pass 2, last pass 7, span midpoint (2 + 7) / 2 = 4.5, which rounds to 4 or 5. Setting 4 passes; setting 5 fails. So the same chooser is correct or broken depending on its rounding direction — and neither choice is defensible, because the span is not a window.
The correct reading is that there are two windows and the chooser must pick within one of them. Window A is settings 2–4, midpoint 3. Window B is setting 7 alone. §6's discriminating experiment — rotate the sweep start — decides whether B is an alias of A across a wrap or a genuine second region.
And fragmented is a published output, not an internal condition. §14's ledger raises it the moment a second window opens, because a run that committed from a fragmented bitmap must be distinguishable afterwards from one that did not. Both otherwise report a committed setting and success.
14. The Diagnostic Ledger
// ---------------------------------------------------------------------
// train_diag_ledger -- CLASSIFICATION: synthesisable, BINDABLE.
//
// WHAT IT DOES: records one training step's pass bitmap plus the derived
// quantities §2's signature table needs, and latches the FIRST failure
// reason so a later cascading failure cannot overwrite the earliest
// reliable evidence.
//
// WHY IT EXISTS: §2. Eleven signatures are distinguishable only if the
// run's shape is preserved. A single pass/fail flag collapses all
// eleven into one bit, and a retry destroys even that.
//
// WHY A COUNT AND NOT A BIT PER SETTING (§7): an unstable bitmap is a
// real signature, and a one-bit-per-setting record cannot represent
// "passed 4 of 8 attempts". REPEATS>1 makes instability visible.
//
// WHY settings_tried IS PUBLISHED (§9): a timeout's bitmap is PARTIAL.
// Ten zeros after three attempts is not an all-zero signature, and
// §3's four hypotheses do not apply to it.
//
// WHAT IT CANNOT TELL YOU: which of §1's four layers failed. It records
// the classifier's verdict, not its correctness.
//
// SYNTHESIS: counters and a shift register. No DUT handle, no
// hierarchical reference; it sees the sequencer's interface only.
// ---------------------------------------------------------------------
module train_diag_ledger #(
parameter int TAPS = 16, // settings in the sweep range
parameter int LANES = 8,
parameter int REPEATS = 1 // attempts per setting -- §7
)(
input logic clk,
input logic rst_n,
// ---- sequencer interface (observed, never driven)
input logic step_start,
input logic step_done,
input logic setting_applied, // one pulse per attempt
input logic [$clog2(TAPS)-1:0] setting_idx,
input logic verdict_valid,
input logic verdict_pass,
input logic [$clog2(LANES)-1:0] lane_idx,
input logic committed,
input logic [$clog2(TAPS)-1:0] committed_idx,
input logic timeout,
input logic prereq_committed, // §3 hypothesis C
input logic clear, // explicit, §16
// ---- published evidence
output logic [TAPS-1:0] bitmap,
output logic [$clog2(TAPS+1)-1:0] n_pass,
output logic [$clog2(TAPS+1)-1:0] settings_tried,
output logic [$clog2(TAPS)-1:0] first_pass,
output logic [$clog2(TAPS)-1:0] last_pass,
output logic [$clog2(TAPS+1)-1:0] windows,
output logic fragmented,
output logic have_pass,
output logic [2:0] fail_reason,
output logic fail_latched
);
// TAPS and LANES of 1 would make $clog2 zero and every index vector
// illegal as [-1:0]. A power-of-two test alone accepts 1, so the
// bound is explicit. REPEATS of 0 would make the ledger record
// nothing while reporting success.
initial begin
if (TAPS < 2) $fatal(1, "train_diag_ledger: TAPS must be >= 2 (got %0d)", TAPS);
if (LANES < 2) $fatal(1, "train_diag_ledger: LANES must be >= 2 (got %0d)", LANES);
if (REPEATS < 1) $fatal(1, "train_diag_ledger: REPEATS must be >= 1");
end
// §12's three failure states, encoded. NONE is not a failure.
localparam logic [2:0] FR_NONE = 3'd0;
localparam logic [2:0] FR_NO_PASS = 3'd1;
localparam logic [2:0] FR_FRAGMENT = 3'd2;
localparam logic [2:0] FR_TIMEOUT = 3'd3;
localparam logic [2:0] FR_PREREQ = 3'd4;
localparam logic [2:0] FR_STALE = 3'd5;
logic prev_pass; // was the previous CLASSIFIED setting a pass?
logic seen_any; // has any setting been classified yet?
always_ff @(posedge clk) begin
if (!rst_n || clear) begin
bitmap <= '0;
n_pass <= '0;
settings_tried <= '0;
first_pass <= '0;
last_pass <= '0;
windows <= '0;
fragmented <= 1'b0;
have_pass <= 1'b0;
fail_reason <= FR_NONE;
fail_latched <= 1'b0;
prev_pass <= 1'b0;
seen_any <= 1'b0;
end else begin
// A new step clears the per-step evidence but NOT the latched
// failure reason -- §16. The first failure of a boot wins.
if (step_start) begin
bitmap <= '0;
n_pass <= '0;
settings_tried <= '0;
windows <= '0;
fragmented <= 1'b0;
have_pass <= 1'b0;
prev_pass <= 1'b0;
seen_any <= 1'b0;
end
// §9: count attempts separately from verdicts. A sweep that
// stopped early has settings_tried < TAPS, and its zeros are
// untried settings rather than failing ones.
if (setting_applied && settings_tried != TAPS)
settings_tried <= settings_tried + 1'b1;
if (verdict_valid) begin
seen_any <= 1'b1;
if (verdict_pass) begin
bitmap[setting_idx] <= 1'b1;
if (n_pass != TAPS) n_pass <= n_pass + 1'b1;
last_pass <= setting_idx;
if (!have_pass) begin
have_pass <= 1'b1;
first_pass <= setting_idx;
end
// A window OPENS on a pass whose predecessor was a fail, or
// on the very first classified setting. Counting openings
// rather than edges is what makes `windows` a window count
// and not an edge count.
if (!seen_any || !prev_pass) begin
if (windows != TAPS) windows <= windows + 1'b1;
// §6: two or more windows is the fragmented signature, and
// it is sticky -- a later contiguous run must not clear it.
if (windows >= 1) fragmented <= 1'b1;
end
end
prev_pass <= verdict_pass;
end
// ---- FIRST failure wins, and only an explicit clear releases it.
// §16 proves this; the ordering below is the priority, and PREREQ
// is checked before the bitmap shapes because §3 hypothesis C
// means the bitmap may be describing a blameless step.
if (!fail_latched) begin
if (step_done && !prereq_committed) begin
fail_reason <= FR_PREREQ;
fail_latched <= 1'b1;
end else if (timeout) begin
fail_reason <= FR_TIMEOUT;
fail_latched <= 1'b1;
end else if (step_done && !have_pass) begin
fail_reason <= FR_NO_PASS;
fail_latched <= 1'b1;
end else if (step_done && fragmented && committed) begin
// Committing FROM a fragmented bitmap is a finding even
// though the step reported success -- §13's midpoint trap.
fail_reason <= FR_FRAGMENT;
fail_latched <= 1'b1;
end
end
end
end
// Window width around the committed setting, computed combinationally
// so it is readable the cycle after a commit. §5: a one-wide window
// and the centre of a wide window both report success, and this is
// the number that separates them.
logic [$clog2(TAPS+1)-1:0] commit_window_w;
always_comb begin
commit_window_w = '0;
if (committed) begin
for (int i = 0; i < TAPS; i++)
if (bitmap[i]) begin
// count only the contiguous run containing committed_idx
if (i == int'(committed_idx)) commit_window_w = commit_window_w + 1'b1;
else if (i < int'(committed_idx)) begin
automatic bit gap = 1'b0;
for (int k = i; k < int'(committed_idx); k++) if (!bitmap[k]) gap = 1'b1;
if (!gap) commit_window_w = commit_window_w + 1'b1;
end else begin
automatic bit gap2 = 1'b0;
for (int k = int'(committed_idx); k < i; k++) if (!bitmap[k]) gap2 = 1'b1;
if (!gap2) commit_window_w = commit_window_w + 1'b1;
end
end
end
end
endmodulefail_latched is the whole point of the block. The module's third and fourth laws say a retry explains nothing and a vanished failure is not a fix — so the first failure reason is held until an explicit clear, and §16 proves that a second, later failure cannot overwrite it.
settings_tried is separate from n_pass for §9's reason. Ten zeros after three attempts is not an all-zero bitmap. Publishing the attempt count is what makes a timeout's partial bitmap unreadable as a margin result rather than silently readable as one.
And FR_PREREQ is checked before every bitmap shape. §3's hypothesis C means the bitmap under investigation may belong to a blameless step whose prerequisite never committed. Checking the prerequisite first is the module's second law in priority order — the first observed error is not necessarily the first causal error.
15. Turning a Bitmap Into Ranked Hypotheses
// ---------------------------------------------------------------------
// train_signature_classifier -- SIMULATION-ONLY.
//
// Maps §14's evidence to §11's ORDERED domain list. It deliberately
// returns several hypotheses and a next experiment, never one cause:
// §1 establishes that a bitmap is a projection of four independent
// layers onto one bit per setting, so a signature cannot identify a
// layer.
//
// WHAT IT DOES NOT MODEL: the device, the channel, any electrical
// quantity, or the classifier whose verdicts it is reading.
//
// WHAT IT WOULD MISS: two different faults with the same signature.
// That is not a bug in this class; it is the projection.
// ---------------------------------------------------------------------
typedef enum {
SIG_OK, SIG_NO_PASS, SIG_ALL_PASS, SIG_SINGLE, SIG_NARROW,
SIG_FRAGMENTED, SIG_TIMEOUT_PARTIAL, SIG_UNSTABLE, SIG_EDGE_PICK
} train_sig_e;
// §11's six domains, in the cheapest-first order that table establishes.
typedef enum {
DOM_CONTROL, DOM_OBSERVATION, DOM_CONFIG, DOM_ORDERING,
DOM_STALE, DOM_PHYSICAL
} train_domain_e;
class train_evidence;
int taps;
int n_pass;
int settings_tried;
int first_pass;
int last_pass;
int windows;
bit fragmented;
bit have_pass;
bit timed_out;
bit prereq_committed;
bit committed;
int committed_idx;
int commit_window_w;
int repeats; // §7
int min_repeat_passes; // lowest pass count over repeats at any setting
int max_repeat_passes;
endclass
class train_signature_classifier;
// §9: a partial bitmap is not a margin result. Checked FIRST, because
// every shape below assumes the sweep completed.
function train_sig_e signature(train_evidence e);
if (e.timed_out || e.settings_tried < e.taps) return SIG_TIMEOUT_PARTIAL;
// §7: instability outranks shape, because an unstable bitmap has no
// stable shape to classify.
if (e.repeats > 1 && e.min_repeat_passes != e.max_repeat_passes)
return SIG_UNSTABLE;
if (!e.have_pass) return SIG_NO_PASS;
if (e.n_pass == e.taps) return SIG_ALL_PASS;
if (e.fragmented) return SIG_FRAGMENTED;
if (e.n_pass == 1) return SIG_SINGLE;
if (e.n_pass <= 3) return SIG_NARROW;
// §11 signature 10: a commit within one of the outermost settings
// of its own window is an edge pick.
if (e.committed && e.commit_window_w >= 3 &&
(e.committed_idx == e.first_pass || e.committed_idx == e.last_pass))
return SIG_EDGE_PICK;
return SIG_OK;
endfunction
// The ordered domain list. §11: cheapest-first, and each domain
// invalidates the evidence for the ones after it.
function void hypotheses(train_evidence e, ref train_domain_e out[$]);
train_sig_e s = signature(e);
out.delete();
// Ordering is checked before anything else whenever the prerequisite
// is known not to have committed -- §3 hypothesis C, the module's
// second law.
if (!e.prereq_committed) out.push_back(DOM_ORDERING);
case (s)
SIG_NO_PASS: begin
out.push_back(DOM_CONTROL);
out.push_back(DOM_OBSERVATION);
out.push_back(DOM_CONFIG);
out.push_back(DOM_PHYSICAL); // last: §11's argument
end
SIG_ALL_PASS: begin
// §4: this signature is about the INSTRUMENT, so no physical
// hypothesis is offered at all. A non-discriminating classifier
// makes every margin statement unavailable.
out.push_back(DOM_OBSERVATION);
out.push_back(DOM_CONFIG);
end
SIG_SINGLE, SIG_NARROW: begin
out.push_back(DOM_CONFIG); // §5: step size first
out.push_back(DOM_PHYSICAL);
end
SIG_FRAGMENTED: begin
out.push_back(DOM_CONFIG); // §6: aliasing / sweep origin
out.push_back(DOM_OBSERVATION);
out.push_back(DOM_PHYSICAL);
end
SIG_TIMEOUT_PARTIAL: begin
out.push_back(DOM_CONTROL);
out.push_back(DOM_CONFIG);
end
SIG_UNSTABLE: begin
out.push_back(DOM_CONFIG);
out.push_back(DOM_STALE);
out.push_back(DOM_PHYSICAL);
end
SIG_EDGE_PICK: out.push_back(DOM_CONFIG);
default: ; // SIG_OK offers no hypothesis
endcase
endfunction
// The discriminating experiment §11 requires: a named action WITH the
// two outcomes that separate the leading hypotheses. An action with
// no predicted outcomes is random tweaking.
function string next_experiment(train_evidence e);
case (signature(e))
SIG_NO_PASS:
return "read back the applied setting across the sweep; unchanged => control defect, changing => continue to captured data";
SIG_ALL_PASS:
return "apply a setting known to be bad; still passes => classifier proven non-discriminating, fails => widen the sweep range";
SIG_SINGLE, SIG_NARROW:
return "halve the step and re-sweep the neighbourhood; window grows proportionally => sampling artefact, stays one fine step => real at this granularity";
SIG_FRAGMENTED:
return "rotate the sweep start point; windows join => aliasing across a cyclic range, stay disjoint => two genuine regions";
SIG_TIMEOUT_PARTIAL:
return "raise the budget and re-run; completes => budget or liveness, stops at the same index => sweep stuck at that index";
SIG_UNSTABLE:
return "repeat each setting N times and count; a 50/50 setting => classifier threshold, first repeat differs only => uncontrolled prior state";
SIG_EDGE_PICK:
return "re-run the chooser on the recorded bitmap; picks the same edge => chooser defect, picks the centre => bitmap changed between runs";
default:
return "no signature: do not change settings";
endcase
endfunction
// §1's boundary, enforced in code. No method here returns a physical
// cause, and this one exists so a caller cannot ask for one.
function string physical_verdict(train_evidence e);
return "unavailable: a pass bitmap is a digital sample of a classifier's decision, not a measurement of eye height or width (§1, §18)";
endfunction
// §11's last row: the physical hypothesis is admissible only when the
// five cheaper domains have been excluded BY EXPERIMENT, which is a
// fact about the investigation and cannot be derived from a bitmap.
function bit physical_hypothesis_admissible(
bit control_excluded, bit observation_excluded,
bit config_excluded, bit ordering_excluded, bit stale_excluded);
return control_excluded && observation_excluded && config_excluded
&& ordering_excluded && stale_excluded;
endfunction
endclassphysical_verdict() returns a refusal rather than a value, and that is deliberate. A classifier with a method that answered it would be the overclaim §1's callout forbids, and the refusal is easier to defend in review than a comment.
physical_hypothesis_admissible() takes five booleans the class cannot compute. §11 establishes that physical margin is testable only once the cheaper domains are excluded, and exclusion is a fact about what experiments were run — not something a bitmap encodes. So the function demands them as inputs, which makes an investigation that skipped them visibly incomplete.
16. What the Assertions Prove
// Bound to §14's ledger. Every property is guarded by `disable iff`, and
// every antecedent is published as a cover below -- 27.2 measured this
// curriculum at 78.53% implications, so a silent pass is otherwise
// indistinguishable from a property that never armed.
module train_diag_ledger_sva #(
parameter int TAPS = 16
)(
input logic clk, rst_n,
input logic step_start, step_done, setting_applied, verdict_valid,
input logic verdict_pass, committed, timeout, prereq_committed, clear,
input logic [TAPS-1:0] bitmap,
input logic [$clog2(TAPS+1)-1:0] n_pass, settings_tried, windows,
input logic fragmented, have_pass, fail_latched,
input logic [2:0] fail_reason
);
// ---- P1. FIRST FAILURE WINS. Once latched, the reason is stable
// until an explicit clear. This is the module's third and fourth laws
// in one property: a later cascading failure must not overwrite the
// earliest reliable evidence.
property p_first_failure_sticky;
@(posedge clk) disable iff (!rst_n)
(fail_latched && !clear) |=> (fail_reason == $past(fail_reason));
endproperty
assert property (p_first_failure_sticky)
else $error("ledger: latched failure reason changed without a clear");
// ---- P2. FORBIDDEN. A new step must not release the latch. Only
// `clear` does. Without this, a retry erases the evidence.
property p_step_start_does_not_clear_latch;
@(posedge clk) disable iff (!rst_n)
(step_start && fail_latched && !clear) |=> fail_latched;
endproperty
assert property (p_step_start_does_not_clear_latch)
else $error("ledger: step_start released the failure latch");
// ---- P3. Clear actually clears. A latch with no release is a
// one-shot register that silently stops recording after boot.
property p_clear_releases;
@(posedge clk) disable iff (!rst_n)
clear |=> (!fail_latched && fail_reason == 3'd0);
endproperty
assert property (p_clear_releases)
else $error("ledger: clear did not release the latch");
// ---- P4. n_pass counts verdicts, not attempts. §9: collapsing the
// two makes a partial bitmap look like a margin result.
property p_npass_only_on_pass;
@(posedge clk) disable iff (!rst_n)
(verdict_valid && !verdict_pass) |=> (n_pass == $past(n_pass));
endproperty
assert property (p_npass_only_on_pass)
else $error("ledger: n_pass advanced on a failing verdict");
// ---- P5. settings_tried counts attempts, not verdicts.
property p_tried_on_apply;
@(posedge clk) disable iff (!rst_n)
(setting_applied && settings_tried != TAPS)
|=> (settings_tried == $past(settings_tried) + 1);
endproperty
assert property (p_tried_on_apply)
else $error("ledger: settings_tried did not advance on an attempt");
// ---- P6. FORBIDDEN. n_pass never exceeds settings_tried. A bitmap
// reporting more passes than attempts is arithmetically impossible
// and indicates the two are being driven from one event.
property p_pass_le_tried;
@(posedge clk) disable iff (!rst_n)
(n_pass <= settings_tried);
endproperty
assert property (p_pass_le_tried)
else $error("ledger: n_pass %0d exceeds settings_tried %0d", n_pass, settings_tried);
// ---- P7. INVARIANT. n_pass never exceeds the sweep width. The
// counter is sized for TAPS+1 values precisely so this cannot wrap
// silently -- COUNT versus INDEX.
property p_npass_bounded;
@(posedge clk) disable iff (!rst_n)
(n_pass <= TAPS);
endproperty
assert property (p_npass_bounded)
else $error("ledger: n_pass exceeded TAPS");
// ---- P8. have_pass is sticky within a step. §14: first_pass must
// keep the FIRST index, so the flag that guards it cannot drop.
property p_have_pass_sticky;
@(posedge clk) disable iff (!rst_n)
(have_pass && !step_start && !clear) |=> have_pass;
endproperty
assert property (p_have_pass_sticky)
else $error("ledger: have_pass dropped mid-step");
// ---- P9. FORBIDDEN. fragmented is sticky: a later contiguous run
// must not clear it. §6 -- a run that committed from a fragmented
// bitmap has to stay distinguishable afterwards.
property p_fragmented_sticky;
@(posedge clk) disable iff (!rst_n)
(fragmented && !step_start && !clear) |=> fragmented;
endproperty
assert property (p_fragmented_sticky)
else $error("ledger: fragmented dropped without a new step");
// ---- P10. fragmented implies at least two windows, and conversely.
// The two must agree or `fragmented` is decoration.
property p_fragmented_matches_windows;
@(posedge clk) disable iff (!rst_n)
fragmented |-> (windows >= 2);
endproperty
assert property (p_fragmented_matches_windows)
else $error("ledger: fragmented asserted with windows=%0d", windows);
// ---- P11. FORBIDDEN. A prerequisite failure outranks every bitmap
// shape. §3 hypothesis C: the bitmap may describe a blameless step,
// so the reason must be PREREQ and not NO_PASS.
property p_prereq_outranks_shape;
@(posedge clk) disable iff (!rst_n)
(step_done && !prereq_committed && !$past(fail_latched))
|=> (fail_reason == 3'd4);
endproperty
assert property (p_prereq_outranks_shape)
else $error("ledger: prerequisite failure did not outrank the bitmap shape");
// ---- P12. FORBIDDEN. Committing from a fragmented bitmap is
// recorded as a finding even though the step reported success --
// §13's midpoint trap, which otherwise reports a clean commit.
property p_fragment_commit_recorded;
@(posedge clk) disable iff (!rst_n)
(step_done && fragmented && committed && !$past(fail_latched))
|=> fail_latched;
endproperty
assert property (p_fragment_commit_recorded)
else $error("ledger: a commit from a fragmented bitmap was not recorded");
// ---- 27.2 §7: publish every antecedent. Without these the twelve
// properties above are indistinguishable from a bound checker whose
// sequencer was never connected.
cover property (@(posedge clk) disable iff (!rst_n) step_start);
cover property (@(posedge clk) disable iff (!rst_n) step_done);
cover property (@(posedge clk) disable iff (!rst_n) setting_applied);
cover property (@(posedge clk) disable iff (!rst_n) verdict_valid && verdict_pass);
cover property (@(posedge clk) disable iff (!rst_n) verdict_valid && !verdict_pass);
cover property (@(posedge clk) disable iff (!rst_n) committed);
cover property (@(posedge clk) disable iff (!rst_n) timeout);
cover property (@(posedge clk) disable iff (!rst_n) clear);
cover property (@(posedge clk) disable iff (!rst_n) fail_latched);
cover property (@(posedge clk) disable iff (!rst_n) fragmented);
// The signature-specific covers: each is one of §2's rows, and an
// empty bin means that signature was never exercised.
cover property (@(posedge clk) disable iff (!rst_n) step_done && !have_pass);
cover property (@(posedge clk) disable iff (!rst_n) step_done && (n_pass == TAPS));
cover property (@(posedge clk) disable iff (!rst_n) step_done && (n_pass == 1));
cover property (@(posedge clk) disable iff (!rst_n) step_done && fragmented && committed);
cover property (@(posedge clk) disable iff (!rst_n) step_done && !prereq_committed);
endmodule17. DV — Testing the Ledger
// ---------------------------------------------------------------------
// bitmap_reference -- SIMULATION-ONLY independent reference for §14.
//
// WHY A DIFFERENT ALGORITHM: the ledger derives windows and
// fragmentation in ONE streaming pass, incrementally, as verdicts
// arrive. This model rescans the FINISHED bitmap for contiguous runs.
// Two different algorithms agreeing is evidence; the same algorithm
// written twice is a restatement -- 27.4 §15's argument.
//
// WHAT IT DOES NOT MODEL: the sequencer, classifier, or device.
//
// WHAT IT WOULD MISS: an error both implementations make identically.
// They share the bitmap, so a corrupted bitmap agrees with itself.
// ---------------------------------------------------------------------
class bitmap_reference #(parameter int TAPS = 16);
// Contiguous runs of set bits, rescanned from the finished bitmap.
function int windows(logic [TAPS-1:0] bm);
int n = 0;
bit prev = 1'b0;
for (int i = 0; i < TAPS; i++) begin
if (bm[i] && !prev) n++;
prev = bm[i];
end
return n;
endfunction
function bit fragmented(logic [TAPS-1:0] bm);
return windows(bm) >= 2;
endfunction
function int n_pass(logic [TAPS-1:0] bm);
int n = 0;
for (int i = 0; i < TAPS; i++) if (bm[i]) n++;
return n;
endfunction
// Returns -1 when the bitmap is empty, so "no pass" is a distinct
// answer rather than index 0 -- the same three-valued discipline
// 27.3 §6 and 27.4 §2 arrived at, here for an index.
function int first_pass(logic [TAPS-1:0] bm);
for (int i = 0; i < TAPS; i++) if (bm[i]) return i;
return -1;
endfunction
function int last_pass(logic [TAPS-1:0] bm);
for (int i = TAPS - 1; i >= 0; i--) if (bm[i]) return i;
return -1;
endfunction
// §5: the width of the contiguous run CONTAINING idx -- not the span
// between the outermost passes, which §13 shows can straddle a gap.
function int commit_window(logic [TAPS-1:0] bm, int idx);
int lo, hi;
if (idx < 0 || idx >= TAPS || !bm[idx]) return 0;
lo = idx; while (lo > 0 && bm[lo-1]) lo--;
hi = idx; while (hi < TAPS - 1 && bm[hi+1]) hi++;
return hi - lo + 1;
endfunction
// §13's trap, computed so a test can assert it is NOT what the
// chooser used: the midpoint of the outermost-pass span.
function int span_midpoint(logic [TAPS-1:0] bm);
int f = first_pass(bm), l = last_pass(bm);
if (f < 0) return -1;
return (f + l) / 2;
endfunction
function bit span_midpoint_is_failing(logic [TAPS-1:0] bm);
int mid = span_midpoint(bm);
if (mid < 0) return 1'b0;
return !bm[mid];
endfunction
endclass| Check | What it establishes |
|---|---|
| Drive §13's verdict stream; compare all five derived outputs | Streaming ledger and rescanning model agree |
| Sweep 4,096 random 12-bit bitmaps through both | Two algorithms agree on windows, fragmented, n_pass, first, last |
| Empty bitmap | first_pass and last_pass return −1, not 0 |
Bitmap 12'b000000000001 | windows=1, fragmented=0, commit_window(0)=1 |
Bitmap 12'b000010011100 (§13's) | windows=2, fragmented=1, commit_window(4)=3, span_midpoint=4 |
Bitmap 12'b000010001100 | span_midpoint_is_failing true — the trap, reproduced |
| Bitmap all ones | windows=1, fragmented=0, n_pass=TAPS |
Bitmap alternating 101010101010 | windows=6, fragmented=1 — maximal fragmentation |
Drive verdict_pass with no setting_applied | P6 fires — n_pass > settings_tried |
Assert timeout after 3 of 16 attempts | settings_tried=3; classifier returns SIG_TIMEOUT_PARTIAL |
Assert step_done with prereq_committed=0 | fail_reason=FR_PREREQ, P11 |
| Assert a second failure after the first | First reason retained, P1/P2 |
Assert clear | Latch released, P3 |
| Run a whole sweep with the sequencer disconnected | All 12 properties pass; all 15 covers empty |
The last row is the report worth publishing, and it is this chapter's version of a checker that proves nothing:
A BOUND LEDGER THAT PROVED NOTHING
stimulus : the ledger is bound, reset is released, and the training
sequencer is never started
p_first_failure_sticky PASS
p_step_start_does_not_clear_latch PASS
p_clear_releases PASS
p_npass_only_on_pass PASS
p_tried_on_apply PASS
p_pass_le_tried PASS
p_npass_bounded PASS
p_have_pass_sticky PASS
p_fragmented_sticky PASS
p_fragmented_matches_windows PASS
p_prereq_outranks_shape PASS
p_fragment_commit_recorded PASS
------------------------------------------------
cover step_start 0 hits
cover verdict_valid && pass 0 hits
cover verdict_valid && !pass 0 hits
cover fail_latched 0 hits
cover fragmented 0 hits
... all 15 covers 0 hits
ten of the twelve properties are implications, so with no sweep they
never arm. The two INVARIANTS -- p_pass_le_tried and
p_npass_bounded -- also pass, correctly: zero never exceeds zero.
diagnosis : this is 27.2's vacuity argument in a debug block. The
covers are the only thing separating a working ledger from an
unconnected one, and a boot log showing "training diagnostics:
no failures recorded" is produced by BOTH.
the fix : read the covers, not the asserts. A ledger whose
step_start cover is empty recorded nothing because nothing ran --
which is a different finding from a clean training pass, and the
module's first law says the difference matters.18. When the Physical Hypothesis Becomes Admissible
§11's last row said physical margin is testable only once the five cheaper domains are excluded. Here is what that exclusion requires and what it still does not buy.
| Domain | Excluded by | Cost |
|---|---|---|
| Control | applied-setting readback changes across the sweep | minutes |
| Observation | captured data changes, and a known-bad setting fails | minutes |
| Configuration | a finer step does not change the window; a wider range finds both edges | an hour |
| Ordering | every prerequisite's committed flag is true | minutes |
| Stale state | the result's provenance matches the active configuration — 28.4 | minutes |
With all five excluded, the surviving statement is narrow and worth quoting exactly: at this frequency, on this pattern, at this voltage and temperature, with this classifier, no setting in the swept range was judged acceptable.
That is a digital result about a digital experiment. It is consistent with a physical margin problem and it is not a measurement of one.
So the escalation is a handoff, not a conclusion. Chapter 28.6 owns what digital evidence justifies moving a hypothesis into the physical channel domain, and what that domain then requires — which is instrumentation this chapter does not have and RTL cannot fake. The honest output of a training investigation that reaches this row is a well-characterised digital experiment plus a named unanswered physical question, not a verdict.
19. Corner Cases
| Case | Behaviour | Why |
|---|---|---|
TAPS = 1 or LANES = 1 | Elaboration fails | $clog2(1) is 0; index vectors would be [-1:0] |
REPEATS = 0 | Elaboration fails | the ledger would record nothing and report success |
| Timeout with 3 of 16 settings tried | SIG_TIMEOUT_PARTIAL, not SIG_NO_PASS | §9 — thirteen zeros were never attempted |
| Bitmap all zero, prerequisite false | FR_PREREQ, not FR_NO_PASS | §3 C, P11 — the step may be blameless |
| Bitmap all ones | SIG_ALL_PASS, no physical hypothesis offered | §4 — the instrument is the finding |
| Two windows, then a third | fragmented stays set, windows = 3 | P9 — stickiness |
| Fragmented bitmap, commit succeeded | Recorded as a finding | P12 — §13's midpoint trap |
| Second failure after a first | First reason retained | P1, P2 — earliest evidence wins |
clear asserted | Latch and reason released | P3 — a latch with no release stops recording |
step_start with a latch set | Per-step evidence cleared, latch retained | §14 — a retry must not erase the boot's first failure |
Commit at first_pass of a 5-wide window | SIG_EDGE_PICK | §2 signature 10 |
| One setting passes 4 of 8 repeats | SIG_UNSTABLE outranks shape | §7 — an unstable bitmap has no stable shape |
| Verdict pass with no prior attempt | P6 fires | n_pass > settings_tried is impossible |
| All five domains excluded | Physical hypothesis admissible | §18 — and still not a measurement |
Rows four and five are the pair to hold together. An all-zero bitmap with a false prerequisite and an all-one bitmap are both signatures about something other than the device, and both are routinely read as statements about margin.
20. Misconceptions
“The pass bitmap is the eye.” §1. It is a digital sample of one classifier's decisions at the settings the search tried, on one pattern, at one voltage and temperature. Eye height and width appear nowhere in it.
“A wide window means good margin.” §1, §4. A weak classifier widens the window and an aggressive pattern narrows it. Width is a property of the experiment as much as the channel.
“All taps passing is a good result.” §4. It is the signature of a classifier that may not be able to fail, and the cheapest test is to demand a failure at a setting known to be bad.
“An all-zero bitmap means no margin.” §3. It is equally consistent with a control defect, an observation defect, an unmet prerequisite, and a mis-programmed range — and three of those are cheaper to exclude.
“A one-tap window is a one-tap-wide window.” §5. It means the window is at or below the step size. A finer sweep distinguishes a badly sampled comfortable window from a genuinely narrow one.
“Take the midpoint of the passing range.” §6, §13. With disjoint windows the span's midpoint can be a failing setting, and the chooser then commits a bad value while reporting success.
“Training timed out, so training failed.” §9. A timeout leaves a partial bitmap whose zeros include settings never tried. It supports nothing about margin.
“It passed on retry, so it is fine.” The module's fourth law. A passing retry does not explain the first attempt, and if the first differs from all later ones, the first ran in a state the others did not.
“Lane 3 fails, so lane 3's channel is bad.” §8. Lane-local is a location result. That path includes the lane's delay setting, its capture logic, its classifier share, and its board and device pin.
“Raising the timing setting fixed it.” The module's third law. A configuration change that makes a failure disappear is an experiment; without excluding §11's cheaper domains it tested nothing.
“The ledger tells you the root cause.” §16's callout. It tells you the first recorded failure and the shape of the evidence. §1's four layers are all upstream of every signal it sees.
21. Interview Reasoning
Training failed. What is your first question? Not why did the device fail — whether the sweep actually happened. Read back the applied setting across the sweep; if it never changed, the bitmap contains no information about the device.
What does an all-zero bitmap tell you? That the composition of control, capture, physics and classification produced no pass. Four hypotheses, and margin is the last to test because it is the only one that needs the others excluded first.
Why is an all-passing bitmap suspicious? Because a classifier that cannot fail produces it. Apply a setting known to be bad and demand a failure; if it passes, every bitmap that instrument ever produced is uninterpretable.
You see two separated passing windows. What do you do? Rotate the sweep start point. If the range is cyclic the two may be one window seen across the wrap; if they stay disjoint there are two genuine regions. Either way, do not take the midpoint of the span.
Why not the midpoint? With passes at 2–4 and 7, the span midpoint is 4.5 and settings 5 and 6 both fail. The chooser commits a failing value and reports success.
Training timed out. Is that the same as failing? No. The bitmap is partial and its zeros include settings never attempted, so no margin statement is available. Raise the budget: completing means a budget or liveness problem, stopping at the same index localises a stuck sweep.
One lane fails. What have you localised? A path, not a cause. That path is the lane's delay setting, its capture logic, its share of the classifier, its package and board trace, and its device pin. Swapping the device tells you which side of it the cause is on.
A second training pass gives a different answer. What does that mean? The step depends on state it does not control. Compare pass two with pass three: if they agree with each other and not with pass one, pass one ran in a state the others did not.
When may you say the problem is physical margin? Only after excluding control, observation, configuration, ordering and stale state by experiment. And the surviving statement is still a digital one — no setting in the swept range was judged acceptable under these conditions.
Your bitmap looks fine and the system still fails. What now? The bitmap is not the eye. A committed setting at the centre of a wide window under a weak pattern can fail under real traffic, which is why 28.5 treats corruption as a separate investigation rather than a training result.
22. Exercises
-
§1 decomposes a bitmap bit into four layers. For each layer, construct a fault that produces an all-zero bitmap, then give the cheapest observation that distinguishes it from the other three.
-
§5 shows a one-tap window under a one-tap step. Derive the range of true window widths consistent with that observation, stating your alignment assumption, and say what a half-step sweep would show for each.
-
§6 lists three mechanisms for disjoint windows. Design a single sweep that distinguishes all three in one pass, and state what it costs compared with three separate experiments.
-
§13's chooser averages the span extremes. Write the rule you would use instead, then construct the bitmap on which your rule also fails.
-
§14 latches the first failure reason. Construct the boot sequence in which this hides a more informative later failure, and decide whether you would change the priority.
-
§15's
physical_hypothesis_admissible()takes five booleans it cannot compute. Argue for and against deriving them from the ledger instead, then decide. -
§7 distinguishes instability in four locations. For the "first repeat differs, later repeats agree" signature, write the bring-up change that would remove it and say which of 28.7's stages it belongs to.
-
A colleague reports that lowering the frequency makes training pass, and proposes shipping at the lower frequency. Identify every hypothesis that result is consistent with, and state what would have to be true for it to be a fix rather than an experiment.
23. Where This Goes
A training failure is a signature, and a signature is a projection. A bitmap bit is the composition of control, capture, physics and classification, so no shape identifies a layer; the eleven signatures each admit several causes; the six domains are testable cheapest-first and each invalidates the evidence for the next; and the physical hypothesis is admissible only once the other five are excluded — at which point the surviving statement is still digital.
Four results carry forward. An all-passing bitmap is a finding about the instrument, and the test is to demand a failure. A timeout's bitmap is partial, so its zeros are not evidence. The span midpoint of a fragmented bitmap can be a failing setting. And the first recorded failure is not the first causal failure — which is why §14 latches a reason and checks prerequisites before shapes.
Two things stay open. Nothing here measures margin, and §18's escalation is a handoff with a named unanswered question rather than a conclusion. And the prerequisite's own committed flag is taken on trust — a step can report success and commit a stale or unconverged result, which is 28.4's subject.
Chapter 28.2 takes the next failure family, and its character is different in a way worth stating. A training failure is a search that did not succeed; a timing violation is a rule that was broken, and rules name their own evidence. Module 14 owns the parameters and Module 17 owns the scheduler that must respect them, so the question is never whether something is wrong — it is which issued command violated which resource-specific contract, and answering it requires reconstructing the command that came before, on the same resource, and the separation the device actually required.
Continue learning
Related tutorials
- Related topic
Timing Alignment
A write command and its data leave the PHY on different paths and must arrive in a defined relationship. The device specifies the relationship; the PHY absorbs the difference between the paths.
- Related topic
Write Leveling Algorithm
Chapter 20.4 built a probe that asks the device one yes-or-no question. Turning it into a search means sweeping a delay, distrusting any single answer near the boundary, confirming a transition, and keeping the candidate out of the production datapath.
- Related topic
Read Leveling
The read side has no phase comparator, only a correctness bit. That forces a two-edge search over a full sweep, an MPR stimulus whose format decides what can be trained at all, and per-bit adjustment to recover per-pin skew.
- Related topic
Gate Training
The DQS gate exists only inside the PHY, so JEDEC defines no procedure for it — only a preamble the PHY can find. The resulting search has a one-sided pass region whose safe side produces no observable at all.
Standards & specifications
- Governing standard
- JEDEC JESD79 (DDR SDRAM)(opens JEDEC Solid State Technology Association in a new tab)
Defines the DDR SDRAM device itself — signals, command encoding, mode registers, timing parameters and the initialisation sequence — one document per generation. Memory-controller microarchitecture, address-mapping policy, PHY training algorithms and board-level design are not specified by it.
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 DDR curriculum.
