countzero: Reorganize to have fewer levels of logic and fewer LUTs
[microwatt.git] / countzero.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6
7 entity zero_counter is
8 port (
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)
13 );
14 end entity zero_counter;
15
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);
21
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
25 begin
26 if right = '0' then
27 if v(3) = '1' then
28 return "11";
29 elsif v(2) = '1' then
30 return "10";
31 elsif v(1) = '1' then
32 return "01";
33 else
34 return "00";
35 end if;
36 else
37 if v(0) = '1' then
38 return "00";
39 elsif v(1) = '1' then
40 return "01";
41 elsif v(2) = '1' then
42 return "10";
43 else
44 return "11";
45 end if;
46 end if;
47 end;
48
49 begin
50 zerocounter0: process(all)
51 begin
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);
60 else
61 sel(5) <= '0';
62 if count_right = '0' then
63 sel(4) <= z(1);
64 else
65 sel(4) <= not z(0);
66 end if;
67 end if;
68
69 -- Select the leftmost/rightmost non-zero group of 16 bits
70 case sel(5 downto 4) is
71 when "00" =>
72 v16 <= rs(15 downto 0);
73 when "01" =>
74 v16 <= rs(31 downto 16);
75 when "10" =>
76 v16 <= rs(47 downto 32);
77 when others =>
78 v16 <= rs(63 downto 48);
79 end case;
80
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);
87
88 -- Select the leftmost/rightmost non-zero group of 4 bits
89 case sel(3 downto 2) is
90 when "00" =>
91 v4 <= v16(3 downto 0);
92 when "01" =>
93 v4 <= v16(7 downto 4);
94 when "10" =>
95 v4 <= v16(11 downto 8);
96 when others =>
97 v4 <= v16(15 downto 12);
98 end case;
99
100 sel(1 downto 0) <= encoder(v4, count_right);
101
102 -- sel is now the index of the leftmost/rightmost 1 bit in rs
103 if v4 = "0000" then
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);
109 else
110 result <= x"00000000000000" & "00" & sel;
111 end if;
112
113 end process;
114 end behaviour;