litedram/litedram/modules.py

384 lines
8.5 KiB
Python

from math import ceil
from migen import *
from litedram.common import GeomSettings, TimingSettings
class SDRAMModule:
"""SDRAM module geometry and timings.
SDRAM controller has to ensure that all geometry and
timings parameters are fulfilled. Timings parameters
can be expressed in ns, in SDRAM clock cycles or both
and controller needs to use the greater value.
SDRAM modules with the same geometry exist can have
various speedgrades.
"""
def __init__(self, clk_freq, rate, speedgrade=None):
self.clk_freq = clk_freq
self.rate = rate
self.speedgrade = speedgrade
self.geom_settings = GeomSettings(
bankbits=log2_int(self.nbanks),
rowbits=log2_int(self.nrows),
colbits=log2_int(self.ncols),
)
self.timing_settings = TimingSettings(
tRP=self.ns_to_cycles(self.get("tRP")),
tRCD=self.ns_to_cycles(self.get("tRCD")),
tWR=self.ns_to_cycles(self.get("tWR")),
tREFI=self.ns_to_cycles(self.get("tREFI"), False),
tRFC=self.ns_to_cycles(self.get("tRFC")),
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")),
tCCD=None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")),
tRRD=None if self.get("tRRD") is None else self.ns_to_cycles_trrd(self.get("tRRD")),
)
def get(self, name):
if self.speedgrade is not None and name in ["tRP", "tRCD", "tWR", "tRFC", "tFAW"]:
name += "_" + self.speedgrade
try:
return getattr(self, name)
except:
return None
def ns_to_cycles_trrd(self, t):
lower_bound = {
"1:1" : 4,
"1:2" : 2,
"1:4" : 1
}
if (t is None):
if self.memtype == "DDR3":
return lower_bound[self.rate]
else:
return 0 #Review: Is this needed for DDR2 and below?
return max(lower_bound[self.rate], self.ns_to_cycles(t, margin=False))
def ns_to_cycles(self, t, margin=True):
clk_period_ns = 1e9/self.clk_freq
if margin:
margins = {
"1:1" : 0,
"1:2" : clk_period_ns/2,
"1:4" : 3*clk_period_ns/4
}
t += margins[self.rate]
return ceil(t/clk_period_ns)
def ck_to_cycles(self, c):
d = {
"1:1" : 1,
"1:2" : 2,
"1:4" : 4
}
return ceil(c/d[self.rate])
def ck_ns_to_cycles(self, c, t):
c = 0 if c is None else c
t = 0 if t is None else t
return max(self.ck_to_cycles(c), self.ns_to_cycles(t))
# SDR
class IS42S16160(SDRAMModule):
memtype = "SDR"
# geometry
nbanks = 4
nrows = 8192
ncols = 512
# speedgrade invariant timings
tRP = 20
tRCD = 20
tWR = 20
tREFI = 64e6/8192
tRFC = 70
# speedgrade related timings
tWTR = (2, None)
class MT48LC4M16(SDRAMModule):
memtype = "SDR"
# geometry
nbanks = 4
nrows = 4096
ncols = 256
# speedgrade invariant timings
tREFI = 64e6/4096
tWTR = (2, None)
# speedgrade related timings
tRP = 15
tRCD = 15
tWR = 14
tRFC = 66
class AS4C16M16(SDRAMModule):
memtype = "SDR"
# geometry
nbanks = 4
nrows = 8192
ncols = 512
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (2, None)
# speedgrade related timings
tRP = 18
tRCD = 18
tWR = 12
tRFC = 60
# DDR
class MT46V32M16(SDRAMModule):
memtype = "DDR"
# geometry
nbanks = 4
nrows = 8192
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (2, None)
# speedgrade related timings
tRP = 15
tRCD = 15
tWR = 15
tRFC = 70
# LPDDR
class MT46H32M16(SDRAMModule):
memtype = "LPDDR"
# geometry
nbanks = 4
nrows = 8192
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (2, None)
# speedgrade related timings
tRP = 15
tRCD = 15
tWR = 15
tRFC = 72
class MT46H32M32(SDRAMModule):
memtype = "LPDDR"
# geometry
nbanks = 4
nrows = 8192
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (2, None)
# speedgrade related timings
tRP = 15
tRCD = 15
tWR = 15
tRFC = 72
# DDR2
class MT47H128M8(SDRAMModule):
memtype = "DDR2"
# geometry
nbanks = 8
nrows = 16384
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (None, 7.5)
# speedgrade related timings
tRP = 15
tRCD = 15
tWR = 15
tRFC = 127.5
class MT47H64M16(SDRAMModule):
memtype = "DDR2"
# geometry
nbanks = 8
nrows = 8192
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (None, 7.5)
# speedgrade related timings
tRP = 15
tRCD = 15
tWR = 15
tREFI = 64e6/8192
tRFC = 127.5
class P3R1GE4JGF(SDRAMModule):
memtype = "DDR2"
# geometry
nbanks = 8
nrows = 8192
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (None, 7.5)
# speedgrade related timings
tRP = 12.5
tRCD = 12.5
tWR = 15
tREFI = 64e6/8192
tRFC = 127.5
# DDR3
class MT41J128M16(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 16384
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
tRRD = 10
# speedgrade related timings
# DDR3-1066
tRP_1066 = 13.1
tRCD_1066 = 13.1
tWR_1066 = 13.1
tRFC_1066 = 86
tFAW_1066 = (27, None)
# DDR3-1333
tRP_1333 = 13.5
tRCD_1333 = 13.5
tWR_1333 = 13.5
tRFC_1333 = 107
tFAW_1333 = (30, None)
# DDR3-1600
tRP_1600 = 13.75
tRCD_1600 = 13.75
tWR_1600 = 13.75
tRFC_1600 = 128
tFAW_1600 = (32, None)
# API retro-compatibility
tRP = tRP_1600
tRCD = tRCD_1600
tWR = tWR_1600
tRFC = tRFC_1600
tFAW = tFAW_1600
class MT41K128M16(MT41J128M16):
pass
class MT41J256M16(MT41J128M16):
# geometry
nrows = 32768
# speedgrade related timings
tRFC_1066 = 139
tRFC_1333 = 174
tRFC_1600 = 208
# API retro-compatibility
tRFC = tRFC_1600
class MT41K256M16(MT41J256M16):
pass
class MT8JTF12864(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 16384
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
# speedgrade related timings
# DDR3-1066
tRP_1066 = 15
tRCD_1066 = 15
tWR_1066 = 15
tRFC_1066 = 86
tFAW_1066 = (27, None)
# DDR3-1333
tRP_1333 = 15
tRCD_1333 = 15
tWR_1333 = 15
tRFC_1333 = 107
tFAW_1333 = (30, None)
# API retro-compatibility
tRP = tRP_1333
tRCD = tRCD_1333
tWR = tWR_1333
tRFC = tRFC_1333
tFAW = tFAW_1333
class MT18KSF1G72HZ(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 65536
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
# DDR3-1066
tRP_1066 = 15
tRCD_1066 = 15
tWR_1066 = 15
tRFC_1066 = 86
tFAW_1066 = (27, None)
# DDR3-1333
tRP_1333 = 15
tRCD_1333 = 15
tWR_1333 = 15
tRFC_1333 = 107
tFAW_1333 = (30, None)
# DDR3-1600
tRP_1600 = 13.125
tRCD_1600 = 13.125
tWR_1600 = 13.125
tRFC_1600 = 128
tFAW_1600 = (32, None)
# API retro-compatibility
tRP = tRP_1600
tRCD = tRCD_1600
tWR = tWR_1600
tRFC = tRFC_1600
tFAW = tFAW_1600
class K4B2G1646FBCK0(SDRAMModule): ### TODO: optimize and revalidate all timings, at cold and hot temperatures
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 16384
ncols = 1024
# speedgrade invariant timings
tREFI = 7800 # 3900 refresh more often at 85C+
tWTR = (14, 35)
tCCD = (4, None)
tRRD = 10 # 4 * clk = 10ns
# speedgrade related timings
# DDR3-1600
tRP_1600 = 13.125
tRCD_1600 = 13.125
tWR_1600 = 35 # this is hard-coded in MR0 to be 14 cycles, 14 * 2.5 = 35, see sdram_init.py@L224
tRFC_1600 = 160
tFAW_1600 = (None, 40)
# API retro-compatibility
tRP = tRP_1600
tRCD = tRCD_1600
tWR = tWR_1600
tRFC = tRFC_1600
tFAW = tFAW_1600