Skip to content
VLSI Mentor

DDR · Module 6

CK / CK# — The Differential Clock

CK/CK# is the timing reference for the command and address path — and only for that path. What a differential pair buys, and why data uses a separate source-synchronous reference, is the distinction the rest of the DDR interface rests on.

Module 5 built the structure a request moves through — channel, rank, bank group, bank, row. It treated the wires themselves as abstractions: "the command bus", "the data bus", "the chip select".

This module makes them concrete. Its question is:

What crosses a DDR interface, who drives each wire at each moment, and how do those signals cooperate to perform a memory operation?

That is deliberately a question about relationships, not names. A list of pin names is available in any datasheet and teaches almost nothing; what a datasheet does not tell you is which signals belong to which timing domain, which side owns a wire during which operation, and what a waveform looks like when the relationship is wrong.

This chapter starts with the clock, because the clock is what makes "when" mean anything at all.

1. A Taxonomy Before Any Pin Names

Signals are easier to reason about in families than individually, because members of a family share a timing domain, a direction discipline and a failure mode.

Eight families of DDR interface signals. Clock and timing reference establishes when command events happen. Command and address carries the operation and its selection fields. Selection and qualification decides which device acts. Data carries the payload. Source-synchronous strobes carry the data's own timing. Mask and data qualification modifies what a write commits. Reset and power-state control establishes operating conditions. Alert and sideband reports errors back to the controller.A · ClockCK / CK# — this chapterB · Command/addresswhat and whereC · Qualificationwho actsD · Datathe payloadE · Strobesdata's own timingF · Maskwhat commitsG · Reset / poweroperating conditionsH · Alert / sidebanderrors backtimeswithleads totimes12
Figure 1 — eight signal families; each chapter in this module locates itself here.

The two "times" edges are the most important thing in that figure. The clock times the command path. A strobe times the data path. They are different timing references for different signal groups, and conflating them is the single most common structural misunderstanding of a DDR interface — §5 is about why.

A caution about the figure's completeness. These are families, not a pin list, and which pins populate each family depends on the generation. Family G contains a dedicated CKE pin in DDR4 and does not in DDR5. Family B contains dedicated RAS#/CAS#/WE# pins in DDR3 and does not in DDR5. The families are stable; the membership is not, and every chapter in this module states its generation scope explicitly.

2. What a Clock Establishes

Chapter 4.1 §1 established what making DRAM synchronous changed: it replaced a continuous analog timing negotiation with a clocked contract in which obligations are expressed in counts of cycles. CK is that contract's reference.

Concretely, CK establishes a repeating instant at which the command and address inputs mean something. Outside that instant the CA lines are in transition and carry nothing. A command is not a level held on a wire; it is a value sampled at an event, and CK defines the event.

Three consequences follow, and all three matter later.

It makes commands countable. "Data appears N cycles after the column command" is only expressible because there is a shared notion of a cycle. Every timing parameter in Modules 13 and 14 is a count of these events.

It makes the interface specifiable. Both sides can be designed against "sample on this edge" without either knowing the other's internal implementation — which is what makes multi-vendor interoperability possible.

And it makes stability, not level, the requirement on CA. Because the value is sampled at an instant, what the controller owes is that the CA lines are settled and unchanging around that instant. §4's RTL models exactly that obligation.

3. Why Differential

CK is not one wire. It is a pair — CK_t and CK_c, commonly written CK and CK#, carrying complementary signals.

The sampling instant is defined by their crossing point, not by either wire reaching a threshold. That single change is worth three specific benefits.

The reference moves with the signal. A single-ended receiver compares the incoming wire against a fixed threshold voltage, so anything that shifts the signal relative to that threshold — supply droop, ground offset between two packages, temperature drift — moves the apparent timing of the edge. A differential receiver compares the two wires against each other, so a disturbance that affects both equally moves neither the crossing point nor the decision.

