From: Jacob Lifshay Date: Fri, 10 Dec 2021 23:42:11 +0000 (-0800) Subject: add initial grev implementation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=51e5a621621c12bb34b44d6bb8a29f1f668a111e;p=nmutil.git add initial grev implementation --- diff --git a/src/nmutil/grev.py b/src/nmutil/grev.py new file mode 100644 index 0000000..390b43e --- /dev/null +++ b/src/nmutil/grev.py @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: LGPL-3-or-later +# See Notices.txt for copyright information + +from nmigen.hdl.ast import Signal +from nmigen.hdl.dsl import Module +from nmigen.hdl.ir import Elaboratable + + +class GRev(Elaboratable): + def __init__(self, log2_width): + assert isinstance(log2_width, int) + self.log2_width = log2_width + self.width = 1 << log2_width + + self.input = Signal(self.width) + self.chunk_sizes = Signal(log2_width) + + def step(i): + return Signal(self.width, name=f"step{i}") + self._steps = [step(i) for i in range(log2_width)] + + self.output = Signal(self.width) + + def elaborate(self, platform): + m = Module() + for i, step_o in enumerate(self._steps): + step_i = self.input if i == 0 else self._steps[i - 1] + chunk_size = 1 << i + with m.If(self.chunk_sizes[i]): + for j in range(self.width): + m.d.comb += step_o[j].eq(step_i[j ^ chunk_size]) + with m.Else(): + m.d.comb += step_o.eq(step_i) + m.d.comb += self.output.eq(self._steps[-1]) + return m