c5206e6ce6c9151bb0d2621e236fff73fe01b679
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) # TODO: remove. unnecessary.
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 _steps
= [] # cumulative list of steps (for unit test purposes only)
35 step_i
= self
.input # start combinatorial chain with the input
37 # TODO: comment that this creates a full combinatorial chain
38 # of RADIX-2 butterfly-network "swappers"
39 for i
, step_o
in enumerate(_steps
):
40 step_o
= Signal(self
.width
, name
="step_%d" % i
)
42 # TODO explain that chunk swap-sizes jump by a power2 each time
44 # TODO comment that this is creating the mux-swapper
45 with m
.If(self
.chunk_sizes
[i
]):
47 for j
in range(self
.width
):
48 # TODO explain what this XOR does
49 m
.d
.comb
+= step_o
[j
].eq(step_i
[j ^ chunk_size
])
51 # the mux straight path
52 m
.d
.comb
+= step_o
.eq(step_i
)
53 step_i
= step_o
# for next loop, to create the combinatorial chain
54 # TODO comment that the last "step" is the output
55 m
.d
.comb
+= self
.output
.eq(_steps
[-1]) # TODO: replace with step_o
57 # give access to the steps list for testing purposes