move ripple.py to nmutil
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 1 May 2020 13:29:20 +0000 (14:29 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 1 May 2020 13:29:20 +0000 (14:29 +0100)
src/ieee754/part_cmp/ripple.py

index 032512047f2e58c3ce50bc869e4a064738647943..af9c854b76c40aa4e753763ec76549d6ec0441a8 100644 (file)
@@ -1,81 +1,2 @@
-# need to ripple the starting LSB of each partition up through the
-# rest of the partition.  a Mux on the partition gate therefore selects
-# either the current "thing" being propagated, or, if the gate is set open,
-# will select the current bit from the input.
-#
-# this is actually a useful function, it's one of "set before first" or
-# "set after first" from vector predication processing.
-
-from nmigen import Signal, Module, Elaboratable, Mux, Cat
-from nmigen.cli import main
-
-
-class RippleLSB(Elaboratable):
-    """RippleLSB
-
-    based on a partition mask, the LSB is "rippled" (duplicated)
-    up to the beginning of the next partition.
-    """
-    def __init__(self, width):
-        self.width = width
-        self.results_in = Signal(width, reset_less=True)
-        self.gates = Signal(width-1, reset_less=True)
-        self.output = Signal(width, reset_less=True)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        width = self.width
-
-        current_result = self.results_in[0]
-        comb += self.output[0].eq(current_result)
-
-        for i in range(width-1):
-            cur = Mux(self.gates[i], self.results_in[i+1], self.output[i])
-            comb += self.output[i+1].eq(cur)
-
-        return m
-
-
-class MoveMSBDown(Elaboratable):
-    """MoveMSBDown
-
-    based on a partition mask, moves the MSB down to the LSB position.
-    only the MSB is relevant, other bits are ignored.  works by first
-    rippling the MSB across the entire partition (TODO: split that out
-    into its own useful module), then ANDs the (new) LSB with the
-    partition mask to isolate it.
-    """
-    def __init__(self, width):
-        self.width = width
-        self.results_in = Signal(width, reset_less=True)
-        self.gates = Signal(width-1, reset_less=True)
-        self.output = Signal(width, reset_less=True)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        width = self.width
-        intermed = Signal(width, reset_less=True)
-
-        # first propagate MSB down until the nearest partition gate
-        comb += intermed[-1].eq(self.results_in[-1]) # start at MSB
-        for i in range(width-2, -1, -1):
-            cur = Mux(self.gates[i], self.results_in[i], intermed[i+1])
-            comb += intermed[i].eq(cur)
-
-        # now only select those bits where the mask starts
-        out = [intermed[0]] # LSB of first part always set
-        for i in range(width-1): # length of partition gates
-            out.append(self.gates[i] & intermed[i+1])
-        comb += self.output.eq(Cat(*out))
-
-        return m
-
-
-if __name__ == "__main__":
-    # python3 ieee754/part_cmp/ripple.py generate -t il > ripple.il
-    # then check with yosys "read_ilang ripple.il; show top"
-    alu = MoveMSBDown(width=4)
-    main(alu, ports=[alu.results_in, alu.gates, alu.output])
-
+# moved to nmutil
+from nmutil.ripple import RippleLSB, MoveMSBDown