mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
commit
db4ec67741
3 changed files with 36 additions and 12 deletions
|
@ -38,15 +38,18 @@ class BankMachine(Module):
|
|||
self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(a, ba))
|
||||
|
||||
# # #
|
||||
auto_precharge = Signal()
|
||||
|
||||
# Command buffer
|
||||
cmd_buffer_layout = [("we", 1), ("adr", len(req.adr))]
|
||||
cmd_buffer = stream.SyncFIFO(cmd_buffer_layout, settings.cmd_buffer_depth)
|
||||
self.submodules += cmd_buffer
|
||||
cmd_bufferPre = stream.SyncFIFO(cmd_buffer_layout, settings.cmd_buffer_depth)
|
||||
cmd_buffer = stream.Buffer(cmd_buffer_layout) # 1 depth buffer to detect row change
|
||||
self.submodules += cmd_buffer, cmd_bufferPre
|
||||
self.comb += [
|
||||
req.connect(cmd_buffer.sink, omit=["wdata_valid", "wdata_ready",
|
||||
req.connect(cmd_bufferPre.sink, omit=["wdata_valid", "wdata_ready",
|
||||
"rdata_valid", "rdata_ready",
|
||||
"lock"]),
|
||||
cmd_bufferPre.source.connect(cmd_buffer.sink),
|
||||
cmd_buffer.source.ready.eq(req.wdata_ready | req.rdata_valid),
|
||||
req.lock.eq(cmd_buffer.source.valid),
|
||||
]
|
||||
|
@ -75,7 +78,7 @@ class BankMachine(Module):
|
|||
If(sel_row_adr,
|
||||
cmd.a.eq(slicer.row(cmd_buffer.source.adr))
|
||||
).Else(
|
||||
cmd.a.eq(slicer.col(cmd_buffer.source.adr))
|
||||
cmd.a.eq((auto_precharge << 10) | slicer.col(cmd_buffer.source.adr))
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -86,6 +89,15 @@ class BankMachine(Module):
|
|||
cmd.ready &
|
||||
cmd.is_write))
|
||||
|
||||
# Auto Precharge
|
||||
self.comb += [
|
||||
If(cmd_bufferPre.source.valid & cmd_buffer.source.valid,
|
||||
If(slicer.row(cmd_bufferPre.source.adr) != slicer.row(cmd_buffer.source.adr),
|
||||
auto_precharge.eq(self.precharge_timer.done & (track_close == 0))
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
# Control and command generation FSM
|
||||
# Note: tRRD, tFAW, tCCD, tWTR timings are enforced by the multiplexer
|
||||
self.submodules.fsm = fsm = FSM()
|
||||
|
@ -105,7 +117,10 @@ class BankMachine(Module):
|
|||
req.rdata_valid.eq(cmd.ready),
|
||||
cmd.is_read.eq(1)
|
||||
),
|
||||
cmd.cas.eq(1)
|
||||
cmd.cas.eq(1),
|
||||
If(cmd.ready & auto_precharge,
|
||||
NextState("AUTOPRECHARGE")
|
||||
)
|
||||
)
|
||||
).Else(
|
||||
NextState("PRECHARGE")
|
||||
|
@ -128,6 +143,12 @@ class BankMachine(Module):
|
|||
),
|
||||
track_close.eq(1)
|
||||
)
|
||||
fsm.act("AUTOPRECHARGE",
|
||||
If(self.precharge_timer.done,
|
||||
NextState("TRP")
|
||||
),
|
||||
track_close.eq(1)
|
||||
)
|
||||
fsm.act("ACTIVATE",
|
||||
sel_row_adr.eq(1),
|
||||
track_open.eq(1),
|
||||
|
|
|
@ -198,10 +198,12 @@ class Multiplexer(Module, AutoCSR):
|
|||
|
||||
# tRRD timing (Row to Row delay)
|
||||
self.trrdcon = trrdcon = tXXDController(settings.timing.tRRD)
|
||||
self.submodules += trrdcon
|
||||
self.comb += trrdcon.valid.eq(choose_cmd.accept() & choose_cmd.activate())
|
||||
|
||||
# tFAW timing (Four Activate Window)
|
||||
self.tfawcon = tfawcon = tFAWController(settings.timing.tFAW)
|
||||
self.submodules += tfawcon
|
||||
self.comb += tfawcon.valid.eq(choose_cmd.accept() & choose_cmd.activate())
|
||||
|
||||
# RAS control
|
||||
|
@ -210,7 +212,8 @@ class Multiplexer(Module, AutoCSR):
|
|||
|
||||
# tCCD timing (Column to Column delay)
|
||||
self.tccdcon = tccdcon = tXXDController(settings.timing.tCCD)
|
||||
self.comb += tccdcon.valid.eq(choose_cmd.accept() & (choose_cmd.write() | choose_cmd.read()))
|
||||
self.submodules += tccdcon
|
||||
self.comb += tccdcon.valid.eq(choose_req.accept() & (choose_req.write() | choose_req.read()))
|
||||
|
||||
# CAS control
|
||||
self.comb += cas_allowed.eq(tccdcon.ready)
|
||||
|
@ -221,6 +224,7 @@ class Multiplexer(Module, AutoCSR):
|
|||
settings.timing.tWTR +
|
||||
# tCCD must be added since tWTR begins after the transfer is complete
|
||||
settings.timing.tCCD if settings.timing.tCCD is not None else 0)
|
||||
self.submodules += twtrcon
|
||||
self.comb += twtrcon.valid.eq(choose_req.accept() & choose_req.write())
|
||||
|
||||
# Read/write turnaround
|
||||
|
@ -325,7 +329,7 @@ class Multiplexer(Module, AutoCSR):
|
|||
fsm.act("REFRESH",
|
||||
steerer.sel[0].eq(STEER_REFRESH),
|
||||
refresher.cmd.ready.eq(1),
|
||||
If(~refresher.cmd.valid,
|
||||
If(refresher.cmd.last,
|
||||
NextState("READ")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -45,16 +45,14 @@ class Refresher(Module):
|
|||
self.comb += self.timer.wait.eq(settings.with_refresh & ~self.timer.done)
|
||||
|
||||
# Control FSM
|
||||
cmd_valid = Signal()
|
||||
self.submodules.fsm = fsm = FSM()
|
||||
fsm.act("IDLE",
|
||||
If(self.timer.done,
|
||||
cmd_valid.eq(1),
|
||||
NextState("WAIT_GRANT")
|
||||
)
|
||||
)
|
||||
fsm.act("WAIT_GRANT",
|
||||
cmd_valid.eq(1),
|
||||
cmd.valid.eq(1),
|
||||
If(cmd.ready,
|
||||
seq_start.eq(1),
|
||||
NextState("WAIT_SEQ")
|
||||
|
@ -62,8 +60,9 @@ class Refresher(Module):
|
|||
)
|
||||
fsm.act("WAIT_SEQ",
|
||||
If(seq_done,
|
||||
cmd_valid.eq(0),
|
||||
cmd.last.eq(1),
|
||||
NextState("IDLE")
|
||||
).Else(
|
||||
cmd.valid.eq(1)
|
||||
)
|
||||
)
|
||||
self.sync += cmd.valid.eq(cmd_valid)
|
||||
|
|
Loading…
Reference in a new issue