add ZQ periodic short calibration support (default to 1s)

This commit is contained in:
Florent Kermarrec 2019-09-09 15:07:38 +02:00
parent 6e176d40ac
commit 188b6a8feb
5 changed files with 161 additions and 49 deletions

View file

@ -53,7 +53,7 @@ class GeomSettings(Settings):
class TimingSettings(Settings): class TimingSettings(Settings):
def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, tFAW, tCCD, tRRD, tRC, tRAS): def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, tFAW, tCCD, tRRD, tRC, tRAS, tZQCS):
self.set_attributes(locals()) self.set_attributes(locals())
# Layouts/Interface ------------------------------------------------------------ # Layouts/Interface ------------------------------------------------------------

View file

@ -18,7 +18,7 @@ class ControllerSettings(Settings):
cmd_buffer_depth=8, cmd_buffer_buffered=False, cmd_buffer_depth=8, cmd_buffer_buffered=False,
read_time=32, write_time=16, read_time=32, write_time=16,
with_bandwidth=False, with_bandwidth=False,
with_refresh=True, refresher_cls=Refresher, with_refresh=True, refresher_cls=Refresher, refresher_zqcs_freq=1e0,
with_auto_precharge=True, with_auto_precharge=True,
address_mapping="ROW_BANK_COL"): address_mapping="ROW_BANK_COL"):
self.set_attributes(locals()) self.set_attributes(locals())
@ -26,7 +26,7 @@ class ControllerSettings(Settings):
# Controller --------------------------------------------------------------------------------------- # Controller ---------------------------------------------------------------------------------------
class LiteDRAMController(Module): class LiteDRAMController(Module):
def __init__(self, phy_settings, geom_settings, timing_settings, def __init__(self, phy_settings, geom_settings, timing_settings, clk_freq,
controller_settings=ControllerSettings()): controller_settings=ControllerSettings()):
address_align = log2_int(burst_lengths[phy_settings.memtype]) address_align = log2_int(burst_lengths[phy_settings.memtype])
@ -53,7 +53,7 @@ class LiteDRAMController(Module):
# # # # # #
# Refresher -------------------------------------------------------------------------------- # Refresher --------------------------------------------------------------------------------
self.submodules.refresher = self.settings.refresher_cls(self.settings) self.submodules.refresher = self.settings.refresher_cls(self.settings, clk_freq)
# Bank Machines ---------------------------------------------------------------------------- # Bank Machines ----------------------------------------------------------------------------
bank_machines = [] bank_machines = []

View file

@ -20,7 +20,7 @@ class RefreshExecuter(Module):
- Send a "Precharge All" command - Send a "Precharge All" command
- Wait tRP - Wait tRP
- Send an "Auto Refresh" command - Send an "Auto Refresh" command
- Wait rRFC - Wait tRFC
""" """
def __init__(self, cmd, trp, trfc): def __init__(self, cmd, trp, trfc):
self.start = Signal() self.start = Signal()
@ -29,22 +29,39 @@ class RefreshExecuter(Module):
# # # # # #
self.sync += [ self.sync += [
cmd.a.eq(2**10), cmd.a.eq( 0),
cmd.ba.eq(0), cmd.ba.eq( 0),
cmd.cas.eq(0), cmd.cas.eq(0),
cmd.ras.eq(0), cmd.ras.eq(0),
cmd.we.eq(0), cmd.we.eq( 0),
]
self.sync += [
self.done.eq(0), self.done.eq(0),
# Wait start # Wait start
timeline(self.start, [ timeline(self.start, [
# Precharge All # Precharge All
(0, [cmd.ras.eq(1), cmd.we.eq(1)]), (0, [
cmd.a.eq( 2**10),
cmd.ba.eq( 0),
cmd.cas.eq(0),
cmd.ras.eq(1),
cmd.we.eq( 1)
]),
# Auto Refresh after tRP # Auto Refresh after tRP
(trp, [cmd.cas.eq(1), cmd.ras.eq(1)]), (trp, [
cmd.a.eq( 0),
cmd.ba.eq( 0),
cmd.cas.eq(1),
cmd.ras.eq(1),
cmd.we.eq( 0),
]),
# Done after tRP + tRFC # Done after tRP + tRFC
(trp + trfc, [self.done.eq(1)]) (trp + trfc, [
cmd.a.eq( 0),
cmd.ba.eq( 0),
cmd.cas.eq(0),
cmd.ras.eq(0),
cmd.we.eq( 0),
self.done.eq(1),
]),
]) ])
] ]
@ -132,6 +149,56 @@ class RefreshAccumulator(Module):
) )
] ]
# ZQCSExecuter ----------------------------------------------------------------------------------
class ZQCSExecuter(Module):
"""ZQ Short Calibration Executer
Execute the ZQCS sequence to the DRAM:
- Send a "Precharge All" command
- Wait tRP
- Send an "ZQ Short Calibration" command
- Wait tZQCS
"""
def __init__(self, cmd, trp, tzqcs):
self.start = Signal()
self.done = Signal()
# # #
self.sync += [
# Note: Don't set cmd to 0 since already done in RefreshExecuter
self.done.eq(0),
# Wait start
timeline(self.start, [
# Precharge All
(0, [
cmd.a.eq( 2**10),
cmd.ba.eq( 0),
cmd.cas.eq(0),
cmd.ras.eq(1),
cmd.we.eq( 1)
]),
# ZQ Short Calibration after tRP
(trp, [
cmd.a.eq( 0),
cmd.ba.eq( 0),
cmd.cas.eq(0),
cmd.ras.eq(0),
cmd.we.eq( 1),
]),
# Done after tRP + tZQCS
(trp + tzqcs, [
cmd.a.eq( 0),
cmd.ba.eq( 0),
cmd.cas.eq(0),
cmd.ras.eq(0),
cmd.we.eq( 0),
self.done.eq(1)
]),
])
]
# Refresher ---------------------------------------------------------------------------------------- # Refresher ----------------------------------------------------------------------------------------
class Refresher(Module): class Refresher(Module):
@ -148,51 +215,86 @@ class Refresher(Module):
transactions are done, the Refresher can execute the refresh Sequence and release the Controller. transactions are done, the Refresher can execute the refresh Sequence and release the Controller.
""" """
def __init__(self, settings, n=1): def __init__(self, settings, clk_freq, n=1):
abits = settings.geom.addressbits abits = settings.geom.addressbits
babits = settings.geom.bankbits + log2_int(settings.phy.nranks) babits = settings.geom.bankbits + log2_int(settings.phy.nranks)
self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(a=abits, ba=babits)) self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(a=abits, ba=babits))
# # # # # #
wants_refresh = Signal()
wants_zqcs = Signal()
# Refresh Timer ---------------------------------------------------------------------------- # Refresh Timer ----------------------------------------------------------------------------
timer = RefreshTimer(settings.timing.tREFI) timer = RefreshTimer(settings.timing.tREFI)
self.submodules.timer = timer self.submodules.timer = timer
self.comb += self.timer.wait.eq(~self.timer.done) self.comb += timer.wait.eq(~timer.done)
# Refresh Accumulator ---------------------------------------------------------------------- # Refresh Accumulator ----------------------------------------------------------------------
accum = RefreshAccumulator(n=n) accum = RefreshAccumulator(n=n)
self.submodules.accum = accum self.submodules.accum = accum
self.comb += accum.req_i.eq(self.timer.done) self.comb += accum.req_i.eq(self.timer.done)
self.comb += wants_refresh.eq(accum.req_o)
# Refresh Sequencer ------------------------------------------------------------------------ # Refresh Sequencer ------------------------------------------------------------------------
sequencer = RefreshSequencer(cmd, settings.timing.tRP, settings.timing.tRFC, n=n) sequencer = RefreshSequencer(cmd, settings.timing.tRP, settings.timing.tRFC, n=n)
self.submodules.sequencer = sequencer self.submodules.sequencer = sequencer
if settings.timing.tZQCS is not None:
# ZQCS Timer ---------------------------------------------------------------------------
zqcs_timer = RefreshTimer(int(clk_freq/settings.refresher_zqcs_freq))
self.submodules.zqcs_timer = zqcs_timer
self.comb += wants_zqcs.eq(zqcs_timer.done)
# ZQCS Executer ------------------------------------------------------------------------
zqcs_executer = ZQCSExecuter(cmd, settings.timing.tRP, settings.timing.tZQCS)
self.submodules.zqs_executer = zqcs_executer
self.comb += zqcs_timer.wait.eq(~zqcs_executer.done)
# Refresh FSM ------------------------------------------------------------------------------ # Refresh FSM ------------------------------------------------------------------------------
self.submodules.fsm = fsm = FSM() self.submodules.fsm = fsm = FSM()
fsm.act("IDLE", fsm.act("IDLE",
If(settings.with_refresh, If(settings.with_refresh,
# Wait refresh accumulator If(wants_refresh,
If(accum.req_o, NextState("WAIT-BANK-MACHINES")
NextState("WAIT-GRANT")
) )
) )
) )
fsm.act("WAIT-GRANT", fsm.act("WAIT-BANK-MACHINES",
# Advertise Controller, wait grant and start Sequencer
cmd.valid.eq(1), cmd.valid.eq(1),
If(cmd.ready, If(cmd.ready,
sequencer.start.eq(1), sequencer.start.eq(1),
NextState("WAIT-SEQUENCER") NextState("DO-REFRESH")
) )
) )
fsm.act("WAIT-SEQUENCER", if settings.timing.tZQCS is None:
# Wait Sequencer and advertise Controller when done fsm.act("DO-REFRESH",
cmd.valid.eq(1), cmd.valid.eq(1),
If(sequencer.done, If(sequencer.done,
cmd.valid.eq(0), cmd.valid.eq(0),
cmd.last.eq(1), cmd.last.eq(1),
NextState("IDLE") NextState("IDLE")
)
)
else:
fsm.act("DO-REFRESH",
cmd.valid.eq(1),
If(sequencer.done,
If(wants_zqcs,
zqcs_executer.start.eq(1),
NextState("DO-ZQCS")
).Else(
cmd.valid.eq(0),
cmd.last.eq(1),
NextState("IDLE")
)
)
)
fsm.act("DO-ZQCS",
cmd.valid.eq(1),
If(zqcs_executer.done,
cmd.valid.eq(0),
cmd.last.eq(1),
NextState("IDLE")
)
) )
)

