926 lines
36 KiB
Python
926 lines
36 KiB
Python
#
|
|
# This file is part of LiteDRAM.
|
|
#
|
|
# Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
|
|
# Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
# Copyright (c) 2018 John Sully <john@csquare.ca>
|
|
# Copyright (c) 2019 Ambroz Bizjak <abizjak.pro@gmail.com>
|
|
# Copyright (c) 2019 Antony Pavlov <antonynpavlov@gmail.com>
|
|
# Copyright (c) 2018 bunnie <bunnie@kosagi.com>
|
|
# Copyright (c) 2018 David Shah <dave@ds0.me>
|
|
# Copyright (c) 2019 Steve Haynal - VSD Engineering
|
|
# Copyright (c) 2018 Tim 'mithro' Ansell <me@mith.ro>
|
|
# Copyright (c) 2018 Daniel Kucera <daniel.kucera@gmail.com>
|
|
# Copyright (c) 2018 Mikołaj Sowiński <mikolaj.sowinski@gmail.com>
|
|
# Copyright (c) 2020 Antmicro <www.antmicro.com>
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
from math import ceil
|
|
from collections import namedtuple
|
|
|
|
from migen import *
|
|
|
|
from litedram.common import Settings, GeomSettings, TimingSettings
|
|
|
|
# Timings ------------------------------------------------------------------------------------------
|
|
|
|
_technology_timings = ["tREFI", "tWTR", "tCCD", "tRRD", "tZQCS"]
|
|
|
|
class _TechnologyTimings(Settings):
|
|
def __init__(self, tREFI, tWTR, tCCD, tRRD, tZQCS=None):
|
|
self.set_attributes(locals())
|
|
|
|
|
|
_speedgrade_timings = ["tRP", "tRCD", "tWR", "tRFC", "tFAW", "tRAS"]
|
|
|
|
class _SpeedgradeTimings(Settings):
|
|
def __init__(self, tRP, tRCD, tWR, tRFC, tFAW, tRAS):
|
|
self.set_attributes(locals())
|
|
|
|
# SPD ----------------------------------------------------------------------------------------------
|
|
|
|
def _read_field(byte, nbits, shift):
|
|
mask = 2**nbits - 1
|
|
return (byte & (mask << shift)) >> shift
|
|
|
|
def _twos_complement(value, nbits):
|
|
if value & (1 << (nbits - 1)):
|
|
value -= (1 << nbits)
|
|
return value
|
|
|
|
def _word(msb, lsb):
|
|
return (msb << 8) | lsb
|
|
|
|
# most signifficant (upper) / least signifficant (lower) nibble
|
|
def _msn(byte):
|
|
return _read_field(byte, nbits=4, shift=4)
|
|
|
|
def _lsn(byte):
|
|
return _read_field(byte, nbits=4, shift=0)
|
|
|
|
|
|
class DDR3SPDData:
|
|
memtype = "DDR3"
|
|
_speedgrades = [800, 1066, 1333, 1600, 1866, 2133]
|
|
|
|
def __init__(self, spd_data):
|
|
self.get_geometry(spd_data)
|
|
self.init_timebase(spd_data)
|
|
self.get_timings(spd_data)
|
|
|
|
def get_geometry(self, data):
|
|
bankbits = {
|
|
0b000: 3,
|
|
0b001: 4,
|
|
0b010: 5,
|
|
0b011: 6,
|
|
}[_read_field(data[4], nbits=3, shift=4)]
|
|
rowbits = {
|
|
0b000: 12,
|
|
0b001: 13,
|
|
0b010: 14,
|
|
0b011: 15,
|
|
0b100: 16,
|
|
}[_read_field(data[5], nbits=3, shift=3)]
|
|
colbits = {
|
|
0b000: 9,
|
|
0b001: 10,
|
|
0b010: 11,
|
|
0b011: 12,
|
|
}[_read_field(data[5], nbits=3, shift=0)]
|
|
|
|
self.nbanks = 2**bankbits
|
|
self.nrows = 2**rowbits
|
|
self.ncols = 2**colbits
|
|
|
|
def get_timings(self, spd_data):
|
|
b = spd_data
|
|
tck_min = self.txx_ns(mtb=b[12], ftb=b[34])
|
|
taa_min = self.txx_ns(mtb=b[16], ftb=b[35])
|
|
twr_min = self.txx_ns(mtb=b[17])
|
|
trcd_min = self.txx_ns(mtb=b[18], ftb=b[36])
|
|
trrd_min = self.txx_ns(mtb=b[19])
|
|
trp_min = self.txx_ns(mtb=b[20], ftb=b[37])
|
|
tras_min = self.txx_ns(mtb=_word(_lsn(b[21]), b[22]))
|
|
trc_min = self.txx_ns(mtb=_word(_msn(b[21]), b[23]), ftb=b[38])
|
|
trfc_min = self.txx_ns(mtb=_word(b[25], b[24]))
|
|
twtr_min = self.txx_ns(mtb=b[26])
|
|
trtp_min = self.txx_ns(mtb=b[27])
|
|
tfaw_min = self.txx_ns(mtb=_word(_lsn(b[28]), b[29]))
|
|
|
|
technology_timings = _TechnologyTimings(
|
|
tREFI = 64e6/8192, # 64ms/8192ops
|
|
tWTR = (4, twtr_min), # min 4 cycles
|
|
tCCD = (4, None), # min 4 cycles
|
|
tRRD = (4, trrd_min), # min 4 cycles
|
|
tZQCS = (64, 80),
|
|
)
|
|
speedgrade_timings = _SpeedgradeTimings(
|
|
tRP = trp_min,
|
|
tRCD = trcd_min,
|
|
tWR = twr_min,
|
|
tRFC = (None, trfc_min),
|
|
tFAW = (None, tfaw_min),
|
|
tRAS = tras_min,
|
|
)
|
|
|
|
self.speedgrade = str(self.speedgrade_freq(tck_min))
|
|
self.technology_timings = technology_timings
|
|
self.speedgrade_timings = {
|
|
self.speedgrade: speedgrade_timings,
|
|
"default": speedgrade_timings,
|
|
}
|
|
|
|
def init_timebase(self, data):
|
|
# All the DDR3 timings are defined in the units of "timebase", which
|
|
# consists of medium timebase (nanosec) and fine timebase (picosec).
|
|
fine_timebase_dividend = _read_field(data[9], nbits=4, shift=4)
|
|
fine_timebase_divisor = _read_field(data[9], nbits=4, shift=0)
|
|
fine_timebase_ps = fine_timebase_dividend / fine_timebase_divisor
|
|
self.fine_timebase_ns = fine_timebase_ps * 1e-3
|
|
medium_timebase_dividend = data[10]
|
|
medium_timebase_divisor = data[11]
|
|
self.medium_timebase_ns = medium_timebase_dividend / medium_timebase_divisor
|
|
|
|
def txx_ns(self, mtb, ftb=0):
|
|
"""Get tXX in nanoseconds from medium and (optional) fine timebase."""
|
|
# decode FTB encoded in 8-bit two's complement
|
|
ftb = _twos_complement(ftb, 8)
|
|
return mtb * self.medium_timebase_ns + ftb * self.fine_timebase_ns
|
|
|
|
@classmethod
|
|
def speedgrade_freq(cls, tck_ns):
|
|
# Calculate rounded speedgrade frequency from tck_min
|
|
freq_mhz = (1 / (tck_ns * 1e-9)) / 1e6
|
|
freq_mhz *= 2 # clock rate -> transfer rate (DDR)
|
|
for f in cls._speedgrades:
|
|
# Due to limited tck accuracy of 1ps, calculations may yield higher
|
|
# frequency than in reality (e.g. for DDR3-1866: tck=1.071 ns ->
|
|
# -> f=1867.4 MHz, while real is f=1866.6(6) MHz).
|
|
max_error = 2
|
|
if abs(freq_mhz - f) < max_error:
|
|
return f
|
|
raise ValueError("Transfer rate = {:.2f} does not correspond to any speedgrade"
|
|
.format(freq_mhz))
|
|
|
|
|
|
class DDR4SPDData(DDR3SPDData):
|
|
memtype = "DDR4"
|
|
_speedgrades = [1600, 1866, 2133, 2400, 2666, 2933, 3200]
|
|
|
|
def get_geometry(self, data):
|
|
bankgroupbits = {
|
|
0b00: 0,
|
|
0b01: 1,
|
|
0b10: 2,
|
|
}[_read_field(data[4], nbits=2, shift=6)]
|
|
bankbits = {
|
|
0b00: 2,
|
|
0b01: 3,
|
|
}[_read_field(data[4], nbits=2, shift=4)]
|
|
rowbits = {
|
|
0b000: 12,
|
|
0b001: 13,
|
|
0b010: 14,
|
|
0b011: 15,
|
|
0b100: 16,
|
|
0b101: 17,
|
|
0b110: 18,
|
|
}[_read_field(data[5], nbits=3, shift=3)]
|
|
colbits = {
|
|
0b000: 9,
|
|
0b001: 10,
|
|
0b010: 11,
|
|
0b011: 12,
|
|
}[_read_field(data[5], nbits=3, shift=0)]
|
|
|
|
self.ngroups = 2**bankgroupbits
|
|
self.ngroupbanks = 2**bankbits
|
|
self.nbanks = self.ngroups * self.ngroupbanks
|
|
self.nrows = 2**rowbits
|
|
self.ncols = 2**colbits
|
|
|
|
def init_timebase(self, data):
|
|
# there is only one possible value for DDR4
|
|
self.medium_timebase_ns = {
|
|
0b00: 125e-3,
|
|
}[_read_field(data[17], nbits=2, shift=2)]
|
|
self.fine_timebase_ns = {
|
|
0b00: 1e-3,
|
|
}[_read_field(data[17], nbits=2, shift=0)]
|
|
|
|
def get_timings(self, data):
|
|
b = data
|
|
|
|
self.trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
|
|
|
|
tckavg_min = self.txx_ns(mtb=b[18], ftb=b[125])
|
|
tckavg_max = self.txx_ns(mtb=b[19], ftb=b[124])
|
|
taa_min = self.txx_ns(mtb=b[24], ftb=b[123])
|
|
trcd_min = self.txx_ns(mtb=b[25], ftb=b[122])
|
|
trp_min = self.txx_ns(mtb=b[26], ftb=b[121])
|
|
tras_min = self.txx_ns(mtb=_word(_lsn(b[27]), b[28]))
|
|
trc_min = self.txx_ns(mtb=_word(_msn(b[27]), b[29]), ftb=b[120])
|
|
self.trfc = {
|
|
"1x": (None, self.txx_ns(mtb=_word(b[31], b[30]))),
|
|
"2x": (None, self.txx_ns(mtb=_word(b[33], b[32]))),
|
|
"4x": (None, self.txx_ns(mtb=_word(b[35], b[34]))),
|
|
}
|
|
tfaw_min = self.txx_ns(mtb=_word(_lsn(b[36]), b[37]))
|
|
trrd_s_min = self.txx_ns(mtb=b[38], ftb=b[119])
|
|
trrd_l_min = self.txx_ns(mtb=b[39], ftb=b[118])
|
|
tccd_l_min = self.txx_ns(mtb=b[40], ftb=b[117]) # min 6 cycles?
|
|
twr_min = self.txx_ns(mtb=_word(_lsn(b[41]), b[42]))
|
|
twtr_s_min = self.txx_ns(mtb=_word(_lsn(b[43]), b[44]))
|
|
twtr_l_min = self.txx_ns(mtb=_word(_msn(b[43]), b[45]))
|
|
|
|
# minimum tFAW in clock cycles depends on page size
|
|
sdram_device_width = {
|
|
0b000: 4,
|
|
0b001: 8,
|
|
0b010: 16,
|
|
0b011: 32,
|
|
}[_read_field(b[12], nbits=3, shift=0)]
|
|
page_size_bytes = self.ncols * sdram_device_width / 8
|
|
tfaw_min_ck = {
|
|
512: 16,
|
|
1024: 20,
|
|
2048: 28,
|
|
}[page_size_bytes]
|
|
|
|
technology_timings = _TechnologyTimings(
|
|
tREFI = self.trefi,
|
|
tWTR = (4, twtr_l_min),
|
|
tCCD = (4, tccd_l_min),
|
|
tRRD = (4, trrd_l_min),
|
|
tZQCS = (128, 80),
|
|
)
|
|
speedgrade_timings = _SpeedgradeTimings(
|
|
tRP = trp_min,
|
|
tRCD = trcd_min,
|
|
tWR = twr_min,
|
|
tRFC = self.trfc,
|
|
tFAW = (tfaw_min_ck, tfaw_min),
|
|
tRAS = tras_min,
|
|
)
|
|
|
|
self.speedgrade = str(self.speedgrade_freq(tckavg_min))
|
|
self.technology_timings = technology_timings
|
|
self.speedgrade_timings = {
|
|
self.speedgrade: speedgrade_timings,
|
|
"default": speedgrade_timings,
|
|
}
|
|
|
|
def parse_spd_hexdump(filename):
|
|
"""Parse data dumped using the `spdread` command in LiteX BIOS
|
|
|
|
This will read files in format:
|
|
Memory dump:
|
|
0x00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
|
|
0x00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................
|
|
"""
|
|
data = []
|
|
last_addr = -1
|
|
with open(filename) as f:
|
|
for line in f:
|
|
if line.startswith("0x"):
|
|
tokens = line.strip().split()
|
|
addr = int(tokens[0], 16)
|
|
assert addr > last_addr
|
|
values = [int(v, 16) for v in tokens[1:17]]
|
|
data.extend(values)
|
|
last_addr = addr
|
|
return data
|
|
|
|
# SDRAMModule --------------------------------------------------------------------------------------
|
|
|
|
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.
|
|
"""
|
|
registered = False
|
|
def __init__(self, clk_freq, rate, speedgrade=None, fine_refresh_mode=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),
|
|
)
|
|
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(
|
|
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", fine_refresh_mode), False),
|
|
tRFC = self.ck_ns_to_cycles(*self.get("tRFC", fine_refresh_mode)),
|
|
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.ck_ns_to_cycles(*self.get("tRRD")),
|
|
tRC = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRP") + 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"))
|
|
)
|
|
self.timing_settings.fine_refresh_mode = fine_refresh_mode
|
|
|
|
def get(self, name, key=None):
|
|
r = None
|
|
if name in _speedgrade_timings:
|
|
if hasattr(self, "speedgrade_timings"):
|
|
speedgrade = "default" if self.speedgrade is None else self.speedgrade
|
|
r = getattr(self.speedgrade_timings[speedgrade], name)
|
|
else:
|
|
name = name + "_" + self.speedgrade if self.speedgrade is not None else name
|
|
try:
|
|
r = getattr(self, name)
|
|
except:
|
|
pass
|
|
else:
|
|
if hasattr(self, "technology_timings"):
|
|
r = getattr(self.technology_timings, name)
|
|
else:
|
|
try:
|
|
r = getattr(self, name)
|
|
except:
|
|
pass
|
|
if (r is not None) and (key is not None):
|
|
r = r[key]
|
|
return r
|
|
|
|
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))
|
|
|
|
@classmethod
|
|
def from_spd_data(cls, spd_data, clk_freq, fine_refresh_mode=None):
|
|
# set parameters from SPD data based on memory type
|
|
spd_cls = {
|
|
0x0b: DDR3SPDData,
|
|
0x0c: DDR4SPDData,
|
|
}[spd_data[2]]
|
|
spd = spd_cls(spd_data)
|
|
|
|
# Create a deriving class to avoid modifying this one
|
|
class _SDRAMModule(cls):
|
|
memtype = spd.memtype
|
|
nbanks = spd.nbanks
|
|
nrows = spd.nrows
|
|
ncols = spd.ncols
|
|
technology_timings = spd.technology_timings
|
|
speedgrade_timings = spd.speedgrade_timings
|
|
# Save data for runtime verification
|
|
_spd_data = spd_data
|
|
|
|
nphases = {
|
|
"SDR": 1,
|
|
"DDR": 2,
|
|
"LPDDR": 2,
|
|
"DDR2": 2,
|
|
"DDR3": 4,
|
|
"DDR4": 4,
|
|
}[spd.memtype]
|
|
rate = "1:{}".format(nphases)
|
|
|
|
return _SDRAMModule(clk_freq,
|
|
rate = rate,
|
|
speedgrade = spd.speedgrade,
|
|
fine_refresh_mode = fine_refresh_mode)
|
|
|
|
class SDRAMRegisteredModule(SDRAMModule): registered = True
|
|
|
|
# SDR ----------------------------------------------------------------------------------------------
|
|
|
|
class SDRModule(SDRAMModule): memtype = "SDR"
|
|
class SDRRegisteredModule(SDRAMRegisteredModule): memtype = "SDR"
|
|
|
|
class IS42S16160(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 512
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=20, tRFC=(None, 70), tFAW=None, tRAS=None)}
|
|
|
|
class IS42S16320(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=20, tRFC=(None, 70), tFAW=None, tRAS=None)}
|
|
|
|
class MT48LC4M16(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 4096
|
|
ncols = 256
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=14, tRFC=(None, 66), tFAW=None, tRAS=None)}
|
|
|
|
class MT48LC16M16(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 512
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 15))
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=15, tRFC=(None, 66), tFAW=None, tRAS=44)}
|
|
|
|
class AS4C16M16(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 512
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=18, tRCD=18, tWR=12, tRFC=(None, 60), tFAW=None, tRAS=None)}
|
|
|
|
class AS4C32M16(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=18, tRCD=18, tWR=12, tRFC=(None, 60), tFAW=None, tRAS=None)}
|
|
|
|
class AS4C32M8(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 15))
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=15, tRFC=(None, 66), tFAW=None, tRAS=44)}
|
|
|
|
class M12L64322A(SDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 2048
|
|
ncols = 256
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/4096, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 10))
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 55), tFAW=None, tRAS=40)}
|
|
|
|
class M12L16161A(SDRModule):
|
|
# geometry
|
|
nbanks = 2
|
|
nrows = 2048
|
|
ncols = 256
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/4096, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 10))
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 55), tFAW=None, tRAS=40)}
|
|
|
|
# DDR ----------------------------------------------------------------------------------------------
|
|
|
|
class DDRModule(SDRAMModule): memtype = "DDR"
|
|
class DDRRegisteredModule(SDRAMRegisteredModule): memtype = "DDR"
|
|
|
|
class MT46V32M16(DDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 70), tFAW=None, tRAS=None)}
|
|
|
|
# LPDDR --------------------------------------------------------------------------------------------
|
|
|
|
class LPDDRModule(SDRAMModule): memtype = "LPDDR"
|
|
class LPDDRRegisteredModule(SDRAMRegisteredModule): memtype = "LPDDR"
|
|
|
|
class MT46H32M16(LPDDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 72), tFAW=None, tRAS=None)}
|
|
|
|
class MT46H32M32(LPDDRModule):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 72), tFAW=None, tRAS=None)}
|
|
|
|
# DDR2 ---------------------------------------------------------------------------------------------
|
|
|
|
class DDR2Module(SDRAMModule): memtype = "DDR2"
|
|
class DDR2RegisteredModule(SDRAMRegisteredModule): memtype = "DDR2"
|
|
|
|
class MT47H128M8(DDR2Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
|
|
|
|
class MT47H32M16(DDR2Module):
|
|
# geometry
|
|
nbanks = 4
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
|
|
|
|
class MT47H64M16(DDR2Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
|
|
|
|
class P3R1GE4JGF(DDR2Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
|
|
speedgrade_timings = {"default": _SpeedgradeTimings(tRP=12.5, tRCD=12.5, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
|
|
|
|
# DDR3 (Chips) -------------------------------------------------------------------------------------
|
|
|
|
class DDR3Module(SDRAMModule): memtype = "DDR3"
|
|
class DDR3RegisteredModule(SDRAMRegisteredModule): memtype = "DDR3"
|
|
|
|
class MT41K64M16(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 8192
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(64, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(86, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=13.5, tRFC=(107, None), tFAW=(None, 45), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(128, None), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class MT41J128M16(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(64, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(86, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=13.5, tRFC=(107, None), tFAW=(None, 45), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(128, None), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class MT41K128M16(MT41J128M16): pass
|
|
|
|
class MT41J256M16(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 32768
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(139, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(138, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=13.5, tRFC=(174, None), tFAW=(None, 45), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(208, None), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class MT41K256M16(MT41J256M16): pass
|
|
|
|
class MT41J512M16(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(280, None), tFAW=(None, 40), tRAS=39),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class MT41K512M16(MT41J512M16): pass
|
|
|
|
class K4B1G0446F(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(120, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(160, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=(200, None), tFAW=(None, 45), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(240, None), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class K4B2G1646F(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(104, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(139, None), tFAW=(None, 50), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=(174, None), tFAW=(None, 45), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(208, None), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class H5TC4G63CFR(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 7.5), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(260, None), tFAW=(None, 40), tRAS=37.5),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["800"]
|
|
|
|
class IS43TR16128B(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 160), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
|
|
# DDR3 (SO-DIMM) -----------------------------------------------------------------------------------
|
|
|
|
class MT8JTF12864(DDR3Module):
|
|
# base chip: MT41J128M8
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 16384
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 110), tFAW=(None, 37.5), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 110), tFAW=(None, 30), tRAS=36),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1333"]
|
|
|
|
class MT8KTF51264(DDR3Module):
|
|
# base chip: MT41K512M8
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800" : _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=35),
|
|
"1866": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 27), tRAS=34),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1866"]
|
|
|
|
class MT18KSF1G72HZ(DDR3Module):
|
|
# base chip: MT41K512M8
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class AS4C256M16D3A(DDR3Module):
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 32768
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 7.5), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=35),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1600"]
|
|
|
|
class MT16KTF1G64HZ(DDR3Module):
|
|
# base chip: MT41K512M8
|
|
# geometry
|
|
nbanks = 8
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
|
|
speedgrade_timings = {
|
|
"800" : _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
|
|
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
|
|
"1333": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=36),
|
|
"1600": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=35),
|
|
"1866": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 27), tRAS=34),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["1866"]
|
|
|
|
|
|
# DDR4 (Chips) -------------------------------------------------------------------------------------
|
|
|
|
class DDR4Module(SDRAMModule): memtype = "DDR4"
|
|
class DDR4RegisteredModule(SDRAMRegisteredModule): memtype = "DDR4"
|
|
|
|
class EDY4016A(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 2
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 32768
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(28, 30), tRAS=32),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
|
|
|
class MT40A1G8(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 4
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"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=trfc, tFAW=(20, 21), tRAS=32),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
|
|
|
class MT40A256M16(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 2
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 32768
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(28, 35), tRAS=32),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
|
|
|
class MT40A512M8(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 4
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 32768
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"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=trfc, tFAW=(20, 21), tRAS=32),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
|
|
|
class MT40A512M16(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 2
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|
|
|
|
# DDR4 (SO-DIMM) -----------------------------------------------------------------------------------
|
|
|
|
class KVR21SE15S84(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 4
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 32768
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"2133": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=33),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2133"]
|
|
|
|
class MTA4ATF51264HZ(DDR4Module):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 2
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 65536
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"2133": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=33),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2133"]
|
|
|
|
# DDR4 (RDIMM) -------------------------------------------------------------------------------------
|
|
|
|
class MTA18ASF2G72PZ(DDR4RegisteredModule):
|
|
# geometry
|
|
ngroupbanks = 4
|
|
ngroups = 4
|
|
nbanks = ngroups * ngroupbanks
|
|
nrows = 131072
|
|
ncols = 1024
|
|
# timings
|
|
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 = {
|
|
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
|
|
}
|
|
speedgrade_timings["default"] = speedgrade_timings["2400"]
|