Skip to content

Commit e734a09

Browse files
committed
test: Lock DDR3 PHY write latency contracts
Exercise the ECP5, GW2 and GW5 DDR3 PHY settings across frequencies on both sides of a CWL transition. Verify that settings.cwl keeps the DDR3 memory value selected from tCK while settings.write_latency describes each PHY pipeline: cwl_sys_latency for ECP5 and cwl_sys_latency - 1 for GW2/GW5. This prevents primitive-specific compensation from leaking into the memory timing configuration.
1 parent c9d753e commit e734a09

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

test/test_ddr3_phy_settings.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#
2+
# This file is part of LiteDRAM.
3+
#
4+
# Copyright (c) 2026 Florent Kermarrec <florent@enjoy-digital.fr>
5+
# SPDX-License-Identifier: BSD-2-Clause
6+
7+
import unittest
8+
9+
from migen import *
10+
11+
from litedram.common import get_default_cwl, get_sys_latency
12+
from litedram.phy.ecp5ddrphy import ECP5DDRPHY
13+
from litedram.phy.gw2ddrphy import GW2DDRPHY
14+
from litedram.phy.gw5ddrphy import GW5DDRPHY
15+
16+
17+
class TestDDR3PHYSettings(unittest.TestCase):
18+
phys = [
19+
("ecp5", ECP5DDRPHY, 0),
20+
("gw2", GW2DDRPHY, -1),
21+
("gw5", GW5DDRPHY, -1),
22+
]
23+
sys_clk_freqs = [75e6, 100e6, 125e6, 166e6, 200e6, 250e6]
24+
25+
@staticmethod
26+
def get_pads():
27+
return Record([
28+
("a", 15),
29+
("ba", 3),
30+
("ras_n", 1),
31+
("cas_n", 1),
32+
("we_n", 1),
33+
("clk_p", 1),
34+
("clk_n", 1),
35+
("dq", 8),
36+
("dm", 1),
37+
("dqs_p", 1),
38+
("dqs_n", 1),
39+
])
40+
41+
def test_default_cwl_is_preserved(self):
42+
for name, phy_cls, _ in self.phys:
43+
for sys_clk_freq in self.sys_clk_freqs:
44+
with self.subTest(phy=name, sys_clk_freq=sys_clk_freq):
45+
phy = phy_cls(self.get_pads(), sys_clk_freq=sys_clk_freq)
46+
tck = 1/(2*sys_clk_freq)
47+
expected_cwl = get_default_cwl("DDR3", tck)
48+
49+
self.assertEqual(phy.settings.cwl, expected_cwl)
50+
51+
def test_write_latency_matches_phy_pipeline(self):
52+
for name, phy_cls, write_latency_offset in self.phys:
53+
for sys_clk_freq in self.sys_clk_freqs:
54+
with self.subTest(phy=name, sys_clk_freq=sys_clk_freq):
55+
phy = phy_cls(self.get_pads(), sys_clk_freq=sys_clk_freq)
56+
cwl = phy.settings.cwl
57+
cwl_sys_latency = get_sys_latency(phy.settings.nphases, cwl)
58+
59+
self.assertEqual(
60+
phy.settings.write_latency,
61+
cwl_sys_latency + write_latency_offset,
62+
)

0 commit comments

Comments
 (0)