common: use cmd/wdata/rdata stream on LiteDRAMPort

This commit is contained in:
Florent Kermarrec 2016-05-13 15:46:15 +02:00
parent 30bacfeb1b
commit 8d066caea9
4 changed files with 68 additions and 73 deletions

View File

@ -1,4 +1,5 @@
from litex.gen import * from litex.gen import *
from litex.soc.interconnect import stream
class PhySettings: class PhySettings:
def __init__(self, memtype, dfi_databits, def __init__(self, memtype, dfi_databits,
@ -47,10 +48,8 @@ def cmd_layout(aw):
("adr", aw, DIR_M_TO_S), ("adr", aw, DIR_M_TO_S),
("lock", 1, DIR_S_TO_M), # only used internally ("lock", 1, DIR_S_TO_M), # only used internally
("wdata_valid", 1, DIR_M_TO_S),
("wdata_ready", 1, DIR_S_TO_M), ("wdata_ready", 1, DIR_S_TO_M),
("rdata_valid", 1, DIR_S_TO_M), ("rdata_valid", 1, DIR_S_TO_M)
("rdata_ready", 1, DIR_M_TO_S)
] ]
@ -73,15 +72,33 @@ class LiteDRAMInterface(Record):
layout += data_layout(self.dw) layout += data_layout(self.dw)
Record.__init__(self, layout) 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): def __init__(self, aw, dw, cd):
self.aw = aw self.aw = aw
self.dw = dw self.dw = dw
self.cd = cd self.cd = cd
layout = cmd_layout(aw) + data_layout(dw) self.lock = Signal()
Record.__init__(self, layout)
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): def cmd_request_layout(a, ba):

View File

@ -14,9 +14,9 @@ class LiteDRAMWishboneBridge(Module):
) )
) )
fsm.act("REQUEST", fsm.act("REQUEST",
port.valid.eq(1), port.cmd.valid.eq(1),
port.we.eq(wishbone.we), port.cmd.we.eq(wishbone.we),
If(port.ready, If(port.cmd.ready,
If(wishbone.we, If(wishbone.we,
NextState("WRITE_DATA") NextState("WRITE_DATA")
).Else( ).Else(
@ -25,15 +25,15 @@ class LiteDRAMWishboneBridge(Module):
) )
) )
fsm.act("WRITE_DATA", fsm.act("WRITE_DATA",
port.wdata_valid.eq(1), port.wdata.valid.eq(1),
If(port.wdata_ready, If(port.wdata.ready,
wishbone.ack.eq(1), wishbone.ack.eq(1),
NextState("IDLE") NextState("IDLE")
) )
) )
fsm.act("READ_DATA", fsm.act("READ_DATA",
port.rdata_ready.eq(1), port.rdata.ready.eq(1),
If(port.rdata_valid, If(port.rdata.valid,
wishbone.ack.eq(1), wishbone.ack.eq(1),
NextState("IDLE") NextState("IDLE")
) )
@ -41,8 +41,8 @@ class LiteDRAMWishboneBridge(Module):
# Address / Datapath # Address / Datapath
self.comb += [ self.comb += [
port.adr.eq(wishbone.adr), port.cmd.adr.eq(wishbone.adr),
port.wdata_we.eq(wishbone.sel), port.wdata.we.eq(wishbone.sel),
port.wdata.eq(wishbone.dat_w), port.wdata.data.eq(wishbone.dat_w),
wishbone.dat_r.eq(port.rdata) wishbone.dat_r.eq(port.rdata.data)
] ]

View File

@ -21,43 +21,24 @@ class LiteDRAMAsyncAdapter(Module):
cmd_fifo = ClockDomainsRenamer({"write": cd_from, "read": cd_to})(cmd_fifo) cmd_fifo = ClockDomainsRenamer({"write": cd_from, "read": cd_to})(cmd_fifo)
self.submodules += cmd_fifo self.submodules += cmd_fifo
self.comb += [ self.comb += [
cmd_fifo.sink.valid.eq(port_from.valid), port_from.cmd.connect(cmd_fifo.sink),
cmd_fifo.sink.we.eq(port_from.we), cmd_fifo.source.connect(port_to.cmd)
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)
] ]
wdata_fifo = stream.AsyncFIFO([("data", dw), ("we", dw//8)], 4) wdata_fifo = stream.AsyncFIFO([("data", dw), ("we", dw//8)], 4)
wdata_fifo = ClockDomainsRenamer({"write": cd_from, "read": cd_to})(wdata_fifo) wdata_fifo = ClockDomainsRenamer({"write": cd_from, "read": cd_to})(wdata_fifo)
self.submodules += wdata_fifo self.submodules += wdata_fifo
self.comb += [ self.comb += [
wdata_fifo.sink.valid.eq(port_from.wdata_valid), port_from.wdata.connect(wdata_fifo.sink),
wdata_fifo.sink.data.eq(port_from.wdata), wdata_fifo.source.connect(port_to.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)
] ]
rdata_fifo = stream.AsyncFIFO([("data", dw)], 4) rdata_fifo = stream.AsyncFIFO([("data", dw)], 4)
rdata_fifo = ClockDomainsRenamer({"write": cd_to, "read": cd_from})(rdata_fifo) rdata_fifo = ClockDomainsRenamer({"write": cd_to, "read": cd_from})(rdata_fifo)
self.submodules += rdata_fifo self.submodules += rdata_fifo
self.comb += [ self.comb += [
rdata_fifo.sink.valid.eq(port_to.rdata_valid), port_to.rdata.connect(rddata_fifo.sink),
rdata_fifo.sink.data.eq(port_to.rdata), rddata_fifo.source.connect(port_from.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)
] ]
@ -118,7 +99,7 @@ class LiteDRAMCrossbar(Module):
# arbitrate # arbitrate
bank_selected = [(ba == nb) & ~locked for ba, locked in zip(m_ba, master_locked)] 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 += [ self.comb += [
arbiter.request.eq(Cat(*bank_requested)), arbiter.request.eq(Cat(*bank_requested)),
arbiter.ce.eq(~bank.valid & ~bank.lock) arbiter.ce.eq(~bank.valid & ~bank.lock)
@ -127,7 +108,7 @@ class LiteDRAMCrossbar(Module):
# route requests # route requests
self.comb += [ self.comb += [
bank.adr.eq(Array(m_rca)[arbiter.grant]), 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]) bank.valid.eq(Array(bank_requested)[arbiter.grant])
] ]
master_readys = [master_ready | ((arbiter.grant == nm) & bank_selected[nm] & bank.ready) 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 master_rdata_valids[nm] = master_rdata_valid
for master, master_ready in zip(self.masters, master_readys): 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): 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): 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 # route data writes
wdata_cases = {} wdata_cases = {}
for nm, master in enumerate(self.masters): for nm, master in enumerate(self.masters):
wdata_cases[2**nm] = [ wdata_cases[2**nm] = [
controller.wdata.eq(master.wdata), controller.wdata.eq(master.wdata.data),
controller.wdata_we.eq(master.wdata_we) controller.wdata_we.eq(master.wdata.we)
] ]
wdata_cases["default"] = [ wdata_cases["default"] = [
controller.wdata.eq(0), controller.wdata.eq(0),
@ -173,7 +154,7 @@ class LiteDRAMCrossbar(Module):
# route data reads # route data reads
for master in self.masters: 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): def split_master_addresses(self, bank_bits, rca_bits, cba_shift):
m_ba = [] # bank address m_ba = [] # bank address
@ -182,15 +163,15 @@ class LiteDRAMCrossbar(Module):
cba = Signal(self.bank_bits) cba = Signal(self.bank_bits)
rca = Signal(self.rca_bits) rca = Signal(self.rca_bits)
cba_upper = cba_shift + bank_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.rca_bits:
if cba_shift: if cba_shift:
self.comb += rca.eq(Cat(master.adr[:cba_shift], self.comb += rca.eq(Cat(master.cmd.adr[:cba_shift],
master.adr[cba_upper:])) master.cmd.adr[cba_upper:]))
else: else:
self.comb += rca.eq(master.adr[cba_upper:]) self.comb += rca.eq(master.cmd.adr[cba_upper:])
else: else:
self.comb += rca.eq(master.adr[:cba_shift]) self.comb += rca.eq(master.cmd.adr[:cba_shift])
ba = cba ba = cba

View File

@ -15,11 +15,11 @@ class LiteDRAMDMAReader(Module):
request_issued = Signal() request_issued = Signal()
self.comb += [ self.comb += [
port.we.eq(0), port.cmd.we.eq(0),
port.valid.eq(sink.valid & request_enable), port.cmd.valid.eq(sink.valid & request_enable),
port.adr.eq(sink.address), port.cmd.adr.eq(sink.address),
sink.ready.eq(port.ready & request_enable), sink.ready.eq(port.cmd.ready & request_enable),
request_issued.eq(port.valid & port.ready) request_issued.eq(port.cmd.valid & port.cmd.ready)
] ]
# FIFO reservation level counter # FIFO reservation level counter
@ -41,10 +41,7 @@ class LiteDRAMDMAReader(Module):
self.submodules += fifo self.submodules += fifo
self.comb += [ self.comb += [
fifo.sink.data.eq(port.rdata), port.rdata.connect(fifo.sink),
fifo.sink.valid.eq(port.rdata_valid),
port.rdata_ready.eq(fifo.sink.ready),
fifo.source.connect(source), fifo.source.connect(source),
data_dequeued.eq(source.valid & source.ready) data_dequeued.eq(source.valid & source.ready)
] ]
@ -61,17 +58,17 @@ class LiteDRAMDMAWriter(Module):
self.submodules += fifo self.submodules += fifo
self.comb += [ self.comb += [
port.we.eq(1), port.cmd.we.eq(1),
port.valid.eq(fifo.sink.ready & sink.valid), port.cmd.valid.eq(fifo.sink.ready & sink.valid),
port.adr.eq(sink.address), port.cmd.adr.eq(sink.address),
sink.ready.eq(fifo.sink.ready & port.ready), sink.ready.eq(fifo.sink.ready & port.cmd.ready),
fifo.sink.valid.eq(sink.valid & port.ready), fifo.sink.valid.eq(sink.valid & port.cmd.ready),
fifo.sink.data.eq(sink.data) fifo.sink.data.eq(sink.data)
] ]
self.comb += [ self.comb += [
port.wdata_valid.eq(fifo.source.valid), port.wdata.valid.eq(fifo.source.valid),
fifo.source.ready.eq(port.wdata_ready), fifo.source.ready.eq(port.wdata.ready),
port.wdata_we.eq(2**(port.dw//8)-1), port.wdata.we.eq(2**(port.dw//8)-1),
port.wdata.eq(fifo.source.data) port.wdata.data.eq(fifo.source.data)
] ]