Count Leading Zeros

Medium · Combinational Logic · Parameterization & Generate

Implement a parameterized count-leading-zeros (CLZ) circuit.

CLZ counts how many 0 bits there are above the most significant 1. It is used for floating-point normalization, priority logic and fast logarithms, and many CPUs have a CLZ instruction.

Parameters and ports

module clz #(
    parameter int WIDTH = 16
) (
    input  logic [WIDTH-1:0]           din,
    output logic [$clog2(WIDTH+1)-1:0] count
);
NameKindWidthMeaning
WIDTHparameter—Input width, any integer ≥ 1 (not necessarily a power of two). Default 16.
dininputWIDTHUnsigned input vector.
countoutput$clog2(WIDTH+1)Number of leading zeros, 0 … WIDTH.

Behavior

count = WIDTH - 1 - k.

The circuit is purely combinational.

Why $clog2(WIDTH+1) bits? count can take WIDTH + 1 different values (0 through WIDTH inclusive). For WIDTH = 16 that is 17 values, which needs 5 bits; 4 bits ($clog2(16)) could only reach 15, so an all-zero input could not be represented.

Examples (WIDTH = 16)

dincount
16'b1000_0000_0000_00000
16'b0100_0000_0000_00001
16'b0000_0000_1010_10108
16'b0000_0000_0000_000115
16'b0000_0000_0000_000016
16'b1111_1111_1111_11110

Notes

the default WIDTH = 16 and at other widths (including a non-power-of-two width, the smallest legal width and one wider than 32 bits), so do not hard-code 16 anywhere except the parameter default. This is how parameterized IP is written in practice. The visible examples use WIDTH = 16 only.

Remember that in a procedural block the last assignment wins; pick the loop direction accordingly (or think about why a "count zeros until the first one" loop needs to stop).

count = ($clog2(WIDTH+1))'(WIDTH - 1 - i);, or via a localparam, to keep Verilator's width lint quiet.

Sign up free to solve Count Leading Zeros in your browser.

More Combinational Logic problems