1 # SPDX-License-Identifier: LGPL-3-or-later
2 # See Notices.txt for copyright information
4 # TODO add funding and explicit copyright notice (contractually required by
7 from nmigen
.hdl
.ast
import Signal
8 from nmigen
.hdl
.dsl
import Module
9 from nmigen
.hdl
.ir
import Elaboratable
11 # TODO link to bugreport
13 class GRev(Elaboratable
):
14 """TODO comments, "this is a half-butterfly aka "generalised reverse"
15 so that it shows up in the auto-generated documentation
16 link to wikipedia etc. etc. https://en.wikipedia.org/wiki/Butterfly_network
20 def __init__(self
, log2_width
):
21 assert isinstance(log2_width
, int)
22 self
.log2_width
= log2_width
23 self
.width
= 1 << log2_width
25 self
.input = Signal(self
.width
)
26 self
.chunk_sizes
= Signal(log2_width
)
28 self
.output
= Signal(self
.width
)
30 def elaborate(self
, platform
):
33 # XXX internal signals do not need to be members of the module.
34 # more to the point: why is the array needed at all?
36 return Signal(self
.width
, name
=f
"step{i}")
37 _steps
= [step(i
) for i
in range(self
.log2_width
)]
39 for i
, step_o
in enumerate(_steps
):
40 step_i
= self
.input if i
== 0 else _steps
[i
- 1]
42 # TODO comment that this is creating the mux-swapper
43 with m
.If(self
.chunk_sizes
[i
]):
45 for j
in range(self
.width
):
46 # TODO explain what this XOR does
47 m
.d
.comb
+= step_o
[j
].eq(step_i
[j ^ chunk_size
])
50 m
.d
.comb
+= step_o
.eq(step_i
)
51 # TODO comment that the last "step" is the output
52 m
.d
.comb
+= self
.output
.eq(_steps
[-1])