Blog
Technology Sharing
Tower I3C Host Adapter Usage Example (6)hits:6


Easyi3C is a leading supplier of embedded system tools that simplify the development and debugging of various communication protocols. The company offers a range of products designed to help engineers and developers use I3C/I2C , USB and MIPI, JEDEC, MCTP and other protocols more efficiently.



Testing a DDR5 SPD HUB based on a Tower I3C Host Adapter (1)


1. Background Introduction


Starting with DDR5, according to the JEDEC specification, an additional chip, the SPD HUB, is added to the memory.

In DDR4 and earlier memory, devices that require external access (SPD, Temperature Sensor) are usually directly connected to the board (directly connected to the SOC controller). With DDR5, more devices are integrated into the memory, and direct connection would make the system too complex. Therefore, DDR5 memory introduced the SPD HUB.

As shown in the diagram above, the SPD HUB is a hub device connected to the I2C/I3C bus. It contains 1024 bytes of SPD data and connects to other devices required for DDR5 memory, such as RCD, PMIC, and TS (temperature senser).

The SPD Hub supports I2C and I3C protocols. JEDEC recommends using I3C for its superior performance, especially for RDIMMs, which involve numerous RCD accesses during memory training. I3C can significantly reduce system boot time. The I3C bus functionality of the SPD Hub delivers substantial performance improvements and design optimizations in DDR5 memory systems. Its core advantages are primarily reflected in the following aspects:

1) High-speed transmission and increased bandwidth:
The I3C bus frequency can reach up to 12.5MHz, which is 12.5 to 125 times faster than the I2C used by DDR4 (typically 400kHz)
. This upgrade significantly reduces memory initialization time; for example, server BIOS startup speed can be improved by about 30%, which is especially suitable for AI training scenarios that require frequent restarts for parameter tuning.

2) Simplified System Design and Signal Isolation:
As a hub device on the I3C bus, the SPD Hub upgrades the traditional parallel SMBus to a high-speed serial bus, effectively isolating the host from local devices (such as RCDs, PMICs, temperature sensors, etc.). This design reduces the complexity of motherboard signal integrity calibration and avoids the need for level conversion circuits (I3C uses 1.0V voltage, compatible with the CPU power rail).

3) Support for More Devices and Dynamic Management:
The number of devices that need to be managed by DDR5 memory modules has increased significantly (such as SPD, RCD, PMIC, temperature sensors, etc.). The I3C bus supports up to 40 slave devices through the Hub structure (DDR4 only supports 16). In addition, I3C supports in-band interrupts, dynamic addressing, and multi-channel operation, which can more efficiently coordinate memory status adjustment and temperature monitoring.

4) Energy Efficiency Optimization and Enhanced Stability:
The I3C bus adopts a lower voltage design (1.0V), significantly reducing power consumption and heat generation compared to I2C (2.5V). Combined with the high-precision temperature sensor built into the SPD Hub, the system can monitor the memory module temperature in real time, dynamically adjust the operating status, prevent overheating and frequency throttling, and ensure long-term stability in high-load scenarios such as AI servers.

In summary, the I3C bus functionality of SPD Hub, through high-speed transmission, simplified design, expanded device support, and energy efficiency optimization, has become a key technological support for unleashing the performance of DDR5 memory.


2. Testing a DDR5 SPD HUB based on a Tower I3C Host Adapter


As introduced above, testing the communication of the SPD HUB chip on DDR5 memory under I3C is an important new requirement. On the motherboard, the SPD HUB is accessed via the I3C protocol through the BMC or CPU as the controller. This is suitable for the final mass production stage of the chip delivered to the customer. However, during the debugging and chip design verification phases, this method is extremely inconvenient. The newly added I3C testing introduces many new requirements, such as testing CCC commands, IBI, and PEC. The Tower I3C Host Adapter can easily meet these testing needs. We can perform debugging and verification using diagrams similar to the one shown below, easily verifying the chip's various functions, providing timely feedback to the design and development team, and shortening the chip development cycle.

To facilitate testing of DDR5 devices, we have specifically provided APIs related to DDR5 SPD HUBs. These APIs encapsulate complex protocols, making them easy for users to use. Our APIs fully comply with the JEDEC JESD403-1 standard. The relevant APIs are as follows:

For more detailed information, please log in Easyi3C Visit the official website to download and learn more for free.

Using the APIs provided above, we can build automated test scripts to meet different needs, making it convenient to test various functions. Below is a code example:

# ==========================================================================
# Easyi3C Interface Library
# --------------------------------------------------------------------------
# Copyright © 2025 by Easyi3C, Inc.
# All rights reserved.
# --------------------------------------------------------------------------
# ==========================================================================
import sys
from ezi3c.api import *
from ezi3c.utils import hex_string

