From: Sebastien Bourdeauducq Date: Sat, 23 Nov 2013 16:51:22 +0000 (+0100) Subject: lasmibus/Crossbar: more flexible master assignment X-Git-Tag: 24jan2021_ls180~2099^2~439 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=948d7e7332c781c952d91a1590234abe9ed59d30;p=litex.git lasmibus/Crossbar: more flexible master assignment --- diff --git a/migen/bus/lasmibus.py b/migen/bus/lasmibus.py index 62f5db06..906fd2ca 100644 --- a/migen/bus/lasmibus.py +++ b/migen/bus/lasmibus.py @@ -41,39 +41,51 @@ def _getattr_all(l, attr): return r class Crossbar(Module): - def __init__(self, controllers, nmasters, cba_shift): - ncontrollers = len(controllers) - rca_bits = _getattr_all(controllers, "aw") - dw = _getattr_all(controllers, "dw") - nbanks = _getattr_all(controllers, "nbanks") - req_queue_size = _getattr_all(controllers, "req_queue_size") - read_latency = _getattr_all(controllers, "read_latency") - write_latency = _getattr_all(controllers, "write_latency") + def __init__(self, controllers, cba_shift): + self._controllers = controllers + self._cba_shift = cba_shift - bank_bits = log2_int(nbanks, False) - controller_bits = log2_int(ncontrollers, False) - self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, req_queue_size, read_latency, write_latency) - for i in range(nmasters)] + self._rca_bits = _getattr_all(controllers, "aw") + self._dw = _getattr_all(controllers, "dw") + self._nbanks = _getattr_all(controllers, "nbanks") + self._req_queue_size = _getattr_all(controllers, "req_queue_size") + self._read_latency = _getattr_all(controllers, "read_latency") + self._write_latency = _getattr_all(controllers, "write_latency") - ### + self._bank_bits = log2_int(self._nbanks, False) + self._controller_bits = log2_int(len(self._controllers), False) - m_ca, m_ba, m_rca = self._split_master_addresses(controller_bits, bank_bits, rca_bits, cba_shift) + self._masters = [] + + def get_master(self): + if self.finalized: + raise FinalizeError + lasmi_master = Interface(self._rca_bits + self._bank_bits + self._controller_bits, + self._dw, 1, self._req_queue_size, self._read_latency, self._write_latency) + self._masters.append(lasmi_master) + return lasmi_master + + def do_finalize(self): + nmasters = len(self._masters) + + m_ca, m_ba, m_rca = self._split_master_addresses(self._controller_bits, + self._bank_bits, self._rca_bits, self._cba_shift) - for nc, controller in enumerate(controllers): - if controller_bits: + for nc, controller in enumerate(self._controllers): + if self._controller_bits: controller_selected = [ca == nc for ca in m_ca] else: controller_selected = [1]*nmasters master_req_acks = [0]*nmasters master_dat_acks = [0]*nmasters - rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(nbanks)] + rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self._nbanks)] self.submodules += rrs for nb, rr in enumerate(rrs): bank = getattr(controller, "bank"+str(nb)) # for each master, determine if another bank locks it master_locked = [] - for nm, master in enumerate(self.masters): + for nm, master in enumerate(self._masters): locked = 0 for other_nb, other_rr in enumerate(rrs): if other_nb != nb: @@ -83,7 +95,7 @@ class Crossbar(Module): # arbitrate 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 += [ rr.request.eq(Cat(*bank_requested)), rr.ce.eq(~bank.stb & ~bank.lock) @@ -92,7 +104,7 @@ class Crossbar(Module): # route requests self.comb += [ 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]) ] master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & bank.req_ack) @@ -100,20 +112,20 @@ class Crossbar(Module): master_dat_acks = [master_dat_ack | ((rr.grant == nm) & bank.dat_ack) for nm, master_dat_ack in enumerate(master_dat_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_ack.eq(master_dat_ack) for master, master_dat_ack in zip(self.masters, master_dat_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_ack.eq(master_dat_ack) for master, master_dat_ack in zip(self._masters, master_dat_acks)] # route data writes controller_selected_wl = controller_selected - for i in range(write_latency): + for i in range(self._write_latency): 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)] controller_selected_wl = n_controller_selected_wl dat_w_maskselect = [] dat_we_maskselect = [] - for master, selected in zip(self.masters, controller_selected_wl): - o_dat_w = Signal(dw) - o_dat_we = Signal(dw//8) + for master, selected in zip(self._masters, controller_selected_wl): + o_dat_w = Signal(self._dw) + o_dat_we = Signal(self._dw//8) self.comb += If(selected, o_dat_w.eq(master.dat_w), o_dat_we.eq(master.dat_we) @@ -126,31 +138,31 @@ class Crossbar(Module): ] # route data reads - if controller_bits: - for master in self.masters: - controller_sel = Signal(controller_bits) - for nc, controller in enumerate(controllers): + if self._controller_bits: + for master in self._masters: + controller_sel = Signal(self._controller_bits) + for nc, controller in enumerate(self._controllers): for nb in range(nbanks): bank = getattr(controller, "bank"+str(nb)) self.comb += If(bank.stb & bank.ack, controller_sel.eq(nc)) - for i in range(read_latency): - n_controller_sel = Signal(controller_bits) + for i in range(self._read_latency): + n_controller_sel = Signal(self._controller_bits) self.sync += n_controller_sel.eq(controller_sel) controller_sel = n_controller_sel - self.comb += master.dat_r.eq(Array(controllers)[controller_sel].dat_r) + self.comb += master.dat_r.eq(Array(self._controllers)[controller_sel].dat_r) else: - self.comb += [master.dat_r.eq(controllers[0].dat_r) for master in self.masters] + self.comb += [master.dat_r.eq(self._controllers[0].dat_r) for master in self._masters] def _split_master_addresses(self, controller_bits, bank_bits, rca_bits, cba_shift): m_ca = [] # controller address m_ba = [] # bank address m_rca = [] # row and column address - for master in self.masters: - cba = Signal(controller_bits + bank_bits) - rca = Signal(rca_bits) + for master in self._masters: + cba = Signal(self._controller_bits + self._bank_bits) + rca = Signal(self._rca_bits) cba_upper = cba_shift + controller_bits + bank_bits self.comb += cba.eq(master.adr[cba_shift:cba_upper]) - if cba_shift < rca_bits: + if cba_shift < self._rca_bits: if cba_shift: self.comb += rca.eq(Cat(master.adr[:cba_shift], master.adr[cba_upper:])) else: @@ -158,9 +170,9 @@ class Crossbar(Module): else: self.comb += rca.eq(master.adr[:cba_shift]) - if controller_bits: - ca = Signal(controller_bits) - ba = Signal(bank_bits) + if self._controller_bits: + ca = Signal(self._controller_bits) + ba = Signal(self._bank_bits) self.comb += Cat(ba, ca).eq(cba) else: ca = None