Livt packages

Eccelerators.BitTwiddling

Version 0.1.1

Readable 32-bit bit manipulation, counting, scanning, permutation, and arithmetic utilities for Livt.

Published files (26)

src/encoding/WordEncoding32.lvt

namespace Eccelerators.BitTwiddling.Encoding

/**
 * Provides Gray-code and one-hot conversions for unsigned 32-bit words.
 *
 * The helpers only transform values. Gray-code conversion does not provide the
 * synchronization required to safely cross clock domains.
 */
class WordEncoding32
{
    /**
     * Converts a 32-bit binary value to reflected Gray code.
     *
     * Adjacent binary counter values produce Gray words differing in one bit.
     */
    public static fn BinaryToGray[](value: uint) uint
    {
        return value ^ (value >> 1)
    }

    /**
     * Converts a reflected 32-bit Gray-code value back to binary.
     */
    public static fn GrayToBinary[](value: uint) uint
    {
        var result: uint = value
        result = result ^ (result >> 16)
        result = result ^ (result >> 8)
        result = result ^ (result >> 4)
        result = result ^ (result >> 2)
        result = result ^ (result >> 1)
        return result
    }

    /**
     * Returns true when value contains exactly one set bit.
     *
     * Zero is not considered one-hot.
     */
    public static fn IsOneHot[](value: uint) bool
    {
        return (value != (0 as uint)) &&
            ((value & (value - (1 as uint))) == (0 as uint))
    }

    /**
     * Returns true when value contains at most one set bit.
     *
     * Unlike IsOneHot, this predicate accepts zero.
     */
    public static fn IsOneHotOrZero[](value: uint) bool
    {
        return (value == (0 as uint)) ||
            ((value & (value - (1 as uint))) == (0 as uint))
    }

    /**
     * Converts a bit index into a 32-bit one-hot word.
     *
     * Valid indices are 0 through 31. An invalid index returns zero.
     */
    public static fn IndexToOneHot[](index: int) uint
    {
        if ((index < 0) || (index > 31))
        {
            return 0
        }
        return (1 as uint) << index
    }

    /**
     * Converts a one-hot word into its set-bit index.
     *
     * A valid one-hot input returns an index from 0 through 31. Zero and words
     * containing multiple set bits return -1.
     */
    public static fn OneHotToIndex[](value: uint) int
    {
        if (!WordEncoding32.IsOneHot(value))
        {
            return -1
        }

        var workingValue: uint = value
        var index: int = 0
        while (workingValue > (1 as uint))
        {
            workingValue = workingValue >> 1
            index = index + 1
        }
        return index
    }
}