Initial implementation of out of order controller
This commit is contained in:
parent
f1fea6dbd6
commit
2fa2a6d9f2
|
@ -56,11 +56,12 @@ def cmd_layout(aw):
|
|||
]
|
||||
|
||||
|
||||
def data_layout(dw):
|
||||
def data_layout(dw, bankbits):
|
||||
return [
|
||||
("wdata", dw, DIR_M_TO_S),
|
||||
("wdata_we", dw//8, DIR_M_TO_S),
|
||||
("rdata", dw, DIR_S_TO_M)
|
||||
("rdata", dw, DIR_S_TO_M),
|
||||
("rbank", bankbits, DIR_S_TO_M)
|
||||
]
|
||||
|
||||
|
||||
|
@ -72,7 +73,7 @@ class LiteDRAMInterface(Record):
|
|||
self.settings = settings
|
||||
|
||||
layout = [("bank"+str(i), cmd_layout(self.aw)) for i in range(self.nbanks)]
|
||||
layout += data_layout(self.dw)
|
||||
layout += data_layout(self.dw, settings.geom.bankbits)
|
||||
Record.__init__(self, layout)
|
||||
|
||||
def cmd_description(aw):
|
||||
|
@ -87,12 +88,12 @@ def wdata_description(dw):
|
|||
("we", dw//8)
|
||||
]
|
||||
|
||||
def rdata_description(dw):
|
||||
return [("data", dw)]
|
||||
def rdata_description(dw, nbanks):
|
||||
return [("data", dw), ("bank", nbanks)]
|
||||
|
||||
|
||||
class LiteDRAMPort:
|
||||
def __init__(self, mode, aw, dw, cd="sys", id=0):
|
||||
def __init__(self, mode, aw, dw, bankbits, cd="sys", id=0):
|
||||
self.mode = mode
|
||||
self.aw = aw
|
||||
self.dw = dw
|
||||
|
@ -103,7 +104,7 @@ class LiteDRAMPort:
|
|||
|
||||
self.cmd = stream.Endpoint(cmd_description(aw))
|
||||
self.wdata = stream.Endpoint(wdata_description(dw))
|
||||
self.rdata = stream.Endpoint(rdata_description(dw))
|
||||
self.rdata = stream.Endpoint(rdata_description(dw, bankbits))
|
||||
|
||||
self.flush = Signal()
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@ class LiteDRAMCrossbar(Module):
|
|||
dw = self.dw
|
||||
|
||||
# crossbar port
|
||||
port = LiteDRAMPort(mode, self.rca_bits + self.bank_bits, self.dw, "sys", len(self.masters))
|
||||
port = LiteDRAMPort(mode, self.rca_bits + self.bank_bits, self.dw, self.bank_bits, "sys", len(self.masters))
|
||||
self.masters.append(port)
|
||||
|
||||
# clock domain crossing
|
||||
if cd != "sys":
|
||||
new_port = LiteDRAMPort(mode, port.aw, port.dw, cd, port.id)
|
||||
new_port = LiteDRAMPort(mode, port.aw, port.dw, self.bank_bits, cd, port.id)
|
||||
self.submodules += LiteDRAMPortCDC(new_port, port)
|
||||
port = new_port
|
||||
|
||||
|
@ -48,7 +48,7 @@ class LiteDRAMCrossbar(Module):
|
|||
adr_shift = -log2_int(dw//self.dw)
|
||||
else:
|
||||
adr_shift = log2_int(self.dw//dw)
|
||||
new_port = LiteDRAMPort(mode, port.aw + adr_shift, dw, cd, port.id)
|
||||
new_port = LiteDRAMPort(mode, port.aw + adr_shift, dw, self.bank_bits, cd, port.id)
|
||||
self.submodules += ClockDomainsRenamer(cd)(LiteDRAMPortConverter(new_port, port, reverse))
|
||||
port = new_port
|
||||
|
||||
|
@ -68,6 +68,8 @@ class LiteDRAMCrossbar(Module):
|
|||
|
||||
arbiters = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self.nbanks)]
|
||||
self.submodules += arbiters
|
||||
|
||||
rbank = Signal(max=self.nbanks)
|
||||
for nb, arbiter in enumerate(arbiters):
|
||||
bank = getattr(controller, "bank"+str(nb))
|
||||
|
||||
|
@ -89,6 +91,12 @@ class LiteDRAMCrossbar(Module):
|
|||
arbiter.ce.eq(~bank.valid & ~bank.lock)
|
||||
]
|
||||
|
||||
# Get rdata source bank
|
||||
self.sync += \
|
||||
If((arbiter.grant == nm) & bank.rdata_valid,
|
||||
rbank.eq(nb)
|
||||
)
|
||||
|
||||
# route requests
|
||||
self.comb += [
|
||||
bank.adr.eq(Array(m_rca)[arbiter.grant]),
|
||||
|
@ -116,6 +124,12 @@ class LiteDRAMCrossbar(Module):
|
|||
master_rdata_valid = new_master_rdata_valid
|
||||
master_rdata_valids[nm] = master_rdata_valid
|
||||
|
||||
# Delay bank output to match rvalid
|
||||
for i in range(self.read_latency-1):
|
||||
new_master_rbank = Signal(max=self.nbanks)
|
||||
self.sync += new_master_rbank.eq(rbank)
|
||||
rbank = new_master_rbank
|
||||
|
||||
for master, master_ready in zip(self.masters, master_readys):
|
||||
self.comb += master.cmd.ready.eq(master_ready)
|
||||
for master, master_wdata_ready in zip(self.masters, master_wdata_readys):
|
||||
|
@ -139,15 +153,18 @@ class LiteDRAMCrossbar(Module):
|
|||
# route data reads
|
||||
for master in self.masters:
|
||||
self.comb += master.rdata.data.eq(self.controller.rdata)
|
||||
self.comb += master.rdata.bank.eq(rbank)
|
||||
|
||||
def split_master_addresses(self, bank_bits, rca_bits, cba_shift):
|
||||
m_ba = [] # bank address
|
||||
m_rca = [] # row and column address
|
||||
print("cba_shift: " + str(cba_shift))
|
||||
for master in self.masters:
|
||||
cba = Signal(self.bank_bits)
|
||||
rca = Signal(self.rca_bits)
|
||||
cba_upper = cba_shift + bank_bits
|
||||
self.comb += cba.eq(master.cmd.adr[cba_shift:cba_upper])
|
||||
print("cba_shift: " + str(cba_shift) + " cba_upper: " + str(cba_upper))
|
||||
if cba_shift < self.rca_bits:
|
||||
if cba_shift:
|
||||
self.comb += rca.eq(Cat(master.cmd.adr[:cba_shift],
|
||||
|
|
|
@ -69,7 +69,7 @@ class LiteDRAMDMAReader(Module):
|
|||
self.submodules += fifo
|
||||
|
||||
self.comb += [
|
||||
port.rdata.connect(fifo.sink),
|
||||
port.rdata.connect(fifo.sink, omit=["bank"]),
|
||||
fifo.source.connect(source),
|
||||
data_dequeued.eq(source.valid & source.ready)
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue