Skip to content
VLSI Mentor

DDR · Module 34

“CAS Latency Equals Memory Latency”

The first of six beliefs this module takes apart. CL is one additive term of four, it is the only one a datasheet prints, and its share of a real read falls from 61% at idle to 7% under load — so the belief is exactly right in the one case a bench test measures.

This module is the last in the DDR track, and it is the only one whose six chapters each begin with a sentence that is wrong.

“CAS latency is the memory latency. A CL16 part has lower latency than a CL18 part.”

That is not a beginner's sentence. It is said by engineers who have configured controllers, who can name tRCD and tRP, and who would recognise every term they have just left out. DERIVED: the belief is not an absence of knowledge — it is a correct statement about one term of a sum, applied to the sum.

And it is nearly exact in one case. CURRICULUM-DERIVED from 23.1's decomposition: on a row hit to an already-open bank, with an empty queue and no refresh in flight, a read's latency really is CL plus a small fixed constant — and that case is exactly what a single-threaded bench test with a pointer-chase benchmark measures. The belief survives because the measurement that would refute it is not the measurement anybody runs first.

This chapter's job is not to state the correction — 23.1 already owns it. It is to establish why the belief is plausible, the region in which it is true, the measurement that leaves that region, and what the belief costs when somebody buys a part with it.

1. The Anatomy of a Misconception

This module has six chapters and they share one structure, because the six beliefs share one structure. Establishing it here saves five repetitions.

DERIVED: none of the six beliefs in this module is an invention. Each is a true statement with a scope, repeated until the scope fell off. So “refuting” one is not a matter of showing it false — it is false almost nowhere interesting — but of recovering the scope.

PartThe question it answersWhy it is required
1 Why it is believedwhat true statement is this a corruption of?a belief with no true core is not held by competent people
2 The regionunder exactly what conditions is it true?stated as a conjunction, so leaving it is checkable
3 The boundarywhat does leaving the region cost, in named units?converts a correction into arithmetic
4 The costwhat does acting on it produce?a belief with no consequence needs no chapter
5 The downstreamwhich further beliefs does it generate?misconceptions arrive in families

Part 2 is the one that distinguishes this module from a list of errata, and it has a formal consequence. DERIVED: because each belief is true in its region, each chapter's central property is a conditional that affirms it alongside one that denies it outside — §15's p_claim_holds_in_its_region and p_claim_fails_outside_its_region are that pair, and every chapter in this module has one.

CURRICULUM-DERIVED from 33.8 §11, which asked of any claim where does it stop being true and found five of six general claims true inside a region and stated as universaland from 18.4 §1's four evidence grades, whose failure mode is category drift. DERIVED: every belief in this module is a grade A fact — documented for a named configuration — consumed as a grade B rule, so category drift is the name of the mechanism all six share.

And one structural property is worth flagging now because three of the six chapters share it. DERIVED: in 34.4, 34.5 and 34.6 the belief supplies its own denominator — it counts obligations, retraining triggers or generational changes against a total it chose — and each therefore passes its own completeness check. CURRICULUM-DERIVED from 33.1 §5, whose first review action is “arithmetic: count the blocks against thirteen”: the denominator has to come from outside, and a belief is a mental model with no outside.

One more property of the family is worth stating in advance, because it recurs and it is the least obvious. DERIVED: several of these beliefs are false in a correct system and true in a common broken one — §11 measures the first instance, where a documented controller defect makes lower CL means more bandwidth come out true. A belief that its own system's bugs confirm is the hardest kind to dislodge, because the evidence is real.

2. The One-Sentence Correction

CL is the delay from a column command to the first data beat, and nothing elseso it is one additive term in a decomposition of four, it is the only one of the four that a datasheet prints, and its share of a real read's latency falls as load rises, from about a quarter at idle to under a tenth under pressure.

CURRICULUM-DERIVED from 14.9, which owns CL as a fixed, programmed latency13.3 §2's class B — and from 23.1, which owns the decomposition whose components sum exactly to the total.

3. What This Chapter Owns

GroundOwner
CL as a fixed programmed latency, and its two-sided obligation14.9
The latency decomposition whose components sum exactly; the unbounded term23.1
tRCD, tRP, tRAS as parameters14.1, 14.2, 14.3
Row hit, miss and conflict as classes, and what produces them9.3, 23.3
The interview form: the numeric comparison under unit conversion30.4
The latency budget in which CL is a measured share30.4 §4
Delay versus occupancy, and the reservation defect30.4 §7, 30.4 §8
Which latency statistic to publish, and against which deadline33.5 §10
Why the belief is plausible, where it holds, and what it costs to act onthis chapter

The boundary with 30.4 is the one that needs care, because that chapter already contains the correction.

30.4 owns the interview form: three questions that sound like one, the unit conversion that changes the answer, and the finding that CL is a measured share rather than a headline. This chapter owns the belief formDERIVED: 30.4 asks what a candidate should say; this chapter asks why a competent engineer says the wrong thing, and what happens when a purchasing decision is made on it. A reader who has worked 30.4 has the correction. §13's part-selection model is what 30.4 has no reason to build.

And the boundary with 33.5 is a division by scale. That gate reviews a latency figure somebody published. This chapter reviews the belief that produced the figure — and §14's cost is a decision, not a number.

4. Teaching-Model Boundary And Source Discipline

Every SystemVerilog block below is an educational model. None is a controller.

Claim classWhat it means hereExample below
Structurala documented mechanism, or an arithmetic identityCL as a programmed column-to-data delay; the exact-sum requirement
Curriculum-derivedfollows from a cited chapter of this trackthe decomposition, the three classes, the unbounded term
Derivedcomputed in this chapter from the models belowevery share and every gap in §16
Illustrativea chosen number that makes a mechanism visibleall cycle counts, loads, hit rates and part parameters

Every timing number in this chapter is ILLUSTRATIVE and labelled. CURRICULUM-DERIVED from 14.9 and 30.4 §2, which owns the conversion between nanoseconds and cycles and the fact that the answer changes with the metric: a real CL comes from a device datasheet at a stated speed bin, and this chapter derives none. DERIVED: every argument below is about a share or a ratio, and each holds for any parameter set in which the terms have the same relative magnitudes.

The two parts compared in §13 are constructed. DERIVED: a CL16 part and a CL18 part at the same data rate is a real purchasing choice, and the numbers attached to them here are chosen to make the arithmetic legible rather than to describe a product. No external source was consulted and no network tool was used.

5. Why a Competent Engineer Believes It

Four reasons, and none of them is ignorance. Each is a true statement that the belief over-generalises.

#The true statementWhat the belief does with it
1CL is the only latency number a datasheet prints prominentlytreats the printed number as the quantity
2CL is the largest single fixed termtreats largest fixed as largest
3On a row hit to an open bank with an empty queue, latency ≈ CL + a constanttreats the best case as the case
4Lowering CL really does lower latency, all else equaltreats all else equal as a description of a running system

Reason 3 is the load-bearing one, and it is worth stating precisely because it is not an approximation — it is exact. CURRICULUM-DERIVED from 23.1's decomposition: on a row hit, tRCD and tRP are both zero by construction, and with an empty queue the unbounded term is zero too. DERIVED: three of the four additive terms vanish simultaneously in exactly the condition a single-outstanding bench test creates, so the belief is not merely plausible in that condition — it is correct.

Reason 2 is the subtlest and it is where the category error lives. DERIVED: CL is the largest fixed term and the queueing term is the largest term — but the queueing term has no fixed value to compare against, so a comparison of constants finds CL at the top. CURRICULUM-DERIVED from 23.1, which identifies the one component with no upper bound: a quantity with no upper bound does not appear in a table of quantities, so a table-driven comparison structurally omits the term that dominates.

And reason 4 is true and useless in the same sentence. DERIVED: all else equal requires the row state, the queue depth, the bank conflict rate and the refresh phase to be identical between the two parts — and a part with a lower CL at the same bin typically has the same tRCD and tRP, so the conflict path is unchanged and only the hit path improves. §13 measures what that is worth.

6. The Region Where the Claim Is True

State the region exactly, because the region is what makes this a misconception rather than an error.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   THE CLAIM "latency == CL" HOLDS WHEN ALL FOUR ARE TRUE:

     1  the access is a ROW HIT          -> tRCD term = 0
     2  the bank is OPEN and not busy    -> tRP term   = 0
     3  the request queue is EMPTY       -> queueing    = 0
     4  no refresh is in flight          -> drain term  = 0

   and then:  read_latency = CL + PHY_FIXED        (STRUCTURAL)

   In that region the claim is not approximately right. It is exact,
   up to a constant the datasheet does not print.

