2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
9 rs : in std_ulogic_vector(63 downto 0);
10 count_right : in std_ulogic;
11 is_32bit : in std_ulogic;
12 result : out std_ulogic_vector(63 downto 0)
14 end entity zero_counter;
16 architecture behaviour of zero_counter is
17 signal y, z : std_ulogic_vector(3 downto 0);
18 signal v16 : std_ulogic_vector(15 downto 0);
19 signal v4 : std_ulogic_vector(3 downto 0);
20 signal sel : std_ulogic_vector(5 downto 0);
22 -- Return the index of the leftmost or rightmost 1 in a set of 4 bits.
23 -- Assumes v is not "0000"; if it is, return (right ? "11" : "00").
24 function encoder(v: std_ulogic_vector(3 downto 0); right: std_ulogic) return std_ulogic_vector is
50 zerocounter0: process(all)
52 -- Test 4 groups of 16 bits each.
53 -- The top 2 groups are considered to be zero in 32-bit mode.
54 z(0) <= or (rs(15 downto 0));
55 z(1) <= or (rs(31 downto 16));
56 z(2) <= or (rs(47 downto 32));
57 z(3) <= or (rs(63 downto 48));
58 if is_32bit = '0' then
59 sel(5 downto 4) <= encoder(z, count_right);
62 if count_right = '0' then
69 -- Select the leftmost/rightmost non-zero group of 16 bits
70 case sel(5 downto 4) is
72 v16 <= rs(15 downto 0);
74 v16 <= rs(31 downto 16);
76 v16 <= rs(47 downto 32);
78 v16 <= rs(63 downto 48);
81 -- Test 4 groups of 4 bits
82 y(0) <= or (v16(3 downto 0));
83 y(1) <= or (v16(7 downto 4));
84 y(2) <= or (v16(11 downto 8));
85 y(3) <= or (v16(15 downto 12));
86 sel(3 downto 2) <= encoder(y, count_right);
88 -- Select the leftmost/rightmost non-zero group of 4 bits
89 case sel(3 downto 2) is
91 v4 <= v16(3 downto 0);
93 v4 <= v16(7 downto 4);
95 v4 <= v16(11 downto 8);
97 v4 <= v16(15 downto 12);
100 sel(1 downto 0) <= encoder(v4, count_right);
102 -- sel is now the index of the leftmost/rightmost 1 bit in rs
104 -- operand is zero, return 32 for 32-bit, else 64
105 result <= x"00000000000000" & '0' & not is_32bit & is_32bit & "00000";
106 elsif count_right = '0' then
107 -- return (63 - sel), trimmed to 5 bits in 32-bit mode
108 result <= x"00000000000000" & "00" & (not sel(5) and not is_32bit) & not sel(4 downto 0);
110 result <= x"00000000000000" & "00" & sel;