execute1: Simplify the interrupt logic a little
[microwatt.git] / logical.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.decode_types.all;
7
8 entity logical is
9 port (
10 rs : in std_ulogic_vector(63 downto 0);
11 rb : in std_ulogic_vector(63 downto 0);
12 op : in insn_type_t;
13 invert_in : in std_ulogic;
14 invert_out : in std_ulogic;
15 result : out std_ulogic_vector(63 downto 0);
16 datalen : in std_logic_vector(3 downto 0);
17 popcnt : out std_ulogic_vector(63 downto 0);
18 parity : out std_ulogic_vector(63 downto 0)
19 );
20 end entity logical;
21
22 architecture behaviour of logical is
23
24 subtype twobit is unsigned(1 downto 0);
25 type twobit32 is array(0 to 31) of twobit;
26 signal pc2 : twobit32;
27 subtype threebit is unsigned(2 downto 0);
28 type threebit16 is array(0 to 15) of threebit;
29 signal pc4 : threebit16;
30 subtype fourbit is unsigned(3 downto 0);
31 type fourbit8 is array(0 to 7) of fourbit;
32 signal pc8 : fourbit8;
33 subtype sixbit is unsigned(5 downto 0);
34 type sixbit2 is array(0 to 1) of sixbit;
35 signal pc32 : sixbit2;
36 signal par0, par1 : std_ulogic;
37
38 begin
39 logical_0: process(all)
40 variable rb_adj, tmp : std_ulogic_vector(63 downto 0);
41 begin
42 rb_adj := rb;
43 if invert_in = '1' then
44 rb_adj := not rb;
45 end if;
46
47 case op is
48 when OP_AND =>
49 tmp := rs and rb_adj;
50 when OP_OR =>
51 tmp := rs or rb_adj;
52 when others =>
53 tmp := rs xor rb_adj;
54 end case;
55
56 result <= tmp;
57 if invert_out = '1' then
58 result <= not tmp;
59 end if;
60
61 -- population counts
62 for i in 0 to 31 loop
63 pc2(i) <= unsigned("0" & rs(i * 2 downto i * 2)) + unsigned("0" & rs(i * 2 + 1 downto i * 2 + 1));
64 end loop;
65 for i in 0 to 15 loop
66 pc4(i) <= ('0' & pc2(i * 2)) + ('0' & pc2(i * 2 + 1));
67 end loop;
68 for i in 0 to 7 loop
69 pc8(i) <= ('0' & pc4(i * 2)) + ('0' & pc4(i * 2 + 1));
70 end loop;
71 for i in 0 to 1 loop
72 pc32(i) <= ("00" & pc8(i * 4)) + ("00" & pc8(i * 4 + 1)) +
73 ("00" & pc8(i * 4 + 2)) + ("00" & pc8(i * 4 + 3));
74 end loop;
75 popcnt <= (others => '0');
76 if datalen(3 downto 2) = "00" then
77 -- popcntb
78 for i in 0 to 7 loop
79 popcnt(i * 8 + 3 downto i * 8) <= std_ulogic_vector(pc8(i));
80 end loop;
81 elsif datalen(3) = '0' then
82 -- popcntw
83 for i in 0 to 1 loop
84 popcnt(i * 32 + 5 downto i * 32) <= std_ulogic_vector(pc32(i));
85 end loop;
86 else
87 popcnt(6 downto 0) <= std_ulogic_vector(('0' & pc32(0)) + ('0' & pc32(1)));
88 end if;
89
90 -- parity calculations
91 par0 <= rs(0) xor rs(8) xor rs(16) xor rs(24);
92 par1 <= rs(32) xor rs(40) xor rs(48) xor rs(56);
93 parity <= (others => '0');
94 if datalen(3) = '1' then
95 parity(0) <= par0 xor par1;
96 else
97 parity(0) <= par0;
98 parity(32) <= par1;
99 end if;
100
101 end process;
102 end behaviour;