DERIVED: the region is non-empty, reachable, and it is where a first measurement lands. A pointer-chase microbenchmark on an idle machine with one outstanding request satisfies all four conditions on most of its accesses. CURRICULUM-DERIVED from 23.3, which owns what produces hit, miss and conflict counts: a sequential or strided walk within one row produces hits, so a benchmark chosen to isolate latency also isolates the region in which CL is the answer.

And that is the general shape of every chapter in this module. DERIVED: each of the six beliefs has a non-empty region of truth, and in every case the region is the one a simple first experiment occupies. CURRICULUM-DERIVED from 33.8 §11, which asked of any claim where does it stop being true and found that five of six general claims were true inside a region and stated as universalthis module is those regions computed.

7. The Boundary, Computed

Leaving the region costs a named number of cycles, and each exit is a different term.

ExitConditionAdded cyclesOwner of the mechanism
1row closed (miss)+ tRCD14.1
2wrong row open (conflict)+ tRP + tRCD14.2, 14.1
3queue non-emptyunbounded23.1
4refresh in flight+ remaining tRFC15.2, 15.3
5bus turnaround+ turnaround14.6, 22.x

ILLUSTRATIVE parameter set, used for every number in this chapter: CL = 22, tRCD = 24, tRP = 24, PHY_FIXED = 14, tRFC = 350.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   read latency, by class          (ILLUSTRATIVE, cycles)

     row hit,  empty queue     22 + 14            =  36    CL share 61%
     row miss, empty queue     22 + 24 + 14       =  60    CL share 37%
     conflict, empty queue     22 + 24 + 24 + 14  =  84    CL share 26%
     conflict, 45% load        84 + 0             =  84    CL share 26%
     conflict, 92% load        84 + 225           = 309    CL share  7%

DERIVED: CL's share falls from 61% to 7% across a range every real system spans, and the belief is a statement about the first row. CURRICULUM-DERIVED from 33.5 §14, which measured the same two load points and found a 3.7× latency difference in the queueing term: that term is row 5's, and it is the one with no entry in any datasheet.

The 92% row is the one to carry. DERIVED: at that load CL is 7% of the read latency, so a two-cycle CL improvement changes the total by 0.6% — and §13 shows what the same two cycles are worth against a change in the conflict rate.

8. The Decomposition, and What CL Actually Is

CURRICULUM-DERIVED from 14.9, which owns CL and states its class: a fixed, programmed latency, 13.3 §2's class B, with a two-sided obligation. And from 30.4 §4, which owns where CL actually sits in a budget.

Two properties of CL do the work in this chapter, and both are consequences of it being class B rather than class A.

First: CL is a delay, not an occupancy. CURRICULUM-DERIVED from 30.4 §7 and 30.4 §8, which own the distinction and the reservation defect it produces: a delay says when data appears; an occupancy says how long a resource is held. DERIVED: CL reserves nothing. A controller that issues a column command every tCCD sustains one transfer per tCCD regardless of CLso CL affects when the first beat of a given request arrives and not how many requests per second the interface carries.

