core/refresher: improve naming/parameters of refresh postponing
This commit is contained in:
parent
dc1bb53a88
commit
f861d99903
2
README
2
README
|
@ -33,7 +33,7 @@ Core:
|
|||
- Fully pipelined, high performance.
|
||||
- Configurable commands depth on bankmachines.
|
||||
- Auto-Precharge.
|
||||
- Periodic refresh/ZQ short calibration.
|
||||
- Periodic refresh/ZQ short calibration (up to 8 postponed refreshes).
|
||||
Frontend:
|
||||
- Configurable crossbar (simply use crossbar.get_port() to add a new port!)
|
||||
- Ports arbitration transparent to the user.
|
||||
|
|
|
@ -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, refresher_zqcs_freq=1e0,
|
||||
with_refresh=True, refresh_cls=Refresher, refresh_zqcs_freq=1e0, refresh_postponing=1,
|
||||
with_auto_precharge=True,
|
||||
address_mapping="ROW_BANK_COL"):
|
||||
self.set_attributes(locals())
|
||||
|
@ -53,7 +53,10 @@ class LiteDRAMController(Module):
|
|||
# # #
|
||||
|
||||
# Refresher --------------------------------------------------------------------------------
|
||||
self.submodules.refresher = self.settings.refresher_cls(self.settings, clk_freq)
|
||||
self.submodules.refresher = self.settings.refresh_cls(self.settings,
|
||||
clk_freq = clk_freq,
|
||||
zqcs_freq = self.settings.refresh_zqcs_freq,
|
||||
postponing = self.settings.refresh_postponing)
|
||||
|
||||
# Bank Machines ----------------------------------------------------------------------------
|
||||
bank_machines = []
|
||||
|
|
|
@ -72,7 +72,7 @@ class RefreshSequencer(Module):
|
|||
|
||||
Sequence N refreshs to the DRAM.
|
||||
"""
|
||||
def __init__(self, cmd, trp, trfc, n=1):
|
||||
def __init__(self, cmd, trp, trfc, postponing=1):
|
||||
self.start = Signal()
|
||||
self.done = Signal()
|
||||
|
||||
|
@ -81,7 +81,7 @@ class RefreshSequencer(Module):
|
|||
executer = RefreshExecuter(cmd, trp, trfc)
|
||||
self.submodules += executer
|
||||
|
||||
count = Signal(bits_for(n), reset=n-1)
|
||||
count = Signal(bits_for(postponing), reset=postponing-1)
|
||||
self.sync += [
|
||||
If(self.start,
|
||||
count.eq(count.reset)
|
||||
|
@ -124,20 +124,20 @@ class RefreshTimer(Module):
|
|||
self.count.eq(count)
|
||||
]
|
||||
|
||||
# RefreshAccumulator -------------------------------------------------------------------------------
|
||||
# RefreshPostponer -------------------------------------------------------------------------------
|
||||
|
||||
class RefreshAccumulator(Module):
|
||||
"""Refresh Accumulator
|
||||
class RefreshPostponer(Module):
|
||||
"""Refresh Postponer
|
||||
|
||||
Accumulate N Refresh requests and generate a request when N is reached.
|
||||
Postpone N Refresh requests and generate a request when N is reached.
|
||||
"""
|
||||
def __init__(self, n=1):
|
||||
def __init__(self, postponing=1):
|
||||
self.req_i = Signal()
|
||||
self.req_o = Signal()
|
||||
|
||||
# # #
|
||||
|
||||
count = Signal(bits_for(n), reset=n-1)
|
||||
count = Signal(bits_for(postponing), reset=postponing-1)
|
||||
self.sync += [
|
||||
self.req_o.eq(0),
|
||||
If(self.req_i,
|
||||
|
@ -215,7 +215,8 @@ class Refresher(Module):
|
|||
transactions are done, the Refresher can execute the refresh Sequence and release the Controller.
|
||||
|
||||
"""
|
||||
def __init__(self, settings, clk_freq, n=1):
|
||||
def __init__(self, settings, clk_freq, zqcs_freq=1e0, postponing=1):
|
||||
assert postponing <= 8
|
||||
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))
|
||||
|
@ -230,19 +231,19 @@ class Refresher(Module):
|
|||
self.submodules.timer = timer
|
||||
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 Postponer ------------------------------------------------------------------------
|
||||
postponer = RefreshPostponer(postponing)
|
||||
self.submodules.postponer = postponer
|
||||
self.comb += postponer.req_i.eq(self.timer.done)
|
||||
self.comb += wants_refresh.eq(postponer.req_o)
|
||||
|
||||
# Refresh Sequencer ------------------------------------------------------------------------
|
||||
sequencer = RefreshSequencer(cmd, settings.timing.tRP, settings.timing.tRFC, n=n)
|
||||
sequencer = RefreshSequencer(cmd, settings.timing.tRP, settings.timing.tRFC, postponing)
|
||||
self.submodules.sequencer = sequencer
|
||||
|
||||
if settings.timing.tZQCS is not None:
|
||||
# ZQCS Timer ---------------------------------------------------------------------------
|
||||
zqcs_timer = RefreshTimer(int(clk_freq/settings.refresher_zqcs_freq))
|
||||
zqcs_timer = RefreshTimer(int(clk_freq/zqcs_freq))
|
||||
self.submodules.zqcs_timer = zqcs_timer
|
||||
self.comb += wants_zqcs.eq(zqcs_timer.done)
|
||||
|
||||
|
|
|
@ -66,11 +66,11 @@ class TestRefresh(unittest.TestCase):
|
|||
for i in range(1, 32):
|
||||
self.refresh_timer_test(i)
|
||||
|
||||
def refresher_test(self, n):
|
||||
def refresher_test(self, postponing):
|
||||
class Obj: pass
|
||||
settings = Obj()
|
||||
settings.with_refresh = True
|
||||
settings.refresher_zqcs_freq = 1e0
|
||||
settings.refresh_zqcs_freq = 1e0
|
||||
settings.timing = Obj()
|
||||
settings.timing.tREFI = 64
|
||||
settings.timing.tRP = 1
|
||||
|
@ -95,14 +95,14 @@ class TestRefresh(unittest.TestCase):
|
|||
while (yield dut.cmd.valid) == 0:
|
||||
cmd_valid_gap += 1
|
||||
yield
|
||||
if cmd_valid_gap != n*settings.timing.tREFI:
|
||||
if cmd_valid_gap != postponing*settings.timing.tREFI:
|
||||
print(cmd_valid_gap)
|
||||
dut.errors += 1
|
||||
|
||||
dut = Refresher(settings, n=n, clk_freq=100e6)
|
||||
dut = Refresher(settings, clk_freq=100e6, postponing=postponing)
|
||||
run_simulation(dut, [generator(dut)])
|
||||
self.assertEqual(dut.errors, 0)
|
||||
|
||||
def test_refresher(self):
|
||||
for i in [1, 2, 4, 8]:
|
||||
self.refresher_test(n=i)
|
||||
self.refresher_test(postponing=i)
|
||||
|
|
Loading…
Reference in New Issue