Main Content

Bitwise Operations in MATLAB for HDL Code Generation

HDL Coder™ supports bit shift, bit rotate, bit slice operations that mimic HDL-specific operators without saturation and rounding logic.

Bit Shifting and Rotation

The following code implements a barrel shifter/rotator that performs a selected operation (based on the mode argument) on a fixed-point input operand.

function y   = fcn(u, mode)
% Multi Function Barrel Shifter/Rotator

% fixed width shift operation
fixed_width = uint8(3);

switch mode
    case 1
        % shift left logical
        y = bitsll(u, fixed_width);
    case 2
        % shift right logical
        y = bitsrl(u, fixed_width);
    case 3
        % shift right arithmetic
        y = bitsra(u, fixed_width);
    case 4
        % rotate left
        y = bitrol(u, fixed_width);
    case 5
        % rotate right
        y = bitror(u, fixed_width);
    otherwise
        % do nothing
        y = u;
end

This table shows the generated VHDL and Verilog code.

Generated VHDL codeGenerated Verilog code

In VHDL® code generated for this function, the shift and rotate functions map directly to shift and rotate instructions in VHDL.

     CASE mode IS
            WHEN "00000001" =>
                -- shift left logical
                --'<S2>:1:8'
                cr := signed(u) sll 3;
                y <= std_logic_vector(cr);
            WHEN "00000010" =>
                -- shift right logical
                --'<S2>:1:11'
                b_cr := signed(u) srl 3;
                y <= std_logic_vector(b_cr);
            WHEN "00000011" =>
                -- shift right arithmetic
                --'<S2>:1:14'
                c_cr := SHIFT_RIGHT(signed(u) , 3);
                y <= std_logic_vector(c_cr);
            WHEN "00000100" =>
                -- rotate left
                --'<S2>:1:17'
                d_cr := signed(u) rol 3;
                y <= std_logic_vector(d_cr);
            WHEN "00000101" =>
                -- rotate right
                --'<S2>:1:20'
                e_cr := signed(u) ror 3;
                y <= std_logic_vector(e_cr);
            WHEN OTHERS => 
                -- do nothing
                --'<S2>:1:23'
                y <= u;
        END CASE;

The corresponding Verilog® code is similar, except that Verilog does not have native operators for rotate instructions.

             case ( mode)
                1 :
                    begin
                        // shift left logical
                        //'<S2>:1:8'
                        cr = u <<< 3;
                        y = cr;
                    end
                2 :
                    begin
                        // shift right logical
                        //'<S2>:1:11'
                        b_cr = u >> 3;
                        y = b_cr;
                    end
                3 :
                    begin
                        // shift right arithmetic
                        //'<S2>:1:14'
                        c_cr = u >>> 3;
                        y = c_cr;
                    end
                4 :
                    begin
                        // rotate left
                        //'<S2>:1:17'
                        d_cr = {u[12:0], u[15:13]};
                        y = d_cr;
                    end
                5 :
                    begin
                        // rotate right
                        //'<S2>:1:20'
                        e_cr = {u[2:0], u[15:3]};
                        y = e_cr;
                    end
                default :
                    begin
                        // do nothing
                        //'<S2>:1:23'
                        y = u;
                    end
            endcase

Bit Slicing and Bit Concatenation

The bitsliceget and bitconcat functions map directly to slice and concatenate operators in both VHDL and Verilog.

You can use the functions bitsliceget and bitconcat to access and manipulate bit slices (fields) in a fixed-point or integer word. As an example, consider the operation of swapping the upper and lower 4-bit nibbles of an 8-bit byte. The following example accomplishes this task without resorting to traditional mask-and-shift techniques.

function y = fcn(u)
% NIBBLE SWAP 
y = bitconcat( …
      bitsliceget(u, 4, 1), 
      bitsliceget(u, 8, 5));

This table shows the generated VHDL and Verilog code.

Generated VHDL codeGenerated Verilog code

The following listing shows the corresponding generated VHDL code.

ENTITY fcn IS
    PORT (
        clk : IN std_logic; 
        clk_enable : IN std_logic; 
        reset : IN std_logic;
        u : IN std_logic_vector(7 DOWNTO 0);
        y : OUT std_logic_vector(7 DOWNTO 0));
END nibble_swap_7b;


ARCHITECTURE fsm_SFHDL OF fcn IS


BEGIN
    -- NIBBLE SWAP
    y <= u(3 DOWNTO 0) & u(7 DOWNTO 4);
END fsm_SFHDL;

The following listing shows the corresponding generated Verilog code.

module fcn (clk, clk_enable, reset, u, y );
    input clk;
    input clk_enable;
    input reset;
    input [7:0] u;
    output [7:0] y;

    // NIBBLE SWAP
    assign y = {u[3:0], u[7:4]};

endmodule

See Also

|

Related Topics