frontend: add LiteDRAMAsyncAdapter for asynchronous ports (need more tests)

This commit is contained in:
Florent Kermarrec 2016-05-13 15:27:12 +02:00
parent 19a0bd59d2
commit 30bacfeb1b
6 changed files with 78 additions and 11 deletions

View File

@ -45,10 +45,12 @@ def cmd_layout(aw):
("ready", 1, DIR_S_TO_M),
("we", 1, DIR_M_TO_S),
("adr", aw, DIR_M_TO_S),
("lock", 1, DIR_S_TO_M),
("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_valid", 1, DIR_S_TO_M),
("rdata_ready", 1, DIR_M_TO_S)
]
@ -73,9 +75,10 @@ class LiteDRAMInterface(Record):
class LiteDRAMPort(Record):
def __init__(self, aw, dw):
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)

View File

@ -46,7 +46,9 @@ class BankMachine(Module):
settings.cmd_buffer_depth)
self.submodules += cmd_buffer
self.comb += [
req.connect(cmd_buffer.sink, omit=["wdata_ready", "rdata_valid", "lock"]),
req.connect(cmd_buffer.sink, omit=["wdata_valid", "wdata_ready",
"rdata_valid", "rdata_ready",
"lock"]),
cmd_buffer.source.ready.eq(req.wdata_ready | req.rdata_valid),
req.lock.eq(cmd_buffer.source.valid),
]

View File

@ -25,12 +25,14 @@ class LiteDRAMWishboneBridge(Module):
)
)
fsm.act("WRITE_DATA",
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,
wishbone.ack.eq(1),
NextState("IDLE")

View File

@ -4,8 +4,62 @@ from operator import or_
from litex.gen import *
from litex.gen.genlib import roundrobin
from litex.soc.interconnect import stream
from litedram.common import *
class LiteDRAMAsyncAdapter(Module):
def __init__(self, port_from, port_to):
aw = port_from.aw
dw = port_from.dw
cd_from = port_from.cd
cd_to = port_from.cd
# # #
cmd_fifo = stream.AsyncFIFO([("we", 1), ("adr", aw)], 4)
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)
]
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)
]
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)
]
class LiteDRAMCrossbar(Module):
def __init__(self, controller, cba_shift):
@ -23,13 +77,17 @@ class LiteDRAMCrossbar(Module):
self.masters = []
def get_port(self):
def get_port(self, cd="sys"):
if self.finalized:
raise FinalizeError
port = LiteDRAMPort(self.rca_bits + self.bank_bits,
self.dw)
self.masters.append(port)
return port
port_to = LiteDRAMPort(self.rca_bits + self.bank_bits, self.dw, "sys")
self.masters.append(port_to)
if cd != "sys":
port_from = LiteDRAMPort(self.rca_bits + self.bank_bits, self.dw, cd)
self.submodules += LiteDRAMAsyncAdapter(port_from, port_to)
return port_from
else:
return port_to
def do_finalize(self):
nmasters = len(self.masters)

View File

@ -43,6 +43,7 @@ class LiteDRAMDMAReader(Module):
self.comb += [
fifo.sink.data.eq(port.rdata),
fifo.sink.valid.eq(port.rdata_valid),
port.rdata_ready.eq(fifo.sink.ready),
fifo.source.connect(source),
data_dequeued.eq(source.valid & source.ready)
@ -69,6 +70,7 @@ class LiteDRAMDMAWriter(Module):
]
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)

View File

@ -8,8 +8,8 @@ from litedram.frontend.bist import LiteDRAMBISTChecker
class TB(Module):
def __init__(self):
self.write_port = LiteDRAMPort(aw=32, dw=32)
self.read_port = LiteDRAMPort(aw=32, dw=32)
self.write_port = LiteDRAMPort(aw=32, dw=32, cd="sys")
self.read_port = LiteDRAMPort(aw=32, dw=32, cd="sys")
self.submodules.generator = LiteDRAMBISTGenerator(self.write_port)
self.submodules.checker = LiteDRAMBISTChecker(self.read_port)