Add Tercel PHY reset synchronization
[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 use work.helpers.all;
7
8 entity zero_counter is
9 port (
10 clk : in std_logic;
11 rs : in std_ulogic_vector(63 downto 0);
12 count_right : in std_ulogic;
13 is_32bit : in std_ulogic;
14 result : out std_ulogic_vector(63 downto 0)
15 );
16 end entity zero_counter;
17
18 architecture behaviour of zero_counter is
19 signal inp : std_ulogic_vector(63 downto 0);
20 signal sum : std_ulogic_vector(64 downto 0);
21 signal msb_r : std_ulogic;
22 signal onehot : std_ulogic_vector(63 downto 0);
23 signal onehot_r : std_ulogic_vector(63 downto 0);
24 signal bitnum : std_ulogic_vector(5 downto 0);
25
26 begin
27 countzero_r: process(clk)
28 begin
29 if rising_edge(clk) then
30 msb_r <= sum(64);
31 onehot_r <= onehot;
32 end if;
33 end process;
34
35 countzero: process(all)
36 begin
37 if is_32bit = '0' then
38 if count_right = '0' then
39 inp <= bit_reverse(rs);
40 else
41 inp <= rs;
42 end if;
43 else
44 inp(63 downto 32) <= x"FFFFFFFF";
45 if count_right = '0' then
46 inp(31 downto 0) <= bit_reverse(rs(31 downto 0));
47 else
48 inp(31 downto 0) <= rs(31 downto 0);
49 end if;
50 end if;
51
52 sum <= std_ulogic_vector(unsigned('0' & not inp) + 1);
53 onehot <= sum(63 downto 0) and inp;
54
55 -- The following occurs after a clock edge
56 bitnum <= bit_number(onehot_r);
57
58 result <= x"00000000000000" & "0" & msb_r & bitnum;
59 end process;
60 end behaviour;