From: Cesar Strauss Date: Sun, 21 Feb 2021 12:44:56 +0000 (-0300) Subject: Move the selection field function to nmutil X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=48c46eed0705ce0807fc1e097b25dc42d81f7510;p=nmutil.git Move the selection field function to nmutil Make it return a new Signal, while adding the wires to a Module. That way, it becomes explicit that the function add wires to the design. --- diff --git a/src/nmutil/util.py b/src/nmutil/util.py index 8a00ad9..a49b442 100644 --- a/src/nmutil/util.py +++ b/src/nmutil/util.py @@ -6,7 +6,7 @@ """ from collections.abc import Iterable -from nmigen import Mux, Signal +from nmigen import Mux, Signal, Cat # XXX this already exists in nmigen._utils # see https://bugs.libre-soc.org/show_bug.cgi?id=297 @@ -77,3 +77,33 @@ except ImportError: def Display(*args): return [] + +def sel(m, r, sel_bits, field_width=None, name=None): + """Forms a subfield from a selection of bits of the signal `r` + ("register"). + + :param m: nMigen Module for adding the wires + :param r: signal containing the field from which to select the subfield + :param sel_bits: bit indices of the subfield, in "MSB 0" convention, + from most significant to least significant. Note that + the indices are allowed to be non-contiguous and/or + out-of-order. + :param field_width: field width. If absent, use the signal `r` own width. + :param name: name of the generated Signal + :returns: a new Signal which gets assigned to the subfield + """ + # find the MSB index in LSB0 numbering + if field_width is None: + msb = len(r) - 1 + else: + msb = field_width - 1 + # extract the selected bits + sig_list = [] + for idx in sel_bits: + sig_list.append(r[msb - idx]) + # place the LSB at the front of the list, + # since, in nMigen, Cat starts from the LSB + sig_list.reverse() + sel_ret = Signal(len(sig_list), name=name) + m.d.comb += sel_ret.eq(Cat(*sig_list)) + return sel_ret