2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
10 rs : in std_ulogic_vector(63 downto 0);
11 count_right : in std_ulogic;
12 is_32bit : in std_ulogic;
13 result : out std_ulogic_vector(63 downto 0)
15 end entity zero_counter;
17 architecture behaviour of zero_counter is
18 type intermediate_result is record
19 v16: std_ulogic_vector(15 downto 0);
20 sel_hi: std_ulogic_vector(1 downto 0);
22 count_right: std_ulogic;
25 signal r, r_in : intermediate_result;
27 -- Return the index of the leftmost or rightmost 1 in a set of 4 bits.
28 -- Assumes v is not "0000"; if it is, return (right ? "11" : "00").
29 function encoder(v: std_ulogic_vector(3 downto 0); right: std_ulogic) return std_ulogic_vector is
55 zerocounter_0: process(clk)
57 if rising_edge(clk) then
62 zerocounter_1: process(all)
63 variable v: intermediate_result;
64 variable y, z: std_ulogic_vector(3 downto 0);
65 variable sel: std_ulogic_vector(5 downto 0);
66 variable v4: std_ulogic_vector(3 downto 0);
69 -- Test 4 groups of 16 bits each.
70 -- The top 2 groups are considered to be zero in 32-bit mode.
71 z(0) := or (rs(15 downto 0));
72 z(1) := or (rs(31 downto 16));
73 z(2) := or (rs(47 downto 32));
74 z(3) := or (rs(63 downto 48));
75 if is_32bit = '0' then
76 v.sel_hi := encoder(z, count_right);
79 if count_right = '0' then
82 v.sel_hi(0) := not z(0);
86 -- Select the leftmost/rightmost non-zero group of 16 bits
89 v.v16 := rs(15 downto 0);
91 v.v16 := rs(31 downto 16);
93 v.v16 := rs(47 downto 32);
95 v.v16 := rs(63 downto 48);
98 -- Latch this and do the rest in the next cycle, for the sake of timing
99 v.is_32bit := is_32bit;
100 v.count_right := count_right;
102 sel(5 downto 4) := r.sel_hi;
104 -- Test 4 groups of 4 bits
105 y(0) := or (r.v16(3 downto 0));
106 y(1) := or (r.v16(7 downto 4));
107 y(2) := or (r.v16(11 downto 8));
108 y(3) := or (r.v16(15 downto 12));
109 sel(3 downto 2) := encoder(y, r.count_right);
111 -- Select the leftmost/rightmost non-zero group of 4 bits
112 case sel(3 downto 2) is
114 v4 := r.v16(3 downto 0);
116 v4 := r.v16(7 downto 4);
118 v4 := r.v16(11 downto 8);
120 v4 := r.v16(15 downto 12);
123 sel(1 downto 0) := encoder(v4, r.count_right);
125 -- sel is now the index of the leftmost/rightmost 1 bit in rs
127 -- operand is zero, return 32 for 32-bit, else 64
128 result <= x"00000000000000" & '0' & not r.is_32bit & r.is_32bit & "00000";
129 elsif r.count_right = '0' then
130 -- return (63 - sel), trimmed to 5 bits in 32-bit mode
131 result <= x"00000000000000" & "00" & (not sel(5) and not r.is_32bit) & not sel(4 downto 0);
133 result <= x"00000000000000" & "00" & sel;