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.ppc_fx_insns.all;
11 use work.sim_console.all;
15 SIM : boolean := false
20 e_in : in Decode2ToExecute1Type;
21 f_out : out Execute1ToFetch1Type;
22 e_out : out Execute1ToExecute2Type;
24 terminate_out : out std_ulogic
28 architecture behaviour of execute1 is
29 signal e: Decode2ToExecute1Type := Decode2ToExecute1Init;
30 signal ctrl: ctrl_t := (carry => '0', others => (others => '0'));
31 signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0'));
33 execute1_0: process(clk)
35 if rising_edge(clk) then
41 execute1_1: process(all)
42 variable result : std_ulogic_vector(63 downto 0);
43 variable result_with_carry : std_ulogic_vector(64 downto 0);
44 variable result_en : integer;
45 variable crnum : integer;
46 variable lo, hi : integer;
48 result := (others => '0');
49 result_with_carry := (others => '0');
52 e_out <= Execute1ToExecute2Init;
53 f_out <= Execute1ToFetch1TypeInit;
55 -- FIXME: run at 512MHz not core freq
56 ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
62 e_out.write_reg <= e.write_reg;
64 report "execute " & to_hstring(e.nia);
66 case_0: case e.insn_type is
74 result := ppc_add(e.read_data1, e.read_data2);
77 result_with_carry := ppc_adde(e.read_data1, e.read_data2, ctrl.carry and e.input_carry);
78 result := result_with_carry(63 downto 0);
79 ctrl_tmp.carry <= result_with_carry(64) and e.output_carry;
82 result := ppc_and(e.read_data1, e.read_data2);
85 result := ppc_andc(e.read_data1, e.read_data2);
88 f_out.redirect <= '1';
89 f_out.redirect_nia <= std_ulogic_vector(signed(e.nia) + signed(e.read_data2));
91 if e.const1(4-2) = '0' then
92 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
94 if ppc_bc_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr, ctrl.ctr) = 1 then
95 f_out.redirect <= '1';
96 f_out.redirect_nia <= std_ulogic_vector(signed(e.nia) + signed(e.read_data2));
99 if e.const1(4-2) = '0' then
100 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
102 if ppc_bc_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr, ctrl.ctr) = 1 then
103 f_out.redirect <= '1';
104 f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
107 if ppc_bcctr_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr) = 1 then
108 f_out.redirect <= '1';
109 f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
112 result := ppc_cmpb(e.read_data1, e.read_data2);
115 e_out.write_cr_enable <= '1';
116 crnum := to_integer(unsigned(e.const1(2 downto 0)));
117 e_out.write_cr_mask <= num_to_fxm(crnum);
121 e_out.write_cr_data(hi downto lo) <= ppc_cmp(e.const2(0), e.read_data1, e.read_data2);
124 e_out.write_cr_enable <= '1';
125 crnum := to_integer(unsigned(e.const1(2 downto 0)));
126 e_out.write_cr_mask <= num_to_fxm(crnum);
130 e_out.write_cr_data(hi downto lo) <= ppc_cmpl(e.const2(0), e.read_data1, e.read_data2);
133 result := ppc_cntlzw(e.read_data1);
136 result := ppc_cnttzw(e.read_data1);
139 result := ppc_cntlzd(e.read_data1);
142 result := ppc_cnttzd(e.read_data1);
145 result := ppc_extsb(e.read_data1);
148 result := ppc_extsh(e.read_data1);
151 result := ppc_extsw(e.read_data1);
154 result := ppc_eqv(e.read_data1, e.read_data2);
157 crnum := to_integer(unsigned(e.const1));
158 if e.cr(31-crnum) = '1' then
159 result := e.read_data1;
161 result := e.read_data2;
174 ctrl_tmp.ctr <= e.read_data1;
176 ctrl_tmp.lr <= e.read_data1;
178 result := x"00000000" & e.cr;
181 crnum := fxm_to_num(e.const1(7 downto 0));
182 result := (others => '0');
183 -- result((4*(7-crnum)+3) downto (4*(7-crnum))) := e.cr((4*(7-crnum)+3) downto (4*(7-crnum))); FIXME
188 result(hi downto lo) := e.cr(hi downto lo);
193 e_out.write_cr_enable <= '1';
194 e_out.write_cr_mask <= e.const1(7 downto 0);
195 e_out.write_cr_data <= e.read_data1(31 downto 0);
197 e_out.write_cr_enable <= '1';
198 -- We require one hot priority encoding here
199 crnum := fxm_to_num(e.const1(7 downto 0));
200 e_out.write_cr_mask <= num_to_fxm(crnum);
201 e_out.write_cr_data <= e.read_data1(31 downto 0);
203 result := ppc_nand(e.read_data1, e.read_data2);
206 result := ppc_neg(e.read_data1);
209 result := ppc_nor(e.read_data1, e.read_data2);
212 result := ppc_or(e.read_data1, e.read_data2);
215 result := ppc_orc(e.read_data1, e.read_data2);
218 result := ppc_popcntb(e.read_data1);
221 result := ppc_popcntw(e.read_data1);
224 result := ppc_popcntd(e.read_data1);
227 result := ppc_prtyd(e.read_data1);
230 result := ppc_prtyw(e.read_data1);
233 result := ppc_rldcl(e.read_data1, e.read_data2, e.const2(5 downto 0));
236 result := ppc_rldcr(e.read_data1, e.read_data2, e.const2(5 downto 0));
239 result := ppc_rldicl(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0));
242 result := ppc_rldicr(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0));
245 result := ppc_rlwnm(e.read_data1, e.read_data2, e.const2(4 downto 0), e.const3(4 downto 0));
248 result := ppc_rlwinm(e.read_data1, e.const1(4 downto 0), e.const2(4 downto 0), e.const3(4 downto 0));
251 result := ppc_rldic(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0));
254 result := ppc_rldimi(e.read_data1, e.read_data2, e.const1(5 downto 0), e.const2(5 downto 0));
257 result := ppc_rlwimi(e.read_data1, e.read_data2, e.const1(4 downto 0), e.const2(4 downto 0), e.const3(4 downto 0));
260 result := ppc_sld(e.read_data1, e.read_data2);
263 result := ppc_slw(e.read_data1, e.read_data2);
266 result_with_carry := ppc_sraw(e.read_data1, e.read_data2);
267 result := result_with_carry(63 downto 0);
268 ctrl_tmp.carry <= result_with_carry(64);
271 result_with_carry := ppc_srawi(e.read_data1, e.const1(5 downto 0));
272 result := result_with_carry(63 downto 0);
273 ctrl_tmp.carry <= result_with_carry(64);
276 result_with_carry := ppc_srad(e.read_data1, e.read_data2);
277 result := result_with_carry(63 downto 0);
278 ctrl_tmp.carry <= result_with_carry(64);
281 result_with_carry := ppc_sradi(e.read_data1, e.const1(5 downto 0));
282 result := result_with_carry(63 downto 0);
283 ctrl_tmp.carry <= result_with_carry(64);
286 result := ppc_srd(e.read_data1, e.read_data2);
289 result := ppc_srw(e.read_data1, e.read_data2);
292 result := ppc_subf(e.read_data1, e.read_data2);
295 result_with_carry := ppc_subfe(e.read_data1, e.read_data2, ctrl.carry or not(e.input_carry));
296 result := result_with_carry(63 downto 0);
297 ctrl_tmp.carry <= result_with_carry(64) and e.output_carry;
300 result := ppc_xor(e.read_data1, e.read_data2);
306 sim_console_read(result);
309 terminate_out <= '1';
314 sim_console_poll(result);
317 terminate_out <= '1';
322 sim_console_write(e.read_data1);
324 terminate_out <= '1';
327 when OP_SIM_CONFIG =>
329 result := x"0000000000000001";
331 result := x"0000000000000000";
336 -- Keep our test cases happy for now, ignore trap instructions
337 report "OP_TDI FIXME";
341 result := ppc_divdu(e.read_data1, e.read_data2);
344 terminate_out <= '1';
349 result := ppc_divd(e.read_data1, e.read_data2);
352 terminate_out <= '1';
357 result := ppc_divwu(e.read_data1, e.read_data2);
360 terminate_out <= '1';
365 result := ppc_divw(e.read_data1, e.read_data2);
368 terminate_out <= '1';
372 terminate_out <= '1';
377 ctrl_tmp.lr <= std_ulogic_vector(unsigned(e.nia) + 4);
380 if result_en = 1 then
381 e_out.write_data <= result;
382 e_out.write_enable <= '1';
387 end architecture behaviour;