__ALL__ = ["gramCrossbar"]
+class DelayLine(Elaboratable):
+ def __init__(self, delay):
+ if delay < 1:
+ raise ValueError("delay value must be 1+")
+ self.delay = delay
+
+ self.i = Signal()
+ self.o = Signal()
+
+ def elaborate(self, platform):
+ m = Module()
+
+ buffer = Signal(self.delay)
+ m.d.sync += [
+ buffer.eq(Cat(self.i, buffer))
+ ]
+ m.d.comb += self.o.eq(buffer[-1])
+
+ return m
+
class gramCrossbar(Elaboratable):
"""Multiplexes LiteDRAMController (slave) between ports (masters)
for other_nb, other_arbiter in enumerate(arbiters):
if other_nb != nb:
other_bank = getattr(controller, "bank"+str(other_nb))
- locked = locked | (other_bank.lock & (
- other_arbiter.grant == nm))
+ locked = locked | (other_bank.lock & (other_arbiter.grant == nm))
master_locked.append(locked)
# Arbitrate ----------------------------------------------------------------------------
# Delay write/read signals based on their latency
for nm, master_wdata_ready in enumerate(master_wdata_readys):
- for i in range(self.write_latency):
- new_master_wdata_ready = Signal()
- m.d.sync += new_master_wdata_ready.eq(master_wdata_ready)
- master_wdata_ready = new_master_wdata_ready
- master_wdata_readys[nm] = master_wdata_ready
+ delayline = DelayLine(self.write_latency)
+ m.submodules += delayline
+ m.d.comb += delayline.i.eq(master_wdata_ready)
+ master_wdata_readys[nm] = delayline.o
for nm, master_rdata_valid in enumerate(master_rdata_valids):
- for i in range(self.read_latency):
- new_master_rdata_valid = Signal()
- m.d.sync += new_master_rdata_valid.eq(master_rdata_valid)
- master_rdata_valid = new_master_rdata_valid
- master_rdata_valids[nm] = master_rdata_valid
+ delayline = DelayLine(self.read_latency)
+ m.submodules += delayline
+ m.d.comb += delayline.i.eq(master_rdata_valid)
+ master_rdata_valids[nm] = delayline.o
for master, master_ready in zip(self.masters, master_readys):
m.d.comb += master.cmd.ready.eq(master_ready)
m.d.comb += twtrcon.valid.eq(choose_req.accept() & choose_req.write())
# Read/write turnaround --------------------------------------------------------------------
- read_available = Signal()
- write_available = Signal()
- reads = [req.valid & req.is_read for req in requests]
- writes = [req.valid & req.is_write for req in requests]
- m.d.comb += [
- read_available.eq(reads.any()),
- write_available.eq(writes.any())
- ]
+ reads = Signal(len(requests))
+ m.d.comb += reads.eq(Cat([req.valid & req.is_read for req in requests]))
+ writes = Signal(len(requests))
+ m.d.comb += writes.eq(Cat([req.valid & req.is_write for req in requests]))
# Anti Starvation --------------------------------------------------------------------------
m.submodules.read_antistarvation = read_antistarvation = _AntiStarvation(settings.read_time)
# Refresh ----------------------------------------------------------------------------------
m.d.comb += [bm.refresh_req.eq(refresher.cmd.valid) for bm in bank_machines]
- go_to_refresh = Signal()
- bm_refresh_gnts = [bm.refresh_gnt for bm in bank_machines]
- m.d.comb += go_to_refresh.eq(bm_refresh_gnts.all())
+ bm_refresh_gnts = Signal(len(bank_machines))
+ m.d.comb += bm_refresh_gnts.eq(Cat([bm.refresh_gnt for bm in bank_machines]))
# Datapath ---------------------------------------------------------------------------------
all_rddata = [p.rddata for p in dfi.phases]
choose_req.cmd.ready.eq(cas_allowed),
]
- with m.If(write_available):
- # TODO: switch only after several cycles of ~read_available?
- with m.If(~read_available | read_antistarvation.max_time):
+ with m.If(writes.any()):
+ # TODO: switch only after several cycles of ~reads.any()?
+ with m.If(~reads.any() | read_antistarvation.max_time):
m.next = "RTW"
- with m.If(go_to_refresh):
+ with m.If(bm_refresh_gnts.all()):
m.next = "Refresh"
with m.State("Write"):
choose_req.cmd.ready.eq(cas_allowed),
]
- with m.If(read_available):
- with m.If(~write_available | write_antistarvation.max_time):
+ with m.If(reads.any()):
+ with m.If(~writes.any() | write_antistarvation.max_time):
m.next = "WTR"
- with m.If(go_to_refresh):
+ with m.If(bm_refresh_gnts.all()):
m.next = "Refresh"
with m.State("Refresh"):