2015-09-22 12:36:47 -04:00
|
|
|
from migen import *
|
2013-02-24 06:31:00 -05:00
|
|
|
from migen.genlib.misc import timeline
|
|
|
|
from migen.genlib.fsm import FSM
|
2012-03-15 15:29:26 -04:00
|
|
|
|
2015-09-22 12:35:02 -04:00
|
|
|
from misoc.mem.sdram.core.lasmicon.multiplexer import *
|
2012-03-14 13:26:05 -04:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2013-03-10 14:32:38 -04:00
|
|
|
class Refresher(Module):
|
2015-04-13 10:19:55 -04:00
|
|
|
def __init__(self, a, ba, tRP, tREFI, tRFC, enabled=True):
|
|
|
|
self.req = Signal()
|
2015-04-13 11:16:12 -04:00
|
|
|
self.ack = Signal() # 1st command 1 cycle after assertion of ack
|
2015-04-13 10:19:55 -04:00
|
|
|
self.cmd = CommandRequest(a, ba)
|
2014-10-17 05:14:35 -04:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
###
|
2013-03-10 14:32:38 -04:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
if enabled:
|
|
|
|
# Refresh sequence generator:
|
|
|
|
# PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
|
|
|
|
seq_start = Signal()
|
|
|
|
seq_done = Signal()
|
|
|
|
self.sync += [
|
|
|
|
self.cmd.a.eq(2**10),
|
|
|
|
self.cmd.ba.eq(0),
|
|
|
|
self.cmd.cas_n.eq(1),
|
|
|
|
self.cmd.ras_n.eq(1),
|
|
|
|
self.cmd.we_n.eq(1),
|
|
|
|
seq_done.eq(0)
|
|
|
|
]
|
|
|
|
self.sync += timeline(seq_start, [
|
|
|
|
(1, [
|
|
|
|
self.cmd.ras_n.eq(0),
|
|
|
|
self.cmd.we_n.eq(0)
|
|
|
|
]),
|
|
|
|
(1+tRP, [
|
|
|
|
self.cmd.cas_n.eq(0),
|
|
|
|
self.cmd.ras_n.eq(0)
|
|
|
|
]),
|
|
|
|
(1+tRP+tRFC, [
|
|
|
|
seq_done.eq(1)
|
|
|
|
])
|
|
|
|
])
|
2014-10-17 05:14:35 -04:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
# Periodic refresh counter
|
|
|
|
counter = Signal(max=tREFI)
|
|
|
|
start = Signal()
|
|
|
|
self.sync += [
|
|
|
|
start.eq(0),
|
|
|
|
If(counter == 0,
|
|
|
|
start.eq(1),
|
|
|
|
counter.eq(tREFI - 1)
|
|
|
|
).Else(
|
|
|
|
counter.eq(counter - 1)
|
|
|
|
)
|
|
|
|
]
|
2014-10-17 05:14:35 -04:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
# Control FSM
|
|
|
|
fsm = FSM()
|
|
|
|
self.submodules += fsm
|
|
|
|
fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
|
|
|
|
fsm.act("WAIT_GRANT",
|
|
|
|
self.req.eq(1),
|
|
|
|
If(self.ack,
|
|
|
|
seq_start.eq(1),
|
|
|
|
NextState("WAIT_SEQ")
|
|
|
|
)
|
|
|
|
)
|
|
|
|
fsm.act("WAIT_SEQ",
|
|
|
|
self.req.eq(1),
|
|
|
|
If(seq_done, NextState("IDLE"))
|
|
|
|
)
|