Noise that couples into both wires cancels. Two conductors routed together pick up nearly the same interference, and a receiver looking at the difference rejects the common part. That is the same argument Chapter 4.4 §2 made about why the heavily loaded command path was the first thing DDR3 had to fix — a clock that reaches every device is the most exposed signal on the board.

And the crossing point is sharper than a threshold crossing. The two signals move in opposite directions, so the voltage difference changes at roughly twice the rate either wire does, and a faster transition through the decision point means less timing uncertainty from amplitude noise.

4. RTL — The Sampling Contract, Digitally

Engineering problem

A command is a value sampled at a clock event, so the controller owes the device stability across a window around that event. A design that changes a CA line at the moment it is being sampled has not issued a command — it has issued an unknown.

Model that obligation digitally: not as a picosecond setup/hold check, but as the architectural contract that produces one.

Classification

SYNTHESIZABLE RTL — a digital stand-in for a timing contract, not a timing check.

What it represents: that CA must be held stable across a modelled acceptance window, that a command is only meaningful when it is, and that a violation is detectable and reportable.

What it explicitly does not represent, and this distinction is the whole point: setup and hold are analog quantities measured in picoseconds against a real clock edge, and no RTL can check them. Real setup/hold verification is static timing analysis and PHY-level characterisation — Modules 19 to 21. The WINDOW parameter here is a cycle count in an educational model, chosen so the shape of the obligation is simulable. It is not a timing parameter and must never be read as one.

Interface contract

ca_in and cs_n present a command. sample_evt marks the modelled sampling event. ca_captured and capture_valid report what was accepted. stability_violation reports CA changing inside the window.

State

A shadow copy of CA from the previous cycles, used to detect change across the window, plus a small counter positioning the window.

Combinational behaviour

Change detection and window membership.

Sequential behaviour

The shadow register advances every cycle; capture happens on the sampling event.

How to simulate

vlog ca_sample_contract.sv tb_ca_sample_contract.sv then vsim -c tb_ca_sample_contract -do "run -all"; VCS vcs -sverilog ca_sample_contract.sv tb_ca_sample_contract.sv && ./simv; Xcelium xrun -sv ca_sample_contract.sv tb_ca_sample_contract.sv. Every RTL block in Module 6 simulates the same way.

Expected result: commands presented stably are captured; a command whose CA lines change inside the window is reported and not captured.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// CA SAMPLE CONTRACT.
// Classification: SYNTHESIZABLE RTL -- a DIGITAL STAND-IN for a timing
// contract, NOT a timing check.
//
// A command is a VALUE SAMPLED AT AN EVENT, so the controller owes the
// device stability around that event. This models the OBLIGATION.
//
// WHAT THIS IS NOT, AND THE DISTINCTION MATTERS MORE THAN THE CODE:
// setup and hold are ANALOG quantities in picoseconds, measured against a
// real clock edge, and NO RTL CAN CHECK THEM. Real verification of them is
// static timing analysis and PHY characterisation -- Modules 19 to 21.
//
// WINDOW below is a CYCLE COUNT IN AN EDUCATIONAL MODEL, chosen so the
// SHAPE of the obligation is simulable. IT IS NOT A TIMING PARAMETER.
// Nothing here corresponds to any JEDEC value and nothing here should be
// used to size anything.
//
// Also not modelled: CK/CK# as a differential pair (the crossing point is
// analog), clock jitter, duty cycle, or any electrical property.
// ─────────────────────────────────────────────────────────────────────────
module ca_sample_contract #(
  parameter int CA_W = 24,
  // Cycles of stability required around the sampling event. EDUCATIONAL.
  // 1 means "stable on the event cycle and the one before it".
  parameter int WINDOW = 1
) (
  input  logic            clk,
  input  logic            rst_n,

  input  logic [CA_W-1:0] ca_in,
  // Active low, as chip select conventionally is. Chapter 6.3 owns this
  // signal properly; here it only qualifies whether a command is present.
  input  logic            cs_n,
  // The modelled sampling event. In a real interface this is the CK
  // crossing; here it is an explicit input so the model never pretends to
  // derive an analog instant.
  input  logic            sample_evt,

  output logic [CA_W-1:0] ca_captured,
  output logic            capture_valid,
  // CA changed inside the stability window of a sampling event.
  output logic            stability_violation
);

  // ── COMPILE-TIME legality.
  if (CA_W < 1) begin : g_ca_w
    initial $fatal(1, "ca_sample_contract: CA_W must be >= 1");
  end
  if (WINDOW < 1) begin : g_win
    initial $fatal(1, "ca_sample_contract: WINDOW must be >= 1");
  end

  // ── Shadow history of CA. WINDOW+1 entries so the event cycle and the
  //    WINDOW cycles before it can all be compared.
  logic [CA_W-1:0] ca_hist [WINDOW+1];

  // Did CA change anywhere inside the window ending at this cycle?
  logic ca_changed;
  always_comb begin
    ca_changed = 1'b0;
    for (int i = 0; i < WINDOW; i++) begin
      if (ca_hist[i] != ca_hist[i+1]) ca_changed = 1'b1;
    end
    // Also compare the live input against the most recent shadow entry, so
    // a change on the event cycle itself is caught rather than being seen
    // only one cycle late.
    if (ca_in != ca_hist[0]) ca_changed = 1'b1;
  end

  // A command is present only when chip select qualifies it. An event with
  // cs_n high is a deselect and carries no command, so its CA lines are
  // free to be anything -- checking their stability would report a
  // violation on every idle cycle.
  logic cmd_present;
  assign cmd_present = sample_evt && !cs_n;

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      for (int i = 0; i <= WINDOW; i++) ca_hist[i] <= '0;
      ca_captured         <= '0;
      capture_valid       <= 1'b0;
      stability_violation <= 1'b0;
    end else begin
      // Shift the history. Unconditional: the window is a property of the
      // interface, not of whether a command happened to be present.
      for (int i = WINDOW; i > 0; i--) ca_hist[i] <= ca_hist[i-1];
      ca_hist[0] <= ca_in;

      capture_valid       <= 1'b0;
      stability_violation <= 1'b0;

      if (cmd_present) begin
        if (ca_changed) begin
          // REPORT, NEVER REPAIR. Capturing a value that was moving would
          // record a command nobody issued -- and on real hardware that is
          // exactly what happens, silently. The model's value is that it
          // makes the silent case visible.
          stability_violation <= 1'b1;
        end else begin
          ca_captured   <= ca_in;
          capture_valid <= 1'b1;
        end
      end
    end
  end

endmodule

Cycle-by-cycle example

CA_W = 8, WINDOW = 1:

Cycleca_incs_nsample_evtResult
00010idle
1A501CA stable since cycle 0? no — it changed from 00
2A510idle, CA still A5
3A501stable → captured A5
43C01changed on the event cycle → violation, nothing captured

Cycle 1 is the instructive one. The command value is perfectly reasonable and the model refuses it, because CA moved into place at the sampling event rather than before it. That is the actual obligation — the controller must present a command early enough that it has settled by the time the device looks — and it is why a real interface specifies a setup time at all.

Waveform expectation

§5. Watch that capture_valid and stability_violation are mutually exclusive, and that idle cycles with cs_n high produce neither.

Synthesis implication

(WINDOW+1) × CA_W flip-flops plus a comparator tree — small, and it grows linearly with the window. A real controller does not contain this block: the obligation it models is met by the PHY's output timing and verified by static timing analysis, not by comparing shadow registers at runtime. It is a teaching model of a contract that real hardware satisfies by construction.

Corner cases

WINDOW == 1 is the minimum meaningful window. A sampling event with cs_n high is a deselect and is never checked — without that guard the model would report a violation on essentially every idle cycle, which is the most common way this kind of checker becomes unusable. Reset clears the history, so the first sampling event after reset compares against zeros and will report a violation unless CA was already zero — that is correct and worth keeping, because a command issued immediately out of reset has genuinely not been held stable.

Debugging clues

