From 8d066caea93bb363d27167e93a9148811234bd85 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 13 May 2016 15:46:15 +0200 Subject: [PATCH] common: use cmd/wdata/rdata stream on LiteDRAMPort --- litedram/common.py | 29 ++++++++++++++---- litedram/frontend/bridge.py | 22 +++++++------- litedram/frontend/crossbar.py | 57 ++++++++++++----------------------- litedram/frontend/dma.py | 33 +++++++++----------- 4 files changed, 68 insertions(+), 73 deletions(-) diff --git a/litedram/common.py b/litedram/common.py index 8f7c98c..a04a25d 100644 --- a/litedram/common.py +++ b/litedram/common.py @@ -1,4 +1,5 @@ from litex.gen import * +from litex.soc.interconnect import stream class PhySettings: def __init__(self, memtype, dfi_databits, @@ -47,10 +48,8 @@ def cmd_layout(aw): ("adr", aw, DIR_M_TO_S), ("lock", 1, DIR_S_TO_M), # only used internally - ("wdata_valid", 1, DIR_M_TO_S), ("wdata_ready", 1, DIR_S_TO_M), - ("rdata_valid", 1, DIR_S_TO_M), - ("rdata_ready", 1, DIR_M_TO_S) + ("rdata_valid", 1, DIR_S_TO_M) ] @@ -73,15 +72,33 @@ class LiteDRAMInterface(Record): layout += data_layout(self.dw) Record.__init__(self, layout) +def cmd_description(aw): + return [ + ("we", 1), + ("adr", aw) + ] -class LiteDRAMPort(Record): +def wdata_description(dw): + return [ + ("data", dw), + ("we", dw//8) + ] + +def rdata_description(dw): + return [("data", dw)] + + +class LiteDRAMPort: def __init__(self, aw, dw, cd): self.aw = aw self.dw = dw self.cd = cd - layout = cmd_layout(aw) + data_layout(dw) - Record.__init__(self, layout) + self.lock = Signal() + + self.cmd = stream.Endpoint(cmd_description(aw)) + self.wdata = stream.Endpoint(wdata_description(dw)) + self.rdata = stream.Endpoint(rdata_description(dw)) def cmd_request_layout(a, ba): diff --git a/litedram/frontend/bridge.py b/litedram/frontend/bridge.py index 0f02924..51c199b 100644 --- a/litedram/frontend/bridge.py +++ b/litedram/frontend/bridge.py @@ -14,9 +14,9 @@ class LiteDRAMWishboneBridge(Module): ) ) fsm.act("REQUEST", - port.valid.eq(1), - port.we.eq(wishbone.we), - If(port.ready, + port.cmd.valid.eq(1), + port.cmd.we.eq(wishbone.we), + If(port.cmd.ready, If(wishbone.we, NextState("WRITE_DATA") ).Else( @@ -25,15 +25,15 @@ class LiteDRAMWishboneBridge(Module): ) ) fsm.act("WRITE_DATA", - port.wdata_valid.eq(1), - If(port.wdata_ready, + port.wdata.valid.eq(1), + If(port.wdata.ready, wishbone.ack.eq(1), NextState("IDLE") ) ) fsm.act("READ_DATA", - port.rdata_ready.eq(1), - If(port.rdata_valid, + port.rdata.ready.eq(1), + If(port.rdata.valid, wishbone.ack.eq(1), NextState("IDLE") ) @@ -41,8 +41,8 @@ class LiteDRAMWishboneBridge(Module): # Address / Datapath self.comb += [ - port.adr.eq(wishbone.adr), - port.wdata_we.eq(wishbone.sel), - port.wdata.eq(wishbone.dat_w), - wishbone.dat_r.eq(port.rdata) + port.cmd.adr.eq(wishbone.adr), + port.wdata.we.eq(wishbone.sel), + port.wdata.data.eq(wishbone.dat_w), + wishbone.dat_r.eq(port.rdata.data) ] diff --git a/litedram/frontend/crossbar.py b/litedram/frontend/crossbar.py index 0786bb7..38b6439 100644 --- a/litedram/frontend/crossbar.py +++ b/litedram/frontend/crossbar.py @@ -21,43 +21,24 @@ class LiteDRAMAsyncAdapter(Module): cmd_fifo = ClockDomainsRenamer({"write": cd_from, "read": cd_to})(cmd_fifo) self.submodules += cmd_fifo self.comb += [ - cmd_fifo.sink.valid.eq(port_from.valid), - cmd_fifo.sink.we.eq(port_from.we), - cmd_fifo.sink.adr.eq(port_from.adr), - port_from.ready.eq(cmd_fifo.sink.ready), - - port_to.valid.eq(cmd_fifo.source.valid), - port_to.we.eq(cmd_fifo.source.we), - port_to.adr.eq(cmd_fifo.source.adr), - cmd_fifo.source.ready.eq(port_to.ready) + port_from.cmd.connect(cmd_fifo.sink), + cmd_fifo.source.connect(port_to.cmd) ] wdata_fifo = stream.AsyncFIFO([("data", dw), ("we", dw//8)], 4) wdata_fifo = ClockDomainsRenamer({"write": cd_from, "read": cd_to})(wdata_fifo) self.submodules += wdata_fifo self.comb += [ - wdata_fifo.sink.valid.eq(port_from.wdata_valid), - wdata_fifo.sink.data.eq(port_from.wdata), - wdata_fifo.sink.we.eq(port_from.wdata_we), - port_from.wdata_ready.eq(wdata_fifo.sink.ready), - - port_to.wdata_valid.eq(wdata_fifo.source.valid), - port_to.wdata.eq(wdata_fifo.source.data), - port_to.wdata_we.eq(wdata_fifo.source.we), - wdata_fifo.source.ready.eq(port_to.wdata_ready) + port_from.wdata.connect(wdata_fifo.sink), + wdata_fifo.source.connect(port_to.wdata) ] rdata_fifo = stream.AsyncFIFO([("data", dw)], 4) rdata_fifo = ClockDomainsRenamer({"write": cd_to, "read": cd_from})(rdata_fifo) self.submodules += rdata_fifo self.comb += [ - rdata_fifo.sink.valid.eq(port_to.rdata_valid), - rdata_fifo.sink.data.eq(port_to.rdata), - port_to.rdata_ready.eq(rdata_fifo.sink.ready), - - port_from.rdata_valid.eq(rdata_fifo.source.valid), - port_from.rdata.eq(rdata_fifo.source.data), - rdata_fifo.source.ready.eq(port_from.rdata_ready) + port_to.rdata.connect(rddata_fifo.sink), + rddata_fifo.source.connect(port_from.rdata) ] @@ -118,7 +99,7 @@ class LiteDRAMCrossbar(Module): # arbitrate bank_selected = [(ba == nb) & ~locked for ba, locked in zip(m_ba, master_locked)] - bank_requested = [bs & master.valid for bs, master in zip(bank_selected, self.masters)] + bank_requested = [bs & master.cmd.valid for bs, master in zip(bank_selected, self.masters)] self.comb += [ arbiter.request.eq(Cat(*bank_requested)), arbiter.ce.eq(~bank.valid & ~bank.lock) @@ -127,7 +108,7 @@ class LiteDRAMCrossbar(Module): # route requests self.comb += [ bank.adr.eq(Array(m_rca)[arbiter.grant]), - bank.we.eq(Array(self.masters)[arbiter.grant].we), + bank.we.eq(Array(self.masters)[arbiter.grant].cmd.we), bank.valid.eq(Array(bank_requested)[arbiter.grant]) ] master_readys = [master_ready | ((arbiter.grant == nm) & bank_selected[nm] & bank.ready) @@ -152,18 +133,18 @@ class LiteDRAMCrossbar(Module): master_rdata_valids[nm] = master_rdata_valid for master, master_ready in zip(self.masters, master_readys): - self.comb += master.ready.eq(master_ready) + self.comb += master.cmd.ready.eq(master_ready) for master, master_wdata_ready in zip(self.masters, master_wdata_readys): - self.comb += master.wdata_ready.eq(master_wdata_ready) + self.comb += master.wdata.ready.eq(master_wdata_ready) for master, master_rdata_valid in zip(self.masters, master_rdata_valids): - self.comb += master.rdata_valid.eq(master_rdata_valid) + self.comb += master.rdata.valid.eq(master_rdata_valid) # route data writes wdata_cases = {} for nm, master in enumerate(self.masters): wdata_cases[2**nm] = [ - controller.wdata.eq(master.wdata), - controller.wdata_we.eq(master.wdata_we) + controller.wdata.eq(master.wdata.data), + controller.wdata_we.eq(master.wdata.we) ] wdata_cases["default"] = [ controller.wdata.eq(0), @@ -173,7 +154,7 @@ class LiteDRAMCrossbar(Module): # route data reads for master in self.masters: - self.comb += master.rdata.eq(self.controller.rdata) + self.comb += master.rdata.data.eq(self.controller.rdata) def split_master_addresses(self, bank_bits, rca_bits, cba_shift): m_ba = [] # bank address @@ -182,15 +163,15 @@ class LiteDRAMCrossbar(Module): cba = Signal(self.bank_bits) rca = Signal(self.rca_bits) cba_upper = cba_shift + bank_bits - self.comb += cba.eq(master.adr[cba_shift:cba_upper]) + self.comb += cba.eq(master.cmd.adr[cba_shift:cba_upper]) if cba_shift < self.rca_bits: if cba_shift: - self.comb += rca.eq(Cat(master.adr[:cba_shift], - master.adr[cba_upper:])) + self.comb += rca.eq(Cat(master.cmd.adr[:cba_shift], + master.cmd.adr[cba_upper:])) else: - self.comb += rca.eq(master.adr[cba_upper:]) + self.comb += rca.eq(master.cmd.adr[cba_upper:]) else: - self.comb += rca.eq(master.adr[:cba_shift]) + self.comb += rca.eq(master.cmd.adr[:cba_shift]) ba = cba diff --git a/litedram/frontend/dma.py b/litedram/frontend/dma.py index 278567d..9008b11 100644 --- a/litedram/frontend/dma.py +++ b/litedram/frontend/dma.py @@ -15,11 +15,11 @@ class LiteDRAMDMAReader(Module): request_issued = Signal() self.comb += [ - port.we.eq(0), - port.valid.eq(sink.valid & request_enable), - port.adr.eq(sink.address), - sink.ready.eq(port.ready & request_enable), - request_issued.eq(port.valid & port.ready) + port.cmd.we.eq(0), + port.cmd.valid.eq(sink.valid & request_enable), + port.cmd.adr.eq(sink.address), + sink.ready.eq(port.cmd.ready & request_enable), + request_issued.eq(port.cmd.valid & port.cmd.ready) ] # FIFO reservation level counter @@ -41,10 +41,7 @@ class LiteDRAMDMAReader(Module): self.submodules += fifo self.comb += [ - fifo.sink.data.eq(port.rdata), - fifo.sink.valid.eq(port.rdata_valid), - port.rdata_ready.eq(fifo.sink.ready), - + port.rdata.connect(fifo.sink), fifo.source.connect(source), data_dequeued.eq(source.valid & source.ready) ] @@ -61,17 +58,17 @@ class LiteDRAMDMAWriter(Module): self.submodules += fifo self.comb += [ - port.we.eq(1), - port.valid.eq(fifo.sink.ready & sink.valid), - port.adr.eq(sink.address), - sink.ready.eq(fifo.sink.ready & port.ready), - fifo.sink.valid.eq(sink.valid & port.ready), + port.cmd.we.eq(1), + port.cmd.valid.eq(fifo.sink.ready & sink.valid), + port.cmd.adr.eq(sink.address), + sink.ready.eq(fifo.sink.ready & port.cmd.ready), + fifo.sink.valid.eq(sink.valid & port.cmd.ready), fifo.sink.data.eq(sink.data) ] self.comb += [ - port.wdata_valid.eq(fifo.source.valid), - fifo.source.ready.eq(port.wdata_ready), - port.wdata_we.eq(2**(port.dw//8)-1), - port.wdata.eq(fifo.source.data) + port.wdata.valid.eq(fifo.source.valid), + fifo.source.ready.eq(port.wdata.ready), + port.wdata.we.eq(2**(port.dw//8)-1), + port.wdata.data.eq(fifo.source.data) ]