How to avoid unintended fixed priority arbiter usage in RTL?

We discussed how to optimize PPA in RTL coding, and we will cover how to avoid unintended fixed priority arbiters in RTL.

Fixed priority arbiters are “expensive” in RTL implementation. The more requests the arbiter has, the more level of logic the final grant will have. Let’s say we want to design a fixed priority arbiter with 8 requests, the arbiter can be coded using a for-loop:

        logic [2:0] grant_idx; // binary encoding of grant index
        logic [7:0] grant;       // 1-hot encoding of grant index

        always_comb begin
            grant_idx = ‘0;

            // for-loop index must decrement
            // ensuring req[0] has the highest priority
            for (int i = 7; i >= 0; i--) 
                if (req[i])
                    grant_idx = 3’(i);

            // binary to 1-hot conversion
            grant = 8’b00000001 << grant_idx;
            // if no requests, grant should be 0
            if (~|req) grant = ‘0;
        end

The for-loop can essentially be translated to:

        assign grant[0] = req[0];
        assign grant[1] = req[1] & ~req[0];
        ... ...
        assign grant[7] = req[7] & ~req[6] & ~req[5] & ~req[4] 
                       & ~req[3] & ~req[2] & ~req[1] & ~req[0];

For the purposes of PPA optimization, RTL designers should avoid using fixed priority arbiters if not absolutely required. For example, if we want to convert a 1-hot encoding value to binary value, instead of having the coding style below, where “binaryVal” is implemented as a fixed priority arbiter:

        logic [7:0] oneHotVal; // 1-hot encoding
        logic [2:0] binaryVal;

        always_comb begin
            binaryVal = ‘0;

            // this is essentially a fixed priority arbiter
            // with oneHotVal[7] having the highest priority
            for (int i = 0; i < 8; i++)
                if (oneHotVal[i])
                    binaryVal = 3’(i);
        end

Consider using the coding style below:

        always_comb begin
            binaryVal = ‘0;

            for (int i = 0; i < 8; i++)
                binaryVal |= {3{oneHotVal[i]}} & 3’(i);
        end

Synthesis tools will attempt to implement a binary-tree structure, instead of linear “long-chain” structure.

Subscribe

Enter your email to get updates from us. You might need to check the spam folder for the confirmation email.

Leave a comment