-
Notifications
You must be signed in to change notification settings - Fork 0
Worst Case Methodology
BIOS applies exactly one value for each timing parameter, system-wide, across every populated slot on a channel — there's no per-DIMM tRCD setting in consumer BIOS. So for a mixed kit to run stably, every installed module's own minimum requirement for a given timing has to be satisfied simultaneously by whatever single value BIOS actually applies. The safe value for any one parameter is therefore:
system_value = max(module.value for module in installed_modules)
...taken independently, per parameter, across every module. This is correct and sufficient for almost everything on this page: CL, tRCD, tRP, tRAS, tRFC1/2/4, tFAW, tRRD_S/L, tCCD_L, tWR, tWTR_S/L. Whichever module declares the tightest (highest-in-ns) requirement for a given parameter sets the floor for everyone.
As covered in Primary Timings CL tRCD tRP tRAS tRC, tRC is not an
independent physical quantity — it's the full ACT-to-ACT cycle, and by
definition:
tRC >= tRAS + tRP
Taking max(tRC) across modules independently of max(tRAS) and
max(tRP) can produce a result that's internally inconsistent with the
protocol: if the module with the loosest tRC isn't the same module with
the loosest tRAS+tRP combination, the naive per-parameter maximum
under-reports what's actually required.
This happened for real, not hypothetically, on this project's own
reference kit: one module's SPD declares tRC = 44.5ns, which is itself
already less than its own tRAS + tRP = 32.375 + 14.0 = 46.375ns — real
vendor data, not corrupted or misread. When another module in the kit
separately holds the record for worst-case tRC at 45.75ns, a naive
max(tRC) across all modules reports 45.75ns as "the" governing tRC —
which is less than 46.375ns, the actual floor implied by that first
module's own tRAS+tRP. The table would have printed a real, provably
insufficient tRC value.
worst["tRC"] = max(worst["tRC"], worst["tRAS"] + worst["tRP"])
Using the system-wide worst-case tRAS and worst-case tRP (already
independently computed as maxima) as the floor, rather than trying to
track which specific module's own tRAS+tRP combination is largest, is a
safe over-approximation: since system-wide worst-tRAS is, by
construction, >= any individual module's own tRAS (same for tRP), their
sum is guaranteed >= any single module's own tRAS+tRP requirement too.
It may occasionally be very slightly more conservative than the
theoretical minimum, but never less than what's actually required —
exactly the direction a "safe" calculator should round its uncertainty.
The source annotation for a floor-corrected tRC (e.g. 1-0053 (tRAS+tRP floor)) exists specifically so the number doesn't look like it silently
appeared from nowhere — every other value's source line just names the
one module that set it; this is the one line that explains why the
value is what it is.
spd-matchtable's --selftest includes a synthetic two-module scenario
reproducing this exact case byte-for-byte (module A: tRAS=32.0,
tRP=13.75, tRC=45.75; module B: tRAS=32.375, tRP=14.0, tRC=44.5 — the
real reference-kit numbers), asserting the corrected tRC comes out to
46.375ns with an annotated source, specifically so a future change to the
worst-case logic can't silently regress this without a test failing.