frotend/crossbar: make parameters public
This commit is contained in:
parent
cb32238b01
commit
400de46980
|
@ -9,49 +9,49 @@ from litedram.common import *
|
||||||
|
|
||||||
class LiteDRAMCrossbar(Module):
|
class LiteDRAMCrossbar(Module):
|
||||||
def __init__(self, controller, cba_shift):
|
def __init__(self, controller, cba_shift):
|
||||||
self._controller = controller
|
self.controller = controller
|
||||||
self._cba_shift = cba_shift
|
self.cba_shift = cba_shift
|
||||||
|
|
||||||
self._rca_bits = controller.aw
|
self.rca_bits = controller.aw
|
||||||
self._dw = controller.dw
|
self.dw = controller.dw
|
||||||
self._nbanks = controller.nbanks
|
self.nbanks = controller.nbanks
|
||||||
self._req_queue_size = controller.req_queue_size
|
self.req_queue_size = controller.req_queue_size
|
||||||
self._read_latency = controller.read_latency
|
self.read_latency = controller.read_latency
|
||||||
self._write_latency = controller.write_latency
|
self.write_latency = controller.write_latency
|
||||||
|
|
||||||
self._bank_bits = log2_int(self._nbanks, False)
|
self.bank_bits = log2_int(self.nbanks, False)
|
||||||
|
|
||||||
self._masters = []
|
self.masters = []
|
||||||
|
|
||||||
def get_port(self):
|
def get_port(self):
|
||||||
if self.finalized:
|
if self.finalized:
|
||||||
raise FinalizeError
|
raise FinalizeError
|
||||||
port = Interface(self._rca_bits + self._bank_bits,
|
port = Interface(self.rca_bits + self.bank_bits,
|
||||||
self._dw, 1, self._req_queue_size, self._read_latency, self._write_latency)
|
self.dw, 1, self.req_queue_size, self.read_latency, self.write_latency)
|
||||||
self._masters.append(port)
|
self.masters.append(port)
|
||||||
return port
|
return port
|
||||||
|
|
||||||
def do_finalize(self):
|
def do_finalize(self):
|
||||||
nmasters = len(self._masters)
|
nmasters = len(self.masters)
|
||||||
|
|
||||||
m_ba, m_rca = self._split_master_addresses(self._bank_bits,
|
m_ba, m_rca = self.split_master_addresses(self.bank_bits,
|
||||||
self._rca_bits,
|
self.rca_bits,
|
||||||
self._cba_shift)
|
self.cba_shift)
|
||||||
|
|
||||||
controller = self._controller
|
controller = self.controller
|
||||||
controller_selected = [1]*nmasters
|
controller_selected = [1]*nmasters
|
||||||
master_req_acks = [0]*nmasters
|
master_req_acks = [0]*nmasters
|
||||||
master_dat_w_acks = [0]*nmasters
|
master_dat_w_acks = [0]*nmasters
|
||||||
master_dat_r_acks = [0]*nmasters
|
master_dat_r_acks = [0]*nmasters
|
||||||
|
|
||||||
rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self._nbanks)]
|
rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self.nbanks)]
|
||||||
self.submodules += rrs
|
self.submodules += rrs
|
||||||
for nb, rr in enumerate(rrs):
|
for nb, rr in enumerate(rrs):
|
||||||
bank = getattr(controller, "bank"+str(nb))
|
bank = getattr(controller, "bank"+str(nb))
|
||||||
|
|
||||||
# for each master, determine if another bank locks it
|
# for each master, determine if another bank locks it
|
||||||
master_locked = []
|
master_locked = []
|
||||||
for nm, master in enumerate(self._masters):
|
for nm, master in enumerate(self.masters):
|
||||||
locked = 0
|
locked = 0
|
||||||
for other_nb, other_rr in enumerate(rrs):
|
for other_nb, other_rr in enumerate(rrs):
|
||||||
if other_nb != nb:
|
if other_nb != nb:
|
||||||
|
@ -61,7 +61,7 @@ class LiteDRAMCrossbar(Module):
|
||||||
|
|
||||||
# arbitrate
|
# arbitrate
|
||||||
bank_selected = [cs & (ba == nb) & ~locked for cs, ba, locked in zip(controller_selected, m_ba, master_locked)]
|
bank_selected = [cs & (ba == nb) & ~locked for cs, ba, locked in zip(controller_selected, m_ba, master_locked)]
|
||||||
bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self._masters)]
|
bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self.masters)]
|
||||||
self.comb += [
|
self.comb += [
|
||||||
rr.request.eq(Cat(*bank_requested)),
|
rr.request.eq(Cat(*bank_requested)),
|
||||||
rr.ce.eq(~bank.stb & ~bank.lock)
|
rr.ce.eq(~bank.stb & ~bank.lock)
|
||||||
|
@ -70,7 +70,7 @@ class LiteDRAMCrossbar(Module):
|
||||||
# route requests
|
# route requests
|
||||||
self.comb += [
|
self.comb += [
|
||||||
bank.adr.eq(Array(m_rca)[rr.grant]),
|
bank.adr.eq(Array(m_rca)[rr.grant]),
|
||||||
bank.we.eq(Array(self._masters)[rr.grant].we),
|
bank.we.eq(Array(self.masters)[rr.grant].we),
|
||||||
bank.stb.eq(Array(bank_requested)[rr.grant])
|
bank.stb.eq(Array(bank_requested)[rr.grant])
|
||||||
]
|
]
|
||||||
master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & bank.req_ack)
|
master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & bank.req_ack)
|
||||||
|
@ -81,34 +81,34 @@ class LiteDRAMCrossbar(Module):
|
||||||
for nm, master_dat_r_ack in enumerate(master_dat_r_acks)]
|
for nm, master_dat_r_ack in enumerate(master_dat_r_acks)]
|
||||||
|
|
||||||
for nm, master_dat_w_ack in enumerate(master_dat_w_acks):
|
for nm, master_dat_w_ack in enumerate(master_dat_w_acks):
|
||||||
for i in range(self._write_latency):
|
for i in range(self.write_latency):
|
||||||
new_master_dat_w_ack = Signal()
|
new_master_dat_w_ack = Signal()
|
||||||
self.sync += new_master_dat_w_ack.eq(master_dat_w_ack)
|
self.sync += new_master_dat_w_ack.eq(master_dat_w_ack)
|
||||||
master_dat_w_ack = new_master_dat_w_ack
|
master_dat_w_ack = new_master_dat_w_ack
|
||||||
master_dat_w_acks[nm] = master_dat_w_ack
|
master_dat_w_acks[nm] = master_dat_w_ack
|
||||||
|
|
||||||
for nm, master_dat_r_ack in enumerate(master_dat_r_acks):
|
for nm, master_dat_r_ack in enumerate(master_dat_r_acks):
|
||||||
for i in range(self._read_latency):
|
for i in range(self.read_latency):
|
||||||
new_master_dat_r_ack = Signal()
|
new_master_dat_r_ack = Signal()
|
||||||
self.sync += new_master_dat_r_ack.eq(master_dat_r_ack)
|
self.sync += new_master_dat_r_ack.eq(master_dat_r_ack)
|
||||||
master_dat_r_ack = new_master_dat_r_ack
|
master_dat_r_ack = new_master_dat_r_ack
|
||||||
master_dat_r_acks[nm] = master_dat_r_ack
|
master_dat_r_acks[nm] = master_dat_r_ack
|
||||||
|
|
||||||
self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self._masters, master_req_acks)]
|
self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self.masters, master_req_acks)]
|
||||||
self.comb += [master.dat_w_ack.eq(master_dat_w_ack) for master, master_dat_w_ack in zip(self._masters, master_dat_w_acks)]
|
self.comb += [master.dat_w_ack.eq(master_dat_w_ack) for master, master_dat_w_ack in zip(self.masters, master_dat_w_acks)]
|
||||||
self.comb += [master.dat_r_ack.eq(master_dat_r_ack) for master, master_dat_r_ack in zip(self._masters, master_dat_r_acks)]
|
self.comb += [master.dat_r_ack.eq(master_dat_r_ack) for master, master_dat_r_ack in zip(self.masters, master_dat_r_acks)]
|
||||||
|
|
||||||
# route data writes
|
# route data writes
|
||||||
controller_selected_wl = controller_selected
|
controller_selected_wl = controller_selected
|
||||||
for i in range(self._write_latency):
|
for i in range(self.write_latency):
|
||||||
n_controller_selected_wl = [Signal() for i in range(nmasters)]
|
n_controller_selected_wl = [Signal() for i in range(nmasters)]
|
||||||
self.sync += [n.eq(o) for n, o in zip(n_controller_selected_wl, controller_selected_wl)]
|
self.sync += [n.eq(o) for n, o in zip(n_controller_selected_wl, controller_selected_wl)]
|
||||||
controller_selected_wl = n_controller_selected_wl
|
controller_selected_wl = n_controller_selected_wl
|
||||||
dat_w_maskselect = []
|
dat_w_maskselect = []
|
||||||
dat_we_maskselect = []
|
dat_we_maskselect = []
|
||||||
for master, selected in zip(self._masters, controller_selected_wl):
|
for master, selected in zip(self.masters, controller_selected_wl):
|
||||||
o_dat_w = Signal(self._dw)
|
o_dat_w = Signal(self.dw)
|
||||||
o_dat_we = Signal(self._dw//8)
|
o_dat_we = Signal(self.dw//8)
|
||||||
self.comb += If(selected,
|
self.comb += If(selected,
|
||||||
o_dat_w.eq(master.dat_w),
|
o_dat_w.eq(master.dat_w),
|
||||||
o_dat_we.eq(master.dat_we)
|
o_dat_we.eq(master.dat_we)
|
||||||
|
@ -121,17 +121,17 @@ class LiteDRAMCrossbar(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
# route data reads
|
# route data reads
|
||||||
self.comb += [master.dat_r.eq(self._controller.dat_r) for master in self._masters]
|
self.comb += [master.dat_r.eq(self.controller.dat_r) for master in self.masters]
|
||||||
|
|
||||||
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
|
||||||
m_rca = [] # row and column address
|
m_rca = [] # row and column address
|
||||||
for master in self._masters:
|
for master in self.masters:
|
||||||
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.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], master.adr[cba_upper:]))
|
self.comb += rca.eq(Cat(master.adr[:cba_shift], master.adr[cba_upper:]))
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue