setup.py: Removed deps as per bug #1086#c7.
[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
27 class _TechnologyTimings(Settings):
28 def __init__(self, tREFI, tWTR, tCCD, tRRD, tZQCS=None):
29 self.set_attributes(locals())
30
31
32 _speedgrade_timings = ["tRP", "tRCD", "tWR", "tRFC", "tFAW", "tRAS"]
33
34
35 class _SpeedgradeTimings(Settings):
36 def __init__(self, tRP, tRCD, tWR, tRFC, tFAW, tRAS):
37 self.set_attributes(locals())
38
39 # SPD ----------------------------------------------------------------------------------------------
40
41
42 def _read_field(byte, nbits, shift):
43 mask = 2**nbits - 1
44 return (byte & (mask << shift)) >> shift
45
46
47 def _twos_complement(value, nbits):
48 if value & (1 << (nbits - 1)):
49 value -= (1 << nbits)
50 return value
51
52
53 def _word(msb, lsb):
54 return (msb << 8) | lsb
55
56
57 class DDR3SPDData:
58 memtype = "DDR3"
59
60 def __init__(self, spd_data):
61 # Geometry ---------------------------------------------------------------------------------
62 bankbits = {
63 0b000: 3,
64 0b001: 4,
65 0b010: 5,
66 0b011: 6,
67 }[_read_field(spd_data[4], nbits=3, shift=4)]
68 rowbits = {
69 0b000: 12,
70 0b001: 13,
71 0b010: 14,
72 0b011: 15,
73 0b100: 16,
74 }[_read_field(spd_data[5], nbits=3, shift=3)]
75 colbits = {
76 0b000: 9,
77 0b001: 10,
78 0b010: 11,
79 0b011: 12,
80 }[_read_field(spd_data[5], nbits=3, shift=0)]
81
82 self.nbanks = 2**bankbits
83 self.nrows = 2**rowbits
84 self.ncols = 2**colbits
85
86 # Timings ----------------------------------------------------------------------------------
87 self.init_timebase(spd_data)
88
89 # most signifficant (upper) / least signifficant (lower) nibble
90 def msn(byte):
91 return _read_field(byte, nbits=4, shift=4)
92
93 def lsn(byte):
94 return _read_field(byte, nbits=4, shift=0)
95
96 b = spd_data
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]))
109
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
115 tZQCS=(64, 80),
116 )
117 speedgrade_timings = _SpeedgradeTimings(
118 tRP=trp_min,
119 tRCD=trcd_min,
120 tWR=twr_min,
121 tRFC=(None, trfc_min),
122 tFAW=(None, tfaw_min),
123 tRAS=tras_min,
124 )
125
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,
131 }
132
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
143
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
149
150 @staticmethod
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).
160 max_error = 2
161 if abs(freq_mhz - f) < max_error:
162 return f
163 raise ValueError("Transfer rate = {:.2f} does not correspond to any DDR3 speedgrade"
164 .format(freq_mhz))
165
166
167 def parse_spd_hexdump(filename):
168 """Parse data dumped using the `spdread` command in LiteX BIOS
169
170 This will read files in format:
171 Memory dump:
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 ................
174 """
175 data = []
176 last_addr = -1
177 with open(filename) as f:
178 for line in 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]]
184 data.extend(values)
185 last_addr = addr
186 return data
187
188 # SDRAMModule --------------------------------------------------------------------------------------
189
190
191 class SDRAMModule:
192 """SDRAM module geometry and timings.
193
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.
198
199 SDRAM modules with the same geometry exist can have
200 various speedgrades.
201 """
202 registered = False
203
204 def __init__(self, clk_freq, rate, speedgrade=None, fine_refresh_mode=None):
205 self.clk_freq = clk_freq
206 self.rate = rate
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),
212 )
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(
226 *self.get("tFAW")),
227 tCCD=None if self.get("tCCD") is None else self.ck_ns_to_cycles(
228 *self.get("tCCD")),
229 tRRD=None if self.get("tRRD") is None else self.ck_ns_to_cycles(
230 *self.get("tRRD")),
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"))
237 )
238 self.timing_settings.fine_refresh_mode = fine_refresh_mode
239
240 def get(self, name, key=None):
241 r = 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)
246 else:
247 name = name + "_" + self.speedgrade if self.speedgrade is not None else name
248 try:
249 r = getattr(self, name)
250 except:
251 pass
252 else:
253 if hasattr(self, "technology_timings"):
254 r = getattr(self.technology_timings, name)
255 else:
256 try:
257 r = getattr(self, name)
258 except:
259 pass
260 if (r is not None) and (key is not None):
261 r = r[key]
262 return r
263
264 def ns_to_cycles(self, t, margin=True):
265 clk_period_ns = 1e9/self.clk_freq
266 if margin:
267 margins = {
268 "1:1": 0,
269 "1:2": clk_period_ns/2,
270 "1:4": 3*clk_period_ns/4
271 }
272 t += margins[self.rate]
273 return ceil(t/clk_period_ns)
274
275 def ck_to_cycles(self, c):
276 d = {
277 "1:1": 1,
278 "1:2": 2,
279 "1:4": 4
280 }
281 return ceil(c/d[self.rate])
282
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))
287
288 @classmethod
289 def from_spd_data(cls, spd_data, clk_freq, fine_refresh_mode=None):
290 # set parameters from SPD data based on memory type
291 spd_cls = {
292 0x0b: DDR3SPDData,
293 }[spd_data[2]]
294 spd = spd_cls(spd_data)
295
296 # Create a deriving class to avoid modifying this one
297 class _SDRAMModule(cls):
298 memtype = spd.memtype
299 nbanks = spd.nbanks
300 nrows = spd.nrows
301 ncols = spd.ncols
302 technology_timings = spd.technology_timings
303 speedgrade_timings = spd.speedgrade_timings
304
305 nphases = {
306 "SDR": 1,
307 "DDR": 2,
308 "LPDDR": 2,
309 "DDR2": 2,
310 "DDR3": 4,
311 "DDR4": 4,
312 }[spd.memtype]
313 rate = "1:{}".format(nphases)
314
315 return _SDRAMModule(clk_freq,
316 rate=rate,
317 speedgrade=spd.speedgrade,
318 fine_refresh_mode=fine_refresh_mode)
319
320
321 class SDRAMRegisteredModule(SDRAMModule):
322 registered = True
323
324 # DDR3 (Chips) -------------------------------------------------------------------------------------
325
326
327 class DDR3Module(SDRAMModule):
328 memtype = "DDR3"
329
330
331 class DDR3RegisteredModule(SDRAMRegisteredModule):
332 memtype = "DDR3"
333
334
335 class MT41K64M16(DDR3Module):
336 memtype = "DDR3"
337 # geometry
338 nbanks = 8
339 nrows = 8192
340 ncols = 1024
341 # timings
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),
349 }
350 speedgrade_timings["default"] = speedgrade_timings["1600"]
351
352
353 class MT41J128M16(DDR3Module):
354 memtype = "DDR3"
355 # geometry
356 nbanks = 8
357 nrows = 16384
358 ncols = 1024
359 # timings
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),
367 }
368 speedgrade_timings["default"] = speedgrade_timings["1600"]
369
370
371 class MT41K128M16(MT41J128M16):
372 pass
373
374
375 class MT41J256M16(DDR3Module):
376 # geometry
377 nbanks = 8
378 nrows = 32768
379 ncols = 1024
380 # timings
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),
388 }
389 speedgrade_timings["default"] = speedgrade_timings["1600"]
390
391
392 class MT41K256M16(MT41J256M16):
393 pass
394
395
396 class MT41J512M16(DDR3Module):
397 # geometry
398 nbanks = 8
399 nrows = 65536
400 ncols = 1024
401 # timings
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),
406 }
407 speedgrade_timings["default"] = speedgrade_timings["1600"]
408
409
410 class MT41K512M16(MT41J512M16):
411 pass
412
413
414 class K4B1G0446F(DDR3Module):
415 # geometry
416 nbanks = 8
417 nrows = 16384
418 ncols = 1024
419 # timings
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),
427 }
428 speedgrade_timings["default"] = speedgrade_timings["1600"]
429
430
431 class K4B2G1646F(DDR3Module):
432 # geometry
433 nbanks = 8
434 nrows = 16384
435 ncols = 1024
436 # timings
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),
444 }
445 speedgrade_timings["default"] = speedgrade_timings["1600"]
446
447
448 class H5TC4G63CFR(DDR3Module):
449 # geometry
450 nbanks = 8
451 nrows = 16384
452 ncols = 1024
453 # timings
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),
458 }
459 speedgrade_timings["default"] = speedgrade_timings["800"]
460
461
462 class IS43TR16128B(DDR3Module):
463 # geometry
464 nbanks = 8
465 nrows = 16384
466 ncols = 1024
467 # timings
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),
472 }
473 speedgrade_timings["default"] = speedgrade_timings["1600"]
474
475
476 # DDR3 (SO-DIMM) -----------------------------------------------------------------------------------
477
478 class MT8JTF12864(DDR3Module):
479 # base chip: MT41J128M8
480 # geometry
481 nbanks = 8
482 nrows = 16384
483 ncols = 1024
484 # timings
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),
490 }
491 speedgrade_timings["default"] = speedgrade_timings["1333"]
492
493
494 class MT8KTF51264(DDR3Module):
495 # base chip: MT41K512M8
496 # geometry
497 nbanks = 8
498 nrows = 65536
499 ncols = 1024
500 # timings
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),
509 }
510 speedgrade_timings["default"] = speedgrade_timings["1866"]
511
512
513 class MT18KSF1G72HZ(DDR3Module):
514 # base chip: MT41K512M8
515 # geometry
516 nbanks = 8
517 nrows = 65536
518 ncols = 1024
519 # timings
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),
526 }
527 speedgrade_timings["default"] = speedgrade_timings["1600"]
528
529
530 class AS4C256M16D3A(DDR3Module):
531 # geometry
532 nbanks = 8
533 nrows = 32768
534 ncols = 1024
535 # timings
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),
540 }
541 speedgrade_timings["default"] = speedgrade_timings["1600"]
542
543
544 class MT16KTF1G64HZ(DDR3Module):
545 # base chip: MT41K512M8
546 # geometry
547 nbanks = 8
548 nrows = 65536
549 ncols = 1024
550 # timings
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),
559 }
560 speedgrade_timings["default"] = speedgrade_timings["1866"]