ignore /abc.history
[microwatt.git] / countbits.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 bit_counter is
9 port (
10 clk : in std_logic;
11 rs : in std_ulogic_vector(63 downto 0);
12 stall : in std_ulogic;
13 count_right : in std_ulogic;
14 do_popcnt : in std_ulogic;
15 is_32bit : in std_ulogic;
16 datalen : in std_ulogic_vector(3 downto 0);
17 result : out std_ulogic_vector(63 downto 0)
18 );
19 end entity bit_counter;
20
21 architecture behaviour of bit_counter is
22 -- signals for count-leading/trailing-zeroes
23 signal inp : std_ulogic_vector(63 downto 0);
24 signal inp_r : std_ulogic_vector(63 downto 0);
25 signal sum : std_ulogic_vector(64 downto 0);
26 signal sum_r : std_ulogic_vector(64 downto 0);
27 signal onehot : std_ulogic_vector(63 downto 0);
28 signal edge : std_ulogic_vector(63 downto 0);
29 signal bitnum : std_ulogic_vector(5 downto 0);
30 signal cntz : std_ulogic_vector(63 downto 0);
31
32 -- signals for popcnt
33 signal dlen_r : std_ulogic_vector(3 downto 0);
34 signal pcnt_r : std_ulogic;
35 subtype twobit is unsigned(1 downto 0);
36 type twobit32 is array(0 to 31) of twobit;
37 signal pc2 : twobit32;
38 subtype threebit is unsigned(2 downto 0);
39 type threebit16 is array(0 to 15) of threebit;
40 signal pc4 : threebit16;
41 subtype fourbit is unsigned(3 downto 0);
42 type fourbit8 is array(0 to 7) of fourbit;
43 signal pc8 : fourbit8;
44 signal pc8_r : fourbit8;
45 subtype sixbit is unsigned(5 downto 0);
46 type sixbit2 is array(0 to 1) of sixbit;
47 signal pc32 : sixbit2;
48 signal popcnt : std_ulogic_vector(63 downto 0);
49
50 begin
51 countzero_r: process(clk)
52 begin
53 if rising_edge(clk) and stall = '0' then
54 inp_r <= inp;
55 sum_r <= sum;
56 end if;
57 end process;
58
59 countzero: process(all)
60 variable bitnum_e, bitnum_o : std_ulogic_vector(5 downto 0);
61 begin
62 if is_32bit = '0' then
63 if count_right = '0' then
64 inp <= bit_reverse(rs);
65 else
66 inp <= rs;
67 end if;
68 else
69 inp(63 downto 32) <= x"FFFFFFFF";
70 if count_right = '0' then
71 inp(31 downto 0) <= bit_reverse(rs(31 downto 0));
72 else
73 inp(31 downto 0) <= rs(31 downto 0);
74 end if;
75 end if;
76
77 sum <= std_ulogic_vector(unsigned('0' & not inp) + 1);
78
79 -- The following occurs after a clock edge
80 edge <= sum_r(63 downto 0) or inp_r;
81 bitnum_e := edgelocation(edge, 6);
82 onehot <= sum_r(63 downto 0) and inp_r;
83 bitnum_o := bit_number(onehot);
84 bitnum(5 downto 2) <= bitnum_e(5 downto 2);
85 bitnum(1 downto 0) <= bitnum_o(1 downto 0);
86
87 cntz <= 57x"0" & sum_r(64) & bitnum;
88 end process;
89
90 popcnt_r: process(clk)
91 begin
92 if rising_edge(clk) and stall = '0' then
93 for i in 0 to 7 loop
94 pc8_r(i) <= pc8(i);
95 end loop;
96 dlen_r <= datalen;
97 pcnt_r <= do_popcnt;
98 end if;
99 end process;
100
101 popcnt_a: process(all)
102 begin
103 for i in 0 to 31 loop
104 pc2(i) <= unsigned("0" & rs(i * 2 downto i * 2)) + unsigned("0" & rs(i * 2 + 1 downto i * 2 + 1));
105 end loop;
106 for i in 0 to 15 loop
107 pc4(i) <= ('0' & pc2(i * 2)) + ('0' & pc2(i * 2 + 1));
108 end loop;
109 for i in 0 to 7 loop
110 pc8(i) <= ('0' & pc4(i * 2)) + ('0' & pc4(i * 2 + 1));
111 end loop;
112
113 -- after a clock edge
114 for i in 0 to 1 loop
115 pc32(i) <= ("00" & pc8_r(i * 4)) + ("00" & pc8_r(i * 4 + 1)) +
116 ("00" & pc8_r(i * 4 + 2)) + ("00" & pc8_r(i * 4 + 3));
117 end loop;
118
119 popcnt <= (others => '0');
120 if dlen_r(3 downto 2) = "00" then
121 -- popcntb
122 for i in 0 to 7 loop
123 popcnt(i * 8 + 3 downto i * 8) <= std_ulogic_vector(pc8_r(i));
124 end loop;
125 elsif dlen_r(3) = '0' then
126 -- popcntw
127 for i in 0 to 1 loop
128 popcnt(i * 32 + 5 downto i * 32) <= std_ulogic_vector(pc32(i));
129 end loop;
130 else
131 popcnt(6 downto 0) <= std_ulogic_vector(('0' & pc32(0)) + ('0' & pc32(1)));
132 end if;
133 end process;
134
135 result <= cntz when pcnt_r = '0' else popcnt;
136
137 end behaviour;