If violations fire on every command, check whether the controller is presenting CA on the same cycle as the sampling event rather than in advance. If violations never fire, check that ca_changed includes the live-input comparison — omitting it makes a change on the event cycle itself invisible, which is precisely the case that matters. If idle cycles report violations, the cs_n qualification is missing.

Limitations

No analog timing of any kind, as the header says at length. No differential behaviour — CK/CK#'s crossing point is analog and unrepresentable here. No jitter, no duty cycle, no skew. The WINDOW is a cycle count, not a time. And the block checks stability, never correctness: a perfectly stable wrong command is captured without complaint.

5. Stability in Cycles

ca_sample_contract — two accepted commands and one stability violation

10 cycles
Ten cycles. The command and address lines are presented in advance of each sampling event and held stable, so two commands are captured. A third command changes its command and address lines on the sampling event itself, so it is reported as a stability violation and is not captured. Idle cycles with chip select high are not checked at all.held in advance — acceptedheld in advance — acceptedchanged at the eventchanged at the eventstable since cycle 1stable since cycle 1CA moved on the eventCA moved on the eventdeselect — not checkeddeselect — not checkedCKca_in--A5A53C3C7E----B2B2cs_nsample_evtcapture_validca_captured------A5--3C--------stability_violationt0t1t2t3t4t5t6t7t8t9
Figure 2 — a command is a value sampled at an event, so what the controller owes is stability, not a level.

Cycles 1 to 4 are the correct pattern. CA is driven to A5 at cycle 1, the sampling event is at cycle 2, and the capture reports at cycle 3. The value existed before it was needed — which is the whole of what a setup requirement means, expressed without any reference to time.

Cycle 5 is the failure. 7E is presented on the same cycle as the sampling event, so it was still arriving when the device looked. The violation reports at cycle 6 and nothing is captured. On real hardware there would be no violation signal at all: the device would latch something, and that something would be an arbitrary mixture of the old and new values.

Cycles 6 to 8 are idle with cs_n high, and the CA lines change freely without complaint. Un-qualified cycles carry no obligation, which is why Chapter 6.3 matters as much as this one — chip select is what turns a broadcast bus into a command.

These are representative educational cycles. The number of cycles between presenting CA and sampling it is a property of this model, chosen for legibility. Real requirements are analog and are specified per speed grade.

6. Two Assertions Worth Writing

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// VERIFICATION-ONLY, inside ca_sample_contract.

// P1 -- capture and violation are mutually exclusive and exhaustive over
// qualified events. A checker that could report both, or neither, would
// leave the consumer unable to tell whether a command happened.
property p_capture_xor_violation;
  @(posedge clk) disable iff (!rst_n)
    (sample_evt && !cs_n) |=> (capture_valid ^ stability_violation);
endproperty
assert property (p_capture_xor_violation);

// P2 -- an unqualified event produces NEITHER. Without this, a checker
// that reported on every cycle would satisfy P1 and be useless.
property p_no_report_without_qualification;
  @(posedge clk) disable iff (!rst_n)
    !(sample_evt && !cs_n) |=> (!capture_valid && !stability_violation);
endproperty
assert property (p_no_report_without_qualification);

// P3 -- what was captured is what was presented. Guards the actual data
// path rather than the decision: a checker that accepts the right commands
// and records the wrong values is worse than one that rejects everything,
// because it is believed.
property p_captured_matches_input;
  @(posedge clk) disable iff (!rst_n)
    capture_valid |-> (ca_captured == $past(ca_in));
endproperty
assert property (p_captured_matches_input);

P1 and P2 are a pair, and the pairing is the lesson this curriculum keeps returning to: P1 alone is satisfied by a design that reports on every cycle, and P2 alone by one that reports on none. Together they make the reporting a partition of the qualified events.

