-
Notifications
You must be signed in to change notification settings - Fork 0
Primary Timings CL tRCD tRP tRAS tRC
These five numbers are what people mean when they say "RAM timings" — e.g. "CL16-18-18-36." They describe one thing: how long it takes to open a row of DRAM cells, read or write a column within it, and close it again so the bank is ready for the next row. Every other timing in DDR4 exists to protect some physical constraint around this cycle.
A DDR4 chip is organized as a grid: rows and columns of capacitors, each holding one bit as a tiny electric charge. You can't read or write a column directly — you first have to activate its entire row, which copies that row's charge into a row of sense amplifiers (this is literally a read, and it's destructive: pulling charge out of a capacitor to sense it drains it slightly). Only once the row is "open" in the sense amps can you address individual columns within it for actual reads/writes. When you're done with that row, you precharge the bank, which writes the sense-amp values back into the capacitors (restoring the charge you just drained) and resets the bit lines so a different row can be activated next.
So every access to a bank looks like:
ACTIVATE (open a row) --[tRCD]--> READ/WRITE (column access) --...--> PRECHARGE (close the row) --[tRP]--> next ACTIVATE
Time from the ACTIVATE command to when a READ or WRITE command is
allowed to the same bank. This is the sense amplifiers' settling time —
issue the column command too early and you'd be reading/writing before
the row's data has fully resolved onto the bit lines. tRCD is specified
in nanoseconds in SPD and converted to cycles at whatever clock you're
running.
Time from the READ command to when data actually appears on the DQ bus.
Internally this is largely the same physical settling process as tRCD
(hence CL and tRCD often being numerically close or equal in a given
speed bin), but it's specified separately because it governs the read
path specifically, while tRCD governs any column access after an
activate. In the SPD byte layout this is stored as tAA (Access time
from Address) — CL is tAA expressed in clock cycles at a target
frequency, not a separate physical measurement.
The minimum time a row must stay open between ACTIVATE and PRECHARGE. This isn't an arbitrary safety margin — it's how long the sense amps need to finish restoring the row's charge back into the capacitors before you're allowed to close it. Precharge too early and you risk not fully rewriting some cells, which is a real data-corruption mechanism, not just a performance concern. This is why running tRAS tighter than the module supports is one of the more dangerous timings to get wrong versus one that "merely" costs bandwidth.
Time from PRECHARGE to the next ACTIVATE on the same bank — how long the bit lines need to fully reset and equalize before a different row can be sensed cleanly. Same physical family as tRCD, opposite direction.
The full ACT-to-ACT time for the same bank: open, do your work for at least tRAS, close, wait tRP, and only then can you activate again. Physically, this makes tRC a derived quantity, not an independent one:
tRC >= tRAS + tRP
You cannot activate again sooner than tRAS after the last activate (the row has to legally stay open that long) plus tRP after the precharge that follows it. This isn't a design choice — it's what "ACT-then-PRE- then-ACT-again" means sequentially.
Why this matters for spd-matchtable specifically: real vendor SPD
data sometimes declares a tRC value smaller than that same module's own
tRAS + tRP. It's not corrupt data — different characterization/binning
processes can produce a tRC figure that doesn't exactly equal the naive
sum. But when this tool computes the worst-case tRC across several
mixed modules independently per parameter, that naive approach can
produce a tRC below what the also-independently-computed worst-case
tRAS+tRP actually requires. See Worst Case Methodology for the
specific real bug this caused and the fix (tRC = max(tRC, tRAS + tRP),
enforced explicitly rather than trusted to fall out of a per-parameter
maximum).
A CL16 kit at 3200 MT/s and a CL16 kit at 2400 MT/s have very different real latency in nanoseconds — CL is a cycle count, and a cycle is shorter at a higher clock. To compare actual latency, convert to time:
latency_ns = CL_cycles * tCK_ns = CL_cycles * (2000 / MT_per_s)
CL16 @ 3200 MT/s = 16 × 0.625ns = 10.0ns. CL17 @ 2400 MT/s = 17 × 0.833ns = 14.2ns.
This is also why spd-matchtable's recommendation to step from 2400 to
2933 (rather than straight to 3200) on a mixed kit lands at very close to
the same real-world CAS latency as the stock 2400 configuration — you
gain bandwidth for roughly free, rather than trading latency for
bandwidth.