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 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 := Execute1ToExecute2Init;
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;
147 case_0: case e_in.insn_type is
150 terminate_out <= '1';
155 if e_in.invert_a = '0' then
156 a_inv := e_in.read_data1;
158 a_inv := not e_in.read_data1;
160 result_with_carry := ppc_adde(a_inv, e_in.read_data2, decode_input_carry(e_in.input_carry, ctrl.carry));
161 result := result_with_carry(63 downto 0);
162 if e_in.output_carry then
163 ctrl_tmp.carry <= result_with_carry(64);
166 when OP_AND | OP_OR | OP_XOR =>
167 result := logical_result;
170 f_out.redirect <= '1';
171 if (insn_aa(e_in.insn)) then
172 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
174 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
177 bo := insn_bo(e_in.insn);
178 bi := insn_bi(e_in.insn);
179 if bo(4-2) = '0' then
180 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
182 if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then
183 f_out.redirect <= '1';
184 if (insn_aa(e_in.insn)) then
185 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
187 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
191 -- bits 10 and 6 distinguish between bclr, bcctr and bctar
192 bo := insn_bo(e_in.insn);
193 bi := insn_bi(e_in.insn);
194 if bo(4-2) = '0' and e_in.insn(10) = '0' then
195 ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
197 if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then
198 f_out.redirect <= '1';
199 if e_in.insn(10) = '0' then
200 f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
202 f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
206 result := ppc_cmpb(e_in.read_data3, e_in.read_data2);
209 bf := insn_bf(e_in.insn);
210 l := insn_l(e_in.insn);
211 v.e.write_cr_enable := '1';
212 crnum := to_integer(unsigned(bf));
213 v.e.write_cr_mask := num_to_fxm(crnum);
217 v.e.write_cr_data(hi downto lo) := ppc_cmp(l, e_in.read_data1, e_in.read_data2);
220 bf := insn_bf(e_in.insn);
221 l := insn_l(e_in.insn);
222 v.e.write_cr_enable := '1';
223 crnum := to_integer(unsigned(bf));
224 v.e.write_cr_mask := num_to_fxm(crnum);
228 v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2);
231 result := countzero_result;
234 result := ppc_extsb(e_in.read_data3);
237 result := ppc_extsh(e_in.read_data3);
240 result := ppc_extsw(e_in.read_data3);
243 crnum := to_integer(unsigned(insn_bc(e_in.insn)));
244 if e_in.cr(31-crnum) = '1' then
245 result := e_in.read_data1;
247 result := e_in.read_data2;
251 bf := insn_bf(e_in.insn);
252 bfa := insn_bfa(e_in.insn);
253 v.e.write_cr_enable := '1';
254 crnum := to_integer(unsigned(bf));
255 scrnum := to_integer(unsigned(bfa));
256 v.e.write_cr_mask := num_to_fxm(crnum);
261 newcrf := e_in.cr(hi downto lo);
267 v.e.write_cr_data(hi downto lo) := newcrf;
270 if std_match(e_in.insn(20 downto 11), "0100100000") then
273 elsif std_match(e_in.insn(20 downto 11), "0100000000") then
276 elsif std_match(e_in.insn(20 downto 11), "0110001000") then
281 if e_in.insn(20) = '0' then
283 result := x"00000000" & e_in.cr;
286 crnum := fxm_to_num(insn_fxm(e_in.insn));
287 result := (others => '0');
292 result(hi downto lo) := e_in.cr(hi downto lo);
298 v.e.write_cr_enable := '1';
299 if e_in.insn(20) = '0' then
301 v.e.write_cr_mask := insn_fxm(e_in.insn);
303 -- mtocrf: We require one hot priority encoding here
304 crnum := fxm_to_num(insn_fxm(e_in.insn));
305 v.e.write_cr_mask := num_to_fxm(crnum);
307 v.e.write_cr_data := e_in.read_data3(31 downto 0);
309 if std_match(e_in.insn(20 downto 11), "0100100000") then
310 ctrl_tmp.ctr <= e_in.read_data3;
311 elsif std_match(e_in.insn(20 downto 11), "0100000000") then
312 ctrl_tmp.lr <= e_in.read_data3;
315 result := ppc_popcntb(e_in.read_data3);
318 result := ppc_popcntw(e_in.read_data3);
321 result := ppc_popcntd(e_in.read_data3);
324 result := ppc_prtyd(e_in.read_data3);
327 result := ppc_prtyw(e_in.read_data3);
329 when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR =>
330 result := rotator_result;
331 if e_in.output_carry = '1' then
332 ctrl_tmp.carry <= rotator_carry;
335 when OP_SIM_CONFIG =>
336 -- bit 0 was used to select the microwatt console, which
337 -- we no longer support.
339 result := x"0000000000000000";
341 result := x"0000000000000000";
346 -- Keep our test cases happy for now, ignore trap instructions
347 report "OP_TDI FIXME";
350 terminate_out <= '1';
354 if e_in.lr = '1' then
355 ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
358 if result_en = 1 then
359 v.e.write_data := result;
360 v.e.write_enable := '1';
371 flush_out <= f_out.redirect;
373 end architecture behaviour;