What none of them prove, and it is nearly the whole subject of a real clock. Nothing about setup or hold margin, which are analog. Nothing about jitter, duty cycle, or skew between CK and the CA lines it times. Nothing about the differential pair's crossing point. No digital assertion in any simulation can establish that a clock is good enough — that is static timing analysis, PHY characterisation and laboratory measurement, and treating a green simulation as evidence about clock quality is the most expensive category error available in this domain.

7. CK Times Commands. It Does Not Time Data.

This is the distinction the rest of the interface depends on, and it is worth stating as bluntly as possible.

"DDR transfers on both edges of the clock" is an inadequate mental model, and it produces two concrete errors.

The first error is architectural. It suggests that data timing is derived from CK, which would mean a receiver recovering the exact sampling instant for high-rate data from a clock that travelled a different path across the board and package. Chapter 4.2 §3 established why that stops working: the skew between the clock's path and the data's path does not shrink as the transfer interval does, so eventually it consumes the entire budget. The response was to give data its own timing reference that travels with itDQS, which Chapter 6.10 owns.

The second error is practical, and it appears in RTL written by people who understand the first. "Both edges" invites code like always_ff @(posedge clk or negedge clk), which is not synthesizable as DDR I/O and does not describe any real hardware. Real double-rate I/O is built from dedicated output and input primitives in the PHY and the I/O ring — vendor-specific cells, not portable RTL — and Chapter 4.2 §5 explained why a behavioural dual-edge model teaches nothing about what makes double-edge signalling hard.

The accurate statement is narrower and more useful:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   CK / CK#    times the COMMAND and ADDRESS path
               one command per clock cycle
               single timing reference, distributed to every device

   DQS         times the DATA path
               two transfers per clock cycle
               source-synchronous, travels with the data, has a direction

Two timing domains, two different disciplines. Chapter 4.2 §8 noted that a DDR device runs at three internal rates — data fastest, commands slower, the array slower still. This is where the top two of those become visible as physically distinct signals.

8. Who Drives CK

The controller side drives CK/CK#, always. It is the one major signal in this module with no direction ambiguity: there is no operation in which a DRAM device drives the clock.

That permanence is itself informative. Chapter 6.9 is about a bus whose ownership changes several times per transaction, and the contrast is the point — most DDR signals are interesting because their ownership is temporal, and CK is interesting because it is not. A timing reference that changed hands would not be a reference.

The PHY, not the controller's digital logic, generates the actual clock waveform. The controller decides what should happen and when in units of cycles; the PHY produces a differential pair with controlled amplitude, duty cycle and jitter and distributes it to every device. That division — controller decides, PHY realises — recurs in every chapter of this module, and it sharpens progressively: by 6.10 it is the difference between a legal design and an impossible one.

9. Common Misconceptions

"DDR just means using both edges of the clock." Wrong model: one clock times everything, and the trick is to use both of its edges. Why it is tempting: it is the literal expansion of the name, and it is true that data moves twice per clock cycle. Consequence: the engineer expects data to be timed by CK, cannot explain why DQS exists, and — the practical damage — writes always_ff @(posedge clk or negedge clk) expecting DDR I/O. That construct is not synthesizable as double-rate I/O and describes no real hardware; real double-rate I/O is built from dedicated PHY and I/O-cell primitives. Correct model: CK times the command path at one command per cycle. Data is timed by DQS, a separate, source-synchronous, directional reference. "Double data rate" describes observed transfer behaviour on the data path, not an instruction about how to write RTL. Prevention: ask which signal the receiver uses to decide when to sample the data. If the answer is CK, the model is wrong.

"CK# is a backup or a second clock." Wrong model: the complement is redundancy, or a second phase. Why it is tempting: two wires carrying a clock look like two clocks. Consequence: treating the pair as separable — terminating or routing them independently, or reasoning about one wire's threshold crossing — which discards precisely the property the pair exists to provide. Correct model: CK and CK# are one signal carried differentially. The sampling instant is their crossing point, so neither wire is meaningful alone. The pair carries its own reference, which is what makes it immune to threshold and common-mode disturbances. Prevention: ask what defines the sampling instant. If the answer names a voltage threshold on one wire, the differential nature has been discarded.

