1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2018 John Sully <john@csquare.ca>
4 # This file is Copyright (c) 2019 Ambroz Bizjak <abizjak.pro@gmail.com>
5 # This file is Copyright (c) 2019 Antony Pavlov <antonynpavlov@gmail.com>
6 # This file is Copyright (c) 2018 bunnie <bunnie@kosagi.com>
7 # This file is Copyright (c) 2018 David Shah <dave@ds0.me>
8 # This file is Copyright (c) 2019 Steve Haynal - VSD Engineering
9 # This file is Copyright (c) 2018 Tim 'mithro' Ansell <me@mith.ro>
10 # This file is Copyright (c) 2018 Daniel Kucera <daniel.kucera@gmail.com>
11 # This file is Copyright (c) 2018 Mikołaj Sowiński <mikolaj.sowinski@gmail.com>
12 # This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
16 from collections
import namedtuple
18 from nmigen
.utils
import log2_int
20 from gram
.common
import Settings
, GeomSettings
, TimingSettings
22 # Timings ------------------------------------------------------------------------------------------
24 _technology_timings
= ["tREFI", "tWTR", "tCCD", "tRRD", "tZQCS"]
27 class _TechnologyTimings(Settings
):
28 def __init__(self
, tREFI
, tWTR
, tCCD
, tRRD
, tZQCS
=None):
29 self
.set_attributes(locals())
32 _speedgrade_timings
= ["tRP", "tRCD", "tWR", "tRFC", "tFAW", "tRAS"]
35 class _SpeedgradeTimings(Settings
):
36 def __init__(self
, tRP
, tRCD
, tWR
, tRFC
, tFAW
, tRAS
):
37 self
.set_attributes(locals())
39 # SPD ----------------------------------------------------------------------------------------------
42 def _read_field(byte
, nbits
, shift
):
44 return (byte
& (mask
<< shift
)) >> shift
47 def _twos_complement(value
, nbits
):
48 if value
& (1 << (nbits
- 1)):
54 return (msb
<< 8) | lsb
60 def __init__(self
, spd_data
):
61 # Geometry ---------------------------------------------------------------------------------
67 }[_read_field(spd_data
[4], nbits
=3, shift
=4)]
74 }[_read_field(spd_data
[5], nbits
=3, shift
=3)]
80 }[_read_field(spd_data
[5], nbits
=3, shift
=0)]
82 self
.nbanks
= 2**bankbits
83 self
.nrows
= 2**rowbits
84 self
.ncols
= 2**colbits
86 # Timings ----------------------------------------------------------------------------------
87 self
.init_timebase(spd_data
)
89 # most signifficant (upper) / least signifficant (lower) nibble
91 return _read_field(byte
, nbits
=4, shift
=4)
94 return _read_field(byte
, nbits
=4, shift
=0)
97 tck_min
= self
.txx_ns(mtb
=b
[12], ftb
=b
[34])
98 taa_min
= self
.txx_ns(mtb
=b
[16], ftb
=b
[35])
99 twr_min
= self
.txx_ns(mtb
=b
[17])
100 trcd_min
= self
.txx_ns(mtb
=b
[18], ftb
=b
[36])
101 trrd_min
= self
.txx_ns(mtb
=b
[19])
102 trp_min
= self
.txx_ns(mtb
=b
[20], ftb
=b
[37])
103 tras_min
= self
.txx_ns(mtb
=_word(lsn(b
[21]), b
[22]))
104 trc_min
= self
.txx_ns(mtb
=_word(msn(b
[21]), b
[23]), ftb
=b
[38])
105 trfc_min
= self
.txx_ns(mtb
=_word(b
[25], b
[24]))
106 twtr_min
= self
.txx_ns(mtb
=b
[26])
107 trtp_min
= self
.txx_ns(mtb
=b
[27])
108 tfaw_min
= self
.txx_ns(mtb
=_word(lsn(b
[28]), b
[29]))
110 technology_timings
= _TechnologyTimings(
111 tREFI
=64e6
/8192, # 64ms/8192ops
112 tWTR
=(4, twtr_min
), # min 4 cycles
113 tCCD
=(4, None), # min 4 cycles
114 tRRD
=(4, trrd_min
), # min 4 cycles
117 speedgrade_timings
= _SpeedgradeTimings(
121 tRFC
=(None, trfc_min
),
122 tFAW
=(None, tfaw_min
),
126 self
.speedgrade
= str(self
.speedgrade_freq(tck_min
))
127 self
.technology_timings
= technology_timings
128 self
.speedgrade_timings
= {
129 self
.speedgrade
: speedgrade_timings
,
130 "default": speedgrade_timings
,
133 def init_timebase(self
, data
):
134 # All the DDR3 timings are defined in the units of "timebase", which
135 # consists of medium timebase (nanosec) and fine timebase (picosec).
136 fine_timebase_dividend
= _read_field(data
[9], nbits
=4, shift
=4)
137 fine_timebase_divisor
= _read_field(data
[9], nbits
=4, shift
=0)
138 fine_timebase_ps
= fine_timebase_dividend
/ fine_timebase_divisor
139 self
.fine_timebase_ns
= fine_timebase_ps
* 1e-3
140 medium_timebase_dividend
= data
[10]
141 medium_timebase_divisor
= data
[11]
142 self
.medium_timebase_ns
= medium_timebase_dividend
/ medium_timebase_divisor
144 def txx_ns(self
, mtb
, ftb
=0):
145 """Get tXX in nanoseconds from medium and (optional) fine timebase."""
146 # decode FTB encoded in 8-bit two's complement
147 ftb
= _twos_complement(ftb
, 8)
148 return mtb
* self
.medium_timebase_ns
+ ftb
* self
.fine_timebase_ns
151 def speedgrade_freq(tck_ns
):
152 # Calculate rounded speedgrade frequency from tck_min
153 freq_mhz
= (1 / (tck_ns
* 1e-9)) / 1e6
154 freq_mhz
*= 2 # clock rate -> transfer rate (DDR)
155 speedgrades
= [800, 1066, 1333, 1600, 1866, 2133]
156 for f
in speedgrades
:
157 # Due to limited tck accuracy of 1ps, calculations may yield higher
158 # frequency than in reality (e.g. for DDR3-1866: tck=1.071 ns ->
159 # -> f=1867.4 MHz, while real is f=1866.6(6) MHz).
161 if abs(freq_mhz
- f
) < max_error
:
163 raise ValueError("Transfer rate = {:.2f} does not correspond to any DDR3 speedgrade"
167 def parse_spd_hexdump(filename
):
168 """Parse data dumped using the `spdread` command in LiteX BIOS
170 This will read files in format:
172 0x00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
173 0x00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................
177 with
open(filename
) as f
:
179 if line
.startswith("0x"):
180 tokens
= line
.strip().split()
181 addr
= int(tokens
[0], 16)
182 assert addr
> last_addr
183 values
= [int(v
, 16) for v
in tokens
[1:17]]
188 # SDRAMModule --------------------------------------------------------------------------------------
192 """SDRAM module geometry and timings.
194 SDRAM controller has to ensure that all geometry and
195 timings parameters are fulfilled. Timings parameters
196 can be expressed in ns, in SDRAM clock cycles or both
197 and controller needs to use the greater value.
199 SDRAM modules with the same geometry exist can have
204 def __init__(self
, clk_freq
, rate
, speedgrade
=None, fine_refresh_mode
=None):
205 self
.clk_freq
= clk_freq
207 self
.speedgrade
= speedgrade
208 self
.geom_settings
= GeomSettings(
209 bankbits
=log2_int(self
.nbanks
),
210 rowbits
=log2_int(self
.nrows
),
211 colbits
=log2_int(self
.ncols
),
213 assert not (self
.memtype
!= "DDR4" and fine_refresh_mode
!= None)
214 assert fine_refresh_mode
in [None, "1x", "2x", "4x"]
215 if (fine_refresh_mode
is None) and (self
.memtype
== "DDR4"):
216 fine_refresh_mode
= "1x"
217 self
.timing_settings
= TimingSettings(
218 tRP
=self
.ns_to_cycles(self
.get("tRP")),
219 tRCD
=self
.ns_to_cycles(self
.get("tRCD")),
220 tWR
=self
.ns_to_cycles(self
.get("tWR")),
221 tREFI
=self
.ns_to_cycles(
222 self
.get("tREFI", fine_refresh_mode
), False),
223 tRFC
=self
.ck_ns_to_cycles(*self
.get("tRFC", fine_refresh_mode
)),
224 tWTR
=self
.ck_ns_to_cycles(*self
.get("tWTR")),
225 tFAW
=None if self
.get("tFAW") is None else self
.ck_ns_to_cycles(
227 tCCD
=None if self
.get("tCCD") is None else self
.ck_ns_to_cycles(
229 tRRD
=None if self
.get("tRRD") is None else self
.ck_ns_to_cycles(
231 tRC
=None if self
.get("tRAS") is None else self
.ns_to_cycles(
232 self
.get("tRP") + self
.get("tRAS")),
233 tRAS
=None if self
.get(
234 "tRAS") is None else self
.ns_to_cycles(self
.get("tRAS")),
235 tZQCS
=None if self
.get(
236 "tZQCS") is None else self
.ck_ns_to_cycles(*self
.get("tZQCS"))
238 self
.timing_settings
.fine_refresh_mode
= fine_refresh_mode
240 def get(self
, name
, key
=None):
242 if name
in _speedgrade_timings
:
243 if hasattr(self
, "speedgrade_timings"):
244 speedgrade
= "default" if self
.speedgrade
is None else self
.speedgrade
245 r
= getattr(self
.speedgrade_timings
[speedgrade
], name
)
247 name
= name
+ "_" + self
.speedgrade
if self
.speedgrade
is not None else name
249 r
= getattr(self
, name
)
253 if hasattr(self
, "technology_timings"):
254 r
= getattr(self
.technology_timings
, name
)
257 r
= getattr(self
, name
)
260 if (r
is not None) and (key
is not None):
264 def ns_to_cycles(self
, t
, margin
=True):
265 clk_period_ns
= 1e9
/self
.clk_freq
269 "1:2": clk_period_ns
/2,
270 "1:4": 3*clk_period_ns
/4
272 t
+= margins
[self
.rate
]
273 return ceil(t
/clk_period_ns
)
275 def ck_to_cycles(self
, c
):
281 return ceil(c
/d
[self
.rate
])
283 def ck_ns_to_cycles(self
, c
, t
):
284 c
= 0 if c
is None else c
285 t
= 0 if t
is None else t
286 return max(self
.ck_to_cycles(c
), self
.ns_to_cycles(t
))
289 def from_spd_data(cls
, spd_data
, clk_freq
, fine_refresh_mode
=None):
290 # set parameters from SPD data based on memory type
294 spd
= spd_cls(spd_data
)
296 # Create a deriving class to avoid modifying this one
297 class _SDRAMModule(cls
):
298 memtype
= spd
.memtype
302 technology_timings
= spd
.technology_timings
303 speedgrade_timings
= spd
.speedgrade_timings
313 rate
= "1:{}".format(nphases
)
315 return _SDRAMModule(clk_freq
,
317 speedgrade
=spd
.speedgrade
,
318 fine_refresh_mode
=fine_refresh_mode
)
321 class SDRAMRegisteredModule(SDRAMModule
):
324 # DDR3 (Chips) -------------------------------------------------------------------------------------
327 class DDR3Module(SDRAMModule
):
331 class DDR3RegisteredModule(SDRAMRegisteredModule
):
335 class MT41K64M16(DDR3Module
):
342 technology_timings
= _TechnologyTimings(
343 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 10), tZQCS
=(64, 80))
344 speedgrade_timings
= {
345 "800": _SpeedgradeTimings(tRP
=13.1, tRCD
=13.1, tWR
=13.1, tRFC
=(64, None), tFAW
=(None, 50), tRAS
=37.5),
346 "1066": _SpeedgradeTimings(tRP
=13.1, tRCD
=13.1, tWR
=13.1, tRFC
=(86, None), tFAW
=(None, 50), tRAS
=37.5),
347 "1333": _SpeedgradeTimings(tRP
=13.5, tRCD
=13.5, tWR
=13.5, tRFC
=(107, None), tFAW
=(None, 45), tRAS
=36),
348 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=13.75, tRFC
=(128, None), tFAW
=(None, 40), tRAS
=35),
350 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
353 class MT41J128M16(DDR3Module
):
360 technology_timings
= _TechnologyTimings(
361 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 10), tZQCS
=(64, 80))
362 speedgrade_timings
= {
363 "800": _SpeedgradeTimings(tRP
=13.1, tRCD
=13.1, tWR
=13.1, tRFC
=(64, None), tFAW
=(None, 50), tRAS
=37.5),
364 "1066": _SpeedgradeTimings(tRP
=13.1, tRCD
=13.1, tWR
=13.1, tRFC
=(86, None), tFAW
=(None, 50), tRAS
=37.5),
365 "1333": _SpeedgradeTimings(tRP
=13.5, tRCD
=13.5, tWR
=13.5, tRFC
=(107, None), tFAW
=(None, 45), tRAS
=36),
366 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=13.75, tRFC
=(128, None), tFAW
=(None, 40), tRAS
=35),
368 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
371 class MT41K128M16(MT41J128M16
):
375 class MT41J256M16(DDR3Module
):
381 technology_timings
= _TechnologyTimings(
382 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 10), tZQCS
=(64, 80))
383 speedgrade_timings
= {
384 "800": _SpeedgradeTimings(tRP
=13.1, tRCD
=13.1, tWR
=13.1, tRFC
=(139, None), tFAW
=(None, 50), tRAS
=37.5),
385 "1066": _SpeedgradeTimings(tRP
=13.1, tRCD
=13.1, tWR
=13.1, tRFC
=(138, None), tFAW
=(None, 50), tRAS
=37.5),
386 "1333": _SpeedgradeTimings(tRP
=13.5, tRCD
=13.5, tWR
=13.5, tRFC
=(174, None), tFAW
=(None, 45), tRAS
=36),
387 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=13.75, tRFC
=(208, None), tFAW
=(None, 40), tRAS
=35),
389 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
392 class MT41K256M16(MT41J256M16
):
396 class MT41J512M16(DDR3Module
):
402 technology_timings
= _TechnologyTimings(
403 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 10), tZQCS
=(64, 80))
404 speedgrade_timings
= {
405 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=13.75, tRFC
=(280, None), tFAW
=(None, 40), tRAS
=39),
407 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
410 class MT41K512M16(MT41J512M16
):
414 class K4B1G0446F(DDR3Module
):
420 technology_timings
= _TechnologyTimings(
421 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 10), tZQCS
=(64, 80))
422 speedgrade_timings
= {
423 "800": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(120, None), tFAW
=(None, 50), tRAS
=37.5),
424 "1066": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(160, None), tFAW
=(None, 50), tRAS
=37.5),
425 "1333": _SpeedgradeTimings(tRP
=13.5, tRCD
=13.5, tWR
=15, tRFC
=(200, None), tFAW
=(None, 45), tRAS
=36),
426 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=15, tRFC
=(240, None), tFAW
=(None, 40), tRAS
=35),
428 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
431 class K4B2G1646F(DDR3Module
):
437 technology_timings
= _TechnologyTimings(
438 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 10), tZQCS
=(64, 80))
439 speedgrade_timings
= {
440 "800": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(104, None), tFAW
=(None, 50), tRAS
=37.5),
441 "1066": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(139, None), tFAW
=(None, 50), tRAS
=37.5),
442 "1333": _SpeedgradeTimings(tRP
=13.5, tRCD
=13.5, tWR
=15, tRFC
=(174, None), tFAW
=(None, 45), tRAS
=36),
443 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=15, tRFC
=(208, None), tFAW
=(None, 40), tRAS
=35),
445 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
448 class H5TC4G63CFR(DDR3Module
):
454 technology_timings
= _TechnologyTimings(
455 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 7.5), tZQCS
=(64, 80))
456 speedgrade_timings
= {
457 "800": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(260, None), tFAW
=(None, 40), tRAS
=37.5),
459 speedgrade_timings
["default"] = speedgrade_timings
["800"]
462 class IS43TR16128B(DDR3Module
):
468 technology_timings
= _TechnologyTimings(
469 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 6), tZQCS
=(64, 80))
470 speedgrade_timings
= {
471 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=15, tRFC
=(None, 160), tFAW
=(None, 40), tRAS
=35),
473 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
476 # DDR3 (SO-DIMM) -----------------------------------------------------------------------------------
478 class MT8JTF12864(DDR3Module
):
479 # base chip: MT41J128M8
485 technology_timings
= _TechnologyTimings(
486 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 6), tZQCS
=(64, 80))
487 speedgrade_timings
= {
488 "1066": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 110), tFAW
=(None, 37.5), tRAS
=37.5),
489 "1333": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 110), tFAW
=(None, 30), tRAS
=36),
491 speedgrade_timings
["default"] = speedgrade_timings
["1333"]
494 class MT8KTF51264(DDR3Module
):
495 # base chip: MT41K512M8
501 technology_timings
= _TechnologyTimings(
502 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 6), tZQCS
=(64, 80))
503 speedgrade_timings
= {
504 "800": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 40), tRAS
=37.5),
505 "1066": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 40), tRAS
=37.5),
506 "1333": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 30), tRAS
=36),
507 "1600": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 30), tRAS
=35),
508 "1866": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 27), tRAS
=34),
510 speedgrade_timings
["default"] = speedgrade_timings
["1866"]
513 class MT18KSF1G72HZ(DDR3Module
):
514 # base chip: MT41K512M8
520 technology_timings
= _TechnologyTimings(
521 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 6), tZQCS
=(64, 80))
522 speedgrade_timings
= {
523 "1066": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 40), tRAS
=37.5),
524 "1333": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 30), tRAS
=36),
525 "1600": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 30), tRAS
=35),
527 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
530 class AS4C256M16D3A(DDR3Module
):
536 technology_timings
= _TechnologyTimings(
537 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 7.5), tZQCS
=(64, 80))
538 speedgrade_timings
= {
539 "1600": _SpeedgradeTimings(tRP
=13.75, tRCD
=13.75, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 40), tRAS
=35),
541 speedgrade_timings
["default"] = speedgrade_timings
["1600"]
544 class MT16KTF1G64HZ(DDR3Module
):
545 # base chip: MT41K512M8
551 technology_timings
= _TechnologyTimings(
552 tREFI
=64e6
/8192, tWTR
=(4, 7.5), tCCD
=(4, None), tRRD
=(4, 6), tZQCS
=(64, 80))
553 speedgrade_timings
= {
554 "800": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 40), tRAS
=37.5),
555 "1066": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 40), tRAS
=37.5),
556 "1333": _SpeedgradeTimings(tRP
=15, tRCD
=15, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 30), tRAS
=36),
557 "1600": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 30), tRAS
=35),
558 "1866": _SpeedgradeTimings(tRP
=13.125, tRCD
=13.125, tWR
=15, tRFC
=(None, 260), tFAW
=(None, 27), tRAS
=34),
560 speedgrade_timings
["default"] = speedgrade_timings
["1866"]
563 # DDR4 (Chips) -------------------------------------------------------------------------------------
565 class DDR4Module(SDRAMModule
):
569 class DDR4RegisteredModule(SDRAMRegisteredModule
):
573 class EDY4016A(DDR4Module
):
577 nbanks
= ngroups
* ngroupbanks
581 trefi
= {"1x": 64e6
/8192, "2x": (64e6
/8192)/2, "4x": (64e6
/8192)/4}
582 trfc
= {"1x": (None, 260), "2x": (None, 160), "4x": (None, 110)}
583 technology_timings
= _TechnologyTimings(tREFI
=trefi
, tWTR
=(
584 4, 7.5), tCCD
=(4, None), tRRD
=(4, 4.9), tZQCS
=(128, 80))
585 speedgrade_timings
= {
586 "2400": _SpeedgradeTimings(tRP
=13.32, tRCD
=13.32, tWR
=15, tRFC
=trfc
, tFAW
=(28, 30), tRAS
=32),
588 speedgrade_timings
["default"] = speedgrade_timings
["2400"]
591 class MT40A1G8(DDR4Module
):
595 nbanks
= ngroups
* ngroupbanks
599 trefi
= {"1x": 64e6
/8192, "2x": (64e6
/8192)/2, "4x": (64e6
/8192)/4}
600 trfc
= {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
601 technology_timings
= _TechnologyTimings(tREFI
=trefi
, tWTR
=(
602 4, 7.5), tCCD
=(4, None), tRRD
=(4, 6.4), tZQCS
=(128, 80))
603 speedgrade_timings
= {
604 "2400": _SpeedgradeTimings(tRP
=13.32, tRCD
=13.32, tWR
=15, tRFC
=trfc
, tFAW
=(20, 25), tRAS
=32),
605 "2666": _SpeedgradeTimings(tRP
=13.50, tRCD
=13.50, tWR
=15, tRFC
=trfc
, tFAW
=(20, 21), tRAS
=32),
607 speedgrade_timings
["default"] = speedgrade_timings
["2400"]
610 class MT40A256M16(DDR4Module
):
614 nbanks
= ngroups
* ngroupbanks
618 trefi
= {"1x": 64e6
/8192, "2x": (64e6
/8192)/2, "4x": (64e6
/8192)/4}
619 trfc
= {"1x": (None, 260), "2x": (None, 160), "4x": (None, 110)}
620 technology_timings
= _TechnologyTimings(tREFI
=trefi
, tWTR
=(
621 4, 7.5), tCCD
=(4, None), tRRD
=(4, 4.9), tZQCS
=(128, 80))
622 speedgrade_timings
= {
623 "2400": _SpeedgradeTimings(tRP
=13.32, tRCD
=13.32, tWR
=15, tRFC
=trfc
, tFAW
=(28, 35), tRAS
=32),
625 speedgrade_timings
["default"] = speedgrade_timings
["2400"]
628 class MT40A512M8(DDR4Module
):
632 nbanks
= ngroups
* ngroupbanks
636 trefi
= {"1x": 64e6
/8192, "2x": (64e6
/8192)/2, "4x": (64e6
/8192)/4}
637 trfc
= {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
638 technology_timings
= _TechnologyTimings(tREFI
=trefi
, tWTR
=(
639 4, 7.5), tCCD
=(4, None), tRRD
=(4, 4.9), tZQCS
=(128, 80))
640 speedgrade_timings
= {
641 "2400": _SpeedgradeTimings(tRP
=13.32, tRCD
=13.32, tWR
=15, tRFC
=trfc
, tFAW
=(20, 25), tRAS
=32),
642 "2666": _SpeedgradeTimings(tRP
=13.50, tRCD
=13.50, tWR
=15, tRFC
=trfc
, tFAW
=(20, 21), tRAS
=32),
644 speedgrade_timings
["default"] = speedgrade_timings
["2400"]
647 class MT40A512M16(DDR4Module
):
651 nbanks
= ngroups
* ngroupbanks
655 trefi
= {"1x": 64e6
/8192, "2x": (64e6
/8192)/2, "4x": (64e6
/8192)/4}
656 trfc
= {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
657 technology_timings
= _TechnologyTimings(tREFI
=trefi
, tWTR
=(
658 4, 7.5), tCCD
=(4, None), tRRD
=(4, 4.9), tZQCS
=(128, 80))
659 speedgrade_timings
= {
660 "2400": _SpeedgradeTimings(tRP
=13.32, tRCD
=13.32, tWR
=15, tRFC
=trfc
, tFAW
=(20, 25), tRAS
=32),
662 speedgrade_timings
["default"] = speedgrade_timings
["2400"]