From 51e5a621621c12bb34b44d6bb8a29f1f668a111e Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 10 Dec 2021 15:42:11 -0800 Subject: [PATCH] add initial grev implementation --- src/nmutil/grev.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/nmutil/grev.py 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 -- 2.30.2