from ddr5 import Spdhub


ez = ez_open()
if not ez:
    print("Cannot open Adapter")
    sys.exit(-1)
clk = ez_set_bus_clk_freq(ez, 1000, 4000)
print("Cur Clk Freq: {}".format(clk))
ret = ez_set_io_voltage(ez, 1.0)
assert ret == 0, "Faield to set IO voltage"

spd = Spdhub(ez, hid=0x00)

reg = 28

try:
    ret = spd.ccc_rstdaa()
    assert ret == 0, "Failed to reset DAA: addr:{:02X}".format(spd.addr)

    ret, data = spd.i2c_read_reg(0, 2)
    assert ret == 0 and data == (0x51, 0x18), "Failed to read SPD data: addr:{:02X}".format(spd.addr)
    print("SPD Data: {}".format(hex_string(data)))

    spd.switch_to_i3c(send_ccc=True)
    ret, data = spd.i3c_read_reg(0, 2)
    assert ret == 0 and data == (0x51, 0x18), "Failed to read SPD data in I3C mode: addr:{:02X}".format(spd.addr)

    ret = spd.i3c_write_reg(reg, 0xC0)
    assert ret == 0, "Failed to write to SPD register: addr:{:02X}".format(spd.addr)
    ret, data = spd.i3c_read_reg(reg, 1)
    assert ret == 0 and data == 0xC0, "Failed to read SPD register after write: addr:{:02X}".format(spd.addr)

    print("write read with IBI header")
    ret = spd.i3c_write_reg(reg, 0xb0, with_ibi_header=True)
    assert ret == 0, "Failed to write to SPD register: addr:{:02X}".format(spd.addr)
    ret, data = spd.i3c_read_reg(reg, 1, with_ibi_header=True)
    assert ret == 0 and data == 0xb0, "Failed to read SPD register after write: addr:{:02X}".format(spd.addr)

    print("Inject parity error test")
    ret = spd.i3c_write_reg(28, 0xF0, inject_parity_err=True)
    ret, data = spd.i3c_read_reg(28, 1)
    assert ret == 0 and data == 0xb0, "Failed to read SPD register after write: addr:{:02X}".format(spd.addr)

    ret = spd.i3c_write_reg(28, 0xF0)
    assert ret == 0, "Failed to write to SPD register: addr:{:02X}".format(spd.addr)
    ret, data = spd.i3c_read_reg(28, 1)
    assert ret == 0 and data == 0xF0, "Failed to read SPD register after write: addr:{:02X}".format(spd.addr)

    print("Enable PEC then read write register test")
    ret = spd.enable_pec(send_ccc=True)
    assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(spd.addr)

    print("Default Read Address Pointer Mode test")
    # Burst Length for Read Pointer Address for PEC Calculation must 2 Bytes or 4 Bytes
    spd.i3c_read_reg(None, 2)
    spd.i3c_read_reg(None, 4)

    ret, data = spd.i3c_read_reg(0, 1)
    assert ret == 0 and data == 0x51, "Failed to read SPD data in I3C mode with PEC: addr:{:02X}".format(spd.addr)

    print("PEC inject error")
    ret, data = spd.i3c_read_reg(0, 1, inject_pec_err=True)
    assert data is None

    ret = spd.i3c_write_reg(28, 0xF0)
    assert ret == 0, "Failed to write to SPD register: addr:{:02X}".format(spd.addr)
    ret, data = spd.i3c_read_reg(28, 1)
    assert ret == 0 and data == 0xF0, "Failed to read SPD register after write: addr:{:02X}".format(spd.addr)

    print("Disable PEC then read write register test")
    ret = spd.disable_pec(send_ccc=True)
    assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(spd.addr)

    ret, data = spd.ccc_getstatus()
    assert ret == 0, "Failed to get CCC status: addr:{:02X}".format(spd.addr)
    print("CCC Status: {}".format(hex_string(data)))

    ret, data = spd.ccc_devcap()
    assert ret == 0 and data == (0x04, 0x00), "Failed to get Device Capabilities: addr:{:02X}".format(spd.addr)
    print("Device Capabilities: {}".format(hex_string(data)))

    print("Disable PEC")
    ret = spd.disable_pec(send_ccc=True)
    assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(spd.addr)


finally:
    spd.ccc_rstdaa()
    ez_close(ez)
    print("Adapter closed.")


3. Summaries


Based on our Tower I3C Host Adapter, you can easily test DDR5 SPD HUBs, meet complex testing needs, build automated testing environments, and shorten the time to market for chips.




Service Line:

Address:Silicon Valley
Email:support@easyi3c.com

Copyright © Easyi3C Co., LTD