2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
6 use work.decode_types.all;
9 use work.crhelpers.all;
10 use work.insn_helpers.all;
11 use work.ppc_fx_insns.all;
15 SIM : boolean := false
21 flush_out : out std_ulogic;
23 e_in : in Decode2ToExecute1Type;
26 f_out : out Execute1ToFetch1Type;
28 e_out : out Execute1ToExecute2Type;
30 terminate_out : out std_ulogic
34 architecture behaviour of execute1 is
35 type reg_type is record
36 --f : Execute1ToFetch1Type;
37 e : Execute1ToExecute2Type;
40 signal r, rin : reg_type;
42 signal ctrl: ctrl_t := (carry => '0', others => (others => '0'));
43 signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0'));
45 execute1_0: process(clk)
47 if rising_edge(clk) then
53 execute1_1: process(all)
54 variable v : reg_type;
55 variable result : std_ulogic_vector(63 downto 0);
56 variable newcrf : std_ulogic_vector(3 downto 0);
57 variable result_with_carry : std_ulogic_vector(64 downto 0);
58 variable result_en : integer;
59 variable crnum : integer;
60 variable scrnum : integer;
61 variable lo, hi : integer;
63 result := (others => '0');
64 result_with_carry := (others => '0');
68 v.e := Execute1ToExecute2Init;
69 --v.f := Execute1ToFetch1TypeInit;
72 -- FIXME: run at 512MHz not core freq
73 ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
76 f_out <= Execute1ToFetch1TypeInit;
78 if e_in.valid = '1' then
81 v.e.write_reg := e_in.write_reg;
83 case_0: case e_in.insn_type is
91 result := ppc_add(e_in.read_data1, e_in.read_data2);
94 result_with_carry := ppc_adde(e_in.read_data1, e_in.read_data2, ctrl.carry and e_in.input_carry);
95 result := result_with_carry(63 downto 0);
96 ctrl_tmp.carry <= result_with_carry(64) and e_in.output_carry;
99 result := ppc_and(e_in.read_data1, e_in.read_data2);
102 result := ppc_andc(e_in.read_data1, e_in.read_data2);
105 f_out.redirect <= '1';
106 if (insn_aa(e_in.insn)) then
107 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
109 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
112 if e_in.const1(4-2) = '0' then
113 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
115 if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
116 f_out.redirect <= '1';
117 if (insn_aa(e_in.insn)) then
118 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
120 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
124 -- bits 10 and 6 distinguish between bclr, bcctr and bctar
125 if e_in.const1(4-2) = '0' and e_in.insn(10) = '0' then
126 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
128 if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
129 f_out.redirect <= '1';
130 if e_in.insn(10) = '0' then
131 f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
133 f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
137 result := ppc_cmpb(e_in.read_data1, e_in.read_data2);
140 v.e.write_cr_enable := '1';
141 crnum := to_integer(unsigned(e_in.const1(2 downto 0)));
142 v.e.write_cr_mask := num_to_fxm(crnum);
146 v.e.write_cr_data(hi downto lo) := ppc_cmp(e_in.const2(0), e_in.read_data1, e_in.read_data2);
149 v.e.write_cr_enable := '1';
150 crnum := to_integer(unsigned(e_in.const1(2 downto 0)));
151 v.e.write_cr_mask := num_to_fxm(crnum);
155 v.e.write_cr_data(hi downto lo) := ppc_cmpl(e_in.const2(0), e_in.read_data1, e_in.read_data2);
158 result := ppc_cntlzw(e_in.read_data1);
161 result := ppc_cnttzw(e_in.read_data1);
164 result := ppc_cntlzd(e_in.read_data1);
167 result := ppc_cnttzd(e_in.read_data1);
170 result := ppc_extsb(e_in.read_data1);
173 result := ppc_extsh(e_in.read_data1);
176 result := ppc_extsw(e_in.read_data1);
179 result := ppc_eqv(e_in.read_data1, e_in.read_data2);
182 crnum := to_integer(unsigned(e_in.const1));
183 if e_in.cr(31-crnum) = '1' then
184 result := e_in.read_data1;
186 result := e_in.read_data2;
190 v.e.write_cr_enable := '1';
191 crnum := to_integer(unsigned(e_in.const1(2 downto 0)));
192 scrnum := to_integer(unsigned(e_in.const2(2 downto 0)));
193 v.e.write_cr_mask := num_to_fxm(crnum);
198 newcrf := e_in.cr(hi downto lo);
204 v.e.write_cr_data(hi downto lo) := newcrf;
207 if std_match(e_in.insn(20 downto 11), "0100100000") then
210 elsif std_match(e_in.insn(20 downto 11), "0100000000") then
213 elsif std_match(e_in.insn(20 downto 11), "0110001000") then
218 result := x"00000000" & e_in.cr;
221 crnum := fxm_to_num(e_in.const1(7 downto 0));
222 result := (others => '0');
227 result(hi downto lo) := e_in.cr(hi downto lo);
232 v.e.write_cr_enable := '1';
233 v.e.write_cr_mask := e_in.const1(7 downto 0);
234 v.e.write_cr_data := e_in.read_data1(31 downto 0);
236 v.e.write_cr_enable := '1';
237 -- We require one hot priority encoding here
238 crnum := fxm_to_num(e_in.const1(7 downto 0));
239 v.e.write_cr_mask := num_to_fxm(crnum);
240 v.e.write_cr_data := e_in.read_data1(31 downto 0);
242 if std_match(e_in.insn(20 downto 11), "0100100000") then
243 ctrl_tmp.ctr <= e_in.read_data1;
244 elsif std_match(e_in.insn(20 downto 11), "0100000000") then
245 ctrl_tmp.lr <= e_in.read_data1;
248 result := ppc_nand(e_in.read_data1, e_in.read_data2);
251 result := ppc_neg(e_in.read_data1);
254 result := ppc_nor(e_in.read_data1, e_in.read_data2);
257 result := ppc_or(e_in.read_data1, e_in.read_data2);
260 result := ppc_orc(e_in.read_data1, e_in.read_data2);
263 result := ppc_popcntb(e_in.read_data1);
266 result := ppc_popcntw(e_in.read_data1);
269 result := ppc_popcntd(e_in.read_data1);
272 result := ppc_prtyd(e_in.read_data1);
275 result := ppc_prtyw(e_in.read_data1);
278 if e_in.insn(1) = '0' then
279 result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
281 result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
285 result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
288 result := ppc_rldicr(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
291 result := ppc_rlwnm(e_in.read_data1, e_in.read_data2, e_in.const2(4 downto 0), e_in.const3(4 downto 0));
294 result := ppc_rlwinm(e_in.read_data1, e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.const3(4 downto 0));
297 result := ppc_rldic(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
300 result := ppc_rldimi(e_in.read_data1, e_in.read_data2, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
303 result := ppc_rlwimi(e_in.read_data1, e_in.read_data2, e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.const3(4 downto 0));
306 result := ppc_sld(e_in.read_data1, e_in.read_data2);
309 result := ppc_slw(e_in.read_data1, e_in.read_data2);
312 result_with_carry := ppc_sraw(e_in.read_data1, e_in.read_data2);
313 result := result_with_carry(63 downto 0);
314 ctrl_tmp.carry <= result_with_carry(64);
317 result_with_carry := ppc_srawi(e_in.read_data1, e_in.const1(5 downto 0));
318 result := result_with_carry(63 downto 0);
319 ctrl_tmp.carry <= result_with_carry(64);
322 result_with_carry := ppc_srad(e_in.read_data1, e_in.read_data2);
323 result := result_with_carry(63 downto 0);
324 ctrl_tmp.carry <= result_with_carry(64);
327 result_with_carry := ppc_sradi(e_in.read_data1, e_in.const1(5 downto 0));
328 result := result_with_carry(63 downto 0);
329 ctrl_tmp.carry <= result_with_carry(64);
332 result := ppc_srd(e_in.read_data1, e_in.read_data2);
335 result := ppc_srw(e_in.read_data1, e_in.read_data2);
338 result := ppc_subf(e_in.read_data1, e_in.read_data2);
341 result_with_carry := ppc_subfe(e_in.read_data1, e_in.read_data2, ctrl.carry or not(e_in.input_carry));
342 result := result_with_carry(63 downto 0);
343 ctrl_tmp.carry <= result_with_carry(64) and e_in.output_carry;
346 result := ppc_xor(e_in.read_data1, e_in.read_data2);
349 when OP_SIM_CONFIG =>
350 -- bit 0 was used to select the microwatt console, which
351 -- we no longer support.
353 result := x"0000000000000000";
355 result := x"0000000000000000";
360 -- Keep our test cases happy for now, ignore trap instructions
361 report "OP_TDI FIXME";
364 terminate_out <= '1';
368 if e_in.lr = '1' then
369 ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
372 if result_en = 1 then
373 v.e.write_data := result;
374 v.e.write_enable := '1';
385 flush_out <= f_out.redirect;
387 end architecture behaviour;