ignore /abc.history
[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 use work.ppc_fx_insns.all;
8
9 entity logical is
10 port (
11 rs : in std_ulogic_vector(63 downto 0);
12 rb : in std_ulogic_vector(63 downto 0);
13 op : in insn_type_t;
14 invert_in : in std_ulogic;
15 invert_out : in std_ulogic;
16 is_signed : in std_ulogic;
17 result : out std_ulogic_vector(63 downto 0);
18 datalen : in std_logic_vector(3 downto 0)
19 );
20 end entity logical;
21
22 architecture behaviour of logical is
23
24 signal par0, par1 : std_ulogic;
25 signal parity : std_ulogic_vector(63 downto 0);
26 signal permute : std_ulogic_vector(7 downto 0);
27
28 function bcd_to_dpd(bcd: std_ulogic_vector(11 downto 0)) return std_ulogic_vector is
29 variable dpd: std_ulogic_vector(9 downto 0);
30 variable a, b, c, d, e, f, g, h, i, j, k, m: std_ulogic;
31 begin
32 -- The following equations are copied from PowerISA v3.0B Book 1 appendix B
33 a := bcd(11);
34 b := bcd(10);
35 c := bcd(9);
36 d := bcd(8);
37 e := bcd(7);
38 f := bcd(6);
39 g := bcd(5);
40 h := bcd(4);
41 i := bcd(3);
42 j := bcd(2);
43 k := bcd(1);
44 m := bcd(0);
45 dpd(9) := (f and a and i and not e) or (j and a and not i) or (b and not a);
46 dpd(8) := (g and a and i and not e) or (k and a and not i) or (c and not a);
47 dpd(7) := d;
48 dpd(6) := (j and not a and e and not i) or (f and not i and not e) or
49 (f and not a and not e) or (e and i);
50 dpd(5) := (k and not a and e and not i) or (g and not i and not e) or
51 (g and not a and not e) or (a and i);
52 dpd(4) := h;
53 dpd(3) := a or e or i;
54 dpd(2) := (not e and j and not i) or (e and i) or a;
55 dpd(1) := (not a and k and not i) or (a and i) or e;
56 dpd(0) := m;
57 return dpd;
58 end;
59
60 function dpd_to_bcd(dpd: std_ulogic_vector(9 downto 0)) return std_ulogic_vector is
61 variable bcd: std_ulogic_vector(11 downto 0);
62 variable p, q, r, s, t, u, v, w, x, y: std_ulogic;
63 begin
64 -- The following equations are copied from PowerISA v3.0B Book 1 appendix B
65 p := dpd(9);
66 q := dpd(8);
67 r := dpd(7);
68 s := dpd(6);
69 t := dpd(5);
70 u := dpd(4);
71 v := dpd(3);
72 w := dpd(2);
73 x := dpd(1);
74 y := dpd(0);
75 bcd(11) := (not s and v and w) or (t and v and w and s) or (v and w and not x);
76 bcd(10) := (p and s and x and not t) or (p and not w) or (p and not v);
77 bcd(9) := (q and s and x and not t) or (q and not w) or (q and not v);
78 bcd(8) := r;
79 bcd(7) := (v and not w and x) or (s and v and w and x) or (not t and v and w and x);
80 bcd(6) := (p and t and v and w and x and not s) or (s and not x and v) or
81 (s and not v);
82 bcd(5) := (q and t and w and v and x and not s) or (t and not x and v) or
83 (t and not v);
84 bcd(4) := u;
85 bcd(3) := (t and v and w and x) or (s and v and w and x) or (v and not w and not x);
86 bcd(2) := (p and not s and not t and w and v) or (s and v and not w and x) or
87 (p and w and not x and v) or (w and not v);
88 bcd(1) := (q and not s and not t and v and w) or (t and v and not w and x) or
89 (q and v and w and not x) or (x and not v);
90 bcd(0) := y;
91 return bcd;
92 end;
93
94 begin
95 logical_0: process(all)
96 variable rb_adj, rs_adj : std_ulogic_vector(63 downto 0);
97 variable tmp : std_ulogic_vector(63 downto 0);
98 variable negative : std_ulogic;
99 variable j : integer;
100 begin
101 -- parity calculations
102 par0 <= rs(0) xor rs(8) xor rs(16) xor rs(24);
103 par1 <= rs(32) xor rs(40) xor rs(48) xor rs(56);
104 parity <= (others => '0');
105 if datalen(3) = '1' then
106 parity(0) <= par0 xor par1;
107 else
108 parity(0) <= par0;
109 parity(32) <= par1;
110 end if;
111
112 -- bit permutation
113 for i in 0 to 7 loop
114 j := i * 8;
115 if rs(j+7 downto j+6) = "00" then
116 permute(i) <= rb(to_integer(unsigned(not rs(j+5 downto j))));
117 else
118 permute(i) <= '0';
119 end if;
120 end loop;
121
122 rb_adj := rb;
123 if invert_in = '1' then
124 rb_adj := not rb;
125 end if;
126
127 case op is
128 when OP_LOGIC =>
129 -- for now, abuse the 'is_signed' field to indicate inversion of RS
130 rs_adj := rs;
131 if is_signed = '1' then
132 rs_adj := not rs;
133 end if;
134 tmp := rs_adj and rb_adj;
135 if invert_out = '1' then
136 tmp := not tmp;
137 end if;
138 when OP_XOR =>
139 tmp := rs xor rb;
140 if invert_out = '1' then
141 tmp := not tmp;
142 end if;
143
144 when OP_BREV =>
145 if datalen(3) = '1' then
146 tmp := rs( 7 downto 0) & rs(15 downto 8) & rs(23 downto 16) & rs(31 downto 24) &
147 rs(39 downto 32) & rs(47 downto 40) & rs(55 downto 48) & rs(63 downto 56);
148 elsif datalen(2) = '1' then
149 tmp := rs(39 downto 32) & rs(47 downto 40) & rs(55 downto 48) & rs(63 downto 56) &
150 rs( 7 downto 0) & rs(15 downto 8) & rs(23 downto 16) & rs(31 downto 24);
151 else
152 tmp := rs(55 downto 48) & rs(63 downto 56) & rs(39 downto 32) & rs(47 downto 40) &
153 rs(23 downto 16) & rs(31 downto 24) & rs( 7 downto 0) & rs(15 downto 8);
154 end if;
155
156 when OP_PRTY =>
157 tmp := parity;
158 when OP_CMPB =>
159 tmp := ppc_cmpb(rs, rb);
160 when OP_BPERM =>
161 tmp := std_ulogic_vector(resize(unsigned(permute), 64));
162 when OP_BCD =>
163 -- invert_in is abused to indicate direction of conversion
164 if invert_in = '0' then
165 -- cbcdtd
166 tmp := x"000" & bcd_to_dpd(rs(55 downto 44)) & bcd_to_dpd(rs(43 downto 32)) &
167 x"000" & bcd_to_dpd(rs(23 downto 12)) & bcd_to_dpd(rs(11 downto 0));
168 else
169 -- cdtbcd
170 tmp := x"00" & dpd_to_bcd(rs(51 downto 42)) & dpd_to_bcd(rs(41 downto 32)) &
171 x"00" & dpd_to_bcd(rs(19 downto 10)) & dpd_to_bcd(rs(9 downto 0));
172 end if;
173 when OP_EXTS =>
174 -- note datalen is a 1-hot encoding
175 negative := (datalen(0) and rs(7)) or
176 (datalen(1) and rs(15)) or
177 (datalen(2) and rs(31));
178 tmp := (others => negative);
179 if datalen(2) = '1' then
180 tmp(31 downto 16) := rs(31 downto 16);
181 end if;
182 if datalen(2) = '1' or datalen(1) = '1' then
183 tmp(15 downto 8) := rs(15 downto 8);
184 end if;
185 tmp(7 downto 0) := rs(7 downto 0);
186 when others =>
187 -- e.g. OP_MFSPR
188 tmp := rs;
189 end case;
190
191 result <= tmp;
192
193 end process;
194 end behaviour;