mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
add ZQ periodic short calibration support (default to 1s)
This commit is contained in:
parent
6e176d40ac
commit
188b6a8feb
5 changed files with 161 additions and 49 deletions
|
@ -53,7 +53,7 @@ class GeomSettings(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())
|
||||
|
||||
# Layouts/Interface ------------------------------------------------------------
|
||||
|
|
|
@ -18,7 +18,7 @@ class ControllerSettings(Settings):
|
|||
cmd_buffer_depth=8, cmd_buffer_buffered=False,
|
||||
read_time=32, write_time=16,
|
||||
with_bandwidth=False,
|
||||
with_refresh=True, refresher_cls=Refresher,
|
||||
with_refresh=True, refresher_cls=Refresher, refresher_zqcs_freq=1e0,
|
||||
with_auto_precharge=True,
|
||||
address_mapping="ROW_BANK_COL"):
|
||||
self.set_attributes(locals())
|
||||
|
@ -26,7 +26,7 @@ class ControllerSettings(Settings):
|
|||
# Controller ---------------------------------------------------------------------------------------
|
||||
|
||||
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()):
|
||||
address_align = log2_int(burst_lengths[phy_settings.memtype])
|
||||
|
||||
|
@ -53,7 +53,7 @@ class LiteDRAMController(Module):
|
|||
# # #
|
||||
|
||||
# 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 = []
|
||||
|
|
|
@ -20,7 +20,7 @@ class RefreshExecuter(Module):
|
|||
- Send a "Precharge All" command
|
||||
- Wait tRP
|
||||
- Send an "Auto Refresh" command
|
||||
- Wait rRFC
|
||||
- Wait tRFC
|
||||
"""
|
||||
def __init__(self, cmd, trp, trfc):
|
||||
self.start = Signal()
|
||||
|
@ -29,22 +29,39 @@ class RefreshExecuter(Module):
|
|||
# # #
|
||||
|
||||
self.sync += [
|
||||
cmd.a.eq(2**10),
|
||||
cmd.ba.eq(0),
|
||||
cmd.a.eq( 0),
|
||||
cmd.ba.eq( 0),
|
||||
cmd.cas.eq(0),
|
||||
cmd.ras.eq(0),
|
||||
cmd.we.eq(0),
|
||||
]
|
||||
self.sync += [
|
||||
cmd.we.eq( 0),
|
||||
self.done.eq(0),
|
||||
# Wait start
|
||||
timeline(self.start, [
|
||||
# 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
|
||||
(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
|
||||
(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 ----------------------------------------------------------------------------------------
|
||||
|
||||
class Refresher(Module):
|
||||
|
@ -148,51 +215,86 @@ class Refresher(Module):
|
|||
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
|
||||
babits = settings.geom.bankbits + log2_int(settings.phy.nranks)
|
||||
self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(a=abits, ba=babits))
|
||||
|
||||
# # #
|
||||
|
||||
wants_refresh = Signal()
|
||||
wants_zqcs = Signal()
|
||||
|
||||
# Refresh Timer ----------------------------------------------------------------------------
|
||||
timer = RefreshTimer(settings.timing.tREFI)
|
||||
self.submodules.timer = timer
|
||||
self.comb += self.timer.wait.eq(~self.timer.done)
|
||||
self.comb += timer.wait.eq(~timer.done)
|
||||
|
||||
# Refresh Accumulator ----------------------------------------------------------------------
|
||||
accum = RefreshAccumulator(n=n)
|
||||
self.submodules.accum = accum
|
||||
self.comb += accum.req_i.eq(self.timer.done)
|
||||
self.comb += wants_refresh.eq(accum.req_o)
|
||||
|
||||
# Refresh Sequencer ------------------------------------------------------------------------
|
||||
sequencer = RefreshSequencer(cmd, settings.timing.tRP, settings.timing.tRFC, n=n)
|
||||
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 ------------------------------------------------------------------------------
|
||||
self.submodules.fsm = fsm = FSM()
|
||||
fsm.act("IDLE",
|
||||
If(settings.with_refresh,
|
||||
# Wait refresh accumulator
|
||||
If(accum.req_o,
|
||||
NextState("WAIT-GRANT")
|
||||
If(wants_refresh,
|
||||
NextState("WAIT-BANK-MACHINES")
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("WAIT-GRANT",
|
||||
# Advertise Controller, wait grant and start Sequencer
|
||||
fsm.act("WAIT-BANK-MACHINES",
|
||||
cmd.valid.eq(1),
|
||||
If(cmd.ready,
|
||||
sequencer.start.eq(1),
|
||||
NextState("WAIT-SEQUENCER")
|
||||
NextState("DO-REFRESH")
|
||||
)
|
||||
)
|
||||
fsm.act("WAIT-SEQUENCER",
|
||||
# Wait Sequencer and advertise Controller when done
|
||||
cmd.valid.eq(1),
|
||||
If(sequencer.done,
|
||||
cmd.valid.eq(0),
|
||||
cmd.last.eq(1),
|
||||
NextState("IDLE")
|
||||
if settings.timing.tZQCS is None:
|
||||
fsm.act("DO-REFRESH",
|
||||
cmd.valid.eq(1),
|
||||
If(sequencer.done,
|
||||
cmd.valid.eq(0),
|
||||
cmd.last.eq(1),
|
||||
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")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -16,13 +16,20 @@ from collections import namedtuple
|
|||
|
||||
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"]
|
||||
_SpeedgradeTimings = namedtuple("SpeedgradeTimings", _speedgrade_timings)
|
||||
|
||||
class _SpeedgradeTimings(Settings):
|
||||
def __init__(self, tRP, tRCD, tWR, tRFC, tFAW, tRAS):
|
||||
self.set_attributes(locals())
|
||||
|
||||
|
||||
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")),
|
||||
tRRD=None if self.get("tRRD") is None else self.ck_ns_to_cycles(*self.get("tRRD")),
|
||||
tRC=None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRP") + self.get("tRAS")),
|
||||
tRAS=None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS"))
|
||||
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):
|
||||
|
@ -259,7 +267,7 @@ class MT41K64M16(SDRAMModule):
|
|||
nrows = 8192
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -276,7 +284,7 @@ class MT41J128M16(SDRAMModule):
|
|||
nrows = 16384
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -297,7 +305,7 @@ class MT41J256M16(SDRAMModule):
|
|||
nrows = 32768
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -318,7 +326,7 @@ class K4B1G0446F(SDRAMModule):
|
|||
nrows = 16384
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -335,7 +343,7 @@ class K4B2G1646F(SDRAMModule):
|
|||
nrows = 16384
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -352,7 +360,7 @@ class IS43TR16128B(SDRAMModule):
|
|||
nrows = 16384
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -382,7 +390,7 @@ class MT8KTF51264(SDRAMModule):
|
|||
nrows = 16384
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -398,7 +406,7 @@ class MT18KSF1G72HZ(SDRAMModule):
|
|||
nrows = 65536
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -414,7 +422,7 @@ class AS4C256M16D3A(SDRAMModule):
|
|||
nrows = 32768
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -448,7 +456,7 @@ class EDY4016A(SDRAMModule):
|
|||
nrows = 32768
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"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),
|
||||
|
@ -481,7 +489,7 @@ class MT40A512M16(SDRAMModule):
|
|||
nrows = 65536
|
||||
ncols = 1024
|
||||
# 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 = {
|
||||
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32),
|
||||
}
|
||||
|
|
|
@ -70,10 +70,12 @@ class TestRefresh(unittest.TestCase):
|
|||
class Obj: pass
|
||||
settings = Obj()
|
||||
settings.with_refresh = True
|
||||
settings.refresher_zqcs_freq = 1e0
|
||||
settings.timing = Obj()
|
||||
settings.timing.tREFI = 64
|
||||
settings.timing.tRP = 1
|
||||
settings.timing.tRFC = 2
|
||||
settings.timing.tZQCS = 64
|
||||
settings.geom = Obj()
|
||||
settings.geom.addressbits = 16
|
||||
settings.geom.bankbits = 3
|
||||
|
@ -97,7 +99,7 @@ class TestRefresh(unittest.TestCase):
|
|||
print(cmd_valid_gap)
|
||||
dut.errors += 1
|
||||
|
||||
dut = Refresher(settings, n=n)
|
||||
dut = Refresher(settings, n=n, clk_freq=100e6)
|
||||
run_simulation(dut, [generator(dut)])
|
||||
self.assertEqual(dut.errors, 0)
|
||||
|
||||
|
|
Loading…
Reference in a new issue