A Priority Thermometer Mask

by GateForge Consulting Ltd.

Here is a more complex logic design based on techniques from Henry S. Warren Jr.'s Hacker's Delight, which use integer arithmetic extended with Boolean operations (and vice-versa) to describe right-to-left, bit-parallel operations on binary words. You can find the basics in Chapter 2, also available on Warren's website.

We create a set of operations which, given a one-hot bit vector, returns a mask which masks-off all bits less signficant than the one-hot bit, with the special case that an all-zero input generates an all-ones mask, rather than the expected all-zero mask. You can think of the sequence of 1's in the mask as the liquid in a thermometer, hence the name. For example:

00001 --> 11111
00100 --> 11100
01000 --> 11000
00000 --> 11111

This priority thermometer mask has applications when combined with other priority logic, such as a priority arbiter.

// Takes a one-hot bit vector and returns a mask
// which masks-off all bits less significant than the set bit.  

module Thermometer_Mask
    parameter       WORD_WIDTH          = 0
    input   wire    [WORD_WIDTH-1:0]    bitvector,
    output  reg     [WORD_WIDTH-1:0]    mask

    initial begin
        mask = 0;

    localparam zero = {WORD_WIDTH{1'b0}};

    always @(*) begin
        // Outputs 1 at the first set bit and all less significant (leftmost) bits.
        // Outputs 0 for all more significant (rightmost) bits.
        // Outputs all 1's if no bit set.

        mask = bitvector ^ (bitvector - 1);

        // Invert mask to instead mask-off the set bit and the less significant bits
        // Don't invert mask if no bit set (don't want an all-zero mask)

        mask = (bitvector == zero) ? mask : ~mask;

        // Re-add set bit, so it and the more significant (rightmost) bits pass.

        mask = mask | bitvector;