corelogic: operator tree
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 22 Dec 2011 14:46:19 +0000 (15:46 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 22 Dec 2011 14:46:19 +0000 (15:46 +0100)
migen/bus/wishbone.py
migen/corelogic/misc.py [new file with mode: 0644]
migen/corelogic/multimux.py [deleted file]

index 4cae9fd4c031d314892b17d9434e22d4b1be35d9..f9e24a299400ea1de98438088a21b40f59aa317b 100644 (file)
@@ -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 (file)
index 0000000..3b48bad
--- /dev/null
@@ -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 (file)
index fde064e..0000000
+++ /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