DDR · Module 34
“Refresh Only Affects Idle Systems”
Refresh really can be deferred under load — the specification permits eight postponements — and the deferral is exactly what turns a 4.49% average into a 2,240-cycle block at the moment a deadline-bearing requester is waiting.
“Refresh is a few percent, and the controller defers it when we are busy. It only really shows up on an idle system.”
Chapter 34.1 §1 set out the anatomy this module follows: a true statement with a scope, repeated until the scope fell off. This belief has an unusually strong true core — two of its three clauses are correct and verified — and the third is where it inverts.
DERIVED: refresh's average cost really is a few percent. The controller really can defer it under load. And the deferral is the mechanism that converts the average into a burst. The belief is not merely wrong at its boundary; its own stated mechanism is what carries it across.
That makes this the first of two chapters in this module where the belief is self-defeating rather than merely over-generalised, and it is the reason it survives in people who can quote the availability arithmetic.
1. The One-Sentence Correction
Refresh's average cost is a few percent and its instantaneous cost is a full
tRFCduring which the rank serves nothing — and because the specification permits deferring up to eight refreshes, a loaded controller can accumulate them and then owe all eight at once, which is the moment a deadline-bearing requester is most likely to be waiting.
CURRICULUM-DERIVED from 15.5, which owns the availability arithmetic and states the qualification this chapter is built on: it ignores clustering, and “a controller that uses the allowance and then catches up produces a burst of refresh” while the average is unchanged.
2. What This Chapter Owns
| Ground | Owner |
|---|---|
| Why refresh exists, derived from one physical property | 15.1, 30.1 |
The refresh commands and tRFC's occupancy | 15.2 |
| The verified postponement and pull-in allowance; the signed credit ledger | 15.3 §1, 15.3 §4 |
| Due, urgent and overdue; the gap bound | 15.3 §3 |
| Retention time and its temperature dependence | 15.4 |
| The availability arithmetic across density, mode and temperature | 15.5 |
| The average-versus-deadline distinction, as an interview answer | 30.1 |
| The refresh manager, and illegal versus deprioritised | 17.3 |
| The obligation / service / correlation split when refresh is suspected | 28.3 |
| Scheduler misconceptions about how to use the allowance | 15.3 §13 |
| Why the belief is plausible, and that its own mechanism refutes it | this chapter |
Two boundaries need stating, because this belief sits between chapters that each own half the correction.
With 15.3 §13: that section already lists “the controller can postpone refresh indefinitely if traffic is busy” as a misconception, and refutes it with the bound. DERIVED: 15.3's list is about how to build the scheduler and is addressed to someone writing one. This chapter's belief is upstream of that and is held by people who are not writing a scheduler — it is a claim about whether refresh is worth thinking about at all, and §14 measures what it costs an architect who dismisses it.
With 30.1: that chapter owns the average-versus-deadline distinction as the thing that separates a junior answer from a competent one. DERIVED: 30.1 teaches the distinction; this chapter measures the gap between the two quantities and shows that the gap is produced by a feature, not by a defect.
3. Teaching-Model Boundary And Source Discipline
Every SystemVerilog block below is an educational model of a refresh accounting, not a refresh manager. 17.3 owns the manager.
| Claim class | What it means here | Example below |
|---|---|---|
| Structural | a verified datasheet figure or a documented rule | the 8/16/32 postponement limits; the 9×tREFI gap bound; the ±8 ledger |
| Curriculum-derived | follows from a cited chapter of this track | the availability arithmetic, the clustering qualification, the debt ledger |
| Derived | computed in this chapter from the models below | every burst figure and deadline count in §17 |
| Illustrative | a chosen number that makes a mechanism visible | cycle counts, class mixes, deadlines, temperatures |
The postponement limits are STRUCTURAL and verified. CURRICULUM-DERIVED from 15.3 §1, which verifies against a Micron 16Gb DDR4 datasheet: a maximum of 8 postponed REFRESH commands in 1X mode, 16 in 2X, 32 in 4X — and the resulting worst-case interval between surrounding REFRESH commands bounded at 9 × tREFI. This chapter consumes those and derives none.
The availability figures are STRUCTURAL and come from 15.5: at 8Gb with tRFC1 = 350 ns and tREFI = 7.8 µs, the unavailable fraction is 4.49%; at 4Gb with tRFC1 = 260 ns it is 3.33%. Every cycle count below is ILLUSTRATIVE, converted at a chosen clock so the arithmetic is legible.
No external source was consulted and no network tool was used.
4. Why a Competent Engineer Believes It
| # | The true statement | What the belief does with it |
|---|---|---|
| 1 | Refresh's average cost is 4.49% at 8Gb | treats an average as a description of every interval |
| 2 | The specification explicitly permits deferring refresh under load | treats a bounded allowance as an unbounded one |
| 3 | A throughput benchmark loses a few percent and nothing else | treats the metric it measured as the metric that matters |
| 4 | On an idle system refresh is a larger fraction of the work done | treats a larger fraction as a larger cost |
Reason 2 is the one that makes this belief different from the other five in this module, and it deserves the emphasis. CURRICULUM-DERIVED from 15.3 §1, which verifies the datasheet's own words: flexibility is provided “to allow for improved efficiency in scheduling and switching between tasks.” DERIVED: the belief is not ignoring the specification — it is quoting it. A controller does defer refresh when busy, and it does so because the standard invites it.
Reason 4 is an inversion worth naming because it is the belief's namesake. DERIVED: on an idle system refresh is a large fraction of a small amount of work, and on a loaded system it is a small fraction of a large amount — and the absolute cycles are identical. The belief reads the fraction and calls the idle case worse; the fraction is higher and the impact is zero, because nothing is waiting.
THE INVERSION, STATED PLAINLY (ILLUSTRATIVE, one tREFI window)
idle system refresh = 350 ns of 7800 ns of MOSTLY NOTHING
fraction 4.49% requests delayed: 0
loaded system refresh = 350 ns of 7800 ns of SOLID TRAFFIC
fraction 4.49% requests delayed: every one
that arrives in the window
DERIVED: the fraction is the same and the consequence is not.
The belief compares fractions and concludes about consequences.5. The Region Where the Claim Is True
"REFRESH ONLY AFFECTS IDLE SYSTEMS" HOLDS WHEN ALL THREE ARE TRUE:
1 the METRIC is average bandwidth over a window >> tREFI
2 the load has GAPS wide enough to absorb deferred refresh
3 no requester carries a DEADLINE shorter than the gap bound
and then: the cost is 4.49% of bandwidth and nothing else
(STRUCTURAL, 8Gb, 15.5's arithmetic)DERIVED: the region is non-empty and it contains most throughput benchmarks. A streaming bandwidth test measures exactly condition 1, is usually bursty enough for condition 2, and has no deadline at all. CURRICULUM-DERIVED from 15.5, whose scope statement is precisely this region: it computes an availability fraction from published parameters and stops — no workload modelling, no queueing analysis. The belief is 15.5's result with 15.5's scope removed.
Condition 3 is the one that fails first, and it fails by a large margin rather than marginally. DERIVED: the gap bound is 9 × tREFI, and a requester with a deadline shorter than that can be blocked by a mechanism that is entirely legal — CURRICULUM-DERIVED from 15.3 §3, which owns the bound.
6. The Boundary, Computed
ILLUSTRATIVE clock: 1.25 ns per cycle, so tRFC1 = 350 ns = 280 cycles and tREFI = 7.8 µs = 6,240 cycles.
| Exit | Condition | Cost | Owner |
|---|---|---|---|
| 1 | one refresh lands on a waiting request | + 280 cycles | 15.2 |
| 2 | the allowance is used, then repaid | 8 × 280 = 2,240 cycles, clustered | 15.3 §1, 15.5 |
| 3 | a deadline shorter than the gap bound exists | missed, legally | 15.3 §3 |
| 4 | temperature crosses the retention threshold | interval halves; cost doubles | 15.4, 15.5 |
| 5 | finer refresh mode | tRFC4 160 ns but tREFI4 a quarter | 15.5 |
Row 2 is the chapter, and the arithmetic is worth doing slowly. DERIVED: across a long window the average is unchanged — eight deferred refreshes are eight refreshes — but they are no longer spread across eight intervals. CURRICULUM-DERIVED from 15.5: “the average is unchanged” is 15.5's own sentence about exactly this case.
SAME AVERAGE, DIFFERENT WORST CASE (ILLUSTRATIVE, cycles)
spread: 280 every 6240 worst wait for a new request: 280
clustered: 2240 every 49920 worst wait for a new request: 2240
average unavailable fraction: 4.49% in BOTH
worst-case blocking: 8x differentDERIVED: a single number — the average — is identical across an 8× difference in the quantity a real-time requester experiences. That is 30.1's average-versus-deadline distinction with a measured multiplier on it.
7. The Average, and What It Cannot See
CURRICULUM-DERIVED from 15.5, which owns the availability arithmetic and its behaviour across density, mode and temperature. This chapter consumes the arithmetic and models what the arithmetic explicitly excludes.
// ROBUST INSTRUMENT: the average AND the distribution it hides.
// 15.5 computes the fraction and says it ignores clustering; this
// publishes both, so the belief's evidence and its refutation appear
// in the same report.
module availability_arithmetic #(
parameter int TRFC_CYC = 280, // ILLUSTRATIVE: 350 ns at 1.25 ns
parameter int TREFI_CYC = 6240, // ILLUSTRATIVE: 7.8 us
parameter int WIN = 49920 // ILLUSTRATIVE: 8 x tREFI
)(
input logic clk,
input logic rst_n,
input logic refresh_busy, // this cycle serves refresh
input logic request_waiting, // a request is queued right now
output logic report_valid,
output logic [19:0] refresh_cycles,
output logic [19:0] window_cycles,
output logic [7:0] avg_unavail_x100, // the number the belief quotes
output logic [19:0] longest_block, // the number it cannot see
output logic [19:0] blocked_request_cycles,
output logic [15:0] blocks_observed
);
logic [19:0] win_cnt, run_len;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
win_cnt <= '0; run_len <= '0; refresh_cycles <= '0;
window_cycles <= '0; avg_unavail_x100 <= '0; longest_block <= '0;
blocked_request_cycles <= '0; blocks_observed <= '0;
report_valid <= 1'b0;
end else begin
report_valid <= 1'b0;
if (refresh_busy) begin
refresh_cycles <= refresh_cycles + 1'b1;
run_len <= run_len + 1'b1;
// The quantity a deadline experiences: refresh cycles during
// which something was actually waiting. The average cannot
// distinguish these from refresh at idle -- section 4's inversion.
if (request_waiting)
blocked_request_cycles <= blocked_request_cycles + 1'b1;
end else begin
// A run just ended: record its length if it is the longest.
if (run_len != '0) begin
if (run_len > longest_block) longest_block <= run_len;
blocks_observed <= blocks_observed + 1'b1;
end
run_len <= '0;
end
if (win_cnt == WIN[19:0]) begin
window_cycles <= WIN[19:0];
avg_unavail_x100 <= 8'((refresh_cycles * 20'd10000) / 20'(WIN));
report_valid <= 1'b1;
win_cnt <= '0; refresh_cycles <= '0;
end else begin
win_cnt <= win_cnt + 1'b1;
end
end
end
endmodule// INTENTIONALLY DEFECTIVE. WEAK INSTRUMENT: the average alone.
//
// avg_unavail_x100 <= 8'((refresh_cycles * 20'd10000) / 20'(WIN));
// // no run-length tracking, no longest_block, no
// // blocked_request_cycles
//
// CONTRACT VIOLATED: none in the arithmetic -- 15.5's fraction is
// computed exactly right. The defect is that 15.5 STATES it ignores
// clustering and this instrument does not carry the qualification.
//
// WHY IT SURVIVES: the number is correct, it matches the datasheet
// arithmetic, and it is stable across every workload -- which reads as
// robustness and is actually insensitivity.
//
// TRACE (ILLUSTRATIVE, two controllers, 49920-cycle window):
// controller S -- services refresh on time, one per tREFI:
// 8 runs of 280 refresh_cycles 2240
// robust: avg 4.49%, longest_block 280, blocks_observed 8
// weak: avg 4.49%
// controller C -- uses the full allowance, then repays:
// 1 run of 2240 refresh_cycles 2240
// robust: avg 4.49%, longest_block 2240, blocks_observed 1
// weak: avg 4.49%
//
// gap: an 8x difference in the worst-case block, reported as no
// difference. And `blocked_request_cycles` separates them further:
// under load, controller C blocks a waiting request for 2240
// consecutive cycles and controller S never blocks one for more
// than 280.The two controllers are indistinguishable on the belief's metric and differ by 8× on the one a deadline experiences. DERIVED: avg_unavail_x100 reads 4.49% for both, and that number is exactly right for both — so the belief is not relying on a wrong measurement; it is relying on a correct measurement of a quantity that does not answer the question.
8. The Allowance Is Bounded, and the Bound Is the Mechanism
CURRICULUM-DERIVED from 15.3 §4, which owns the signed credit ledger and its verified bounds: D ≤ +8 postponement and D ≥ −8 pull-in in 1X mode, where debt increments every nominal interval and decrements on every refresh accepted.
This chapter consumes the ledger and models the consequence the belief depends on and does not follow through: what happens when the bound is reached.
// ROBUST MODEL: 15.3's signed ledger with its verified bound enforced,
// and the forced-burst consequence made visible.
module postponement_ledger #(
parameter int MAX_DEBT = 8, // STRUCTURAL: 1X mode, verified
parameter int TRFC_CYC = 280, // ILLUSTRATIVE
parameter int TREFI_CYC = 6240 // ILLUSTRATIVE
)(
input logic clk,
input logic rst_n,
input logic interval_tick, // one nominal tREFI elapsed
input logic refresh_done,
input logic traffic_busy,
output logic refresh_request,
output logic refresh_forced, // the allowance is exhausted
output logic signed [7:0] debt,
output logic [15:0] forced_events,
output logic [19:0] forced_burst_cycles,
output logic debt_within_bound
);
logic [7:0] pending_burst;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
debt <= '0; refresh_request <= 1'b0; refresh_forced <= 1'b0;
forced_events <= '0; forced_burst_cycles <= '0;
debt_within_bound <= 1'b1; pending_burst <= '0;
end else begin
if (interval_tick && !refresh_done) debt <= debt + 8'sd1;
else if (refresh_done && !interval_tick) debt <= debt - 8'sd1;
// The bound is 15.3's, and enforcing it is what converts a
// deferral policy into a forced burst. This is the whole item.
debt_within_bound <= (debt <= 8'sd8) && (debt >= -8'sd8);
refresh_forced <= (debt >= 8'sd(MAX_DEBT));
// Below the bound the controller may defer freely -- and the
// belief is correct in exactly this branch.
if (debt >= 8'sd(MAX_DEBT)) begin
// At the bound refresh stops being deferrable. Traffic is
// irrelevant now: 17.3's illegal-versus-deprioritised line.
refresh_request <= 1'b1;
if (pending_burst == '0) begin
pending_burst <= 8'(MAX_DEBT);
forced_events <= forced_events + 1'b1;
end
end else begin
refresh_request <= !traffic_busy;
end
if (pending_burst != '0) begin
forced_burst_cycles <= forced_burst_cycles + 20'(TRFC_CYC);
if (refresh_done) pending_burst <= pending_burst - 1'b1;
end
end
end
endmodule// INTENTIONALLY DEFECTIVE. WEAK MODEL: defer while busy, no bound.
// This is the belief written as RTL -- and note it is the belief's own
// stated mechanism, not a caricature of it.
//
// refresh_request <= !traffic_busy; // <-- and nothing else
// // no MAX_DEBT check, no forced branch, no ledger bound
//
// CONTRACT VIOLATED: 15.3 section 1's verified limit of 8 postponed
// commands, and 15.3 section 4's D <= +8.
//
// WHY IT SURVIVES: under any traffic pattern with gaps, `!traffic_busy`
// fires often enough that the debt never approaches 8. The model is
// correct on every workload that has idle time -- which is every
// workload anybody profiles.
//
// TRACE (ILLUSTRATIVE, 12 intervals; sustained traffic from interval 2):
// intervals 1-2 gaps present, refresh serviced, debt 0
// intervals 3-10 solid traffic:
// robust: debt climbs 1..8; at 8 `refresh_forced` asserts and the
// controller issues refresh REGARDLESS of traffic.
// forced_events 1, forced_burst_cycles 2240,
// debt_within_bound 1 throughout.
// weak: debt climbs 1..8..9..10..11..12 unchecked. No refresh
// is issued for 8 solid intervals and then some.
// debt_within_bound goes FALSE at interval 11.
// interval 11-12 traffic subsides:
// robust: debt already repaid during the forced burst; debt 0
// weak: 12 refreshes issued back to back = 3360 cycles, and
// the retention obligation was already violated at
// interval 11 -- 15.3 section 4: exceeding DEBT risks data.
//
// gap: the robust build pays 2240 cycles at a moment it chooses and
// bounded by the specification; the weak build pays 3360 cycles at a
// moment traffic chooses, after a retention violation.
//
// And the belief's own claim -- that deferral makes refresh free
// under load -- is TRUE for intervals 3 through 10 in both builds.
// It becomes false at interval 11 in one and at the bound in the
// other. The belief describes the first eight intervals exactly.The last paragraph of that trace is this chapter's central finding. DERIVED: the belief is a correct description of the first eight intervals of sustained load, and sustained load lasting more than eight intervals is what a real system does. CURRICULUM-DERIVED from 15.3 §13, which records the scheduler-side form — “a controller that defers under load” meets a bounded allowance — and this chapter's addition is that the deferral window is 8 × 7.8 µs ≈ 62 µs, which is a long time to a profiler and no time at all to a running system.
9. Where the Cost Actually Lands
The belief's third clause — it only shows up on an idle system — is not merely wrong; it points at the wrong requester.
CURRICULUM-DERIVED from Module 32, whose spine is that platform classes differ in their requester mix, and from 33.5 §10, which established that an aggregate statistic over a mixed population is dominated by the members who cannot be late.
// ROBUST INSTRUMENT: per-class exposure, because refresh blocking is
// not distributed like the traffic that caused the deferral.
module deadline_exposure #(
parameter int NCLASS = 4, // 0 realtime 1 latency 2 bulk 3 bg
parameter int TRFC_CYC = 280 // ILLUSTRATIVE
)(
input logic clk,
input logic rst_n,
input logic arrive,
input logic [1:0] req_class,
input logic [15:0] deadline, // 0 = this class has none
input logic refresh_busy,
input logic [15:0] wait_cycles, // this request's observed wait
input logic retire,
input logic [1:0] ret_class,
output logic [15:0] arrivals [0:NCLASS-1],
output logic [15:0] blocked [0:NCLASS-1],
output logic [15:0] misses [0:NCLASS-1],
output logic [15:0] worst_wait [0:NCLASS-1],
output logic any_miss,
output logic [19:0] agg_wait_sum,
output logic [15:0] agg_count,
// per class, because section 9's whole argument is a comparison
// between the aggregate and the class the aggregate hides
output logic [19:0] cls_wait_sum [0:NCLASS-1],
output logic [15:0] cls_retired [0:NCLASS-1],
output logic [15:0] agg_mean,
output logic [15:0] rt_mean,
output logic aggregate_hides_a_class
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
any_miss <= 1'b0; agg_wait_sum <= '0; agg_count <= '0;
agg_mean <= '0; rt_mean <= '0; aggregate_hides_a_class <= 1'b0;
for (int c = 0; c < NCLASS; c++) begin
arrivals[c] <= '0; blocked[c] <= '0;
misses[c] <= '0; worst_wait[c] <= '0;
cls_wait_sum[c] <= '0; cls_retired[c] <= '0;
end
end else begin
if (arrive) begin
arrivals[req_class] <= arrivals[req_class] + 1'b1;
// Arriving INTO a refresh is the exposure the average hides.
if (refresh_busy) blocked[req_class] <= blocked[req_class] + 1'b1;
end
if (retire) begin
// The aggregate is still computed. It is not useless -- it is
// insufficient, and publishing both is the item.
agg_wait_sum <= agg_wait_sum + 20'(wait_cycles);
agg_count <= agg_count + 1'b1;
if (wait_cycles > worst_wait[ret_class])
worst_wait[ret_class] <= wait_cycles;
cls_wait_sum[ret_class] <= cls_wait_sum[ret_class] + 20'(wait_cycles);
cls_retired[ret_class] <= cls_retired[ret_class] + 1'b1;
if ((deadline != '0) && (wait_cycles > deadline)) begin
misses[ret_class] <= misses[ret_class] + 1'b1;
any_miss <= 1'b1;
end
// The two means, side by side. 33.5 section 10's finding is that
// the aggregate is dominated by the members who cannot be late,
// and this makes the domination measurable rather than argued.
agg_mean <= (agg_count == '0) ? '0
: 16'(agg_wait_sum / 20'(agg_count));
rt_mean <= (cls_retired[0] == '0) ? '0
: 16'(cls_wait_sum[0] / 20'(cls_retired[0]));
// The flag a report must carry: a class whose worst case is far
// above the aggregate mean is a class the mean does not describe.
aggregate_hides_a_class <=
(agg_count != '0)
&& (worst_wait[0] > (16'(agg_wait_sum / 20'(agg_count)) * 16'd4));
end
end
end
endmodule// INTENTIONALLY DEFECTIVE. WEAK INSTRUMENT: the aggregate mean wait.
//
// agg_wait_sum <= agg_wait_sum + wait_cycles;
// agg_count <= agg_count + 1;
// // mean_wait = agg_wait_sum / agg_count ; no class split, no
// // deadline comparison, no worst_wait
//
// CONTRACT VIOLATED: 30.1's average-versus-deadline distinction, and
// 23.1's finding that the average is the wrong statistic.
//
// TRACE (ILLUSTRATIVE, 1000 requests over a window containing one
// forced burst of 2240 cycles; mix from Module 32's classes):
// class 0 realtime 40 reqs, deadline 400 cycles
// class 1 latency 160 reqs, deadline 900 cycles
// class 2 bulk 600 reqs, no deadline
// class 3 background 200 reqs, no deadline
//
// robust: blocked = {3, 11, 42, 14} -- proportional to arrivals
// worst_wait = {2263, 2271, 2402, 2388}
// misses = {3, 0, 0, 0} any_miss = 1
// weak: mean wait 61 cycles -- "refresh costs us 4.5%, fine"
//
// gap: three realtime requests missed a 400-cycle deadline because
// they arrived during a 2240-cycle forced burst, and the aggregate
// mean is 61 cycles. 800 of 1000 requesters have no deadline and
// carry 80% of the mean's weight -- 33.5 section 10's mechanism, and
// here the thing the mean is hiding is a legal, specified, bounded
// refresh burst.The two means are the finding, and publishing both is the entire remedy. DERIVED: agg_mean reads 61 cycles and rt_mean reads 402 — a 6.6× separation between the number a dashboard shows and the number the real-time class experiences. And aggregate_hides_a_class asserts when a class's worst case exceeds four times the aggregate mean, which is a condition a single-class stimulus can never produce and a mixed one produces routinely.
And the blocked distribution is worth reading against arrivals, because it is the one place the belief's intuition is nearly right. DERIVED: blocking is proportional to arrivals — {3, 11, 42, 14} against {40, 160, 600, 200} is close to uniform at about 7% — so refresh really does hit every class equally. What differs is not the exposure but the consequence: the bulk class absorbs a 2,400-cycle wait and the realtime class misses. CURRICULUM-DERIVED from Module 32: the classes have incomparable requirements, so an equally-distributed cost has unequally-distributed consequences, and a per-class split is the only instrument that shows it.
Three missed deadlines against an aggregate mean of 61 cycles, and every part of the mechanism is legal. DERIVED: no timing rule was violated, the debt never exceeded 8, the average stayed at 4.49%, and a real-time client glitched. CURRICULUM-DERIVED from 28.3's three-way split: this is a service outcome rather than an obligation failure, and 28.3's point that refresh-correlated corruption is not a retention verdict has a mirror here — refresh-correlated lateness is not a controller defect.
10. One Deadline, One Forced Burst
The diagram earns its place because the failure is a coincidence in time between two independent schedules, and a table cannot show a coincidence.
Read the third and fourth messages together: the controller did the right thing at both. DERIVED: deferring while busy is what the specification invites, and repaying at the bound is what it requires — so the request's lateness is produced by two correct decisions, and there is no line of RTL to fix. CURRICULUM-DERIVED from 17.3's illegal-versus-deprioritised distinction: refresh at the bound is not deprioritisable, and the arrival's timing is not the controller's to choose.
11. Temperature, and the Belief's Second Inversion
CURRICULUM-DERIVED from 15.4, which owns retention and its temperature dependence, and from 15.5, which owns the availability arithmetic's behaviour across temperature.
DERIVED: the belief's region is not fixed — it shrinks as the part heats, and a loaded system is the hot one. That is the second self-defeating property in this chapter: the condition that makes the belief matter is the condition that makes it more wrong.
// ROBUST MODEL: the refresh interval is DERIVED from the retention
// condition, so a hot part refreshes more often and the availability
// cost follows -- 15.5's temperature row, made structural.
module thermal_interval #(
parameter int TREFI_NOM = 6240, // ILLUSTRATIVE cycles, normal range
parameter int T_THRESH = 85, // ILLUSTRATIVE degrees C
parameter int TRFC_CYC = 280 // ILLUSTRATIVE
)(
input logic clk,
input logic rst_n,
input logic [7:0] temp_c,
input logic [1:0] mode, // 0 = 1X, 1 = 2X, 2 = 4X
input logic sample,
output logic [19:0] trefi_in_use,
output logic [7:0] unavail_x100,
output logic [7:0] debt_headroom_intervals,
output logic derived_from_temp
);
// STRUCTURAL, from 15.5: tRFC1 350 ns, tRFC4 160 ns -- UNDER HALF --
// while tREFI4 is a QUARTER of tREFI. Both are needed because the two
// move at different rates, which is the whole of section 6's row 5.
function automatic int unsigned trfc_of_mode();
case (mode)
2'd0: return TRFC_CYC; // 350 ns
2'd1: return (TRFC_CYC * 3) / 4; // ILLUSTRATIVE intermediate
default: return (TRFC_CYC * 4) / 7; // ~160 ns of 350 ns
endcase
endfunction
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
trefi_in_use <= 20'(TREFI_NOM); unavail_x100 <= '0;
debt_headroom_intervals <= 8'd8; derived_from_temp <= 1'b0;
end else if (sample) begin
// Above the extended-range threshold the interval halves. The
// mechanism is 15.4's: retention falls, so the obligation's
// deadline tightens.
automatic logic [19:0] ivl = (temp_c > 8'(T_THRESH))
? 20'(TREFI_NOM / 2) : 20'(TREFI_NOM);
trefi_in_use <= ivl;
unavail_x100 <= 8'((20'(trfc_of_mode()) * 20'd10000)
/ (ivl >> (2 * mode)));
// And the deferral headroom, in WALL TIME, halves with it: the
// COUNT rises with the mode and each interval shrinks faster --
// 15.5's finding that the two rates move at different speeds.
debt_headroom_intervals <= (mode == 2'd0) ? 8'd8
: (mode == 2'd1) ? 8'd16 : 8'd32;
derived_from_temp <= 1'b1;
end
end
endmodule WHAT HALVING THE INTERVAL DOES (ILLUSTRATIVE, tRFC 280 cycles)
normal range tREFI 6240 unavailable 4.49%
deferral headroom 8 x 6240 = 49,920 cycles
extended range tREFI 3120 unavailable 8.97%
deferral headroom 8 x 3120 = 24,960 cycles
DERIVED: the cost doubles AND the time before the forced burst
halves. A hot, loaded part reaches the bound in half the time and
pays twice as much when it gets there.DERIVED: the postponement count stays at 8 and the wall time it buys halves, which is the part the belief's users do not expect — the allowance is denominated in intervals, and the intervals shrank. CURRICULUM-DERIVED from 15.5, which records the same collision for refresh mode: tRFC4 is under half of tRFC1 while tREFI4 is a quarter, so the two rates move at different speeds.
12. Why the Belief Is Self-Defeating
Three of this module's six beliefs are over-generalisations. This one is a loop, and the loop is worth drawing explicitly.
1 refresh is a few percent on average TRUE (15.5)
2 so the controller defers it under load TRUE (15.3 section 1)
3 so under load refresh appears to cost nothing TRUE for <= 8 intervals
4 so deferred refreshes accumulate ... to the bound
5 so they are repaid AS A BURST 2240 cycles (15.5)
6 so the worst-case block is 8x the average DERIVED, section 6
7 which lands on whichever requester is waiting section 9
DERIVED: step 2 -- the mechanism the belief cites as its evidence --
is the direct cause of step 5. The belief's support is its refutation
with four more steps of reasoning applied.That structure is why quoting the availability arithmetic at a holder of this belief does not work. DERIVED: they already have it — it is step 1, and it is correct. The correction has to begin at step 4, which is the only step with a bound in it, and the bound is 15.3 §1's verified 8.
CURRICULUM-DERIVED from 30.1, whose Q4 is exactly this: a controller meets the average refresh rate exactly — is the device guaranteed to retain its data? DERIVED: 30.1 asks the question about retention and the same structure answers a second question about latency — an average over a long window and a per-request exposure are different constraints, and satisfying one says nothing about the other.
It is worth contrasting the two loops this module has now shown, because the difference decides how each belief is corrected.
| 34.1's belief | this chapter's belief | |
|---|---|---|
| Shape | a component mistaken for the sum | a cost deferred and then clustered |
| Its evidence | a datasheet number and a bench test | an availability figure and a specification clause |
| Is the evidence correct? | yes, in the row-hit idle case | yes, in every case |
| Where the correction starts | the decomposition — add the other terms | step 4 — the allowance has a bound |
| What refutes it | a loaded measurement | a 62 µs sustained load |
| Self-defeating? | no — the belief is simply incomplete | yes — its mechanism is the cause |
DERIVED: 34.1's belief is corrected by adding information — the terms it omits. This one is corrected by following its own reasoning further, because steps 1 through 3 are sound and step 4 is where it stops. That is why the two need different conversations: one needs a decomposition and the other needs a bound.
The second self-defeating belief in this module is 34.6's, and the pair is worth naming here. DERIVED: there, unchanged access granularity is cited as evidence that nothing structural changed — and holding granularity constant is precisely what the structural change was performed to achieve. Both beliefs cite the output of a deliberate mechanism as evidence that the mechanism is absent.
And the general form is worth stating once, since two of this module's six beliefs have it. DERIVED: a self-defeating belief cites a real optimisation as evidence that a cost is absent, when the optimisation's function is to relocate the cost. Deferral does not remove refresh cycles; it moves them. CURRICULUM-DERIVED from 15.3 §4's framing of the ledger as a conservation statement — each pulled-in command reduces the number required later by one — which is precisely the statement that a deferral is a relocation, and it sits in the chapter the belief's holders have usually read.
13. Reserving Headroom — The Trade the Belief Conceals
The chapter so far establishes that the burst exists. This section is the actionable half, because a finding with no available response is a complaint.
DERIVED: the specification's limit is 8, and nothing requires a controller to use all of it. A controller that forces repayment at a lower threshold pays more average bandwidth and caps its worst-case block — and that trade is the thing the belief conceals, because a belief that refresh is free under load does not present a trade at all.
// ROBUST MODEL: deferral is bounded by a RESERVE threshold below the
// specification's limit, so the worst-case block is a design choice
// rather than a consequence. 15.3 section 1's 8 is the ceiling; RESERVE
// is where this controller chooses to stop.
module deadline_reserved_deferral #(
parameter int SPEC_MAX = 8, // STRUCTURAL: 1X mode, verified
parameter int RESERVE = 3, // ILLUSTRATIVE design choice, <= SPEC_MAX
parameter int TRFC_CYC = 280, // ILLUSTRATIVE
parameter int TREFI_CYC = 6240 // ILLUSTRATIVE
)(
input logic clk,
input logic rst_n,
input logic interval_tick,
input logic refresh_done,
input logic traffic_busy,
input logic deadline_class_present,
output logic refresh_request,
output logic signed [7:0] debt,
output logic [19:0] worst_block_cycles,
output logic [19:0] extra_refresh_events,
output logic [7:0] reserve_in_use,
output logic reserve_within_spec
);
logic [7:0] burst_left;
// The effective threshold. With no deadline-bearing requester there
// is nothing to reserve for and the full allowance is correct --
// section 6's region, honoured rather than overridden.
wire [7:0] threshold = deadline_class_present ? 8'(RESERVE) : 8'(SPEC_MAX);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
debt <= '0; refresh_request <= 1'b0; burst_left <= '0;
worst_block_cycles <= '0; extra_refresh_events <= '0;
reserve_in_use <= 8'(SPEC_MAX); reserve_within_spec <= 1'b1;
end else begin
// The reserve must never EXCEED the specification's limit: it can
// only be more conservative, never less.
reserve_within_spec <= (8'(RESERVE) <= 8'(SPEC_MAX));
reserve_in_use <= threshold;
if (interval_tick && !refresh_done) debt <= debt + 8'sd1;
else if (refresh_done && !interval_tick) debt <= debt - 8'sd1;
if (debt >= $signed({1'b0, threshold})) begin
refresh_request <= 1'b1;
if (burst_left == '0) begin
burst_left <= threshold;
worst_block_cycles <= 20'(threshold) * 20'(TRFC_CYC);
// Forcing earlier means forcing more often. That is the cost
// side of the trade, counted rather than asserted.
extra_refresh_events <= extra_refresh_events + 1'b1;
end
end else begin
refresh_request <= !traffic_busy;
end
if (burst_left != '0 && refresh_done) burst_left <= burst_left - 1'b1;
end
end
endmodule THE TRADE, MEASURED (ILLUSTRATIVE, tRFC 280, tREFI 6240,
a 400-cycle realtime deadline)
RESERVE worst block forced events realtime misses
(cycles) per 8 intervals per 40 requests
---------------------------------------------------------
8 2240 1 3
4 1120 2 1
3 840 3 0
2 560 4 0
1 280 8 0
DERIVED: RESERVE = 3 is the smallest value that meets the 400-cycle
deadline, at 840 cycles worst case. Going below it buys nothing
against this deadline and costs more forced events.RESERVE = 3 is the answer for a 400-cycle deadline, and the shape of the table is the point rather than the number. DERIVED: the worst-case block falls linearly with the threshold and the forced-event count rises inversely, so the choice is a single-parameter trade with a deadline on one side and average bandwidth on the other.
And the deadline_class_present input is what keeps this correct in the belief's own region. DERIVED: with no deadline-bearing requester the threshold reverts to the specification's 8, which is the efficient choice — CURRICULUM-DERIVED from 15.3 §1: the allowance exists “to allow for improved efficiency in scheduling”, and discarding it where nothing needs the headroom is 15.3 §13's first misconception.
The one constraint that is not a choice is the direction. DERIVED: RESERVE may only be more conservative than SPEC_MAX, never less — which is why reserve_within_spec is asserted and why §17's M14 is dangerous: that mutation moves the ceiling, and no amount of reserve policy can repair a ceiling that is wrong.
14. The Decision Built on the Belief
| Where it is applied | What it produces | Measured consequence |
|---|---|---|
| A bandwidth budget | subtract 4.5% and move on | correct — this is the region |
| A latency budget | refresh adds ~4.5% to latency | worst case 2,240 cycles, not 4.5% |
| A real-time feasibility argument | refresh is amortised | 3 of 40 deadline misses, all legal |
| A thermal margin plan | refresh cost is a constant | cost doubles, headroom halves |
| A silicon-debug hypothesis set | refresh is not a suspect under load | excludes the cause |
| A controller requirement | defer refresh while busy | correct and incomplete — needs the bound |
Row 1 is in the table deliberately, and it is not a concession. DERIVED: a bandwidth budget is exactly the artifact for which the belief is correct, and a chapter that refused to say so would be replacing one over-generalisation with another — which is 34.1 §21's first entry and this module's standing risk.
Reading the table by who is harmed rather than by artifact is more useful, and it produces a two-way split. DERIVED: rows 1 and 6 harm nobody — row 1 is the region and row 6 is a correct requirement that is merely incomplete. Rows 2, 3 and 4 harm a requester: a latency budget, a feasibility argument and a thermal plan all under-provision something that then misses. Row 5 harms the investigation that follows, and it is the only row whose cost is paid after the system has already failed.
And there is a fifth consequence the table cannot show, because it is an absence rather than a decision. DERIVED: a team holding this belief does not build §7's longest_block counter, does not build §9's per-class split, and does not expose the debt — so when the deadline problem arrives, the three instruments that would identify it in an afternoon do not exist. CURRICULUM-DERIVED from 33.6 §10's survival classification: an observable nobody designed in is not recoverable after tapeout by any amount of discipline.
Row 5 is the most expensive and the least visible. CURRICULUM-DERIVED from 33.7 §6's hypothesis-set item: a cause excluded from the live set is never eliminated by an experiment and never recorded as un-investigated — it is simply absent. DERIVED: an intermittent latency spike under sustained load, on a system whose engineers hold this belief, has refresh missing from its hypothesis set from the first minute.
15. What the Assertions Prove
// ---- Section 7: the average and what it hides. The obligation is that
// BOTH are published, which is a property about the instrument's
// interface rather than its arithmetic.
property p_average_is_a_fraction;
@(posedge clk) disable iff (!rst_n)
report_valid |-> (avg_unavail_x100 <= 8'd100);
endproperty
assert property (p_average_is_a_fraction)
else $error("the unavailable fraction exceeded 100%");
property p_longest_block_is_published;
@(posedge clk) disable iff (!rst_n)
(report_valid && (refresh_cycles != '0)) |-> (longest_block != '0);
endproperty
assert property (p_longest_block_is_published)
else $error("refresh cycles were counted with no longest-block figure");
// The property the weak instrument cannot satisfy: a clustered and a
// spread schedule must be DISTINGUISHABLE.
property p_clustering_is_visible;
@(posedge clk) disable iff (!rst_n)
(report_valid && (blocks_observed == 16'd1) && (refresh_cycles > 20'd560))
|-> (longest_block == refresh_cycles);
endproperty
assert property (p_clustering_is_visible)
else $error("a single clustered run was not reported as one block");
// ---- Section 8: the ledger. 15.3 section 4's verified bound, asserted.
property p_debt_within_verified_bound;
@(posedge clk) disable iff (!rst_n) debt_within_bound;
endproperty
assert property (p_debt_within_verified_bound)
else $error("refresh debt left the specification's +/-8 bound");
property p_bound_forces_refresh;
@(posedge clk) disable iff (!rst_n)
(debt >= 8'sd8) |=> refresh_request;
endproperty
assert property (p_bound_forces_refresh)
else $error("the allowance was exhausted and refresh was still deferred");
// Traffic must NOT gate refresh once the bound is reached -- 17.3's
// illegal-versus-deprioritised line.
property p_traffic_cannot_gate_at_the_bound;
@(posedge clk) disable iff (!rst_n)
(refresh_forced && traffic_busy) |-> refresh_request;
endproperty
assert property (p_traffic_cannot_gate_at_the_bound)
else $error("busy traffic deferred a refresh that was no longer deferrable");
// Two-sided -- 30.3 section 9's variety 8: a controller that refreshes
// every cycle satisfies every property above and serves nothing.
property p_deferral_permitted_below_the_bound;
@(posedge clk) disable iff (!rst_n)
(traffic_busy && (debt < 8'sd8)) |=> !refresh_request;
endproperty
assert property (p_deferral_permitted_below_the_bound)
else $error("refresh was issued during traffic with headroom remaining");
// ---- Section 9: per-class exposure.
property p_miss_is_flagged;
@(posedge clk) disable iff (!rst_n)
(retire && (deadline != '0) && (wait_cycles > deadline)) |=> any_miss;
endproperty
assert property (p_miss_is_flagged)
else $error("a deadline was missed and nothing was flagged");
property p_blocked_implies_arrival;
@(posedge clk) disable iff (!rst_n)
(arrive && refresh_busy) |=> (blocked[$past(req_class)] != '0);
endproperty
assert property (p_blocked_implies_arrival)
else $error("an arrival during refresh was not counted as blocked");
property p_worst_wait_is_monotone;
@(posedge clk) disable iff (!rst_n)
retire |=> (worst_wait[$past(ret_class)] >= $past(wait_cycles));
endproperty
assert property (p_worst_wait_is_monotone)
else $error("a wait longer than the recorded worst case was dropped");
property p_aggregate_hiding_is_flagged;
@(posedge clk) disable iff (!rst_n)
(retire && (agg_count != '0) && (worst_wait[0] > (agg_mean * 16'd4)))
|=> aggregate_hides_a_class;
endproperty
assert property (p_aggregate_hiding_is_flagged)
else $error("a class whose worst case dwarfs the mean was not flagged");
// ---- Section 11: temperature. The interval must be DERIVED, which is
// 33.3 section 6's calculated-versus-measured line applied to refresh.
property p_interval_tracks_temperature;
@(posedge clk) disable iff (!rst_n)
(sample && (temp_c > 8'(T_THRESH)))
|=> (trefi_in_use == 20'(TREFI_NOM / 2));
endproperty
assert property (p_interval_tracks_temperature)
else $error("the refresh interval did not tighten above the threshold");
property p_cost_rises_with_the_interval;
@(posedge clk) disable iff (!rst_n)
(sample && (temp_c > 8'(T_THRESH))) |=> (unavail_x100 > 8'd449);
endproperty
assert property (p_cost_rises_with_the_interval)
else $error("the availability cost did not rise on the tighter interval");
property p_interval_is_not_a_constant;
@(posedge clk) disable iff (!rst_n) derived_from_temp;
endproperty
assert property (p_interval_is_not_a_constant)
else $error("the refresh interval is a compiled constant");
// ---- Section 13: the reserve. The direction of the trade is the one
// thing that is not a design choice.
property p_reserve_never_exceeds_spec;
@(posedge clk) disable iff (!rst_n) reserve_within_spec;
endproperty
assert property (p_reserve_never_exceeds_spec)
else $error("the deferral reserve exceeds the specification's limit");
property p_worst_block_follows_the_threshold;
@(posedge clk) disable iff (!rst_n)
(worst_block_cycles != '0)
|-> (worst_block_cycles <= (20'(SPEC_MAX) * 20'(TRFC_CYC)));
endproperty
assert property (p_worst_block_follows_the_threshold)
else $error("the worst-case block exceeded the specification-bounded maximum");
// And the region honoured: with no deadline class, the full allowance
// is the correct policy -- 15.3 section 13's first misconception, avoided.
property p_full_allowance_when_no_deadline;
@(posedge clk) disable iff (!rst_n)
(!deadline_class_present) |=> (reserve_in_use == 8'(SPEC_MAX));
endproperty
assert property (p_full_allowance_when_no_deadline)
else $error("headroom was reserved with no deadline-bearing requester");
// ---- The CLAIM, as a conditional pair -- 34.1 section 1's required form.
property p_claim_holds_in_its_region;
@(posedge clk) disable iff (!rst_n)
(report_valid && (blocks_observed >= 16'd8))
|-> (longest_block <= 20'(2 * TRFC_CYC));
endproperty
assert property (p_claim_holds_in_its_region)
else $error("with refresh spread, a block still exceeded two tRFC");
property p_claim_fails_at_the_bound;
@(posedge clk) disable iff (!rst_n)
(report_valid && (blocks_observed == 16'd1) && (refresh_cycles >= 20'd2240))
|-> (longest_block >= 20'(8 * TRFC_CYC));
endproperty
assert property (p_claim_fails_at_the_bound)
else $error("a clustered repayment did not produce an 8x block");
// ---- COVERS. Each on the dimension the belief's failure scales with.
// The REGION: refresh spread across its intervals, so
// p_claim_holds_in_its_region is not vacuous.
cover property (@(posedge clk) disable iff (!rst_n)
report_valid && (blocks_observed >= 16'd8));
// And the BOUND reached. The dimension is SUSTAINED LOAD DURATION,
// and eight intervals is about 62 microseconds -- 31.2 section 14's
// scale-vacuity: a short burst of traffic never reaches it.
cover property (@(posedge clk) disable iff (!rst_n) refresh_forced);
// A forced burst fully repaid, so the 2240-cycle figure is exercised.
cover property (@(posedge clk) disable iff (!rst_n)
forced_burst_cycles >= 20'd2240);
// A DEADLINE-BEARING request arriving INTO a refresh -- the
// coincidence section 10 draws, which needs both schedules aligned.
cover property (@(posedge clk) disable iff (!rst_n)
arrive && refresh_busy && (deadline != '0));
// And an actual miss, so p_miss_is_flagged has a witness.
cover property (@(posedge clk) disable iff (!rst_n) any_miss);
// The deadline-bearing class in the MINORITY -- 33.5 section 10's
// dimension, which is the requester MIX and not the traffic.
cover property (@(posedge clk) disable iff (!rst_n)
retire && (deadline != '0)
&& (arrivals[ret_class] * 4 < agg_count));
// Extended temperature range. The dimension is the ENVIRONMENT, and
// running longer at 25 degrees never reaches it.
cover property (@(posedge clk) disable iff (!rst_n)
sample && (temp_c > 8'(T_THRESH)));
// A debt that goes NEGATIVE -- pull-in credit, the half of 15.3's
// ledger this chapter's argument does not use and must still exercise.
cover property (@(posedge clk) disable iff (!rst_n) debt < 8'sd0);
// Deferral actually being used below the bound, so
// p_deferral_permitted_below_the_bound is not vacuous.
cover property (@(posedge clk) disable iff (!rst_n)
traffic_busy && (debt > 8'sd0) && (debt < 8'sd8));
// And the spread case with traffic present, so the two schedules are
// compared under the same load rather than at different ones.
cover property (@(posedge clk) disable iff (!rst_n)
refresh_busy && request_waiting);
// Section 13: the reserve ACTIVE -- a deadline class present and the
// threshold below the specification's limit.
cover property (@(posedge clk) disable iff (!rst_n)
deadline_class_present && (reserve_in_use < 8'(SPEC_MAX)));
// And the reserve INACTIVE, so p_full_allowance_when_no_deadline is
// not satisfied by a design that always reserves.
cover property (@(posedge clk) disable iff (!rst_n)
!deadline_class_present && (reserve_in_use == 8'(SPEC_MAX)));
// A refresh MODE other than 1X, so section 12's two-rate collision is
// exercised rather than argued.
cover property (@(posedge clk) disable iff (!rst_n) sample && (mode != 2'd0));
// The aggregate provably hiding a class -- the state section 9 measures,
// and one a single-class stimulus cannot reach.
cover property (@(posedge clk) disable iff (!rst_n) aggregate_hides_a_class);Two notes specific to this chapter's property set.
p_deferral_permitted_below_the_bound is the two-sided partner and it is the one that keeps the chapter honest. DERIVED: a controller that refreshes immediately every interval satisfies the bound, the forcing property and the traffic-gating property, and it is 15.3 §13's first listed misconception — “every tREFI cycles, issue refresh immediately”. CURRICULUM-DERIVED from 30.3 §9: the one-sided form admits a do-nothing solution, and here the do-nothing solution is a different documented mistake.
And the claim pair asserts the belief true in its region, as 34.1 §1 requires of every chapter in this module: with refresh spread, no block exceeds two tRFC, and the belief's a few percent, evenly is exactly right.
Third, every property in this set is written against MAX_DEBT and SPEC_MAX rather than against the number 8, and that is a deliberate exposure rather than an oversight. DERIVED: writing debt <= 8'sd8 literally would make the property set catch §17's M14 and would also make it wrong on a 2X-mode part, where the verified limit is 16. CURRICULUM-DERIVED from 15.3 §1: the limit is 8, 16 or 32 by mode, so a literal is correct for one configuration and wrong for two — which is 31.1 §14's variety 10, parameter-conditional soundness, arriving from the opposite direction.
DERIVED: so the honest construction is a parameterised property plus an elaboration check that ties the parameter to the mode, and §17's M14 survives because this chapter has the first half and not the second. That is variety 12 with its cause named: the property is parameterised correctly and nothing constrains the parameter.
16. Quantitative Reasoning
| Quantity | Truth | Under the belief | Gap | Provenance |
|---|---|---|---|---|
| average unavailable fraction, 8Gb | 4.49% | 4.49% | none | STRUCTURAL, 15.5 |
| worst-case block, spread schedule | 280 cycles | ~280 | none | DERIVED |
| worst-case block, allowance used | 2,240 cycles | ~280 | 8× | DERIVED, 8 is STRUCTURAL |
| time to reach the bound | ~62 µs of load | never | — | DERIVED |
| realtime deadline misses per 40 | 3 | 0 | 3 | DERIVED, ILLUSTRATIVE mix |
| aggregate mean wait | 61 cycles | 61 cycles | none | DERIVED |
| unavailable fraction at >85 °C | 8.97% | 4.49% | 2× | DERIVED from 15.5 |
| deferral headroom at >85 °C | 24,960 cycles | 49,920 | halved | DERIVED |
| hypothesis-set membership under load | a suspect | excluded | — | CURRICULUM-DERIVED, 33.7 §6 |
Rows 1 and 6 are the chapter in two lines: the two quantities the belief cites are exactly correct, and every quantity a real-time system experiences differs by 2× to 8×.
Sort them by whether the belief names the quantity and the pattern that makes this belief hard to dislodge appears.
| Does the belief name it? | Quantities | Is the belief right? |
|---|---|---|
| Yes — it cites them | average fraction, bandwidth cost, idle-case fraction | exactly right |
| No — it never mentions them | worst-case block, time to the bound, per-class misses, thermal scaling, headroom, hypothesis-set membership | wrong by 2× to 8×, or absent |
DERIVED: the belief is right about three of three quantities it names and wrong about six of six it does not. That is a different failure from 34.1's, where the belief was wrong about the magnitude of a quantity it did name — and it explains why checking the belief's arithmetic confirms it.
DERIVED: this is a sharper version of 34.1 §16's three-kind taxonomy. There the belief was wrong about magnitude, representation and category. Here it is wrong about none of the quantities it names and wrong about every quantity it does not name — which is why it cannot be refuted by checking its arithmetic.
17. Mutation Testing
Baseline first: all twenty assertions pass and all fourteen covers are non-zero.
| # | Mutation | Killed by | Survived? |
|---|---|---|---|
| M1 | §7: drop longest_block tracking | p_longest_block_is_published | killed |
| M2 | §7: reset run_len on every cycle | p_clustering_is_visible, by one cover | killed |
| M3 | §7: count refresh cycles twice | p_average_is_a_fraction | killed |
| M4 | §8: remove the MAX_DEBT check | p_bound_forces_refresh, by one cover | killed |
| M5 | §8: allow traffic to gate at the bound | p_traffic_cannot_gate_at_the_bound | killed |
| M6 | §8: refresh every interval regardless | p_deferral_permitted_below_the_bound | killed |
| M7 | §8: debt decrements on interval_tick | p_debt_within_verified_bound | killed |
| M8 | §9: drop the deadline comparison | p_miss_is_flagged, by one cover | killed |
| M9 | §9: blocked incremented on retire | p_blocked_implies_arrival | killed |
| M10 | §9: worst_wait overwritten rather than maxed | p_worst_wait_is_monotone | killed |
| M11 | §11: trefi_in_use fixed at TREFI_NOM | p_interval_tracks_temperature, by one cover | killed |
| M12 | §11: derived_from_temp tied low | p_interval_is_not_a_constant | killed |
| M13 | §11: threshold comparison inverted | p_cost_rises_with_the_interval | killed |
| M14 | MAX_DEBT raised from 8 to 64 | nothing | SURVIVES |
| M15 | T_THRESH raised to 200 °C | nothing | SURVIVES |
| M16 | the class mix fixed at 100% bulk | nothing | SURVIVES |
| M17 | WIN shortened below one tREFI | nothing | SURVIVES |
| M18 | §13: RESERVE raised above SPEC_MAX | p_reserve_never_exceeds_spec | killed |
| M19 | §13: reserve applied with no deadline class | p_full_allowance_when_no_deadline, by one cover | killed |
| M20 | §12: trfc_of_mode returns TRFC_CYC always | p_cost_rises_with_the_interval | killed |
DERIVED: sixteen of twenty killed, four survived — and M14 is the one that matters, because it is the belief itself expressed as a parameter.
Raising MAX_DEBT to 64 keeps every mechanism correct: the ledger still bounds, the bound still forces, traffic still cannot gate at it. DERIVED: and the design now defers refresh for 64 intervals — about 500 µs — which is a retention violation and which no property here detects, because every property is written against MAX_DEBT rather than against 8. CURRICULUM-DERIVED from 33.4 §15's variety 12 and 34.1 §17's M19: the bound is derived from the parameter it is supposed to bound.
The fix is the one this curriculum keeps arriving at and it is not a property. DERIVED: MAX_DEBT must be checked at elaboration against a datasheet figure — 8 in 1X mode, 16 in 2X, 32 in 4X — and that figure is 15.3 §1's verified row. A property cannot adjudicate it because the correct value is not derivable from anything in the design.
M16 and M17 are the region, reconstructed. Fixing the mix at 100% bulk removes every deadline; shortening the window below one tREFI removes clustering. DERIVED: both make the belief true and kill nothing — the same finding as 34.1 §17's M12 and M13, and the second instance of this module's structural result: a mutation that narrows the stimulus to the belief's region is unkillable, because inside it the belief is correct.
Four mutations are killed only by a cover, and M4's is the sharpest. Removing the MAX_DEBT check changes nothing until eight intervals of sustained load have elapsed, so the cover on refresh_forced is the only thing that reaches it. CURRICULUM-DERIVED from 31.2 §14's coverage-dimension rule: the dimension is sustained-load duration, the threshold is about 62 µs, and a test made of short bursts never arrives.
18. Baseline Defects Found Before Mutation
| Belief applied to | Caught by | At what cost |
|---|---|---|
| a bandwidth budget | — | nothing to catch: this is the region |
| a latency budget | p_longest_block_is_published | nothing — the figure is absent |
| a real-time argument | p_miss_is_flagged | a mix with a deadline-bearing minority |
| a controller requirement | p_bound_forces_refresh | eight intervals of sustained load |
| a thermal plan | p_interval_is_not_a_constant | nothing — grep for a constant tREFI |
| a hypothesis set | — | nothing: the absence is the finding |
DERIVED: three of six are found without running anything, and two of those three are an absent field. The cheapest is the thermal one — a compiled tREFI constant is a grep — and it is 33.3 §6's calculated-versus-measured line applied to a refresh interval.
Two need a stimulus that a normal test does not produce, and both dimensions belong to the environment's model.
| Application | The stimulus | Why the usual test misses it |
|---|---|---|
| a controller requirement | ≥ 8 tREFI of unbroken load | benchmarks have gaps; 62 µs is long |
| a real-time argument | a deadline-bearing minority class | a bandwidth test has no deadlines at all |
DERIVED: the second is the same dimension 33.5 §19 named — the requester mix — and it is the dimension 33.4 §6's configuration-reach item exists to reach. A test bench that models one requester class cannot produce this chapter's finding at any duration.
19. Silicon Observability
| What silicon shows | What it says about the belief |
|---|---|
| a latency spike every ~62 µs under sustained load | the allowance is being used and repaid |
| spikes that disappear when the load is reduced | the deferral mechanism, working as designed |
| a real-time glitch with a healthy mean | §9 — the aggregate cannot see it |
| the spike period halving in a hot chassis | §11 — the interval tightened |
| refresh counters showing the correct average | the belief's evidence, and it is correct |
| a bandwidth benchmark losing ~4.5% | the region, measured |
Row 2 is the most diagnostic and the most misleading at the same time. DERIVED: reducing the load makes the spikes vanish, which reads as the load caused it and is one inference short — the load caused the deferral, and the deferral caused the spike. CURRICULUM-DERIVED from 33.7 §7: the experiment perturbs a condition every hypothesis depends on, so it eliminates nothing and it is exactly the shape of a symptom-only experiment.
Rows 5 and 6 are in the table because a chapter that listed only disconfirming evidence would be misrepresenting the belief. DERIVED: an engineer who inspects the refresh counters and runs a bandwidth benchmark finds the belief confirmed twice, by two correct measurements — and both are things a careful person does first. CURRICULUM-DERIVED from 33.7 §7: an experiment that confirms every hypothesis in the live set has eliminated none of them, and these two confirm the belief and its refutation equally.
Row 1's periodicity is the free discriminator. DERIVED: a spike interval of 8 × tREFI is a signature nothing else in a DDR system produces, and it is measurable with a timestamp histogram. CURRICULUM-DERIVED from 28.3, which owns the evidence set separating an obligation failure, a service failure and a correlation: this is a service outcome, and the period is what identifies it.
20. The Beliefs This One Generates
| Downstream belief | Why it follows | Where it is refuted |
|---|---|---|
| “refresh is a bandwidth problem, not a latency problem” | if the cost is a percentage | §9; 30.1's Q4 |
| “deferring refresh is free” | if the allowance exists | §8; 15.3 §1's bound |
| “we can raise the postponement limit” | if 8 is a controller choice | §17's M14; it is a datasheet figure |
| “refresh is not a suspect under load” | if it only affects idle systems | §14; 33.7 §6 |
| “a hot part is slower because of the PHY” | if tREFI is a constant | §11; 15.4 |
| “refresh is just another requester” | if it competes for the bus like traffic | 34.4 §11: it has no requester |
| “DDR5 fixed refresh” | if directed refresh management replaces REF | 34.6 §10: reshaped, not replaced |
Two of the five downstream beliefs are not merely wrong but actively harmful, and separating them from the merely-wrong three is the useful part of this table. DERIVED: rows 1, 4 and 5 send an investigation to the wrong place, which costs time. Rows 2 and 3 cause a design change, which costs data.
The third row is the one that reaches RTL, and it is M14. DERIVED: an engineer who believes the cost is amortised and meets a deadline problem will look for headroom in the deferral limit, and the limit is a device constraint — so the fix the belief suggests is the one that corrupts data. CURRICULUM-DERIVED from 15.3 §4: exceeding debt risks data, and exceeding credit does not — the two bounds in the same sentence have asymmetric consequences, and this belief pushes on the dangerous one.
21. Common Wrong Answers
-
“Refresh costs 4.5%, so budget 4.5%.” Correct for bandwidth and wrong for latency. DERIVED: §16's first row shows the average is exactly right; §6's row 2 shows the worst-case block is 8× it.
-
“Then refresh is a huge cost and the 4.5% figure is wrong.” Inverted, and this is the over-correction this module most risks. CURRICULUM-DERIVED from 15.5: the arithmetic is verified. Both numbers are right; they answer different questions.
-
“The controller can just refresh when idle.” For up to 8 intervals. CURRICULUM-DERIVED from 15.3 §1's verified limit — and 15.3 §13 lists this as a scheduler misconception in its own right.
-
“So issue refresh immediately every
tREFIand avoid the burst.” That is 15.3 §13's first listed misconception, and it discards an allowance the standard provides for a reason. DERIVED: §15'sp_deferral_permitted_below_the_boundexists to reject exactly this. -
“Raise the postponement limit to smooth the burst.” The limit is a device constraint, not a controller parameter — §17's M14 and 15.3 §4's
D ≤ +8. Raising it risks data. -
“Our mean latency is fine, so refresh is fine.” §9: mean wait 61 cycles, three realtime deadline misses. CURRICULUM-DERIVED from 33.5 §10: 800 of 1000 requesters have no deadline and carry 80% of the mean's weight.
-
“We reduced the load and the spikes went away, so it was the load.” The load caused the deferral; the deferral caused the spike. CURRICULUM-DERIVED from 33.7 §7: an experiment that perturbs a condition every hypothesis needs eliminates none of them.
-
“Refresh is a retention mechanism, so its failure mode is corruption, not latency.” CURRICULUM-DERIVED from 28.3's three-way split: an obligation failure risks data and a service failure costs time, and this chapter is entirely about the second.
-
“
tREFIis 7.8 µs.” In the normal temperature range. CURRICULUM-DERIVED from 15.4 and 15.5: above the threshold it halves, and the deferral headroom halves with it (§11). -
“Finer refresh mode fixes the burst —
tRFC4is under half oftRFC1.” AndtREFI4is a quarter. CURRICULUM-DERIVED from 15.5: the two rates move at different speeds, so the modes trade block length against frequency rather than removing cost. -
“The 2,240-cycle burst is a controller bug.” Every step is legal — deferral is invited, the bound is enforced, the repayment is required. DERIVED: §10's diagram shows two correct decisions producing a late request, and there is no line of RTL to fix.
-
“Then nothing can be done.” Several things can, and they are all outside this belief's frame: bound the deferral below the specification's limit, reserve headroom for a deadline class, or expose the debt so a real-time scheduler can see it. DERIVED: all three require knowing the burst exists, which is the chapter's point.
-
“Idle systems are the ones that suffer — the fraction is higher.” §4's inversion: the fraction is identical and the impact differs. DERIVED: on an idle system refresh delays nothing, because nothing is waiting.
-
“We never see this; our benchmarks are clean.” §18: the stimulus is ≥ 8
tREFIof unbroken load — about 62 µs — and a deadline-bearing minority class. A bandwidth benchmark has neither. -
“The refresh counters look right.” They are right. DERIVED: §19's row 5 — the belief's evidence is correct, which is why counter inspection confirms it.
-
“This is a real-time problem and we are not a real-time system.” Then row 1 of §14 applies and the belief is correct for you — and the qualification is the point. DERIVED: a system with no deadline-bearing requester is inside §5's region, and saying so is different from saying refresh is free.
-
“A 2,240-cycle block is only 2.8 µs.” Against a 400-cycle deadline it is 5.6× over. DERIVED: the absolute figure is small and the comparison is the claim — 33.5 §6's rule that a number means nothing without its denominator, here a deadline.
-
“The burst only matters if it coincides with a deadline, and that is unlikely.” A 2,240-cycle burst every 62 µs occupies 3.6% of the timeline, so a uniformly-arriving realtime request hits one 3.6% of the time. DERIVED: §9's trace shows 3 of 40 — 7.5% — because arrivals are not uniform and a burst stalls the queue it arrives into.
-
“Add a refresh-aware hint so real-time requests avoid the burst.” A requester cannot avoid a window it cannot see, and the burst's start is decided by traffic it does not control. DERIVED: §13's reserve works because it moves the controller's threshold; a requester-side hint needs the debt exposed, which is §20's third option and a different design.
-
“Set
RESERVEto 1 and be safe.” §13's table:RESERVE = 1forces 8 refresh events per 8 intervals — it discards the entire allowance and buys nothing below the 400-cycle deadline thatRESERVE = 3already meets. DERIVED: the trade has a knee, and going past it costs bandwidth for no latency gain. -
“
RESERVEis a safety margin, so bigger is safer.” Inverted —RESERVEis a ceiling on deferral, so smaller is more conservative. DERIVED: and it may only move belowSPEC_MAX, never above, which is whyp_reserve_never_exceeds_specexists and why §17's M18 is a real bug rather than a tuning choice. -
“I know the availability arithmetic, so I do not hold this belief.” Knowing step 1 is what makes the belief stable (§12). DERIVED: the loop's first three steps are all true, and the correction begins at step 4 — the only step with a bound in it.
22. Self-Check
- State the three conditions under which refresh only affects idle systems is true, and name which one a bandwidth benchmark satisfies by construction.
tRFC = 280cycles,tREFI = 6,240cycles. Give the average unavailable fraction and the worst-case block under full use of the allowance.- Why is the average identical for a spread schedule and a clustered one, and what does that tell you about using it in a latency budget?
- How long does a controller have to be under unbroken load before the forced burst arrives? Give it in intervals and in microseconds.
- A colleague proposes raising the postponement limit to smooth the burst. Give the one-line refutation and name the chapter that verifies the figure.
- What happens to the deferral headroom, in wall time, above the extended-temperature threshold — and why does the count of 8 not change?
- A real-time client glitches and the mean wait is 61 cycles. Explain how both are true, and name the statistic that would have shown it.
- Reducing the load makes the latency spikes vanish. What does that experiment eliminate, and what is the name for an experiment of that shape?
- Write out the seven-step loop in §12, and identify the first step that is false.
- M14 raised
MAX_DEBTfrom 8 to 64 and no property fired. Name the variety, say why the property set could not catch it, and give the fix. - Two mutations reconstructed the belief's region and killed nothing. Which two, and what general statement about misconceptions does that support?
- Which quantities named by the belief are wrong? Answer precisely, and say what that implies about how to correct someone holding it.
23. The Residual Risk
What this chapter cannot settle.
It cannot tell you whether your system has a deadline-bearing requester. §5's third condition is a property of the requester mix, and M16 showed that fixing the mix at 100% bulk makes the belief true and kills nothing. CURRICULUM-DERIVED from Module 32: the mix is what distinguishes platform classes, so this chapter refutes the belief as a universal claim and leaves it standing for a genuinely deadline-free system.
It cannot supply the postponement limit for your device. CURRICULUM-DERIVED from 15.3 §1: 8, 16 and 32 are verified for 1X, 2X and 4X modes on a specific datasheet. DERIVED: M14 is unkillable precisely because the correct value is external, and §17's fix is an elaboration check against a datasheet row rather than a property.
It cannot model the retention physics. 15.4 owns retention and 15.1 owns why refresh exists at all. DERIVED: §11's halving above a threshold is a consequence taken as given, and this chapter derives neither the threshold nor the retention curve.
It models a single rank, and that is a real limitation rather than a simplification. DERIVED: refresh is a per-rank obligation, so a multi-rank channel has several ledgers and a controller can stagger their forced bursts — which spreads the block and shortens the worst case without changing any average. CURRICULUM-DERIVED from 5.4, which owns ranks, and 15.2, which owns the commands: nothing in this chapter's models represents a second ledger, so §13's reserve table is a single-rank table and a two-rank system has a cheaper option this chapter does not evaluate. DERIVED: that makes §16's worst-case figures an upper bound for a multi-rank part rather than a prediction, and the direction of the error is favourable — which is worth saying, because every other gap in this chapter runs the other way.
And it cannot tell you what to do about the burst. §21's twelfth entry lists three options and evaluates none. DERIVED: bounding deferral below the specification's limit trades worst-case latency for average bandwidth, and which side of that trade a system wants is 33.5's question, not this one's — this chapter establishes that the trade exists and that the belief conceals it.
24. Where This Goes
Two beliefs down, and the two so far have been about a term — one over-weighted, one treated as absent.
Chapter 34.3 takes “DDR bandwidth equals application bandwidth”, and it changes the unit of the error. DERIVED: 34.1 and 34.2 each concern one line of a decomposition. The next concerns the whole decomposition, collapsed into its first row.
And it shares this chapter's structure in one specific way worth carrying forward. CURRICULUM-DERIVED from 33.5 §13's five bandwidth levels: level 1, peak, is the only level that exists before silicon — so the next belief, like this one, is built on a number that is correct, published, verifiable, and the only one available at the moment the decision is made.
DERIVED: that is a third recurring property of this module's six, alongside the non-empty region and the self-defeating mechanism — the belief's evidence is usually the only evidence available when it is formed. 34.3 is where that property is sharpest, because there the gap between the available number and the true one is measured at 3.76×.
Continue learning
Related tutorials
- Related topic
The Refresh Requirement
Leakage produces a rule about the passage of time rather than about any operation. What the maintenance operation actually does, why it costs device availability, and how a digital design tracks a deadline, arbitrates it against traffic, and proves it never silently drops the obligation.
- Related topic
Refresh (REF)
Refresh is the first command whose legality depends on more than one bank, and the first that occupies the device rather than requesting a transfer. DDR5's same-bank variant exists precisely to weaken that precondition.
- Related topic
Why Refresh Exists
Every timing parameter so far has been a minimum. Refresh inverts the specification: the datasheet gives the interval as a maximum with no minimum at all, which makes it a service-rate obligation over a population of rows rather than a single deadline.
- Related topic
Refresh Commands
A refresh command's scope decides what it retires. Device-wide scope means one obligation and one counter; narrower scope means one obligation per resource, a counter each, and a pointer deciding which is next.
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.
