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.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):

View File

@ -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)
]

View File

@ -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

View File

@ -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)
]