"The controller toggles the clock pins with ordinary RTL." Wrong model: clock generation is digital logic in the controller. Why it is tempting: in ordinary synchronous design, clocks do come from logic, and the controller is where all the other decisions are made. Consequence: a design that cannot meet any real interface requirement, and a fundamental confusion about where the controller ends. Amplitude, duty cycle, jitter and distribution are not properties any RTL can express. Correct model: the controller's digital logic works in units of cycles; the PHY produces the physical differential waveform with controlled electrical properties. Modules 19 to 21 own the PHY. Prevention: ask whether the property in question has units of cycles or units of volts and picoseconds. The boundary between controller and PHY sits exactly there.

"If the waveform on a scope looks like a clean square wave, the clock is fine." Wrong model: visual digital appearance proves electrical adequacy. Why it is tempting: a clean-looking trace is genuinely evidence of something, and a badly broken clock does look bad. Consequence: accepting a clock whose jitter or duty-cycle distortion is out of budget, which produces intermittent, temperature-dependent, workload-dependent failures with no functional signature — the hardest class in Chapter 4.4 §11. Correct model: what matters is the distribution of crossing instants over many cycles relative to the budget, not the shape of one cycle. That requires jitter measurement and margin analysis, not inspection. Prevention: ask what was measured, not what was seen. "It looks clean" is not a measurement.

10. Debugging — Commands Are Occasionally Misinterpreted

Symptom. A memory interface mostly works. Occasionally a command appears to be interpreted as a different command — an access lands in the wrong place, or a device enters an unexpected state — with no data corruption pattern and no error reported.

A command-path fault has a distinctive property: its blast radius is unbounded. Chapter 4.5 §3 made this point — a corrupted data bit damages one datum, while a corrupted command bit can activate the wrong row or precharge a bank in use, damaging state belonging to an access that was never issued. So the symptom rarely points at the access that caused it.

Mechanism 1 — CA is not stable across the sampling instant. Inspect: the controller's CA launch timing relative to the clock, and whether the PHY's output timing was ever trained or characterised. Expected evidence: errors that increase with frequency and change with temperature. Discriminator: does it scale with rate? This is §4's contract being violated in its analog form, and it is the most likely cause. A stability problem is a margin problem and behaves like one.

Mechanism 2 — clock jitter or duty-cycle distortion. Inspect: measured jitter on CK/CK# against the interface's budget, and duty cycle. Expected evidence: errors correlated with system activity elsewhere — a noisy supply rail, a nearby high-current event. Discriminator: does it correlate with something outside the memory interface? Distinguished from mechanism 1 by cause rather than symptom: both are margin failures, but this one's trigger is external, so it appears under specific system conditions rather than scaling smoothly with rate.

Mechanism 3 — the command was never qualified. Inspect: chip select timing relative to the CA lines. Expected evidence: commands being acted on by a device that should have ignored them, or ignored by one that should have acted. Discriminator: is the wrong device responding, or the right device doing the wrong thing? This is a Chapter 6.3 problem, not a clock problem, and the distinction is available immediately from which device misbehaved.

Mechanism 4 — not the interface: the controller issued the wrong command. Inspect: the controller's own command stream, upstream of the PHY. Expected evidence: the intended command is already wrong before it reaches any wire. Discriminator: compare intent against the interface. This is worth ruling out early precisely because it is free — reading the controller's own trace costs nothing, and an entire investigation into signal margin is wasted if the command was wrong on departure.

Mechanism 5 — a parity or integrity mechanism is reporting and nobody is listening. Inspect: whether command/address parity is enabled and whether its error output is monitored. Expected evidence: an unmonitored error indication that has been asserting all along. Discriminator: read the alert path. Chapter 6.12 covers this, and it is the mechanism where the system was telling you the answer and nothing was connected to hear it.

Discrimination, cheapest first. Compare the controller's intended command stream against what the interface carried — that separates mechanism 4 from everything else and costs nothing. Then check whether any alert or parity indication is asserting. Then determine whether the wrong device responded or the right device misbehaved. Only then engage with margin, which is where the expensive equipment is.

