modules/init: add DDR4 fine refresh mode support: x1, x2 and x4 (x1=previous and default behavior)
This commit is contained in:
parent
6c9c45f313
commit
eddd6e4eaf
|
@ -298,6 +298,15 @@ def get_ddr4_phy_init_sequence(phy_settings, timing_settings):
|
||||||
mr2 |= rtt_wr << 9
|
mr2 |= rtt_wr << 9
|
||||||
return mr2
|
return mr2
|
||||||
|
|
||||||
|
def format_mr3(fine_refresh_mode):
|
||||||
|
fine_refresh_mode_to_mr3 = {
|
||||||
|
"1x": 0b000,
|
||||||
|
"2x": 0b001,
|
||||||
|
"4x": 0b010
|
||||||
|
}
|
||||||
|
mr3 = fine_refresh_mode_to_mr3[fine_refresh_mode] << 6
|
||||||
|
return mr3
|
||||||
|
|
||||||
def format_mr6(tccd):
|
def format_mr6(tccd):
|
||||||
tccd_to_mr6 = {
|
tccd_to_mr6 = {
|
||||||
4: 0b000,
|
4: 0b000,
|
||||||
|
@ -350,7 +359,7 @@ def get_ddr4_phy_init_sequence(phy_settings, timing_settings):
|
||||||
mr0 = format_mr0(bl, cl, wr, 1)
|
mr0 = format_mr0(bl, cl, wr, 1)
|
||||||
mr1 = format_mr1(1, z_to_ron[ron], z_to_rtt_nom[rtt_nom])
|
mr1 = format_mr1(1, z_to_ron[ron], z_to_rtt_nom[rtt_nom])
|
||||||
mr2 = format_mr2(cwl, z_to_rtt_wr[rtt_wr])
|
mr2 = format_mr2(cwl, z_to_rtt_wr[rtt_wr])
|
||||||
mr3 = 0
|
mr3 = format_mr3(timing_settings.fine_refresh_mode)
|
||||||
mr4 = 0
|
mr4 = 0
|
||||||
mr5 = 0
|
mr5 = 0
|
||||||
mr6 = format_mr6(4) # FIXME: tCCD
|
mr6 = format_mr6(4) # FIXME: tCCD
|
||||||
|
|
|
@ -46,7 +46,7 @@ class SDRAMModule:
|
||||||
SDRAM modules with the same geometry exist can have
|
SDRAM modules with the same geometry exist can have
|
||||||
various speedgrades.
|
various speedgrades.
|
||||||
"""
|
"""
|
||||||
def __init__(self, clk_freq, rate, speedgrade=None):
|
def __init__(self, clk_freq, rate, speedgrade=None, fine_refresh_mode=None):
|
||||||
self.clk_freq = clk_freq
|
self.clk_freq = clk_freq
|
||||||
self.rate = rate
|
self.rate = rate
|
||||||
self.speedgrade = speedgrade
|
self.speedgrade = speedgrade
|
||||||
|
@ -55,12 +55,16 @@ class SDRAMModule:
|
||||||
rowbits = log2_int(self.nrows),
|
rowbits = log2_int(self.nrows),
|
||||||
colbits = log2_int(self.ncols),
|
colbits = log2_int(self.ncols),
|
||||||
)
|
)
|
||||||
|
assert not (self.memtype != "DDR4" and fine_refresh_mode != None)
|
||||||
|
assert fine_refresh_mode in [None, "1x", "2x", "4x"]
|
||||||
|
if (fine_refresh_mode is None) and (self.memtype == "DDR4"):
|
||||||
|
fine_refresh_mode = "1x"
|
||||||
self.timing_settings = TimingSettings(
|
self.timing_settings = TimingSettings(
|
||||||
tRP = self.ns_to_cycles(self.get("tRP")),
|
tRP = self.ns_to_cycles(self.get("tRP")),
|
||||||
tRCD = self.ns_to_cycles(self.get("tRCD")),
|
tRCD = self.ns_to_cycles(self.get("tRCD")),
|
||||||
tWR = self.ns_to_cycles(self.get("tWR")),
|
tWR = self.ns_to_cycles(self.get("tWR")),
|
||||||
tREFI = self.ns_to_cycles(self.get("tREFI"), False),
|
tREFI = self.ns_to_cycles(self.get("tREFI", fine_refresh_mode), False),
|
||||||
tRFC = self.ck_ns_to_cycles(*self.get("tRFC")),
|
tRFC = self.ck_ns_to_cycles(*self.get("tRFC", fine_refresh_mode)),
|
||||||
tWTR = self.ck_ns_to_cycles(*self.get("tWTR")),
|
tWTR = self.ck_ns_to_cycles(*self.get("tWTR")),
|
||||||
tFAW = None if self.get("tFAW") is None else self.ck_ns_to_cycles(*self.get("tFAW")),
|
tFAW = None if self.get("tFAW") is None else self.ck_ns_to_cycles(*self.get("tFAW")),
|
||||||
tCCD = None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")),
|
tCCD = None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")),
|
||||||
|
@ -69,26 +73,31 @@ class SDRAMModule:
|
||||||
tRAS = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS")),
|
tRAS = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS")),
|
||||||
tZQCS = None if self.get("tZQCS") is None else self.ck_ns_to_cycles(*self.get("tZQCS"))
|
tZQCS = None if self.get("tZQCS") is None else self.ck_ns_to_cycles(*self.get("tZQCS"))
|
||||||
)
|
)
|
||||||
|
self.timing_settings.fine_refresh_mode = fine_refresh_mode
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name, key=None):
|
||||||
|
r = None
|
||||||
if name in _speedgrade_timings:
|
if name in _speedgrade_timings:
|
||||||
if hasattr(self, "speedgrade_timings"):
|
if hasattr(self, "speedgrade_timings"):
|
||||||
speedgrade = "default" if self.speedgrade is None else self.speedgrade
|
speedgrade = "default" if self.speedgrade is None else self.speedgrade
|
||||||
return getattr(self.speedgrade_timings[speedgrade], name)
|
r = getattr(self.speedgrade_timings[speedgrade], name)
|
||||||
else:
|
else:
|
||||||
name = name + "_" + self.speedgrade if self.speedgrade is not None else name
|
name = name + "_" + self.speedgrade if self.speedgrade is not None else name
|
||||||
try:
|
try:
|
||||||
return getattr(self, name)
|
r = getattr(self, name)
|
||||||
except:
|
except:
|
||||||
return None
|
pass
|
||||||
else:
|
else:
|
||||||
if hasattr(self, "technology_timings"):
|
if hasattr(self, "technology_timings"):
|
||||||
return getattr(self.technology_timings, name)
|
r = getattr(self.technology_timings, name)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
return getattr(self, name)
|
r = getattr(self, name)
|
||||||
except:
|
except:
|
||||||
return None
|
pass
|
||||||
|
if (r is not None) and (key is not None):
|
||||||
|
r = r[key]
|
||||||
|
return r
|
||||||
|
|
||||||
def ns_to_cycles(self, t, margin=True):
|
def ns_to_cycles(self, t, margin=True):
|
||||||
clk_period_ns = 1e9/self.clk_freq
|
clk_period_ns = 1e9/self.clk_freq
|
||||||
|
@ -462,9 +471,11 @@ class EDY4016A(SDRAMModule):
|
||||||
nrows = 32768
|
nrows = 32768
|
||||||
ncols = 1024
|
ncols = 1024
|
||||||
# timings
|
# timings
|
||||||
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
|
trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
|
||||||
|
trfc = {"1x": (None, 260), "2x": (None, 160), "4x": (None, 110)}
|
||||||
|
technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
|
||||||
speedgrade_timings = {
|
speedgrade_timings = {
|
||||||
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 260), tFAW=(28, 30), tRAS=32),
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(28, 30), tRAS=32),
|
||||||
}
|
}
|
||||||
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
||||||
|
|
||||||
|
@ -478,10 +489,12 @@ class MT40A1G8(SDRAMModule):
|
||||||
nrows = 65536
|
nrows = 65536
|
||||||
ncols = 1024
|
ncols = 1024
|
||||||
# timings
|
# timings
|
||||||
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4), tZQCS=(128, 80))
|
trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
|
||||||
|
trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
|
||||||
|
technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4), tZQCS=(128, 80))
|
||||||
speedgrade_timings = {
|
speedgrade_timings = {
|
||||||
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32),
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
|
||||||
"2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=(None, 350), tFAW=(20, 21), tRAS=32),
|
"2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=trfc, tFAW=(20, 21), tRAS=32),
|
||||||
}
|
}
|
||||||
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
||||||
|
|
||||||
|
@ -495,8 +508,10 @@ class MT40A512M16(SDRAMModule):
|
||||||
nrows = 65536
|
nrows = 65536
|
||||||
ncols = 1024
|
ncols = 1024
|
||||||
# timings
|
# timings
|
||||||
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
|
trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
|
||||||
|
trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
|
||||||
|
technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
|
||||||
speedgrade_timings = {
|
speedgrade_timings = {
|
||||||
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32),
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
|
||||||
}
|
}
|
||||||
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
||||||
|
|
Loading…
Reference in New Issue