2015-03-21 12:44:04 -04:00
|
|
|
# SDRAM memory modules library
|
|
|
|
#
|
|
|
|
# This library avoid duplications of memory modules definitions in targets and
|
|
|
|
# ease SDRAM usage. (User can only select an already existing module or create
|
|
|
|
# one for its board and contribute to this library)
|
|
|
|
#
|
|
|
|
# TODO:
|
|
|
|
# Try to share the maximum information we can between modules:
|
|
|
|
# - ex: MT46V32M16 and MT46H32M16 are almost identical (V=DDR, H=LPDDR)
|
|
|
|
# - Modules can have different configuration:
|
|
|
|
# MT8JTF12864 (1GB), MT8JTF25664 (2GB)
|
|
|
|
# but share all others informations, try to create an unique module for all
|
|
|
|
# configurations.
|
|
|
|
# - Modules can have different speedgrades, add support for it (and also add
|
|
|
|
# a check to verify clk_freq is in the supported range)
|
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
from math import ceil
|
|
|
|
|
|
|
|
from migen.fhdl.std import *
|
|
|
|
from misoclib.mem import sdram
|
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
class SDRAMModule:
|
2015-04-13 10:19:55 -04:00
|
|
|
def __init__(self, clk_freq, memtype, geom_settings, timing_settings):
|
|
|
|
self.clk_freq = clk_freq
|
|
|
|
self.memtype = memtype
|
|
|
|
self.geom_settings = sdram.GeomSettings(
|
|
|
|
bankbits=log2_int(geom_settings["nbanks"]),
|
|
|
|
rowbits=log2_int(geom_settings["nrows"]),
|
|
|
|
colbits=log2_int(geom_settings["ncols"]),
|
|
|
|
)
|
|
|
|
self.timing_settings = sdram.TimingSettings(
|
|
|
|
tRP=self.ns(timing_settings["tRP"]),
|
|
|
|
tRCD=self.ns(timing_settings["tRCD"]),
|
|
|
|
tWR=self.ns(timing_settings["tWR"]),
|
|
|
|
tWTR=timing_settings["tWTR"],
|
|
|
|
tREFI=self.ns(timing_settings["tREFI"], False),
|
|
|
|
tRFC=self.ns(timing_settings["tRFC"])
|
|
|
|
)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
def ns(self, t, margin=True):
|
|
|
|
clk_period_ns = 1000000000/self.clk_freq
|
|
|
|
if margin:
|
|
|
|
t += clk_period_ns/2
|
|
|
|
return ceil(t/clk_period_ns)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
# SDR
|
|
|
|
class IS42S16160(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 4,
|
|
|
|
"nrows": 8192,
|
|
|
|
"ncols": 512
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
# Note: timings for -7 speedgrade (add support for others speedgrades)
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 20,
|
|
|
|
"tRCD": 20,
|
|
|
|
"tWR": 20,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 64*1000*1000/8192,
|
|
|
|
"tRFC": 70
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
|
|
|
|
self.timing_settings)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
class MT48LC4M16(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 4,
|
|
|
|
"nrows": 4096,
|
|
|
|
"ncols": 256
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 15,
|
|
|
|
"tRCD": 15,
|
|
|
|
"tWR": 14,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 64*1000*1000/4096,
|
|
|
|
"tRFC": 66
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
|
|
|
|
self.timing_settings)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 13:38:53 -04:00
|
|
|
class AS4C16M16(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 4,
|
|
|
|
"nrows": 8192,
|
|
|
|
"ncols": 512
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
# Note: timings for -6 speedgrade (add support for others speedgrades)
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 18,
|
|
|
|
"tRCD": 18,
|
|
|
|
"tWR": 12,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 64*1000*1000/8192,
|
|
|
|
"tRFC": 60
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
|
|
|
|
self.timing_settings)
|
2015-03-21 13:38:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
# DDR
|
2015-03-21 12:04:58 -04:00
|
|
|
class MT46V32M16(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 4,
|
|
|
|
"nrows": 8192,
|
|
|
|
"ncols": 1024
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 15,
|
|
|
|
"tRCD": 15,
|
|
|
|
"tWR": 15,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 64*1000*1000/8192,
|
|
|
|
"tRFC": 70
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "DDR", self.geom_settings,
|
|
|
|
self.timing_settings)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
# LPDDR
|
2015-03-21 12:25:36 -04:00
|
|
|
class MT46H32M16(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 4,
|
|
|
|
"nrows": 8192,
|
|
|
|
"ncols": 1024
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 15,
|
|
|
|
"tRCD": 15,
|
|
|
|
"tWR": 15,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 64*1000*1000/8192,
|
|
|
|
"tRFC": 72
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "LPDDR", self.geom_settings,
|
|
|
|
self.timing_settings)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
# DDR2
|
2015-03-21 13:52:10 -04:00
|
|
|
class MT47H128M8(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 8,
|
|
|
|
"nrows": 16384,
|
|
|
|
"ncols": 1024
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 15,
|
|
|
|
"tRCD": 15,
|
|
|
|
"tWR": 15,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 7800,
|
|
|
|
"tRFC": 127.5
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "DDR2", self.geom_settings,
|
|
|
|
self.timing_settings)
|
2015-03-21 11:56:53 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-03-21 11:56:53 -04:00
|
|
|
# DDR3
|
2015-03-21 12:25:36 -04:00
|
|
|
class MT8JTF12864(SDRAMModule):
|
2015-04-13 10:19:55 -04:00
|
|
|
geom_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"nbanks": 8,
|
|
|
|
"nrows": 16384,
|
|
|
|
"ncols": 1024
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
timing_settings = {
|
2015-08-20 16:15:06 -04:00
|
|
|
"tRP": 15,
|
|
|
|
"tRCD": 15,
|
|
|
|
"tWR": 15,
|
|
|
|
"tWTR": 2,
|
|
|
|
"tREFI": 7800,
|
|
|
|
"tRFC": 70
|
2015-04-13 10:19:55 -04:00
|
|
|
}
|
|
|
|
def __init__(self, clk_freq):
|
|
|
|
SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
|
|
|
|
self.timing_settings)
|