View file

@ -16,13 +16,20 @@ from collections import namedtuple
from migen import * from migen import *
from litedram.common import GeomSettings, TimingSettings from litedram.common import Settings, GeomSettings, TimingSettings
_technology_timings = ["tREFI", "tWTR", "tCCD", "tRRD", "tZQCS"]
class _TechnologyTimings(Settings):
def __init__(self, tREFI, tWTR, tCCD, tRRD, tZQCS=None):
self.set_attributes(locals())
_technology_timings = ["tREFI", "tWTR", "tCCD", "tRRD"]
_TechnologyTimings = namedtuple("TechnologyTimings", _technology_timings)
_speedgrade_timings = ["tRP", "tRCD", "tWR", "tRFC", "tFAW", "tRAS"] _speedgrade_timings = ["tRP", "tRCD", "tWR", "tRFC", "tFAW", "tRAS"]
_SpeedgradeTimings = namedtuple("SpeedgradeTimings", _speedgrade_timings)
class _SpeedgradeTimings(Settings):
def __init__(self, tRP, tRCD, tWR, tRFC, tFAW, tRAS):
self.set_attributes(locals())
class SDRAMModule: class SDRAMModule:
@ -56,7 +63,8 @@ class SDRAMModule:
tCCD=None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")), 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")), 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")), 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")) 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"))
) )
def get(self, name): def get(self, name):
@ -259,7 +267,7 @@ class MT41K64M16(SDRAMModule):
nrows = 8192 nrows = 8192
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(64, None), tFAW=(None, 50), tRAS=37.5), "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), "1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(86, None), tFAW=(None, 50), tRAS=37.5),
@ -276,7 +284,7 @@ class MT41J128M16(SDRAMModule):
nrows = 16384 nrows = 16384
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(64, None), tFAW=(None, 50), tRAS=37.5), "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), "1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(86, None), tFAW=(None, 50), tRAS=37.5),
@ -297,7 +305,7 @@ class MT41J256M16(SDRAMModule):
nrows = 32768 nrows = 32768
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(139, None), tFAW=(None, 50), tRAS=37.5), "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), "1066": _SpeedgradeTimings(tRP=13.1, tRCD=13.1, tWR=13.1, tRFC=(138, None), tFAW=(None, 50), tRAS=37.5),
@ -318,7 +326,7 @@ class K4B1G0446F(SDRAMModule):
nrows = 16384 nrows = 16384
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(120, None), tFAW=(None, 50), tRAS=37.5), "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), "1066": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(160, None), tFAW=(None, 50), tRAS=37.5),
@ -335,7 +343,7 @@ class K4B2G1646F(SDRAMModule):
nrows = 16384 nrows = 16384
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(104, None), tFAW=(None, 50), tRAS=37.5), "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), "1066": _SpeedgradeTimings(tRP=13.125, tRCD=13.125, tWR=15, tRFC=(139, None), tFAW=(None, 50), tRAS=37.5),
@ -352,7 +360,7 @@ class IS43TR16128B(SDRAMModule):
nrows = 16384 nrows = 16384
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 160), tFAW=(None, 40), tRAS=35), "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 160), tFAW=(None, 40), tRAS=35),
} }
@ -367,7 +375,7 @@ class MT8JTF12864(SDRAMModule):
nrows = 16384 nrows = 16384
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(86, None), tFAW=(None, 50), tRAS=None), "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(86, None), tFAW=(None, 50), tRAS=None),
"1333": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(107, None), tFAW=(None, 45), tRAS=None), "1333": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(107, None), tFAW=(None, 45), tRAS=None),
@ -382,7 +390,7 @@ class MT8KTF51264(SDRAMModule):
nrows = 16384 nrows = 16384
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800": _SpeedgradeTimings(tRP=13.91, tRCD=13.91, tWR=13.91, tRFC=260, tFAW=(None, 50), tRAS=None), "800": _SpeedgradeTimings(tRP=13.91, tRCD=13.91, tWR=13.91, tRFC=260, tFAW=(None, 50), tRAS=None),
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=86, tFAW=(None, 50), tRAS=None), "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=86, tFAW=(None, 50), tRAS=None),
@ -398,7 +406,7 @@ class MT18KSF1G72HZ(SDRAMModule):
nrows = 65536 nrows = 65536
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(86, None), tFAW=(None, 50), tRAS=None), "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(86, None), tFAW=(None, 50), tRAS=None),
"1333": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(107, None), tFAW=(None, 45), tRAS=None), "1333": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(107, None), tFAW=(None, 45), tRAS=None),
@ -414,7 +422,7 @@ class AS4C256M16D3A(SDRAMModule):
nrows = 32768 nrows = 32768
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 7.5)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 7.5), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=35), "1600": _SpeedgradeTimings(tRP=13.75, tRCD=13.75, tWR=15, tRFC=(None, 260), tFAW=(None, 40), tRAS=35),
} }
@ -428,7 +436,7 @@ class MT16KTF1G64HZ(SDRAMModule):
nrows = 65536 nrows = 65536
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 10), tZQCS=(64, 80))
speedgrade_timings = { speedgrade_timings = {
"800" : _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(140, None), tFAW=(None, 40), tRAS=None), "800" : _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(140, None), tFAW=(None, 40), tRAS=None),
"1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(187, None), tFAW=(None, 40), tRAS=None), "1066": _SpeedgradeTimings(tRP=15, tRCD=15, tWR=15, tRFC=(187, None), tFAW=(None, 40), tRAS=None),
@ -448,7 +456,7 @@ class EDY4016A(SDRAMModule):
nrows = 32768 nrows = 32768
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
speedgrade_timings = { speedgrade_timings = {
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 260), tFAW=(28, 30), tRAS=32), "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 260), tFAW=(28, 30), tRAS=32),
} }
@ -464,7 +472,7 @@ class MT40A1G8(SDRAMModule):
nrows = 65536 nrows = 65536
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4), tZQCS=(128, 80))
speedgrade_timings = { speedgrade_timings = {
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32), "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32),
"2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=(None, 350), tFAW=(20, 21), tRAS=32), "2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=(None, 350), tFAW=(20, 21), tRAS=32),
@ -481,7 +489,7 @@ class MT40A512M16(SDRAMModule):
nrows = 65536 nrows = 65536
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9)) technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
speedgrade_timings = { speedgrade_timings = {
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32), "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32),
} }

View file

@ -70,10 +70,12 @@ class TestRefresh(unittest.TestCase):
class Obj: pass class Obj: pass
settings = Obj() settings = Obj()
settings.with_refresh = True settings.with_refresh = True
settings.refresher_zqcs_freq = 1e0
settings.timing = Obj() settings.timing = Obj()
settings.timing.tREFI = 64 settings.timing.tREFI = 64
settings.timing.tRP = 1 settings.timing.tRP = 1
settings.timing.tRFC = 2 settings.timing.tRFC = 2
settings.timing.tZQCS = 64
settings.geom = Obj() settings.geom = Obj()
settings.geom.addressbits = 16 settings.geom.addressbits = 16
settings.geom.bankbits = 3 settings.geom.bankbits = 3
@ -97,7 +99,7 @@ class TestRefresh(unittest.TestCase):
print(cmd_valid_gap) print(cmd_valid_gap)
dut.errors += 1 dut.errors += 1
dut = Refresher(settings, n=n) dut = Refresher(settings, n=n, clk_freq=100e6)
run_simulation(dut, [generator(dut)]) run_simulation(dut, [generator(dut)])
self.assertEqual(dut.errors, 0) self.assertEqual(dut.errors, 0)