DFI Semantic-Shift Catalog (spec-verified)¶
Status: verified against the actual specification PDFs — DFI v2.1.1 (Denali, Jun 2010), v3.1 (Cadence, Mar 2014), v4.0 (Apr 2018), v5.2 (Oct 2024), v6.0 (May 2026). The first draft of this document was written from release-note hearsay before the PDFs were readable; that draft got several load-bearing facts wrong. This revision is the corrected record — every claim below traces to a chapter-3 signal table or the revision history of one of the books.
Scope: DFI v2.1 through v6.0, DDR1-5 / LPDDR1-6 / HBM4 as each version defines. The signal-level ground truth lives in
dfi_signal_catalog.py; this doc records the behavioral shifts and the corrections that came out of the verification pass.
Corrections from the spec-verification pass (2026-08)¶
The original draft (and the code built from it) fabricated wires and misattributed versions. For the record — and so nobody reintroduces them:
| Fabricated / wrong | Spec reality |
|---|---|
dfi_freq_change_req/ack/protocol |
No such wires in any version. Frequency change is dfi_init_start/dfi_init_complete (v2.1 §4.8; unchanged through v6.0). |
dfi_crc_alert (active high) |
dfi_alert_n (v3.0+, ACTIVE LOW), renamed dfi_alert in v6.0 (polarity follows the memory signal). |
dfi_parity_check |
v2.1: dfi_parity_error; v3.0+: folded into dfi_alert_n. |
dfi_training_active + dfi_training_phase |
Never existed. Training is per-phase wire groups: dfi_rdlvl_*, dfi_wrlvl_*, dfi_calvl_*, dfi_wdqlvl_*, dfi_db_train_*. |
dfi_disconnect_req/ack |
One wire: dfi_disconnect_error (v4.0). A disconnect is the act of breaking an in-flight handshake, not a handshake of its own. |
| "Update handshake rewritten in v3.0" | The full bidirectional handshake (ctrlupd_req/ack + phyupd_req/ack/type) is v2.1 baseline. |
| "Training introduced v3.0" | v2.1 has a full training interface; v3.0 redesigned it (dropped the delay-register wires); v5.x deleted it. |
| "CA parity introduced v3.0 for DDR4" | dfi_parity_in/dfi_parity_error are v2.1.1 (DDR3 registered DIMMs). v3.0 extended parity to DDR4 and renamed the error wire dfi_alert_n. |
| "v5.2 = v4.0 + chapter-title rename" | v5.x REMOVED the training interface and renamed the wires dfi_phymstr_* → dfi_phymngd_*. Both change BFM sampling; V5_2 has its own behavior class. |
The architecture (unchanged; survived verification)¶
Per-version behavior Strategy classes + a registry:
VERSION_BEHAVIOR = {
DFIVersion.V2_1: DFIv2_1Behavior,
DFIVersion.V3_1: DFIv3_1Behavior, # v3.0+v3.1 collapsed
DFIVersion.V4_0: DFIv4_0Behavior,
DFIVersion.V5_2: DFIv5_2Behavior, # v5.0/5.1/5.2 collapsed
DFIVersion.V6_0: DFIv6_0Behavior,
}
Behavior classes are stateless; methods take (bus, state) and return
event objects. Signal presence is the envelope's job
(dfi_signals.py + dfi_signal_catalog.py, min_version/
max_version per signal); behavior classes own the meaning of wires
that exist under the same concept across versions.
Two additions the verification forced:
RemovedInThisVersionError(subclass ofNotSupportedInThisVersionError): the spec doesn't only add interfaces — v5.x deleted training, v6.0 deleted disconnect.- A
low_power()behavior area: the LP handshake exists from v2.1 and shifts twice (v3.1 ctrl/data request split; v5.1 ctrl/data ack + wakeup split).
Shift areas (spec-verified)¶
1. CRC / alert¶
- v2.1: no CRC concept → raises.
- v3.0: DDR4 write CRC; errors reported on
dfi_alert_n(active LOW, mirrors DDR4 ALERT_n). CRC and CA-parity errors share the wire and are indistinguishable at the DFI. - v4.0:
phycrc_modeparameter (MC- vs PHY-generated CRC); same wire. - v5.2: adds Link DQ CRC for DDR5 MRDIMM Mux Mode
(
dfi_wrdata_crc/dfi_rddata_crc,phylinkdqcrc_mode). - v6.0: wire renamed
dfi_alert, polarity per memory protocol;dfi_data_alertadded for protocols with separate write-error paths (HBM4).
2. Update interface¶
- v2.1: full bidirectional handshake already present:
dfi_ctrlupd_req/ack(PHY may ignore) anddfi_phyupd_req/ack(MC MUST ack withintphyupd_resp), withdfi_phyupd_typeselecting one of 4 duration classes. Simultaneous requests: either side may ack the other; the un-acked request may de-assert. - v3.0: idle-bus definition tightened; enhancements only.
- v4.0: a ctrlupd handshake is REQUIRED immediately before
self-refresh exit;
tctrlupd_intervalbounds request cadence. - v6.0: unchanged wires.
3. PHY Master / PHY Managed¶
- v4.0: introduced as PHY Master:
dfi_phymstr_req/ackplus qualifierstype(duration classtphymstr_type0-3),state_sel(IDLE vs self-refresh),cs_state(per-rank DRAM state), withsyscs_stateinactive-CS support. - v5.2: renamed PHY Managed — the wires renamed too
(
dfi_phymngd_*). Same protocol; a v5.2 BFM samples different signal names (handled via the_takeover_prefixclass attribute). - v6.0: unchanged from v5.2; now also the designated home of all training (PHY Independent Mode).
4. Disconnect protocol¶
- v4.0-v5.x: a device breaks an in-flight ctrlupd / phyupd /
training / phymstr handshake (LP and freq-change are explicitly NOT
disconnectable). One dedicated wire:
dfi_disconnect_error(0 = QOS, PHY stays fully operational; 1 = error). Timing bounded by per-interfacet*_disconnect/t*_disconnect_errorpairs. - v6.0: REMOVED → raises
RemovedInThisVersionError.
5. Frequency change¶
Same protocol in every version — dfi_init_start asserted during
normal operation is the request; the PHY accepts by de-asserting
dfi_init_complete within tinit_start cycles, or the offer is
withdrawn ("Not Acknowledged"). What changes is the indicator payload:
- v2.1:
dfi_freq_ratio(2 bits: 1:1 / 1:2 / 1:4). - v4.0:
dfi_frequencyindicator (5 bits, system-defined encodings,phyfreq_range). - v5.1/5.2:
dfi_freq_fsp;dfi_frequencyto 6 bits; v5.2 splitsdfi_freq_ratio→dfi_cmd_freq_ratio+dfi_data_freq_ratio(adds 1:8; backward compat = cmd ratio 'b00). - v6.0: ratios gain 1:3 and 1:6; 3-bit encodings.
6. Training¶
- v2.1: read leveling + gate training (DDR3/LPDDR2) and write
leveling (DDR3): en/req/resp handshakes PLUS a delay-register
protocol (
dfi_rdlvl_delay_X/_load/_edge, MC vs PHY evaluation modes). - v3.0: redesign — delay-register wires and MC evaluation mode
dropped; en/req/resp kept; per-CS training targets
(
dfi_phy_*lvl_cs_n);dfi_lvl_pattern/dfi_lvl_periodic. - v3.1: CA training for LPDDR3 (
dfi_calvl_*); PHY-requested training (dfi_phylvl_req_cs_n/dfi_phylvl_ack_cs_n). - v4.0: optional per-operation (PHY Independent Mode); per-slice
read leveling; write DQ training (
dfi_wdqlvl_*); DB training (DDR4 LRDIMM); LPDDR4 CA VREF training;*_cs_n→*_csrenames. - v5.x: interface deleted. "The DFI specification does not
dictate any training methodology." →
RemovedInThisVersionError. - v6.0: stays deleted.
7. Error interface¶
- v3.0:
dfi_error+dfi_error_info(implementation-defined codes). - v6.0: renamed
dfi_phy_error/dfi_phy_error_info(per data slice, not phased for frequency ratio).
8. CA parity¶
- v2.1.1:
dfi_parity_in(MC-computed) +dfi_parity_error(PHY-reported) for DDR3 registered DIMMs →CAParityEvent. - v3.0:
dfi_parity_error→dfi_alert_n; parity errors merge with CRC reporting (surface asCRCEvent;ca_parity_check()returns None to avoid double-reporting). - v6.0:
dfi_parity_in→dfi_caparity; errors ondfi_alert.
9. Low power control¶
- v2.1:
dfi_lp_req+dfi_lp_wakeup(MC offer) /dfi_lp_ack. - v3.1: request split:
dfi_lp_ctrl_req+dfi_lp_data_req(shared ack + wakeup). - v5.1: ack and wakeup split too:
dfi_lp_ctrl_ack/dfi_lp_data_ack,dfi_lp_ctrl_wakeup/dfi_lp_data_wakeup(3-bit encodings,dfilp_*_wakeup_mapparameters in v6.0). - Explicitly NOT disconnectable (v4.0+).
10. v6.0 new areas (not yet behavior-mapped)¶
- Sleep protocol:
dfi_sleep+tsleep_*family (explicitly not applicable to 5.x parts). Candidate for a new behavior area when a v6 testbench needs it. - Command bus enable (
dfi_cmd_en), parity/ECC/severity data-path buses (dfi_wrparity/dfi_rdparity(_valid)/dfi_wrdata_ecc/dfi_rddata_ecc/dfi_rddata_sev), MRDIMM Mux-Mode pseudo-channel interleave. - Interop hazard: the LPDDR5 2:1 WCK:CK
dfi_wck_toggleencoding CHANGED between 5.x and 6.x (v6.0 Table 34 footnote).
Known spec typos (recorded, not "fixed" silently)¶
- v5.2 Table prints
dfi_rddata_crcas From=MC; body text says the PHY drives it. The catalog encodes PHY (read path). - v4.0 carries editorial leftovers ("adeela: verify" in a default
cell); v2.1 figures label
dfi_bankasdfi_bank_n. - v3.1 is inconsistent on the
dfi_phylvl_*width name (Rank vs Chip Select width).
Testing¶
- Behavior classes: one unit-test file each
(
tests/unit/behaviors/test_{base,v3_1,v4_0,v5_2,v6_0}.py) with a mock bus. Active-low wires (alert_n,phylvl_req_cs_n) idle at 1 in the mock. - Envelope:
tests/unit/test_dfi_signals.pyasserts version windows, renames, and removals against the catalog. - Wire-level proofs:
tests/sim/dfi/over thedfi_shim.svpassthrough (spec-real wires only).