More nMigen conversion and fixes
[gram.git] / gram / modules.py
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>
13 # License: BSD
14
15 from math import ceil
16 from collections import namedtuple
17
18 from nmigen.utils import log2_int
19
20 from gram.common import Settings, GeomSettings, TimingSettings
21
22 # Timings ------------------------------------------------------------------------------------------
23
24 _technology_timings = ["tREFI", "tWTR", "tCCD", "tRRD", "tZQCS"]
25
26 class _TechnologyTimings(Settings):
27 def __init__(self, tREFI, tWTR, tCCD, tRRD, tZQCS=None):
28 self.set_attributes(locals())
29
30
31 _speedgrade_timings = ["tRP", "tRCD", "tWR", "tRFC", "tFAW", "tRAS"]
32
33 class _SpeedgradeTimings(Settings):
34 def __init__(self, tRP, tRCD, tWR, tRFC, tFAW, tRAS):
35 self.set_attributes(locals())
36
37 # SPD ----------------------------------------------------------------------------------------------
38
39 def _read_field(byte, nbits, shift):
40 mask = 2**nbits - 1
41 return (byte & (mask << shift)) >> shift
42
43 def _twos_complement(value, nbits):
44 if value & (1 << (nbits - 1)):
45 value -= (1 << nbits)
46 return value
47
48 def _word(msb, lsb):
49 return (msb << 8) | lsb
50
51
52 class DDR3SPDData:
53 memtype = "DDR3"
54
55 def __init__(self, spd_data):
56 # Geometry ---------------------------------------------------------------------------------
57 bankbits = {
58 0b000: 3,
59 0b001: 4,
60 0b010: 5,
61 0b011: 6,
62 }[_read_field(spd_data[4], nbits=3, shift=4)]
63 rowbits = {
64 0b000: 12,
65 0b001: 13,
66 0b010: 14,
67 0b011: 15,
68 0b100: 16,
69 }[_read_field(spd_data[5], nbits=3, shift=3)]
70 colbits = {
71 0b000: 9,
72 0b001: 10,
73 0b010: 11,
74 0b011: 12,
75 }[_read_field(spd_data[5], nbits=3, shift=0)]
76
77 self.nbanks = 2**bankbits
78 self.nrows = 2**rowbits
79 self.ncols = 2**colbits
80
81 # Timings ----------------------------------------------------------------------------------
82 self.init_timebase(spd_data)
83
84 # most signifficant (upper) / least signifficant (lower) nibble
85 def msn(byte):
86 return _read_field(byte, nbits=4, shift=4)
87
88 def lsn(byte):
89 return _read_field(byte, nbits=4, shift=0)
90
91 b = spd_data
92 tck_min = self.txx_ns(mtb=b[12], ftb=b[34])
93 taa_min = self.txx_ns(mtb=b[16], ftb=b[35])
94 twr_min = self.txx_ns(mtb=b[17])
95 trcd_min = self.txx_ns(mtb=b[18], ftb=b[36])
96 trrd_min = self.txx_ns(mtb=b[19])
97 trp_min = self.txx_ns(mtb=b[20], ftb=b[37])
98 tras_min = self.txx_ns(mtb=_word(lsn(b[21]), b[22]))
99 trc_min = self.txx_ns(mtb=_word(msn(b[21]), b[23]), ftb=b[38])
100 trfc_min = self.txx_ns(mtb=_word(b[25], b[24]))
101 twtr_min = self.txx_ns(mtb=b[26])
102 trtp_min = self.txx_ns(mtb=b[27])
103 tfaw_min = self.txx_ns(mtb=_word(lsn(b[28]), b[29]))
104
105 technology_timings = _TechnologyTimings(
106 tREFI = 64e6/8192, # 64ms/8192ops
107 tWTR = (4, twtr_min), # min 4 cycles
108 tCCD = (4, None), # min 4 cycles
109 tRRD = (4, trrd_min), # min 4 cycles
110 tZQCS = (64, 80),
111 )
112 speedgrade_timings = _SpeedgradeTimings(
113 tRP = trp_min,
114 tRCD = trcd_min,
115 tWR = twr_min,
116 tRFC = (None, trfc_min),
117 tFAW = (None, tfaw_min),
118 tRAS = tras_min,
119 )
120
121 self.speedgrade = str(self.speedgrade_freq(tck_min))
122 self.technology_timings = technology_timings
123 self.speedgrade_timings = {
124 self.speedgrade: speedgrade_timings,
125 "default": speedgrade_timings,
126 }
127
128 def init_timebase(self, data):
129 # All the DDR3 timings are defined in the units of "timebase", which
130 # consists of medium timebase (nanosec) and fine timebase (picosec).
131 fine_timebase_dividend = _read_field(data[9], nbits=4, shift=4)
132 fine_timebase_divisor = _read_field(data[9], nbits=4, shift=0)
133 fine_timebase_ps = fine_timebase_dividend / fine_timebase_divisor
134 self.fine_timebase_ns = fine_timebase_ps * 1e-3
135 medium_timebase_dividend = data[10]
136 medium_timebase_divisor = data[11]
137 self.medium_timebase_ns = medium_timebase_dividend / medium_timebase_divisor
138
139 def txx_ns(self, mtb, ftb=0):
140 """Get tXX in nanoseconds from medium and (optional) fine timebase."""
141 # decode FTB encoded in 8-bit two's complement
142 ftb = _twos_complement(ftb, 8)
143 return mtb * self.medium_timebase_ns + ftb * self.fine_timebase_ns
144
145 @staticmethod
146 def speedgrade_freq(tck_ns):
147 # Calculate rounded speedgrade frequency from tck_min
148 freq_mhz = (1 / (tck_ns * 1e-9)) / 1e6
149 freq_mhz *= 2 # clock rate -> transfer rate (DDR)
150 speedgrades = [800, 1066, 1333, 1600, 1866, 2133]
151 for f in speedgrades:
152 # Due to limited tck accuracy of 1ps, calculations may yield higher
153 # frequency than in reality (e.g. for DDR3-1866: tck=1.071 ns ->
154 # -> f=1867.4 MHz, while real is f=1866.6(6) MHz).
155 max_error = 2
156 if abs(freq_mhz - f) < max_error:
157 return f
158 raise ValueError("Transfer rate = {:.2f} does not correspond to any DDR3 speedgrade"
159 .format(freq_mhz))
160
161 def parse_spd_hexdump(filename):
162 """Parse data dumped using the `spdread` command in LiteX BIOS
163
164 This will read files in format:
165 Memory dump:
166 0x00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
167 0x00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................
168 """
169 data = []
170 last_addr = -1
171 with open(filename) as f:
172 for line in f:
173 if line.startswith("0x"):
174 tokens = line.strip().split()
175 addr = int(tokens[0], 16)
176 assert addr > last_addr
177 values = [int(v, 16) for v in tokens[1:17]]
178 data.extend(values)
179 last_addr = addr
180 return data
181
182 # SDRAMModule --------------------------------------------------------------------------------------
183
184 class SDRAMModule:
185 """SDRAM module geometry and timings.
186
187 SDRAM controller has to ensure that all geometry and
188 timings parameters are fulfilled. Timings parameters
189 can be expressed in ns, in SDRAM clock cycles or both
190 and controller needs to use the greater value.
191
192 SDRAM modules with the same geometry exist can have
193 various speedgrades.
194 """
195 registered = False
196 def __init__(self, clk_freq, rate, speedgrade=None, fine_refresh_mode=None):
197 self.clk_freq = clk_freq
198 self.rate = rate
199 self.speedgrade = speedgrade
200 self.geom_settings = GeomSettings(
201 bankbits = log2_int(self.nbanks),
202 rowbits = log2_int(self.nrows),
203 colbits = log2_int(self.ncols),
204 )
205 assert not (self.memtype != "DDR4" and fine_refresh_mode != None)
206 assert fine_refresh_mode in [None, "1x", "2x", "4x"]
207 if (fine_refresh_mode is None) and (self.memtype == "DDR4"):
208 fine_refresh_mode = "1x"
209 self.timing_settings = TimingSettings(
210 tRP = self.ns_to_cycles(self.get("tRP")),
211 tRCD = self.ns_to_cycles(self.get("tRCD")),
212 tWR = self.ns_to_cycles(self.get("tWR")),
213 tREFI = self.ns_to_cycles(self.get("tREFI", fine_refresh_mode), False),
214 tRFC = self.ck_ns_to_cycles(*self.get("tRFC", fine_refresh_mode)),
215 tWTR = self.ck_ns_to_cycles(*self.get("tWTR")),
216 tFAW = None if self.get("tFAW") is None else self.ck_ns_to_cycles(*self.get("tFAW")),
217 tCCD = None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")),
218 tRRD = None if self.get("tRRD") is None else self.ck_ns_to_cycles(*self.get("tRRD")),
219 tRC = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRP") + self.get("tRAS")),
220 tRAS = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS")),
221 tZQCS = None if self.get("tZQCS") is None else self.ck_ns_to_cycles(*self.get("tZQCS"))
222 )
223 self.timing_settings.fine_refresh_mode = fine_refresh_mode
224
225 def get(self, name, key=None):
226 r = None
227 if name in _speedgrade_timings:
228 if hasattr(self, "speedgrade_timings"):
229 speedgrade = "default" if self.speedgrade is None else self.speedgrade
230 r = getattr(self.speedgrade_timings[speedgrade], name)
231 else:
232 name = name + "_" + self.speedgrade if self.speedgrade is not None else name
233 try:
234 r = getattr(self, name)
235 except:
236 pass
237 else:
238 if hasattr(self, "technology_timings"):
239 r = getattr(self.technology_timings, name)
240 else:
241 try:
242 r = getattr(self, name)
243 except:
244 pass
245 if (r is not None) and (key is not None):
246 r = r[key]
247 return r
248
249 def ns_to_cycles(self, t, margin=True):
250 clk_period_ns = 1e9/self.clk_freq
251 if margin:
252 margins = {
253 "1:1" : 0,
254 "1:2" : clk_period_ns/2,
255 "1:4" : 3*clk_period_ns/4
256 }
257 t += margins[self.rate]
258 return ceil(t/clk_period_ns)
259
260 def ck_to_cycles(self, c):
261 d = {
262 "1:1" : 1,
263 "1:2" : 2,
264 "1:4" : 4
265 }
266 return ceil(c/d[self.rate])
267
268 def ck_ns_to_cycles(self, c, t):
269 c = 0 if c is None else c
270 t = 0 if t is None else t
271 return max(self.ck_to_cycles(c), self.ns_to_cycles(t))
272
273 @classmethod
274 def from_spd_data(cls, spd_data, clk_freq, fine_refresh_mode=None):
275 # set parameters from SPD data based on memory type
276 spd_cls = {
277 0x0b: DDR3SPDData,
278 }[spd_data[2]]
279 spd = spd_cls(spd_data)
280
281 # Create a deriving class to avoid modifying this one
282 class _SDRAMModule(cls):
283 memtype = spd.memtype
284 nbanks = spd.nbanks
285 nrows = spd.nrows
286 ncols = spd.ncols
287 technology_timings = spd.technology_timings
288 speedgrade_timings = spd.speedgrade_timings
289
290 nphases = {
291 "SDR": 1,
292 "DDR": 2,
293 "LPDDR": 2,
294 "DDR2": 2,
295 "DDR3": 4,
296 "DDR4": 4,
297 }[spd.memtype]
298 rate = "1:{}".format(nphases)
299
300 return _SDRAMModule(clk_freq,
301 rate = rate,
302 speedgrade = spd.speedgrade,
303 fine_refresh_mode = fine_refresh_mode)
304
305 class SDRAMRegisteredModule(SDRAMModule): registered = True
306
307 # SDR ----------------------------------------------------------------------------------------------
308
309 class SDRModule(SDRAMModule): memtype = "SDR"
310 class SDRRegisteredModule(SDRAMRegisteredModule): memtype = "SDR"
311
312 class IS42S16160(SDRModule):
313 # geometry
314 nbanks = 4
315 nrows = 8192
316 ncols = 512
317 # timings
318 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
319 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=20, tRFC=(None, 70), tFAW=None, tRAS=None)}
320
321 class IS42S16320(SDRModule):
322 # geometry
323 nbanks = 4
324 nrows = 8192
325 ncols = 1024
326 # timings
327 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
328 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=20, tRFC=(None, 70), tFAW=None, tRAS=None)}
329
330 class MT48LC4M16(SDRModule):
331 # geometry
332 nbanks = 4
333 nrows = 4096
334 ncols = 256
335 # timings
336 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
337 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=14, tRFC=(None, 66), tFAW=None, tRAS=None)}
338
339 class MT48LC16M16(SDRModule):
340 # geometry
341 nbanks = 4
342 nrows = 8192
343 ncols = 512
344 # timings
345 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 15))
346 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=15, tRFC=(None, 66), tFAW=None, tRAS=44)}
347
348 class AS4C16M16(SDRModule):
349 # geometry
350 nbanks = 4
351 nrows = 8192
352 ncols = 512
353 # timings
354 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
355 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=18, tRCD=18, tWR=12, tRFC=(None, 60), tFAW=None, tRAS=None)}
356
357 class AS4C32M16(SDRModule):
358 # geometry
359 nbanks = 4
360 nrows = 8192
361 ncols = 1024
362 # timings
363 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
364 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=18, tRCD=18, tWR=12, tRFC=(None, 60), tFAW=None, tRAS=None)}
365
366 class AS4C32M8(SDRModule):
367 # geometry
368 nbanks = 4
369 nrows = 8192
370 ncols = 1024
371 # timings
372 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 15))
373 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, tRCD=20, tWR=15, tRFC=(None, 66), tFAW=None, tRAS=44)}
374
375 class M12L64322A(SDRModule):
376 # geometry
377 nbanks = 4
378 nrows = 2048
379 ncols = 256
380 # timings
381 technology_timings = _TechnologyTimings(tREFI=64e6/4096, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 10))
382 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 55), tFAW=None, tRAS=40)}
383
384 class M12L16161A(SDRModule):
385 # geometry
386 nbanks = 2
387 nrows = 2048
388 ncols = 256
389 # timings
390 technology_timings = _TechnologyTimings(tREFI=64e6/4096, tWTR=(2, None), tCCD=(1, None), tRRD=(None, 10))
391 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 55), tFAW=None, tRAS=40)}
392
393 # DDR ----------------------------------------------------------------------------------------------
394
395 class DDRModule(SDRAMModule): memtype = "DDR"
396 class DDRRegisteredModule(SDRAMRegisteredModule): memtype = "DDR"
397
398 class MT46V32M16(SDRAMModule):
399 memtype = "DDR"
400 # geometry
401 nbanks = 4
402 nrows = 8192
403 ncols = 1024
404 # timings
405 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
406 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 70), tFAW=None, tRAS=None)}
407
408 # LPDDR --------------------------------------------------------------------------------------------
409
410 class LPDDRModule(SDRAMModule): memtype = "LPDDR"
411 class LPDDRRegisteredModule(SDRAMRegisteredModule): memtype = "LPDDR"
412
413 class MT46H32M16(LPDDRModule):
414 # geometry
415 nbanks = 4
416 nrows = 8192
417 ncols = 1024
418 # timings
419 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
420 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 72), tFAW=None, tRAS=None)}
421
422 class MT46H32M32(LPDDRModule):
423 # geometry
424 nbanks = 4
425 nrows = 8192
426 ncols = 1024
427 # timings
428 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(2, None), tCCD=(1, None), tRRD=None)
429 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 72), tFAW=None, tRAS=None)}
430
431 # DDR2 ---------------------------------------------------------------------------------------------
432
433 class DDR2Module(SDRAMModule): memtype = "DDR2"
434 class DDR2RegisteredModule(SDRAMRegisteredModule): memtype = "DDR2"
435
436 class MT47H128M8(DDR2Module):
437 memtype = "DDR2"
438 # geometry
439 nbanks = 8
440 nrows = 16384
441 ncols = 1024
442 # timings
443 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
444 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
445
446 class MT47H32M16(DDR2Module):
447 memtype = "DDR2"
448 # geometry
449 nbanks = 4
450 nrows = 8192
451 ncols = 1024
452 # timings
453 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
454 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
455
456 class MT47H64M16(DDR2Module):
457 memtype = "DDR2"
458 # geometry
459 nbanks = 8
460 nrows = 8192
461 ncols = 1024
462 # timings
463 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
464 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
465
466 class P3R1GE4JGF(DDR2Module):
467 memtype = "DDR2"
468 # geometry
469 nbanks = 8
470 nrows = 8192
471 ncols = 1024
472 # timings
473 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(None, 7.5), tCCD=(2, None), tRRD=None)
474 speedgrade_timings = {"default": _SpeedgradeTimings(tRP=12.5, tRCD=12.5, tWR=15, tRFC=(None, 127.5), tFAW=None, tRAS=None)}
475
476 # DDR3 (Chips) -------------------------------------------------------------------------------------
477
478 class DDR3Module(SDRAMModule): memtype = "DDR3"
479 class DDR3RegisteredModule(SDRAMRegisteredModule): memtype = "DDR3"
480
481 class MT41K64M16(DDR3Module):
482 memtype = "DDR3"
483 # geometry
484 nbanks = 8
485 nrows = 8192
486 ncols = 1024
487 # timings
488 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
489 speedgrade_timings = {
490 "800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(64, None), tFAW=(None, 50), tRAS=37.5),
491 "1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(86, None), tFAW=(None, 50), tRAS=37.5),
492 "1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=13.5, tRFC=(107, None), tFAW=(None, 45), tRAS=36),
493 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(128, None), tFAW=(None, 40), tRAS=35),
494 }
495 speedgrade_timings["default"] = speedgrade_timings["1600"]
496
497 class MT41J128M16(DDR3Module):
498 memtype = "DDR3"
499 # geometry
500 nbanks = 8
501 nrows = 16384
502 ncols = 1024
503 # timings
504 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
505 speedgrade_timings = {
506 "800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(64, None), tFAW=(None, 50), tRAS=37.5),
507 "1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(86, None), tFAW=(None, 50), tRAS=37.5),
508 "1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=13.5, tRFC=(107, None), tFAW=(None, 45), tRAS=36),
509 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(128, None), tFAW=(None, 40), tRAS=35),
510 }
511 speedgrade_timings["default"] = speedgrade_timings["1600"]
512
513 class MT41K128M16(MT41J128M16): pass
514
515 class MT41J256M16(DDR3Module):
516 # geometry
517 nbanks = 8
518 nrows = 32768
519 ncols = 1024
520 # timings
521 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
522 speedgrade_timings = {
523 "800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(139, None), tFAW=(None, 50), tRAS=37.5),
524 "1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(138, None), tFAW=(None, 50), tRAS=37.5),
525 "1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=13.5, tRFC=(174, None), tFAW=(None, 45), tRAS=36),
526 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(208, None), tFAW=(None, 40), tRAS=35),
527 }
528 speedgrade_timings["default"] = speedgrade_timings["1600"]
529
530 class MT41K256M16(MT41J256M16): pass
531
532 class MT41J512M16(DDR3Module):
533 # geometry
534 nbanks = 8
535 nrows = 65536
536 ncols = 1024
537 # timings
538 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
539 speedgrade_timings = {
540 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=13.75, tRFC=(280, None), tFAW=(None, 40), tRAS=39),
541 }
542 speedgrade_timings["default"] = speedgrade_timings["1600"]
543
544 class MT41K512M16(MT41J512M16): pass
545
546 class K4B1G0446F(DDR3Module):
547 # geometry
548 nbanks = 8
549 nrows = 16384
550 ncols = 1024
551 # timings
552 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
553 speedgrade_timings = {
554 "800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(120, None), tFAW=(None, 50), tRAS=37.5),
555 "1066": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(160, None), tFAW=(None, 50), tRAS=37.5),
556 "1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=(200, None), tFAW=(None, 45), tRAS=36),
557 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(240, None), tFAW=(None, 40), tRAS=35),
558 }
559 speedgrade_timings["default"] = speedgrade_timings["1600"]
560
561 class K4B2G1646F(DDR3Module):
562 # geometry
563 nbanks = 8
564 nrows = 16384
565 ncols = 1024
566 # timings
567 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
568 speedgrade_timings = {
569 "800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(104, None), tFAW=(None, 50), tRAS=37.5),
570 "1066": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(139, None), tFAW=(None, 50), tRAS=37.5),
571 "1333": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=(174, None), tFAW=(None, 45), tRAS=36),
572 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(208, None), tFAW=(None, 40), tRAS=35),
573 }
574 speedgrade_timings["default"] = speedgrade_timings["1600"]
575
576 class H5TC4G63CFR(DDR3Module):
577 # geometry
578 nbanks = 8
579 nrows = 16384
580 ncols = 1024
581 # timings
582 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 7.5), tZQCS=(64, 80))
583 speedgrade_timings = {
584 "800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(260, None), tFAW=(None, 40), tRAS=37.5),
585 }
586 speedgrade_timings["default"] = speedgrade_timings["800"]
587
588 class IS43TR16128B(DDR3Module):
589 # geometry
590 nbanks = 8
591 nrows = 16384
592 ncols = 1024
593 # timings
594 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
595 speedgrade_timings = {
596 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 160), tFAW=(None, 40), tRAS=35),
597 }
598 speedgrade_timings["default"] = speedgrade_timings["1600"]
599
600
601 # DDR3 (SO-DIMM) -----------------------------------------------------------------------------------
602
603 class MT8JTF12864(DDR3Module):
604 # base chip: MT41J128M8
605 # geometry
606 nbanks = 8
607 nrows = 16384
608 ncols = 1024
609 # timings
610 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
611 speedgrade_timings = {
612 "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 110), tFAW=(None, 37.5), tRAS=37.5),
613 "1333": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 110), tFAW=(None, 30), tRAS=36),
614 }
615 speedgrade_timings["default"] = speedgrade_timings["1333"]
616
617 class MT8KTF51264(DDR3Module):
618 # base chip: MT41K512M8
619 # geometry
620 nbanks = 8
621 nrows = 65536
622 ncols = 1024
623 # timings
624 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
625 speedgrade_timings = {
626 "800" : _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
627 "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
628 "1333": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=36),
629 "1600": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=35),
630 "1866": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 27), tRAS=34),
631 }
632 speedgrade_timings["default"] = speedgrade_timings["1866"]
633
634 class MT18KSF1G72HZ(DDR3Module):
635 # base chip: MT41K512M8
636 # geometry
637 nbanks = 8
638 nrows = 65536
639 ncols = 1024
640 # timings
641 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
642 speedgrade_timings = {
643 "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
644 "1333": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=36),
645 "1600": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=35),
646 }
647 speedgrade_timings["default"] = speedgrade_timings["1600"]
648
649 class AS4C256M16D3A(DDR3Module):
650 # geometry
651 nbanks = 8
652 nrows = 32768
653 ncols = 1024
654 # timings
655 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 7.5), tZQCS=(64, 80))
656 speedgrade_timings = {
657 "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=35),
658 }
659 speedgrade_timings["default"] = speedgrade_timings["1600"]
660
661 class MT16KTF1G64HZ(DDR3Module):
662 # base chip: MT41K512M8
663 # geometry
664 nbanks = 8
665 nrows = 65536
666 ncols = 1024
667 # timings
668 technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
669 speedgrade_timings = {
670 "800" : _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
671 "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=37.5),
672 "1333": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=36),
673 "1600": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 30), tRAS=35),
674 "1866": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(None, 260), tFAW=(None, 27), tRAS=34),
675 }
676 speedgrade_timings["default"] = speedgrade_timings["1866"]
677
678
679 # DDR4 (Chips) -------------------------------------------------------------------------------------
680
681 class DDR4Module(SDRAMModule): memtype = "DDR4"
682 class DDR4RegisteredModule(SDRAMRegisteredModule): memtype = "DDR4"
683
684 class EDY4016A(DDR4Module):
685 # geometry
686 ngroupbanks = 4
687 ngroups = 2
688 nbanks = ngroups * ngroupbanks
689 nrows = 32768
690 ncols = 1024
691 # timings
692 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
693 trfc = {"1x": (None, 260), "2x": (None, 160), "4x": (None, 110)}
694 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
695 speedgrade_timings = {
696 "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(28, 30), tRAS=32),
697 }
698 speedgrade_timings["default"] = speedgrade_timings["2400"]
699
700 class MT40A1G8(DDR4Module):
701 # geometry
702 ngroupbanks = 4
703 ngroups = 4
704 nbanks = ngroups * ngroupbanks
705 nrows = 65536
706 ncols = 1024
707 # timings
708 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
709 trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
710 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4), tZQCS=(128, 80))
711 speedgrade_timings = {
712 "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
713 "2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=trfc, tFAW=(20, 21), tRAS=32),
714 }
715 speedgrade_timings["default"] = speedgrade_timings["2400"]
716
717 class MT40A256M16(DDR4Module):
718 # geometry
719 ngroupbanks = 4
720 ngroups = 2
721 nbanks = ngroups * ngroupbanks
722 nrows = 32768
723 ncols = 1024
724 # timings
725 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
726 trfc = {"1x": (None, 260), "2x": (None, 160), "4x": (None, 110)}
727 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
728 speedgrade_timings = {
729 "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(28, 35), tRAS=32),
730 }
731 speedgrade_timings["default"] = speedgrade_timings["2400"]
732
733 class MT40A512M8(DDR4Module):
734 # geometry
735 ngroupbanks = 4
736 ngroups = 4
737 nbanks = ngroups * ngroupbanks
738 nrows = 32768
739 ncols = 1024
740 # timings
741 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
742 trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
743 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
744 speedgrade_timings = {
745 "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
746 "2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=trfc, tFAW=(20, 21), tRAS=32),
747 }
748 speedgrade_timings["default"] = speedgrade_timings["2400"]
749
750 class MT40A512M16(DDR4Module):
751 # geometry
752 ngroupbanks = 4
753 ngroups = 2
754 nbanks = ngroups * ngroupbanks
755 nrows = 65536
756 ncols = 1024
757 # timings
758 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
759 trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
760 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
761 speedgrade_timings = {
762 "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
763 }
764 speedgrade_timings["default"] = speedgrade_timings["2400"]
765
766 # DDR4 (SO-DIMM) -----------------------------------------------------------------------------------
767
768 class KVR21SE15S84(DDR4Module):
769 # geometry
770 ngroupbanks = 4
771 ngroups = 4
772 nbanks = ngroups * ngroupbanks
773 nrows = 32768
774 ncols = 1024
775 # timings
776 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
777 trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
778 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
779 speedgrade_timings = {
780 "2133": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=33),
781 }
782 speedgrade_timings["default"] = speedgrade_timings["2133"]
783
784 class MTA4ATF51264HZ(DDR4Module):
785 # geometry
786 ngroupbanks = 4
787 ngroups = 2
788 nbanks = ngroups * ngroupbanks
789 nrows = 65536
790 ncols = 1024
791 # timings
792 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
793 trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
794 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
795 speedgrade_timings = {
796 "2133": _SpeedgradeTimings(tRP=13.5, tRCD=13.5, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=33),
797 }
798 speedgrade_timings["default"] = speedgrade_timings["2133"]
799
800 # DDR4 (RDIMM) -------------------------------------------------------------------------------------
801
802 class MTA18ASF2G72PZ(DDR4RegisteredModule):
803 # geometry
804 ngroupbanks = 4
805 ngroups = 4
806 nbanks = ngroups * ngroupbanks
807 nrows = 131072
808 ncols = 1024
809 # timings
810 trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
811 trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
812 technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
813 speedgrade_timings = {
814 "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
815 }
816 speedgrade_timings["default"] = speedgrade_timings["2400"]