"""
from functools import reduce
-from operator import xor
+from operator import xor # XXX import operator then use operator.xor
from nmigen.hdl.ir import Elaboratable
from nmigen.hdl.ast import Signal, Cat, Repl, Value
from nmigen.hdl.dsl import Module
+# XXX class to be removed https://bugs.libre-soc.org/show_bug.cgi?id=784
+# functionality covered already entirely by nmutil.util.tree_reduce
class BitwiseXorReduce(Elaboratable):
"""Bitwise Xor lots of stuff together by using tree-reduction on each bit.
class CLMulAdd(Elaboratable):
- """Carry-less multiply-add.
+ """Carry-less multiply-add. (optional add)
Computes:
```
- self.output = (clmul(self.factor1, self.factor2) ^ self.terms[0]
- ^ self.terms[1] ^ self.terms[2] ...)
+ self.output = (clmul(self.factor1, self.factor2) ^
+ self.terms[0] ^
+ self.terms[1] ^
+ self.terms[2] ...)
```
Properties:
self.factor1 = Signal(self.factor_width)
self.factor2 = Signal(self.factor_width)
- def terms():
- for i, inp in enumerate(self.term_widths):
- yield Signal(inp, name=f"term_{i}")
- self.terms = tuple(terms())
+ # build terms at requested widths (if any)
+ self.terms = []
+ for i, inp in enumerate(self.term_widths):
+ self.terms.append(Signal(inp, name=f"term_%d" % i))
+
+ # build output at the maximum bit-width covering all inputs
self.output = Signal(max((self.factor_width * 2 - 1,
*self.term_widths)))
- def __reduce_inputs(self):
+ # XXX to create temporary Signals for mask-shifted expression.
+ # terms ok.
+ def __reduce_inputs(self, m):
for shift in range(self.factor_width):
mask = Repl(self.factor2[shift], self.factor_width)
yield (self.factor1 & mask) << shift
def elaborate(self, platform):
m = Module()
+ # XXX to be replaced with nmutil.util.tree_reduce()
xor_reduce = BitwiseXorReduce(self.__reduce_inputs())
m.submodules.xor_reduce = xor_reduce
m.d.comb += self.output.eq(xor_reduce.output)