The reasoning lesson. The command path is the one place where a single-bit error has unbounded consequences, so it deserves a disproportionate share of the diagnostic effort — but "disproportionate effort" means checking it first, not measuring it first. The three cheapest checks here are all reads of information the system already has: the controller's intent, the alert path, and which device responded. Engineers who reach for an oscilloscope before reading their own controller's trace are not being thorough; they are skipping the free evidence.

11. Interview Reasoning

"What does CK actually establish in a DDR interface?" A repeating instant at which the command and address inputs mean something. A command is not a level held on a wire — it is a value sampled at an event, and CK defines the event. That is what makes commands countable, which is what lets every timing obligation in the interface be expressed as a number of cycles rather than as a duration the controller must generate. It also means what the controller owes on the CA lines is stability around the sampling instant, not a particular level, which is where setup and hold requirements come from.

"Why is the clock differential when the address lines are not?" Because a differential pair carries its own reference. A single-ended receiver compares the wire against a fixed threshold, so anything that shifts the signal relative to that threshold — supply droop, ground offset between packages, temperature — moves the apparent edge timing. A differential receiver compares the two halves against each other, so disturbances common to both cancel, and the crossing point is also sharper because the difference changes at roughly twice the rate either wire does. The reason it is not applied to everything is that a partner costs a pin, so the interface spends differential pairs on the signals that define timing, where reference uncertainty is most damaging, and accepts single-ended signalling for signals that merely carry values sampled by those references.

"Is 'DDR transfers on both clock edges' a good description?" It is accurate about observed behaviour and inadequate as a model, in two ways. Architecturally it implies data is timed by CK, which would mean recovering a high-rate sampling instant from a clock that travelled a different path — and that is exactly what stopped working as rates rose, which is why DQS exists. Practically it invites RTL like a process sensitive to both clock edges, which is not synthesizable as double-rate I/O and describes no real hardware; real double-rate I/O comes from dedicated PHY and I/O-cell primitives. The better statement is that CK times the command path at one command per cycle, and DQS times the data path, source-synchronously and directionally.

"Where is the boundary between the memory controller and the PHY, for a signal like CK?" The controller works in units of cycles and decides what should happen and when; the PHY produces the physical waveform with controlled amplitude, duty cycle and jitter and distributes it. A useful test is the units of the property under discussion: if it is expressed in cycles it is the controller's, and if it is expressed in volts or picoseconds it is the PHY's. That boundary is why no RTL can check setup and hold — those are analog quantities verified by static timing analysis and characterisation, not by comparing registers in simulation.

"An interface occasionally misinterprets a command. Where do you look?" Not at the oscilloscope first, even though the cause is usually margin. The three cheapest checks are all reads of information the system already has. Compare the controller's own intended command stream with what appeared on the interface, because if the command was already wrong on departure then no amount of signal analysis helps. Check whether command/address parity is enabled and whether anything is monitoring its error output, because that mechanism may have been reporting the answer all along. And determine whether the wrong device responded or the right device did the wrong thing, which separates a chip-select qualification problem from a command-integrity problem. Only after those does margin work make sense — and command-path faults deserve priority generally, because unlike a data-path error a single corrupted command bit can damage state belonging to an access that was never issued.

12. Engineering Exercise

Reason about the following. Cycle counts are educational and representative; no real timing values are implied.

1. A controller presents a command on the CA lines and asserts the sampling event in the same cycle. What has it failed to provide, and what would the device actually capture? It failed to provide stability before the event — the lines were still arriving when the device looked. A real device would capture something: an arbitrary mixture of the previous and new values, not necessarily either one. No error would be signalled, which is what makes this class of fault dangerous rather than merely wrong.

2. Why does §4's model refuse to check CA stability when cs_n is high? Because an unqualified event carries no command, so the CA lines are free to change. Checking them would report a violation on nearly every idle cycle, and a checker that fires constantly is indistinguishable from one that is broken — it stops being read. Qualification is what makes the obligation apply.

