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 Execute1ToWritebackType;
30 terminate_out : out std_ulogic
34 architecture behaviour of execute1 is
35 type reg_type is record
36 --f : Execute1ToFetch1Type;
37 e : Execute1ToWritebackType;
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 signal right_shift, rot_clear_left, rot_clear_right: std_ulogic;
46 signal rotator_result: std_ulogic_vector(63 downto 0);
47 signal rotator_carry: std_ulogic;
48 signal logical_result: std_ulogic_vector(63 downto 0);
49 signal countzero_result: std_ulogic_vector(63 downto 0);
51 function decode_input_carry (carry_sel : carry_in_t; ca_in : std_ulogic) return std_ulogic is
64 rotator_0: entity work.rotator
66 rs => e_in.read_data3,
67 ra => e_in.read_data1,
68 shift => e_in.read_data2(6 downto 0),
70 is_32bit => e_in.is_32bit,
71 right_shift => right_shift,
72 arith => e_in.is_signed,
73 clear_left => rot_clear_left,
74 clear_right => rot_clear_right,
75 result => rotator_result,
76 carry_out => rotator_carry
79 logical_0: entity work.logical
81 rs => e_in.read_data3,
82 rb => e_in.read_data2,
84 invert_in => e_in.invert_a,
85 invert_out => e_in.invert_out,
86 result => logical_result
89 countzero_0: entity work.zero_counter
91 rs => e_in.read_data3,
92 count_right => e_in.insn(10),
93 is_32bit => e_in.is_32bit,
94 result => countzero_result
97 execute1_0: process(clk)
99 if rising_edge(clk) then
105 execute1_1: process(all)
106 variable v : reg_type;
107 variable a_inv : std_ulogic_vector(63 downto 0);
108 variable result : std_ulogic_vector(63 downto 0);
109 variable newcrf : std_ulogic_vector(3 downto 0);
110 variable result_with_carry : std_ulogic_vector(64 downto 0);
111 variable result_en : integer;
112 variable crnum : integer;
113 variable scrnum : integer;
114 variable lo, hi : integer;
115 variable sh, mb, me : std_ulogic_vector(5 downto 0);
116 variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
117 variable bo, bi : std_ulogic_vector(4 downto 0);
118 variable bf, bfa : std_ulogic_vector(2 downto 0);
119 variable l : std_ulogic;
121 result := (others => '0');
122 result_with_carry := (others => '0');
124 newcrf := (others => '0');
127 v.e := Execute1ToWritebackInit;
128 --v.f := Execute1ToFetch1TypeInit;
131 -- FIXME: run at 512MHz not core freq
132 ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
134 terminate_out <= '0';
135 f_out <= Execute1ToFetch1TypeInit;
137 -- rotator control signals
138 right_shift <= '1' when e_in.insn_type = OP_SHR else '0';
139 rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0';
140 rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0';
142 if e_in.valid = '1' then
145 v.e.write_reg := e_in.write_reg;
146 v.e.write_len := x"8";
147 v.e.sign_extend := '0';
149 case_0: case e_in.insn_type is
152 terminate_out <= '1';
157 if e_in.invert_a = '0' then
158 a_inv := e_in.read_data1;
160 a_inv := not e_in.read_data1;
162 result_with_carry := ppc_adde(a_inv, e_in.read_data2, decode_input_carry(e_in.input_carry, ctrl.carry));
163 result := result_with_carry(63 downto 0);
164 if e_in.output_carry then
165 ctrl_tmp.carry <= result_with_carry(64);
168 when OP_AND | OP_OR | OP_XOR =>
169 result := logical_result;
172 f_out.redirect <= '1';
173 if (insn_aa(e_in.insn)) then
174 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
176 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
179 bo := insn_bo(e_in.insn);
180 bi := insn_bi(e_in.insn);
181 if bo(4-2) = '0' then
182 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
184 if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then
185 f_out.redirect <= '1';
186 if (insn_aa(e_in.insn)) then
187 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
189 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
193 -- bits 10 and 6 distinguish between bclr, bcctr and bctar
194 bo := insn_bo(e_in.insn);
195 bi := insn_bi(e_in.insn);
196 if bo(4-2) = '0' and e_in.insn(10) = '0' then
197 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
199 if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then
200 f_out.redirect <= '1';
201 if e_in.insn(10) = '0' then
202 f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
204 f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
208 result := ppc_cmpb(e_in.read_data3, e_in.read_data2);
211 bf := insn_bf(e_in.insn);
212 l := insn_l(e_in.insn);
213 v.e.write_cr_enable := '1';
214 crnum := to_integer(unsigned(bf));
215 v.e.write_cr_mask := num_to_fxm(crnum);
219 v.e.write_cr_data(hi downto lo) := ppc_cmp(l, e_in.read_data1, e_in.read_data2);
222 bf := insn_bf(e_in.insn);
223 l := insn_l(e_in.insn);
224 v.e.write_cr_enable := '1';
225 crnum := to_integer(unsigned(bf));
226 v.e.write_cr_mask := num_to_fxm(crnum);
230 v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2);
233 result := countzero_result;
236 v.e.write_len := e_in.data_len;
237 v.e.sign_extend := '1';
238 result := e_in.read_data3;
241 crnum := to_integer(unsigned(insn_bc(e_in.insn)));
242 if e_in.cr(31-crnum) = '1' then
243 result := e_in.read_data1;
245 result := e_in.read_data2;
249 bf := insn_bf(e_in.insn);
250 bfa := insn_bfa(e_in.insn);
251 v.e.write_cr_enable := '1';
252 crnum := to_integer(unsigned(bf));
253 scrnum := to_integer(unsigned(bfa));
254 v.e.write_cr_mask := num_to_fxm(crnum);
259 newcrf := e_in.cr(hi downto lo);
265 v.e.write_cr_data(hi downto lo) := newcrf;
268 if std_match(e_in.insn(20 downto 11), "0100100000") then
271 elsif std_match(e_in.insn(20 downto 11), "0100000000") then
274 elsif std_match(e_in.insn(20 downto 11), "0110001000") then
279 if e_in.insn(20) = '0' then
281 result := x"00000000" & e_in.cr;
284 crnum := fxm_to_num(insn_fxm(e_in.insn));
285 result := (others => '0');
290 result(hi downto lo) := e_in.cr(hi downto lo);
296 v.e.write_cr_enable := '1';
297 if e_in.insn(20) = '0' then
299 v.e.write_cr_mask := insn_fxm(e_in.insn);
301 -- mtocrf: We require one hot priority encoding here
302 crnum := fxm_to_num(insn_fxm(e_in.insn));
303 v.e.write_cr_mask := num_to_fxm(crnum);
305 v.e.write_cr_data := e_in.read_data3(31 downto 0);
307 if std_match(e_in.insn(20 downto 11), "0100100000") then
308 ctrl_tmp.ctr <= e_in.read_data3;
309 elsif std_match(e_in.insn(20 downto 11), "0100000000") then
310 ctrl_tmp.lr <= e_in.read_data3;
313 result := ppc_neg(e_in.read_data1);
316 result := ppc_popcntb(e_in.read_data3);
319 result := ppc_popcntw(e_in.read_data3);
322 result := ppc_popcntd(e_in.read_data3);
325 result := ppc_prtyd(e_in.read_data3);
328 result := ppc_prtyw(e_in.read_data3);
330 when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR =>
331 result := rotator_result;
332 if e_in.output_carry = '1' then
333 ctrl_tmp.carry <= rotator_carry;
336 when OP_SIM_CONFIG =>
337 -- bit 0 was used to select the microwatt console, which
338 -- we no longer support.
340 result := x"0000000000000000";
342 result := x"0000000000000000";
347 -- Keep our test cases happy for now, ignore trap instructions
348 report "OP_TDI FIXME";
351 terminate_out <= '1';
355 if e_in.lr = '1' then
356 ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
359 if result_en = 1 then
360 v.e.write_data := result;
361 v.e.write_enable := '1';
372 flush_out <= f_out.redirect;
374 end architecture behaviour;