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):
|
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 ------------------------------------------------------------
|
||||||
|
|
|
@ -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 = []
|
||||||
|
|
|
@ -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")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue