From: Sebastien Bourdeauducq Date: Thu, 22 Dec 2011 14:46:19 +0000 (+0100) Subject: corelogic: operator tree X-Git-Tag: 24jan2021_ls180~2099^2~1113 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ba40f584912abf62c33a9a35f2dd945176596062;p=litex.git corelogic: operator tree --- diff --git a/migen/bus/wishbone.py b/migen/bus/wishbone.py index 4cae9fd4..f9e24a29 100644 --- a/migen/bus/wishbone.py +++ b/migen/bus/wishbone.py @@ -1,5 +1,6 @@ from migen.fhdl.structure import * -from migen.corelogic import roundrobin, multimux +from migen.corelogic import roundrobin +from migen.corelogic.misc import multimux, optree from migen.bus.simple import Simple, get_sig_name _desc = [ @@ -37,7 +38,7 @@ class Arbiter: m2s_names = [get_sig_name(x, False) for x in _desc if x[0]] m2s_masters = [[getattr(m, name) for name in m2s_names] for m in self.masters] m2s_target = [getattr(self.target, name) for name in m2s_names] - comb += multimux.multimux(self.rr.grant, m2s_masters, m2s_target) + comb += multimux(self.rr.grant, m2s_masters, m2s_target) # connect slave->master signals s2m_names = [get_sig_name(x, False) for x in _desc if not x[0]] @@ -115,21 +116,12 @@ class Decoder: i += 1 # generate master ack (resp. err) by ORing all slave acks (resp. errs) - ackv = Constant(0) - errv = Constant(0) - for slave in self.slaves: - ackv = ackv | slave[1].ack_o - errv = errv | slave[1].err_o - comb.append(self.master.ack_i.eq(ackv)) - comb.append(self.master.err_i.eq(errv)) + comb.append(self.master.ack_i.eq(optree('|', [slave[1].ack_o for slave in self.slaves]))) + comb.append(self.master.err_i.eq(optree('|', [slave[1].err_o for slave in self.slaves]))) # mux (1-hot) slave data return - i = 0 - datav = Constant(0, self.master.dat_i.bv) - for slave in self.slaves: - datav = datav | (Replicate(slave_sel_r[i], self.master.dat_i.bv.width) & slave[1].dat_o) - i += 1 - comb.append(self.master.dat_i.eq(datav)) + masked = [Replicate(slave_sel_r[i], self.master.dat_i.bv.width) & self.slaves[i][1].dat_o for i in range(len(self.slaves))] + comb.append(self.master.dat_i.eq(optree('|', masked))) return Fragment(comb, sync) diff --git a/migen/corelogic/misc.py b/migen/corelogic/misc.py new file mode 100644 index 00000000..3b48bad4 --- /dev/null +++ b/migen/corelogic/misc.py @@ -0,0 +1,33 @@ +from migen.fhdl.structure import * +from migen.fhdl.structure import _Operator + +def multimux(sel, inputs, output): + n = len(inputs) + i = 0 + comb = [] + for osig in output: + choices = [x[i] for x in inputs] + cases = [[Constant(j, sel.bv), osig.eq(choices[j])] for j in range(n)] + cases[n-1][0] = Default() + comb.append(Case(sel, *cases)) + i += 1 + return comb + +def optree(op, operands, lb=None, ub=None, default=None): + if lb is None: + lb = 0 + if ub is None: + ub = len(operands) + l = ub - lb + if l == 0: + if default is None: + raise AttributeError + else: + return default + elif l == 1: + return operands[lb] + else: + s = lb + l//2 + return _Operator(op, + [optree(op, operands, lb, s, default), + optree(op, operands, s, ub, default)]) diff --git a/migen/corelogic/multimux.py b/migen/corelogic/multimux.py deleted file mode 100644 index fde064ee..00000000 --- a/migen/corelogic/multimux.py +++ /dev/null @@ -1,13 +0,0 @@ -from migen.fhdl.structure import * - -def multimux(sel, inputs, output): - n = len(inputs) - i = 0 - comb = [] - for osig in output: - choices = [x[i] for x in inputs] - cases = [[Constant(j, sel.bv), osig.eq(choices[j])] for j in range(n)] - cases[n-1][0] = Default() - comb.append(Case(sel, *cases)) - i += 1 - return comb