Merge pull request #24 from JohnSully/AutoPrecharge

Auto precharge
This commit is contained in:
enjoy-digital 2018-08-15 12:46:29 +02:00 committed by GitHub
commit db4ec67741
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 12 deletions

View file

@ -38,15 +38,18 @@ class BankMachine(Module):
self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(a, ba)) self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(a, ba))
# # # # # #
auto_precharge = Signal()
# Command buffer # Command buffer
cmd_buffer_layout = [("we", 1), ("adr", len(req.adr))] cmd_buffer_layout = [("we", 1), ("adr", len(req.adr))]
cmd_buffer = stream.SyncFIFO(cmd_buffer_layout, settings.cmd_buffer_depth) cmd_bufferPre = stream.SyncFIFO(cmd_buffer_layout, settings.cmd_buffer_depth)
self.submodules += cmd_buffer cmd_buffer = stream.Buffer(cmd_buffer_layout) # 1 depth buffer to detect row change
self.submodules += cmd_buffer, cmd_bufferPre
self.comb += [ 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", "rdata_valid", "rdata_ready",
"lock"]), "lock"]),
cmd_bufferPre.source.connect(cmd_buffer.sink),
cmd_buffer.source.ready.eq(req.wdata_ready | req.rdata_valid), cmd_buffer.source.ready.eq(req.wdata_ready | req.rdata_valid),
req.lock.eq(cmd_buffer.source.valid), req.lock.eq(cmd_buffer.source.valid),
] ]
@ -75,7 +78,7 @@ class BankMachine(Module):
If(sel_row_adr, If(sel_row_adr,
cmd.a.eq(slicer.row(cmd_buffer.source.adr)) cmd.a.eq(slicer.row(cmd_buffer.source.adr))
).Else( ).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.ready &
cmd.is_write)) 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 # Control and command generation FSM
# Note: tRRD, tFAW, tCCD, tWTR timings are enforced by the multiplexer # Note: tRRD, tFAW, tCCD, tWTR timings are enforced by the multiplexer
self.submodules.fsm = fsm = FSM() self.submodules.fsm = fsm = FSM()
@ -105,7 +117,10 @@ class BankMachine(Module):
req.rdata_valid.eq(cmd.ready), req.rdata_valid.eq(cmd.ready),
cmd.is_read.eq(1) cmd.is_read.eq(1)
), ),
cmd.cas.eq(1) cmd.cas.eq(1),
If(cmd.ready & auto_precharge,
NextState("AUTOPRECHARGE")
)
) )
).Else( ).Else(
NextState("PRECHARGE") NextState("PRECHARGE")
@ -128,6 +143,12 @@ class BankMachine(Module):
), ),
track_close.eq(1) track_close.eq(1)
) )
fsm.act("AUTOPRECHARGE",
If(self.precharge_timer.done,
NextState("TRP")
),
track_close.eq(1)
)
fsm.act("ACTIVATE", fsm.act("ACTIVATE",
sel_row_adr.eq(1), sel_row_adr.eq(1),
track_open.eq(1), track_open.eq(1),

View file

@ -198,10 +198,12 @@ class Multiplexer(Module, AutoCSR):
# tRRD timing (Row to Row delay) # tRRD timing (Row to Row delay)
self.trrdcon = trrdcon = tXXDController(settings.timing.tRRD) self.trrdcon = trrdcon = tXXDController(settings.timing.tRRD)
self.submodules += trrdcon
self.comb += trrdcon.valid.eq(choose_cmd.accept() & choose_cmd.activate()) self.comb += trrdcon.valid.eq(choose_cmd.accept() & choose_cmd.activate())
# tFAW timing (Four Activate Window) # tFAW timing (Four Activate Window)
self.tfawcon = tfawcon = tFAWController(settings.timing.tFAW) self.tfawcon = tfawcon = tFAWController(settings.timing.tFAW)
self.submodules += tfawcon
self.comb += tfawcon.valid.eq(choose_cmd.accept() & choose_cmd.activate()) self.comb += tfawcon.valid.eq(choose_cmd.accept() & choose_cmd.activate())
# RAS control # RAS control
@ -210,7 +212,8 @@ class Multiplexer(Module, AutoCSR):
# tCCD timing (Column to Column delay) # tCCD timing (Column to Column delay)
self.tccdcon = tccdcon = tXXDController(settings.timing.tCCD) 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 # CAS control
self.comb += cas_allowed.eq(tccdcon.ready) self.comb += cas_allowed.eq(tccdcon.ready)
@ -221,6 +224,7 @@ class Multiplexer(Module, AutoCSR):
settings.timing.tWTR + settings.timing.tWTR +
# tCCD must be added since tWTR begins after the transfer is complete # tCCD must be added since tWTR begins after the transfer is complete
settings.timing.tCCD if settings.timing.tCCD is not None else 0) 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()) self.comb += twtrcon.valid.eq(choose_req.accept() & choose_req.write())
# Read/write turnaround # Read/write turnaround
@ -325,7 +329,7 @@ class Multiplexer(Module, AutoCSR):
fsm.act("REFRESH", fsm.act("REFRESH",
steerer.sel[0].eq(STEER_REFRESH), steerer.sel[0].eq(STEER_REFRESH),
refresher.cmd.ready.eq(1), refresher.cmd.ready.eq(1),
If(~refresher.cmd.valid, If(refresher.cmd.last,
NextState("READ") NextState("READ")
) )
) )

View file

@ -45,16 +45,14 @@ class Refresher(Module):
self.comb += self.timer.wait.eq(settings.with_refresh & ~self.timer.done) self.comb += self.timer.wait.eq(settings.with_refresh & ~self.timer.done)
# Control FSM # Control FSM
cmd_valid = Signal()
self.submodules.fsm = fsm = FSM() self.submodules.fsm = fsm = FSM()
fsm.act("IDLE", fsm.act("IDLE",
If(self.timer.done, If(self.timer.done,
cmd_valid.eq(1),
NextState("WAIT_GRANT") NextState("WAIT_GRANT")
) )
) )
fsm.act("WAIT_GRANT", fsm.act("WAIT_GRANT",
cmd_valid.eq(1), cmd.valid.eq(1),
If(cmd.ready, If(cmd.ready,
seq_start.eq(1), seq_start.eq(1),
NextState("WAIT_SEQ") NextState("WAIT_SEQ")
@ -62,8 +60,9 @@ class Refresher(Module):
) )
fsm.act("WAIT_SEQ", fsm.act("WAIT_SEQ",
If(seq_done, If(seq_done,
cmd_valid.eq(0), cmd.last.eq(1),
NextState("IDLE") NextState("IDLE")
).Else(
cmd.valid.eq(1)
) )
) )
self.sync += cmd.valid.eq(cmd_valid)