3. A colleague proposes making the CA lines differential to improve command margin. Evaluate. It would genuinely improve their noise immunity for the reasons in §3. It would also roughly double the pin count of the command path, which Chapter 4.5 §3 showed is the resource DDR4 went to considerable trouble to avoid spending — repurposing existing pins rather than adding any. The trade is real and the answer is that timing references earn a partner and value-carrying signals do not, because a disturbance on a reference moves every sample while a disturbance on a data line corrupts one bit.

4. A design uses one differential clock pair distributed to eight devices. Which chapter of Module 5 already told you this is the hardest signal on the board, and why? Chapter 5.6 §2, and 4.4 §2 before it: command and clock signals must reach every device, so they carry the most electrical load and fail first as rates rise. That is why DDR3 changed the routing topology, and why that change forced write leveling into existence.

5. Someone writes always_ff @(posedge ck or negedge ck) to implement DDR data output. Name two separate things wrong with it. First, it is not synthesizable as double-rate I/O — no synthesis tool infers a DDR output register from that, and real double-rate output comes from a dedicated I/O primitive. Second, and more fundamental, it is timing the data with CK, when data is timed by DQS. Even if the construct worked, it would express the wrong architecture. The second error survives fixing the first, which is why the mental model matters more than the syntax.

6. What property do CK and RESET# share that CKE and ODT do not? They must work before or outside the command stream. A clock is required for any command to be sampled at all, and reset must be assertable when the device is in an unknown state. A signal that establishes the conditions under which encoding is possible cannot itself be encoded — which is exactly why CKE and ODT could be moved into CA encoding in DDR5 and these two could not.

13. Summary

CK/CK# is the timing reference for the command and address path, and only for that path. It establishes a repeating instant at which the CA inputs mean something, which converts commands into countable events — the foundation of every cycle-denominated timing obligation in the rest of the curriculum.

What the controller owes the CA lines is stability around that instant, not a level. §4's model expresses that obligation digitally, and is explicit that setup and hold are analog quantities no RTL can check — its WINDOW is a cycle count in an educational model, never a timing parameter.

The clock is differential because a differential pair carries its own reference. The sampling instant is the crossing point of CK and CK#, so a disturbance affecting both wires equally moves neither. That immunity is why timing references get a partner while value-carrying signals do not: a disturbance on a reference moves every sample; a disturbance on a data line corrupts one bit — and a partner costs a pin.

CK times commands. DQS times data. "DDR transfers on both edges of the clock" is accurate about behaviour and inadequate as a model: it implies data is timed by CK, which is exactly the arrangement that stopped working as rates rose, and it invites dual-edge RTL that is neither synthesizable as DDR I/O nor architecturally correct.

CK has no ownership ambiguity — the controller side always drives it — which makes it the exception in a module largely about signals whose ownership changes. And the controller decides in cycles while the PHY realises in volts and picoseconds; that boundary sharpens in every chapter that follows.

And the module's thesis begins here. CK survives as a dedicated signal because it must work before the command path is usable, and a signal that establishes the conditions for encoding cannot itself be encoded. Watch which signals share that property as this module proceeds — and which do not.

14. What Comes Next

Chapter 6.2 takes a signal that does not share it.

CKE determines whether a device is listening at all — whether it samples the command inputs or ignores them. That is a qualification function layered on top of the clock, and in DDR4 it has a dedicated pin.

In DDR5 it does not. The function survives; the pin does not, because power-state control turned out to be expressible in the command encoding that CS and the CA bus already carry. 6.2 is the module's first concrete instance of the thesis — and it makes the question sharp: if a signal's function can be encoded, what was the pin ever buying?

Return to SDR SDRAM for what making DRAM synchronous changed, DDR1 for why data needed its own timing reference, or The Memory-Subsystem View for the structure these signals address. The full path is on the DDR tutorials index.

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.