Second: CL is fixed and programmed, so it is identical for every access. DERIVED: a term that is the same on every access cannot explain any variation in latencyso every question of the form why is this access slow has an answer that is not CL. That is the single most useful consequence of the correction and it needs no arithmetic.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ROBUST MODEL: latency is an exhaustive decomposition, and CL is one
// named term. The components sum exactly to the total -- 23.1's
// requirement, made structural.
module latency_attribution #(
    parameter int CL        = 22,   // ILLUSTRATIVE
    parameter int TRCD      = 24,   // ILLUSTRATIVE
    parameter int TRP       = 24,   // ILLUSTRATIVE
    parameter int PHY_FIXED = 14,   // ILLUSTRATIVE
    parameter int LAT_W     = 16
)(
    input  logic             clk,
    input  logic             rst_n,
    input  logic             retire,
    input  logic [1:0]       cls,          // 0 hit 1 miss 2 conflict
    input  logic [LAT_W-1:0] queue_cycles, // measured, not modelled
    input  logic [LAT_W-1:0] drain_cycles, // refresh, measured
    input  logic [LAT_W-1:0] turn_cycles,  // bus turnaround, measured
    input  logic [LAT_W-1:0] observed_total,
    // the six terms, published separately
    output logic [LAT_W-1:0] t_cl, t_rcd, t_rp, t_queue, t_phy, t_drain, t_turn,
    output logic [LAT_W-1:0] sum_terms,
    output logic             sum_exact,
    output logic [LAT_W-1:0] residue,
    output logic [7:0]       cl_share_pct,
    output logic [31:0]      acc_total, acc_cl
);
  // The whole decomposition in one expression, so the sum and the
  // published terms cannot drift apart -- 23.1's exact-sum requirement
  // depends on there being exactly one source of truth.
  function automatic logic [LAT_W-1:0] total_of(
      logic [1:0] c, logic [LAT_W-1:0] q,
      logic [LAT_W-1:0] d, logic [LAT_W-1:0] tu);
    return LAT_W'(CL) + LAT_W'(PHY_FIXED)
         + ((c != 2'd0) ? LAT_W'(TRCD) : '0)
         + ((c == 2'd2) ? LAT_W'(TRP)  : '0)
         + q + d + tu;
  endfunction

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      t_cl <= '0; t_rcd <= '0; t_rp <= '0; t_queue <= '0;
      t_phy <= '0; t_drain <= '0; t_turn <= '0;
      sum_terms <= '0; sum_exact <= 1'b0; residue <= '0;
      cl_share_pct <= '0; acc_total <= '0; acc_cl <= '0;
    end else if (retire) begin
      automatic logic [LAT_W-1:0] tot = total_of(cls, queue_cycles,
                                                 drain_cycles, turn_cycles);
      // CL and PHY_FIXED are on EVERY access. That is the whole point:
      // a constant term cannot explain a variable outcome.
      t_cl    <= LAT_W'(CL);
      t_phy   <= LAT_W'(PHY_FIXED);
      // tRCD appears on a miss and a conflict; tRP only on a conflict.
      t_rcd   <= (cls != 2'd0) ? LAT_W'(TRCD) : '0;
      t_rp    <= (cls == 2'd2) ? LAT_W'(TRP)  : '0;
      // The three MEASURED terms. 23.1 says queueing has no upper
      // bound, so all three are inputs and never parameters.
      t_queue <= queue_cycles;
      t_drain <= drain_cycles;
      t_turn  <= turn_cycles;

      sum_terms <= tot;
      // The exact-sum check, and the RESIDUE published beside it --
      // 33.5 section 7's named-residue rule, because a decomposition
      // without one puts every unmodelled cause into a modelled term.
      sum_exact <= (tot == observed_total);
      residue   <= (observed_total > tot) ? (observed_total - tot)
                                          : (tot - observed_total);

      acc_total <= acc_total + 32'(observed_total);
      acc_cl    <= acc_cl + 32'(CL);
      cl_share_pct <= (observed_total == '0) ? 8'd0
                    : 8'((32'(CL) * 32'd100) / 32'(observed_total));
    end
  end
endmodule

9. The Term With No Upper Bound

CURRICULUM-DERIVED from 23.1, which identifies the one component with no upper bound and states that the average is the wrong statistic because of it.

DERIVED: that single fact is sufficient to refute the belief, and it does so structurally rather than numerically. A sum containing an unbounded term cannot be dominated by a bounded one at all loads. No parameter set changes this; no part selection changes it; the belief is false for the same reason that a sum with an unbounded term has no bounded maximum.

The practical form is the one worth internalising, and it is a question rather than a number. DERIVED: what would have to change for CL to matter? The answer is the queue would have to be empty, and a queue is empty when the memory system is not the bottleneckso CL matters most precisely when memory latency matters least.

CURRICULUM-DERIVED from 33.5 §8's bound discrimination, which supplies the exact condition: a latency-bound system is one where MAX_OUTST / LAT_FLOOR binds before the service path does. DERIVED: CL is inside LAT_FLOOR, so lowering it raises the latency ceiling — and only on a system already latency-bound does that convert into throughput. That is a real effect and it is the strongest true version of the belief; it is also the version nobody states, because it requires knowing which bound is binding.

10. One Read, Five Segments

The belief is a claim about the length of one segment of a path. The path has five, and the diagram earns its place because prose renders a sequence badly.

A read request crossing five segments: queueing in the controller, precharge and activate on the DRAM, the column command, CAS latency to the first beat, and the PHY return path. CAS latency is one segment of five.One read, five segments — CL is the fourthRequesterControllerPHYDRAMread request arrivesqueueing — unboundedPRE (conflict only)— tRPACT (miss orconflict) — tRCDRD column commandCL — first beatcapture anddeserialisedata returned

Read the diagram as an accounting rather than a picture: the belief names segment four and omits one, two, three and the return. DERIVED: segments one through three are zero in exactly the region §6 states, which is why the diagram collapses to a single arrow on a bench test — and a collapsed diagram is what the belief is a memory of.

11. Delay Versus Occupancy — The Consequence Nobody Draws

CURRICULUM-DERIVED from 30.4 §7 and 30.4 §8, which own the distinction and the RTL review of a read data-bus reservation built on collapsing it. This chapter consumes that and does not rebuild it.

What this chapter adds is the throughput consequence, which follows from the distinction and is the half of the correction people skip.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   TWO PARTS, SAME BIN, DIFFERENT CL     (ILLUSTRATIVE)

     part A:  CL = 22,  tCCD = 8,  tRCD = 24,  tRP = 24
     part B:  CL = 18,  tCCD = 8,  tRCD = 24,  tRP = 24

   FIRST-BEAT LATENCY on a row hit:
     A: 22 + 14 = 36      B: 18 + 14 = 32      B faster by 4 cycles

   SUSTAINED THROUGHPUT, back-to-back column commands:
     both issue one column command every tCCD = 8 cycles
     A: 1 transfer / 8 cycles     B: 1 transfer / 8 cycles     IDENTICAL

   DERIVED: CL is a pipeline DEPTH, not a pipeline RATE. A deeper
   pipeline delays the first result and does not reduce the throughput.

DERIVED: the parts differ in latency and not at all in bandwidth, which is the cleanest single demonstration that CL is a delay. CURRICULUM-DERIVED from 23.2, whose central law this restates from the latency side: peak bandwidth is a property of the interface, and CL is not part of the interface's rate.

The claim deserves a model rather than a table, because it is this chapter's sharpest and it is the one a reader is most likely to doubt.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ROBUST MODEL: the data bus is reserved for the burst's OCCUPANCY,
// beginning CL cycles after the column command. Issue rate is governed
// by tCCD and is independent of CL -- 14.7's parameter, consumed here.
module depth_vs_rate #(
    parameter int CL    = 22,   // ILLUSTRATIVE -- the DELAY
    parameter int TCCD  = 8,    // STRUCTURAL   -- the RATE
    parameter int BL    = 16,   // beats per burst
    parameter int OCC   = BL/2, // bus cycles occupied (2 beats per cycle)
    parameter int PIPE  = 64    // ILLUSTRATIVE pipeline depth, >= CL+OCC
)(
    input  logic        clk,
    input  logic        rst_n,
    input  logic        col_request,
    output logic        col_issue,
    output logic        bus_busy,
    output logic [15:0] issued,
    output logic [15:0] beats_returned,
    output logic [15:0] cycles_elapsed,
    output logic [15:0] first_beat_latency,
    output logic        bus_double_booked
);
  // A shift register standing in for the read pipeline: bit k means a
  // burst's data occupies the bus k cycles from now.
  logic [PIPE-1:0] occ_pipe;
  logic [$clog2(TCCD+1)-1:0] since_col;
  logic                      seen_col;

  // The reservation window: OCC cycles starting at CL. Its WIDTH is the
  // occupancy and its OFFSET is the delay -- and only the width can
  // collide with another burst.
  function automatic logic [PIPE-1:0] window();
    logic [PIPE-1:0] w = '0;
    for (int k = 0; k < OCC; k++) w[CL + k] = 1'b1;
    return w;
  endfunction

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      occ_pipe <= '0; since_col <= '0; seen_col <= 1'b0;
      col_issue <= 1'b0; bus_busy <= 1'b0;
      issued <= '0; beats_returned <= '0; cycles_elapsed <= '0;
      first_beat_latency <= '0; bus_double_booked <= 1'b0;
    end else begin
      cycles_elapsed <= cycles_elapsed + 1'b1;
      col_issue <= 1'b0;

      if (seen_col && (since_col != TCCD[$clog2(TCCD+1)-1:0]))
        since_col <= since_col + 1'b1;

      // Eligibility is tCCD only. CL does not appear in this condition,
      // which is the entire claim.
      if (col_request && (!seen_col
                          || (since_col == TCCD[$clog2(TCCD+1)-1:0]))) begin
        // A double booking would mean the new window overlaps a
        // reservation already in the pipe.
        if ((occ_pipe & window()) != '0) bus_double_booked <= 1'b1;
        occ_pipe  <= (occ_pipe >> 1) | window();
        col_issue <= 1'b1;
        issued    <= issued + 1'b1;
        seen_col  <= 1'b1;
        since_col <= '0;
        if (issued == '0) first_beat_latency <= 16'(CL);
      end else begin
        occ_pipe <= occ_pipe >> 1;
      end

      bus_busy <= occ_pipe[0];
      if (occ_pipe[0]) beats_returned <= beats_returned + 16'd2;
    end
  end
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// INTENTIONALLY DEFECTIVE. WEAK MODEL: reserve the bus for CL cycles.
// This is 30.4 section 8's documented defect, built so its cost can be
// measured rather than asserted.
//
//   // reserve from the command until the data arrives, inclusive
//   function logic [PIPE-1:0] window();
//     logic [PIPE-1:0] w = '0;
//     for (int k = 0; k <= CL + OCC; k++) w[k] = 1'b1;   // <-- defect
//     return w;
//   endfunction
//   // and eligibility now waits for the reservation to clear:
//   if (col_request && (occ_pipe == '0)) begin ... end
//
// CONTRACT VIOLATED: 30.4 section 7's delay-versus-occupancy distinction. A
// delay is not a resource hold, and reserving across it serialises
// requests that the device pipelines.
//
// WHY IT SURVIVES: it is CONSERVATIVE and it never double-books the
// bus. `bus_double_booked` stays low in both builds, every read
// returns correct data, and no protocol checker fires. It costs only
// throughput -- 30.3 section 9's variety 8 exactly, and the reason the
// defect reaches silicon.
//
// TRACE (ILLUSTRATIVE, CL 22, TCCD 8, BL 16 so OCC 8, 400 cycles of
// back-to-back column requests):
//   robust: issue every TCCD = 8 cycles
//           issued 49,  beats 784,  first_beat_latency 22
//   weak:   issue every CL + OCC + 1 = 31 cycles
//           issued 12,  beats 192,  first_beat_latency 22
//
//   sustained throughput: robust 2.00 beats/cycle, weak 0.48
//   gap: 4.1x, and BOTH report the same first-beat latency of 22.
//
//   and the part comparison this produces:
//     on the WEAK controller, a CL18 part issues every 27 cycles
//     instead of 31 -> 14.8% more throughput.
//     on the ROBUST controller, a CL18 part issues every 8 cycles,
//     identical to CL22 -> 0% more throughput.
//   DERIVED: the belief "lower CL means more bandwidth" is FALSE on a
//   correct controller and TRUE on this one. The defect manufactures
//   the evidence for the misconception.

The last four lines of that trace are the most important thing in this chapter. DERIVED: on a correct controller, lowering CL buys exactly zero bandwidth. On a controller carrying 30.4 §8's reservation defect, it buys 14.8%so a team that measures a bandwidth gain from a lower-CL part has evidence of a bug in their own controller, and they will read it as evidence for the belief.

That is the first instance in this module of a pattern the remaining five chapters repeat: a misconception that is false in a correct system and true in a common broken one. CURRICULUM-DERIVED from 30.4 §8, which owns the defect and why it survives; this chapter's contribution is the measurement that shows the defect and the belief are mutually reinforcing.

And note what does not distinguish them: first_beat_latency is 22 in both builds, and bus_double_booked never fires in either. DERIVED: the defect is invisible to every latency measurement and every correctness check, and visible only to a sustained-throughput measurement compared against tCCD.

And the reservation defect 30.4 §8 documents is this confusion turned into RTL. DERIVED: a controller that reserves the data bus for CL cycles — rather than for the burst's occupancy, starting CL cycles later — throws away throughput in proportion to CL, which makes the low-CL part look faster on a bandwidth test for a reason that is a bug in the controller.

12. Where the Belief Breaks First, in Practice

Ranked by how early a real system leaves the region, which is not the order the terms are usually taught in.

RankThe exitWhy it comes first
1the queue stops being emptyany second requester does it; needs no cache miss pattern
2the row stops being the open one23.3: two streams interleaving is enough
3refresh lands on the access15.5: a fixed fraction of all cycles
4the bus turns aroundany read/write mix

DERIVED: rank 1 requires only a second requester, and every real system has one. CURRICULUM-DERIVED from Module 32, whose spine is that platform classes differ in their requester mix: a single-requester system is not a platform class in that module's taxonomy, so the region in §6 is outside every real platform it describes.

Rank 2 deserves one line because it is counter-intuitive. CURRICULUM-DERIVED from 23.3, which records that two mappings with identical hit, miss and conflict counts can have opposite temporal structure: DERIVED: leaving the row-hit region is not a property of the access pattern alone — it is a property of the pattern against the address map, so two systems running the same software can sit on opposite sides of this exit.

13. The Decision Built on the Belief

This is what the belief costs when somebody spends money on it, and it is the part 30.4 has no reason to build.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ROBUST MODEL: parts are ranked by MEAN ACCESS LATENCY over the
// workload's actual class mix, not by CL.
module part_selection #(
    parameter int PHY_FIXED = 14,    // ILLUSTRATIVE
    parameter int LAT_W     = 16
)(
    input  logic             clk,
    input  logic             rst_n,
    input  logic             evaluate,
    // the two candidate parts
    input  logic [7:0]       a_cl, a_trcd, a_trp,
    input  logic [7:0]       b_cl, b_trcd, b_trp,
    // the workload's measured class mix, in percent, summing to 100
    input  logic [7:0]       pct_hit, pct_miss, pct_conflict,
    // and the queueing term, measured on the platform
    input  logic [LAT_W-1:0] queue_mean,
    output logic             verdict_valid,
    output logic [LAT_W-1:0] a_mean, b_mean,
    output logic             b_is_better,
    output logic [7:0]       margin_pct_x10,
    output logic             mix_sums_to_100
);
  // Weighted mean access latency over the three classes, in hundredths
  // of a cycle to keep the mix weighting exact.
  //
  //   every access pays  CL + PHY_FIXED + queue_mean
  //   a miss also pays   tRCD
  //   a conflict pays    tRCD + tRP
  //
  // Section 8's point as arithmetic: only the class-dependent terms are
  // weighted by the mix, and CL is not one of them.
  function automatic logic [LAT_W-1:0] mean_lat(
      logic [7:0] cl, logic [7:0] trcd, logic [7:0] trp,
      logic [7:0] pm, logic [7:0] pc,
      logic [LAT_W-1:0] q);
    automatic int unsigned per_access = 32'(cl) + 32'(PHY_FIXED) + 32'(q);
    automatic int unsigned row_work   = 32'(pm) * 32'(trcd)
                                      + 32'(pc) * (32'(trcd) + 32'(trp));
    // per_access is paid on 100% of accesses; row_work is already
    // weighted in percent, so both are divided by 100 once.
    return LAT_W'(((per_access * 32'd100) + row_work) / 32'd100);
  endfunction

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      verdict_valid <= 1'b0; a_mean <= '0; b_mean <= '0;
      b_is_better <= 1'b0; margin_pct_x10 <= '0; mix_sums_to_100 <= 1'b0;
    end else if (evaluate) begin
      automatic logic [LAT_W-1:0] am = mean_lat(a_cl, a_trcd, a_trp,
                                                pct_miss, pct_conflict,
                                                queue_mean);
      automatic logic [LAT_W-1:0] bm = mean_lat(b_cl, b_trcd, b_trp,
                                                pct_miss, pct_conflict,
                                                queue_mean);
      mix_sums_to_100 <= ((16'(pct_hit) + 16'(pct_miss)
                           + 16'(pct_conflict)) == 16'd100);
      a_mean      <= am;
      b_mean      <= bm;
      b_is_better <= (bm < am);
      // The margin, so a reviewer sees whether the difference is worth
      // anything rather than merely which direction it points.
      margin_pct_x10 <= (am == '0) ? 8'd0
                      : 8'(((32'(am) - 32'(bm)) * 32'd1000) / 32'(am));
      verdict_valid  <= 1'b1;
    end else begin
      verdict_valid <= 1'b0;
    end
  end
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// INTENTIONALLY DEFECTIVE. WEAK MODEL: rank by CL.
//
//   b_is_better    <= (b_cl < a_cl);        // <-- the belief, as code
//   margin_pct_x10 <= 8'(((32'(a_cl) - 32'(b_cl)) * 32'd1000)
//                        / 32'(a_cl));
//
// CONTRACT VIOLATED: 23.1's decomposition. And note what is NOT
// violated: the direction. Part B really does have a lower CL, and on
// a row hit it really is faster.
//
// WHY IT SURVIVES: it is right about the sign in every case where the
// two parts differ only in CL, and it agrees with the bench test that
// gets run. The margin is the only thing it gets wrong, and a margin
// is what a purchasing decision is made on.
//
// TRACE (ILLUSTRATIVE, PHY_FIXED = 14):
//   part A: CL 22, tRCD 24, tRP 24
//   part B: CL 18, tRCD 24, tRP 24      (a "CL18" part, same bin)
//
//   workload 1 -- pointer chase, idle machine:
//     mix 95% hit / 5% miss / 0% conflict, queue_mean 0
//     robust: a_mean 37, b_mean 33, b better, margin 10.8%
//     weak:   b better, margin 18.2%
//     -- same VERDICT, and the weak margin is 1.7x too large.
//
//   workload 2 -- two streams, loaded server:
//     mix 40% hit / 25% miss / 35% conflict, queue_mean 225
//     robust: a_mean 291, b_mean 287, b better, margin 1.4%
//     weak:   b better, margin 18.2%
//     -- same verdict, margin overstated 13x.
//
//   and the decision this actually drives:
//     part C: CL 22, tRCD 20, tRP 20  (same CL as A, tighter row timing)
//     workload 2 mix:
//       robust: a_mean 291, c_mean 285, C better than A by 2.1%
//               and C beats B (287) as well
//       weak:   c_cl == a_cl -> "no difference", C never considered
//
//   gap: the weak model cannot see part C at all, because C differs in
//   no term the belief names. On the loaded workload C is the best of
//   the three and the belief ranks it equal to the worst.

And that is a gap in the pairwise model as well as in the belief, which is worth fixing rather than narrating. DERIVED: part C's exclusion is a property of a shortlist, not of a comparison — a two-part model cannot express it, so the model has to rank a set.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ROBUST MODEL: rank a SHORTLIST, and report what a CL filter would
// have removed from it. The exclusion count is the finding section 13's
// pairwise model cannot produce.
module shortlist_ranking #(
    parameter int NPART     = 4,
    parameter int PHY_FIXED = 14,    // ILLUSTRATIVE
    parameter int LAT_W     = 16
)(
    input  logic             clk,
    input  logic             rst_n,
    input  logic             rank,
    input  logic [7:0]       cl   [0:NPART-1],
    input  logic [7:0]       trcd [0:NPART-1],
    input  logic [7:0]       trp  [0:NPART-1],
    input  logic [7:0]       pct_miss, pct_conflict,
    input  logic [LAT_W-1:0] queue_mean,
    output logic             rank_valid,
    output logic [LAT_W-1:0] mean_of   [0:NPART-1],
    output logic [2:0]       best_by_mean,
    output logic [2:0]       best_by_cl,
    output logic             filter_picks_the_best,
    output logic [2:0]       tied_on_cl,        // candidates a CL sort cannot order
    output logic [LAT_W-1:0] cost_of_the_filter // cycles lost by ranking on CL
);
  function automatic logic [LAT_W-1:0] mean_lat(
      logic [7:0] c, logic [7:0] rcd, logic [7:0] rp,
      logic [7:0] pm, logic [7:0] pc, logic [LAT_W-1:0] q);
    automatic int unsigned per_access = 32'(c) + 32'(PHY_FIXED) + 32'(q);
    automatic int unsigned row_work   = 32'(pm) * 32'(rcd)
                                      + 32'(pc) * (32'(rcd) + 32'(rp));
    return LAT_W'(((per_access * 32'd100) + row_work) / 32'd100);
  endfunction

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      rank_valid <= 1'b0; best_by_mean <= '0; best_by_cl <= '0;
      filter_picks_the_best <= 1'b0; tied_on_cl <= '0;
      cost_of_the_filter <= '0;
      for (int i = 0; i < NPART; i++) mean_of[i] <= '0;
    end else if (rank) begin
      automatic logic [LAT_W-1:0] m [0:NPART-1];
      automatic int bm = 0, bc = 0, ties = 0;

      for (int i = 0; i < NPART; i++) begin
        m[i]       = mean_lat(cl[i], trcd[i], trp[i],
                              pct_miss, pct_conflict, queue_mean);
        mean_of[i] <= m[i];
      end

      for (int i = 1; i < NPART; i++) begin
        if (m[i]     < m[bm])      bm = i;   // the truth
        if (cl[i]    < cl[bc])     bc = i;   // what the belief picks
      end
      // Candidates a CL sort cannot distinguish from its own winner.
      // On this axis they are ties; on the real axis they are not.
      for (int i = 0; i < NPART; i++)
        if ((i != bc) && (cl[i] == cl[bc])) ties++;

      best_by_mean          <= 3'(bm);
      best_by_cl            <= 3'(bc);
      filter_picks_the_best <= (bm == bc);
      tied_on_cl            <= 3'(ties);
      // The cost, in the currency the decision is actually about.
      cost_of_the_filter    <= (m[bc] > m[bm]) ? (m[bc] - m[bm]) : '0;
      rank_valid            <= 1'b1;
    end else begin
      rank_valid <= 1'b0;
    end
  end
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// INTENTIONALLY DEFECTIVE. WEAK MODEL: the shortlist IS the CL sort.
//
//   // parts arrive already filtered: the procurement query was
//   //   "lowest CL at this bin", so every candidate has the same
//   //   tRCD and tRP and they differ only in CL.
//   best_by_mean          <= best_by_cl;          // <-- the defect
//   filter_picks_the_best <= 1'b1;
//   tied_on_cl            <= 3'd0;
//
// CONTRACT VIOLATED: none, on the candidate set it is given. On a
// shortlist where every part has identical row timing, ranking by CL
// IS ranking by mean latency -- the model is correct about its input.
// The defect is that the input was produced by the belief.
//
// TRACE (ILLUSTRATIVE, four parts, loaded mix 40/25/35, queue_mean 225):
//   part 0  CL 22  tRCD 24  tRP 24   -> mean 291
//   part 1  CL 18  tRCD 24  tRP 24   -> mean 287
//   part 2  CL 22  tRCD 20  tRP 20   -> mean 285      (part C)
//   part 3  CL 20  tRCD 22  tRP 26   -> mean 288
//
//   robust: best_by_mean = 2, best_by_cl = 1,
//           filter_picks_the_best = 0,
//           tied_on_cl = 1   (part 0 ties part 2 on CL = 22)
//           cost_of_the_filter = 287 - 285 = 2 cycles
//   weak:   best = 1, filter_picks_the_best = 1, tied_on_cl = 0
//
//   gap: the belief picks part 1 and the answer is part 2. The margin
//   is 2 cycles -- SMALL, and that is the honest result: on this mix
//   the four parts sit within 6 cycles of each other and the belief's
//   error is worth 0.7%.
//
//   The expensive finding is `tied_on_cl = 1`: part 0 and part 2 are
//   indistinguishable on the belief's axis and differ by 6 cycles on
//   the real one. A CL sort cannot order them, so which of the two a
//   procurement query returns is arbitrary -- and one of them is the
//   best part in the list while the other is the worst.

tied_on_cl is the number to take from this chapter, and it is more damaging than cost_of_the_filter. DERIVED: on the loaded mix the four parts span 6 cycles and the belief's pick costs 2 — a 0.7% error, which is genuinely small. But part 0 and part 2 are tied on CL and 6 cycles apart in reality, so a CL-sorted query returns one of them arbitrarily. The belief's real cost is not a wrong ranking; it is a ranking with ties in the places where the differences are.

CURRICULUM-DERIVED from 33.7 §7's discriminating-power item, which supplies the general form: an axis that does not partition the candidate set carries no information about it — and CL does not partition a set in which parts differ in row timing.

Part C is the finding, and it is not a margin error — it is a candidate the belief cannot represent. DERIVED: C has the same CL as A and tighter tRCD/tRP, so a CL-ranked comparison reports no difference and C is dropped from consideration. On the loaded workload C is the best of the three.

And the two workloads show the belief getting the verdict right and the magnitude wrong by 13×. DERIVED: on workload 2 the real margin between A and B is 1.4% and the belief reports 18.2%so the belief does not usually cause a wrong choice between two parts that differ only in CL; it causes a wrong estimate of what that choice is worth, and a wrong exclusion of every part that differs in anything else.

CURRICULUM-DERIVED from 33.5 §9's ceiling item, which is the general form: the belief is an optimisation proposal whose affected fraction is CL's share — 7% at load — so its ceiling at perfect improvement is 7% and its realised gain is 1.4%.

14. What It Costs, Measured

Where the belief is appliedWhat it producesMeasured gap
A latency reportCL + a constant, unchangingreports 36 where the truth is 309 at load
A part comparisonthe right sign, the wrong sizemargin 18.2% versus 1.4%, 13×
A part shortlistevery part with equal CL ranked equalpart C excluded; it was the best
An optimisation proposallower the CL settingceiling 7%, realised 1.4%
A bandwidth estimatelower CL means more bandwidth0%CL is a depth, not a rate
A debug hypothesisthis access was slow because CLCL is constant; it explains no variation

The last row is the cheapest and most useful consequence of the correction, and it needs no numbers. DERIVED: CL is identical on every access, so it cannot appear in any explanation of why one access differed from anotherwhich eliminates it from every debug hypothesis set in 33.7 §6's sense, for free, before any experiment.

And the bandwidth row is the one that changes an architecture argument. DERIVED: a proposal to buy lower-CL parts for a bandwidth-bound system has a ceiling of exactly zeroCURRICULUM-DERIVED from 33.5 §8: the two ceilings are MAX_OUTST × WIN / LAT_FLOOR and the available slots, and CL moves only the first. On a system where the service path binds, CL is not in the binding expression at all.

15. What the Assertions Prove

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // ---- Section 8: the decomposition must be exhaustive. 23.1's exact-sum
  // requirement, and the property that refutes the belief structurally.
  property p_terms_sum_to_observed;
    @(posedge clk) disable iff (!rst_n)
      retire |=> sum_exact;
  endproperty
  assert property (p_terms_sum_to_observed)
    else $error("the latency decomposition does not reproduce the observation");

  // CL is on EVERY access -- the fact that makes it useless as an
  // explanation of variation.
  property p_cl_term_is_constant;
    @(posedge clk) disable iff (!rst_n)
      retire |=> (t_cl == LAT_W'(CL));
  endproperty
  assert property (p_cl_term_is_constant)
    else $error("the CL term varied between accesses: it is not a fixed latency");

  // The class-dependent terms appear exactly where 23.1 says they do.
  property p_rcd_only_on_miss_or_conflict;
    @(posedge clk) disable iff (!rst_n)
      (retire && (cls == 2'd0)) |=> (t_rcd == '0);
  endproperty
  assert property (p_rcd_only_on_miss_or_conflict)
    else $error("a row hit was charged tRCD");

  property p_rp_only_on_conflict;
    @(posedge clk) disable iff (!rst_n)
      (retire && (cls != 2'd2)) |=> (t_rp == '0);
  endproperty
  assert property (p_rp_only_on_conflict)
    else $error("a non-conflict access was charged tRP");

  // ---- The claim itself, asserted as a CONDITIONAL. This is the chapter's
  // central property: the belief is TRUE in section 6's region and the property
  // says exactly that, which is stronger than denying it.
  property p_claim_holds_in_its_region;
    @(posedge clk) disable iff (!rst_n)
      (retire && (cls == 2'd0) && (queue_cycles == '0) && (drain_cycles == '0))
        |=> (sum_terms == (LAT_W'(CL) + LAT_W'(PHY_FIXED)));
  endproperty
  assert property (p_claim_holds_in_its_region)
    else $error("in the row-hit idle region the latency is not CL + PHY_FIXED");

  // And its negation outside the region, which is the correction.
  property p_claim_fails_outside_its_region;
    @(posedge clk) disable iff (!rst_n)
      (retire && ((cls != 2'd0) || (queue_cycles != '0)))
        |=> (sum_terms > (LAT_W'(CL) + LAT_W'(PHY_FIXED)));
  endproperty
  assert property (p_claim_fails_outside_its_region)
    else $error("outside the region the latency did not exceed CL + PHY_FIXED");

  // ---- Section 9: the unbounded term. 30.8 section 11's variety 5 -- a derived
  // share must be a fraction -- and the share must be free to be small.
  property p_cl_share_is_a_fraction;
    @(posedge clk) disable iff (!rst_n)
      retire |=> (cl_share_pct <= 8'd100);
  endproperty
  assert property (p_cl_share_is_a_fraction)
    else $error("the CL share exceeded 100%: the decomposition is inconsistent");

  property p_queue_term_is_not_bounded_by_a_parameter;
    @(posedge clk) disable iff (!rst_n)
      (retire && (queue_cycles > LAT_W'(CL))) |=> (cl_share_pct < 8'd50);
  endproperty
  assert property (p_queue_term_is_not_bounded_by_a_parameter)
    else $error("CL retained a majority share with queueing above CL");

  // ---- Section 13: part selection.
  property p_mix_must_sum_to_100;
    @(posedge clk) disable iff (!rst_n)
      verdict_valid |-> mix_sums_to_100;
  endproperty
  assert property (p_mix_must_sum_to_100)
    else $error("a part verdict was issued on a class mix that does not sum to 100");

  property p_verdict_matches_the_means;
    @(posedge clk) disable iff (!rst_n)
      (verdict_valid && b_is_better) |-> (b_mean < a_mean);
  endproperty
  assert property (p_verdict_matches_the_means)
    else $error("the verdict disagrees with the computed means");

  // The property the weak model cannot satisfy: the margin must be
  // computed from the MEANS, so a part differing only in row timing
  // produces a non-zero margin.
  property p_margin_reflects_row_timing;
    @(posedge clk) disable iff (!rst_n)
      (verdict_valid && (a_cl == b_cl) && (b_trcd < a_trcd)
       && (pct_conflict != '0)) |-> (b_mean < a_mean);
  endproperty
  assert property (p_margin_reflects_row_timing)
    else $error("a part with tighter row timing was ranked equal on equal CL");

  // Two-sided: and a part differing only in CL must NOT be ranked
  // better on a pure-conflict mix by more than CL's share. 30.3 section 9's
  // variety 8 -- a one-sided property is satisfied by ranking nothing.
  property p_cl_only_margin_is_bounded_by_its_share;
    @(posedge clk) disable iff (!rst_n)
      (verdict_valid && (a_trcd == b_trcd) && (a_trp == b_trp)
       && (queue_mean > 16'd100))
        |-> (margin_pct_x10 < 8'd100);
  endproperty
  assert property (p_cl_only_margin_is_bounded_by_its_share)
    else $error("a CL-only difference produced a margin above 10% under load");

  // ---- Section 8: the named residue. 33.5 section 7's rule -- an
  // attribution without a residue category puts unmodelled causes into
  // a modelled term, and here the modelled term would be CL's share.
  property p_residue_is_zero_when_exact;
    @(posedge clk) disable iff (!rst_n)
      (retire && sum_exact) |=> (residue == '0);
  endproperty
  assert property (p_residue_is_zero_when_exact)
    else $error("an exact decomposition reported a non-zero residue");

  property p_turnaround_is_charged_separately;
    @(posedge clk) disable iff (!rst_n)
      retire |=> (t_turn == $past(turn_cycles));
  endproperty
  assert property (p_turnaround_is_charged_separately)
    else $error("the turnaround term was folded into another component");

  // ---- Section 13: the shortlist. The properties the pairwise model
  // could not express, because they are about a SET.
  property p_best_by_mean_is_minimal;
    @(posedge clk) disable iff (!rst_n)
      rank_valid |-> (mean_of[best_by_mean] <= mean_of[best_by_cl]);
  endproperty
  assert property (p_best_by_mean_is_minimal)
    else $error("the mean-ranked winner is not minimal: the ranking is wrong");

  property p_filter_cost_is_the_difference;
    @(posedge clk) disable iff (!rst_n)
      (rank_valid && !filter_picks_the_best)
        |-> (cost_of_the_filter
             == (mean_of[best_by_cl] - mean_of[best_by_mean]));
  endproperty
  assert property (p_filter_cost_is_the_difference)
    else $error("the filter's cost does not equal the gap it produced");

  // And the property that makes `tied_on_cl` load-bearing: a tie on the
  // belief's axis must not be reported as a tie on the real one.
  property p_cl_ties_are_not_mean_ties;
    @(posedge clk) disable iff (!rst_n)
      (rank_valid && (tied_on_cl != '0))
        |-> (mean_of[best_by_mean] != mean_of[best_by_cl])
            || filter_picks_the_best;
  endproperty
  assert property (p_cl_ties_are_not_mean_ties)
    else $error("candidates tied on CL were treated as equivalent overall");

  // ---- Section 11: depth versus rate. The chapter's sharpest claim,
  // asserted: issue eligibility must not mention CL.
  property p_issue_rate_is_tccd_not_cl;
    @(posedge clk) disable iff (!rst_n)
      col_issue |=> ##[0:TCCD-1] (!col_issue);
  endproperty
  assert property (p_issue_rate_is_tccd_not_cl)
    else $error("two column commands issued closer than tCCD");

  property p_issue_permitted_at_tccd;
    @(posedge clk) disable iff (!rst_n)
      (col_request && seen_col && (since_col == TCCD[$clog2(TCCD+1)-1:0]))
        |=> col_issue;
  endproperty
  assert property (p_issue_permitted_at_tccd)
    else $error("a column command eligible at tCCD was not issued: CL is gating");

  // The bus must never be double-booked -- and note that the WEAK build
  // satisfies this too, which is why it survives. 30.3 section 9's
  // variety 8: conservatism violates nothing.
  property p_bus_never_double_booked;
    @(posedge clk) disable iff (!rst_n) !bus_double_booked;
  endproperty
  assert property (p_bus_never_double_booked)
    else $error("two bursts were reserved onto overlapping bus cycles");

  // The throughput bound that the belief predicts and a correct
  // controller refutes: sustained beats must reach the tCCD-governed
  // rate regardless of CL.
  property p_sustained_rate_reaches_tccd_bound;
    @(posedge clk) disable iff (!rst_n)
      (cycles_elapsed == 16'd400)
        |-> (issued >= 16'((400 - CL) / TCCD));
  endproperty
  assert property (p_sustained_rate_reaches_tccd_bound)
    else $error("sustained issue rate fell below the tCCD bound: CL is serialising");

  // ---- COVERS. Each on the dimension the belief's failure scales with.
  // The REGION ITSELF, so p_claim_holds_in_its_region is not vacuous. A
  // loaded-only stimulus never reaches it.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (cls == 2'd0) && (queue_cycles == '0));
  // And outside it. The dimension is LOAD, and an idle-only bench test
  // never reaches this one -- which is why the belief survives.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (queue_cycles > LAT_W'(4*CL)));
  // A CONFLICT, which two interleaving streams produce and one does not.
  cover property (@(posedge clk) disable iff (!rst_n) retire && (cls == 2'd2));
  // A refresh drain landing on an access -- 15.5's fixed fraction.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (drain_cycles != '0));
  // CL's share falling BELOW a tenth: the 92%-load row of section 7, which is
  // the number the belief is most wrong about.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (cl_share_pct < 8'd10));
  // And above a half, so the share is exercised across its range rather
  // than only where the argument is convenient.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (cl_share_pct > 8'd50));
  // Section 13: the PART-C case -- equal CL, different row timing. A
  // shortlist that only varies CL never reaches it.
  cover property (@(posedge clk) disable iff (!rst_n)
                  verdict_valid && (a_cl == b_cl) && (a_trcd != b_trcd));
  // A CL-only comparison under load, where the margin collapses.
  cover property (@(posedge clk) disable iff (!rst_n)
                  verdict_valid && (a_trcd == b_trcd) && (queue_mean > 16'd200));
  // A conflict-heavy mix, which is where the ranking changes.
  cover property (@(posedge clk) disable iff (!rst_n)
                  verdict_valid && (pct_conflict > 8'd30));
  // And a hit-heavy mix, so both ends of the mix axis are reached.
  cover property (@(posedge clk) disable iff (!rst_n)
                  verdict_valid && (pct_hit > 8'd90));
  // Section 11: BACK-TO-BACK issue at exactly tCCD. A stimulus with
  // gaps wider than CL never reaches it -- and a gapped stimulus is
  // what a latency benchmark produces, which is why the reservation
  // defect survives its own regression.
  cover property (@(posedge clk) disable iff (!rst_n)
                  col_issue ##TCCD col_issue);
  // A turnaround charged on a retire, so the sixth term is exercised.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (turn_cycles != '0));
  // And a non-zero residue, so p_residue_is_zero_when_exact has a
  // counterpart: an unmodelled cause actually appearing.
  cover property (@(posedge clk) disable iff (!rst_n)
                  retire && (residue != '0));
  // Section 13: a shortlist the CL filter gets WRONG. A set filtered on
  // CL before it arrives never reaches this -- section 18's self-reinforcing
  // finding, as a coverage hole.
  cover property (@(posedge clk) disable iff (!rst_n)
                  rank_valid && !filter_picks_the_best);
  // And a TIE on CL between two parts of different mean -- the finding
  // that costs more than the mis-ranking.
  cover property (@(posedge clk) disable iff (!rst_n)
                  rank_valid && (tied_on_cl != '0));

Two things about this property set are specific to a misconceptions chapter and worth stating.

First, the central property is a conditional that affirms the belief, not a denial of it. p_claim_holds_in_its_region asserts that in §6's region the latency is CL + PHY_FIXED. DERIVED: a chapter that only asserted the negation would be unable to distinguish a correct model from one that is wrong everywhere — and it would also misrepresent the belief, which is true there. The pair of properties — holds inside, fails outside — is the region, expressed formally.

Second, variety 8 governs p_cl_only_margin_is_bounded_by_its_share. CURRICULUM-DERIVED from 30.3 §9: a one-sided property is satisfied by a model that ranks nothing, so the bound on a CL-only margin is paired with p_margin_reflects_row_timing, which requires the model to find a difference the belief cannot see.

16. Quantitative Reasoning

QuantityTruthUnder the beliefGapProvenance
CL share, row hit, idle61%100%39 pointsDERIVED, ILLUSTRATIVE params
CL share, conflict, idle26%100%74 pointsDERIVED
CL share, conflict, 92% load7%100%93 pointsDERIVED
read latency at 92% load309368.6×DERIVED
A-vs-B margin, pointer chase10.8%18.2%1.7×DERIVED
A-vs-B margin, loaded server1.4%18.2%13×DERIVED
Part C's rank on the loaded mixbest of threeinvisibleexcludedDERIVED
bandwidth gain from lower CL0%implied positiveSTRUCTURAL: CL is a depth
variation explained by CL0all of itDERIVED: it is constant

Sort those by what the belief is wrong about and there are exactly three kinds, which is this chapter's summary.

KindRowsWhat the belief does
Magnitudeshares, latency, marginsright sign, wrong size — up to 13×
Representationpart Ccannot express a candidate that differs elsewhere
Categorybandwidth, variationapplies a delay to a rate, and a constant to a variation

DERIVED: the magnitude errors are the ones people expect and the category errors are the ones that cost architecture arguments. CURRICULUM-DERIVED from 18.4 §1's grades and 32.1 §15's variety 11: the belief is a grade A fact — CL measured for a named configuration, the row-hit idle case — consumed as a grade B rule, and category drift is the exact name for what happens next.

17. Mutation Testing

Baseline first: all twenty-one assertions pass and all fifteen covers are non-zero.

#MutationKilled bySurvived?
M1charge tRCD on a hitp_rcd_only_on_miss_or_conflictkilled
M2charge tRP on a missp_rp_only_on_conflictkilled
M3drop queue_cycles from the sump_terms_sum_to_observed, by one coverkilled
M4make t_cl track observed_totalp_cl_term_is_constantkilled
M5drop drain_cycles from the sump_terms_sum_to_observed, by one coverkilled
M6report cl_share_pct against CL + PHY_FIXEDp_cl_share_is_a_fractionkilled*
M7§13: rank by CLp_margin_reflects_row_timing, by one coverkilled
M8§13: margin from the CL differencep_cl_only_margin_is_bounded_by_its_share, by one coverkilled
M9§13: skip the mix-sum checkp_mix_must_sum_to_100killed
M10§13: invert b_is_betterp_verdict_matches_the_meanskilled
M11PHY_FIXED raised to 200nothingSURVIVES
M12the class mix fixed at 100% hitnothingSURVIVES
M13queue_mean hard-wired to 0nothingSURVIVES
M14§11: reserve the bus for CL + OCCp_sustained_rate_reaches_tccd_boundkilled
M15§11: gate issue on occ_pipe == '0'p_issue_permitted_at_tccdkilled
M16§11: OCC widened from BL/2 to BLp_bus_never_double_bookedkilled
M17§8: fold turn_cycles into t_queuep_turnaround_is_charged_separatelykilled
M18§8: residue hard-wired to zeroby one coverkilled
M19§11: TCCD raised to CL + OCCnothingSURVIVES

DERIVED: fifteen of nineteen killed, four survived — and the four survivors are this module's central finding rather than a coverage gap.

M11, M12 and M13 each move a quantity and keep every mechanism correct. A large PHY_FIXED is still a constant term; a 100%-hit mix still sums to 100; a zero queue_mean is still a measured input. DERIVED: all three keep the decomposition exact and every property green — and M12 and M13 together reconstruct §6's region, which is where the belief is true.

That is variety 12, and here it has a meaning specific to a misconceptions module. CURRICULUM-DERIVED from 33.4 §15: complete about the mechanism, silent about the magnitude. DERIVED: a mutation that narrows the stimulus to the belief's region cannot be killed by any property in this chapter, because inside that region the belief is correctso the thing that makes a misconception survive and the thing that makes variety 12 unkillable are the same thing: a scope that nothing in the design constrains.

M19 is the sharpest of the four and it is a fresh instance rather than a repeat. Raising TCCD to CL + OCC destroys the throughput exactly as the weak build does — and p_sustained_rate_reaches_tccd_bound passes, because its bound is (400 - CL) / TCCD and TCCD is the thing that moved. DERIVED: the property's expectation is derived from the parameter under mutation, so it re-derives a weaker expectation and confirms it.

That is variety 12 in a form none of the eight gates in Module 33 produced, and it is worth naming. CURRICULUM-DERIVED from 33.4 §15: the variety is complete about the mechanism, silent about the magnitude. DERIVED: here the property is not silent about the magnitude — it computes one — and it computes it from the mutated input, which is 33.2 §9's denominator-independence defect relocated into an expectation. A bound is only a bound if it is independent of what it bounds, and TCCD's correct value is a device parameter that belongs in a datasheet row, not in the property.

Four mutations are killed only by a cover, and M7's is the one that matters. Ranking by CL agrees with the robust model on every shortlist where the parts differ only in CL, so the cover on (a_cl == b_cl) && (a_trcd != b_trcd) is the only thing that reaches a disagreement. CURRICULUM-DERIVED from 31.2 §14's coverage-dimension rule: the dimension is the shortlist's variety, and evaluating a hundred parts that differ only in CL never reaches it.

18. Baseline Defects Found Before Mutation

Belief applied toCaught byAt what cost
a latency reportp_terms_sum_to_observednothing — add the components
the CL sharep_cl_share_is_a_fractionnothing — one division
explaining a slow accessp_cl_term_is_constantnothing — CL is the same every time
a two-part comparisonp_cl_only_margin_is_bounded_by_its_sharea loaded measurement
a shortlistp_margin_reflects_row_timinga third part that differs elsewhere
a bandwidth claimSTRUCTURAL: no property needed; tCCD sets the rate

DERIVED: three of six applications are refuted without any measurement, and the cheapest is the third — CL is constant, so it explains no variation.

And two need a stimulus that a first experiment does not produce, which is the whole reason the belief persists.

ApplicationThe stimulusWhy the usual experiment misses it
a two-part comparisona loaded runthe bench test is single-outstanding by design
a shortlista part that differs in tRCD, not CLshortlists are built by filtering on CL

DERIVED: the second is self-reinforcing and is the sharper of the two. A shortlist built by sorting on CL contains only parts that differ in CL, so the experiment that would reveal the belief cannot be run on the candidate set the belief produced. CURRICULUM-DERIVED from 33.4 §6's configuration-reach item: the dimension belongs to the environment's model rather than its stimulus, and here the environment is a purchasing shortlist.

19. Silicon Observability

What silicon showsWhat it says about the belief
mean read latency far above CL + PHY_FIXEDthe system is outside §6's region — always, on a real platform
latency that rises with load while CL is unchangedthe variation is in the queueing term
two parts with different CL and identical bandwidthCL is a depth, not a rate — §11's demonstration, in hardware
a latency histogram with a long tail23.1's unbounded term, visible
a low-CL part that lost a benchmarkthe benchmark was conflict-bound or bandwidth-bound

The third row is the cleanest refutation available and it costs one bandwidth test on each of two parts. DERIVED: if CL were the memory latency in the sense the belief means, a lower CL would raise sustained throughput, and it does notCURRICULUM-DERIVED from 14.6, which owns tCCD: the column-to-column spacing sets the rate, and CL does not appear in it.

And the fourth row is the one that converts the correction into a habit. CURRICULUM-DERIVED from 23.1 and 33.5 §10: publish a histogram with an open top bin, and CL stops looking like the answer the moment the distribution has a shape. A single mean can be confused with CL + PHY_FIXED; a distribution cannot.

20. The Beliefs This One Generates

A misconception is rarely alone. This one is the root of four others, and naming them is part of taking it apart.

Downstream beliefWhy it followsWhere it is refuted
“lower CL means more bandwidth”if CL is the latency, and bandwidth is 1/latency§11; 23.2
“the datasheet timings tell you the performance”if the printed number is the quantity33.5 §13's five levels
“this access was slow, so check the timings”if CL explains latency, it explains variation§8; CL is constant
“memory latency is a property of the memory”if it is a datasheet parameterModule 32: the requester mix decides
“the controller just picks the next request”if latency is a device constant, scheduling cannot matter34.4
“the timings are set once at boot”if CL is the number and it is programmed once34.5

The last row is the most consequential and it is the bridge to the rest of this module. DERIVED: three of the four additive terms depend on what other requesters are doing — the queue, the row state, the refresh phase — so read latency is a property of the system and not of the part. CURRICULUM-DERIVED from Module 32's spine: all five platform classes run the same obligations and differ in the requester mix.

And the second row is the one 34.3 takes as its own subject. DERIVED: the printed number is the quantity is the shared root of this chapter's belief and that one's — here it is CL, there it is the peak transfer rate, and in both cases the printed number is the only level of a five-level decomposition that exists before silicon.

21. Common Wrong Answers

These are the corrections that are themselves wrong — the usual over-shoots when somebody first learns that CL is not the whole story.

  1. CL does not matter.” It is 61% of a row-hit idle read (§7), and on a latency-bound system it sits inside LAT_FLOOR, which is in the binding expression. CURRICULUM-DERIVED from 33.5 §8. The correction is that CL is one term of four, not that it is negligible.

  2. “The real answer is tRCD + CL.” That is a better wrong answer and it is still a wrong answer — it omits tRP, the queueing term and the refresh drain. CURRICULUM-DERIVED from 23.1: the components must sum exactly, and any short list has a residue.

  3. “Just use the average latency instead.” CURRICULUM-DERIVED from 23.1: the average is the wrong statistic, because of the term with no upper bound. And 33.5 §10 measured a mean improving 11% while ten deadlines started missing.

  4. “So buy the part with the lowest tRCD.” Same error, different parameter. DERIVED: §13's model ranks by the weighted mean over the workload's actual class mix, and which parameter dominates is a property of that mix — a hit-heavy workload is not helped by tRCD at all.

  5. “Latency does not matter; bandwidth does.” Which binds? CURRICULUM-DERIVED from 33.5 §8: two workloads at identical queue occupancy had opposite bounds, and on the latency-bound one the data path had 790 unused slots.

  6. CL is in nanoseconds, so a higher CL at a higher bin can be faster.” True, and it is 30.4's subject — that chapter owns the conversion and the finding that the answer changes with the metric. This is the one item in this list that is not a wrong answer; it is a different correct one, and conflating the two corrections is its own error.

  7. “The controller hides CL with pipelining.” It hides it from throughput and not from latency. DERIVED: §11 — both parts sustain one transfer per tCCD, and the first beat still arrives CL cycles after the column command. A pipeline changes the rate and not the depth.

  8. “Out-of-order execution covers memory latency anyway.” Up to the reorder window, and the unbounded term is what exhausts it. CURRICULUM-DERIVED from 23.1: a term with no upper bound is not covered by a fixed window.

  9. “It is CL22 versus CL18 — a 20% difference.” 20% of one term. DERIVED: §13's loaded workload puts the real margin at 1.4%, and the belief reports 18.2%.

  10. “We measured it: the CL18 part was faster.” On which workload? DERIVED: it is faster on both of §13's workloads and by 10.8% on one and 1.4% on the other — and part C, which the shortlist excluded, beats it on the second.

  11. “Row hits are the common case, so §6's region is the normal case.” Row hits are common; an empty queue is not. DERIVED: §12 ranks the queue as the first exit and it needs only a second requester — the region requires all four conditions at once.

  12. “Then nothing in the datasheet is useful.” Inverted. DERIVED: every term except the queueing one comes from the datasheet, and the decomposition in §8 is built entirely from printed parameters plus two measurements. The datasheet is necessary and it is not sufficient.

  13. “The queueing term is the controller's fault.” It is the requester mix's consequence. CURRICULUM-DERIVED from 33.5 §9's owner_cycles: two of six attribution components belong to the requester, and a controller cannot schedule away demand.

  14. CL plus a constant is close enough for an estimate.” It is 8.6× low at 92% load (§16). DERIVED: close enough is a claim about a region, and the region is the one in §6.

  15. “Every part at the same bin has the same tRCD, so only CL varies.” That is the shortlist assumption, and §13's part C is the counterexample. DERIVED: a shortlist filtered on CL contains only parts that differ in CL — the assumption creates the evidence for itself.

  16. “This is a purchasing question, not an engineering one.” §14's last two rows are engineering: a bandwidth proposal with a ceiling of zero, and a debug hypothesis that cannot explain variation. The belief costs more inside a design review than at a purchase order.

  17. “The belief is harmless because the verdict is usually right.” The verdict is usually right and the magnitude is up to 13× wrong, and one candidate class is invisible. DERIVED: a decision procedure that cannot represent part C is not producing a slightly wrong answer; it is answering a different question.

  18. “I know all this; nobody actually believes the simple version.” CURRICULUM-DERIVED from 33.8 §6, which measured the mechanism: three claims delivered at 85–90% self-reported confidence were recognition rather than derivation, and confidence could not separate them from the derived ones. The belief does not require ignorance; it requires not having been asked and at 92% load?.

22. Self-Check

  1. State the four conditions under which latency equals CL is exactly true, and name the term each one zeroes.
  2. CL = 22, tRCD = 24, tRP = 24, PHY_FIXED = 14. Give the read latency for a hit, a miss and a conflict, and CL's share of each.
  3. A colleague says a lower-CL part will improve sustained bandwidth. Give the one-line refutation, and name the parameter that actually sets the rate.
  4. An access took 309 cycles where the mean is 84. Can CL be part of the explanation? Say why in one sentence.
  5. Two parts differ only in CL, 22 versus 18. Give the margin on a pointer chase and on a loaded server, and say which number a purchasing decision uses.
  6. Part C has the same CL as part A and tighter tRCD and tRP. Where does a CL-ranked shortlist place it, and what does that make the error — magnitude, representation, or category?
  7. Why is a shortlist filtered on CL unable to produce the experiment that would refute the belief?
  8. Which evidence grade does “latency is CL” hold, which is it consumed at, and what is the name for the difference?
  9. Name the two terms in §8's decomposition that must be measured rather than read from a datasheet, and say which of the two has no upper bound.
  10. Three mutations survived this chapter's property set. What do they have in common, and why is that the same thing that makes a misconception survive?
  11. p_claim_holds_in_its_region asserts that the belief is true. Why is that property in this chapter, and what would be lost by asserting only its negation?
  12. Name two of the four beliefs this one generates, and the chapter that refutes each.

23. The Residual Risk

What this chapter cannot settle.

It cannot tell you which bound is binding on your system. §9 established that CL matters on a latency-bound system and the two ceilings that decide it are 33.5 §8's. DERIVED: this chapter refutes latency equals CL and does not tell you whether latency is your problem — and on a latency-bound system with an empty queue, a lower CL is a real and correct improvement.

It cannot supply your workload's class mix. §13's verdict is a weighted mean over pct_hit, pct_miss and pct_conflict, and M12 showed that fixing the mix at 100% hit makes the belief correct and kills nothing. CURRICULUM-DERIVED from 23.3: the mix is produced by the access pattern against the address map, so it is measured per system and this chapter derives none.

It cannot bound the queueing term. CURRICULUM-DERIVED from 23.1: the term has no upper bound, so §8's model takes it as an input. DERIVED: every number in §7's table below the third row depends on a measurement this chapter cannot perform, which is why they are labelled ILLUSTRATIVE and why §19's histogram is the recommendation.

And it cannot make the region in §6 uninteresting. DERIVED: the belief is correct there, a real benchmark occupies it, and a reader who concludes that CL never matters has replaced one over-generalisation with another — which is §21's first entry and the failure mode this whole module is most at risk of.

24. Where This Goes

One belief down, and the shape of the next is already visible.

Chapter 34.2 takes “refresh only affects idle systems.” The structure repeats — a true statement over-generalised, a non-empty region, a boundary that can be computed — and the term it drops is the one this chapter ranked third among the exits.

But the mechanism of the belief inverts, and that is worth noticing before reading on. DERIVED: this chapter's belief is a component mistaken for the sum. The next is a cost mistaken for absent — and the two errors point in opposite directions. Here an engineer over-weights a term they can see. There they under-weight a term whose cost is paid somewhere they are not looking.

CURRICULUM-DERIVED from 15.5, which owns the availability arithmetic and its behaviour across density, refresh mode and temperature, and from 30.1, which owns the average-versus-deadline distinction. DERIVED: that distinction is the next chapter's whole subject, and it is the same distinction §21's third entry raised about latencya mean is not a deadline, and refresh is the place in this curriculum where the gap between them is largest.

Continue learning

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.