+ case current.sub_select(1 downto 0) is
+ when "00" =>
+ muldiv_result <= multiply_to_x.result(63 downto 0);
+ when "01" =>
+ muldiv_result <= multiply_to_x.result(127 downto 64);
+ when "10" =>
+ muldiv_result <= multiply_to_x.result(63 downto 32) &
+ multiply_to_x.result(63 downto 32);
+ when others =>
+ muldiv_result <= divider_to_x.write_reg_data;
+ end case;
+
+ -- Compute misc_result
+ case current.sub_select is
+ when "000" =>
+ misc_result <= (others => '0');
+ when "001" =>
+ -- addg6s
+ addg6s := (others => '0');
+ for i in 0 to 14 loop
+ lo := i * 4;
+ hi := (i + 1) * 4;
+ if (a_in(hi) xor b_in(hi) xor sum_with_carry(hi)) = '0' then
+ addg6s(lo + 3 downto lo) := "0110";
+ end if;
+ end loop;
+ if sum_with_carry(64) = '0' then
+ addg6s(63 downto 60) := "0110";
+ end if;
+ misc_result <= addg6s;
+ when "010" =>
+ -- isel
+ crbit := to_integer(unsigned(insn_bc(e_in.insn)));
+ if cr_in(31-crbit) = '1' then
+ isel_result := a_in;
+ else
+ isel_result := b_in;
+ end if;
+ misc_result <= isel_result;
+ when "011" =>
+ -- darn
+ darn := (others => '1');
+ if random_err = '0' then
+ case e_in.insn(17 downto 16) is
+ when "00" =>
+ darn := x"00000000" & random_cond(31 downto 0);
+ when "10" =>
+ darn := random_raw;
+ when others =>
+ darn := random_cond;
+ end case;
+ end if;
+ misc_result <= darn;
+ when "100" =>
+ -- mfmsr
+ misc_result <= ctrl.msr;
+ when "101" =>
+ if e_in.insn(20) = '0' then
+ -- mfcr
+ mfcr_result := x"00000000" & cr_in;
+ else
+ -- mfocrf
+ crnum := fxm_to_num(insn_fxm(e_in.insn));
+ mfcr_result := (others => '0');
+ for i in 0 to 7 loop
+ lo := (7-i)*4;
+ hi := lo + 3;
+ if crnum = i then
+ mfcr_result(hi downto lo) := cr_in(hi downto lo);
+ end if;
+ end loop;
+ end if;
+ misc_result <= mfcr_result;
+ when "110" =>
+ -- setb
+ bfa := insn_bfa(e_in.insn);
+ crbit := to_integer(unsigned(bfa)) * 4;
+ setb_result := (others => '0');
+ if cr_in(31 - crbit) = '1' then
+ setb_result := (others => '1');
+ elsif cr_in(30 - crbit) = '1' then
+ setb_result(0) := '1';
+ end if;
+ misc_result <= setb_result;
+ when others =>
+ misc_result <= (others => '0');
+ end case;
+
+ -- compute comparison results
+ -- Note, we have done RB - RA, not RA - RB
+ if e_in.insn_type = OP_CMP then
+ l := insn_l(e_in.insn);
+ else
+ l := not e_in.is_32bit;
+ end if;
+ zerolo := not (or (a_in(31 downto 0) xor b_in(31 downto 0)));
+ zerohi := not (or (a_in(63 downto 32) xor b_in(63 downto 32)));
+ if zerolo = '1' and (l = '0' or zerohi = '1') then
+ -- values are equal
+ trapval <= "00100";
+ else
+ a_lt_lo := '0';
+ a_lt_hi := '0';
+ if unsigned(a_in(30 downto 0)) < unsigned(b_in(30 downto 0)) then
+ a_lt_lo := '1';
+ end if;
+ if unsigned(a_in(62 downto 31)) < unsigned(b_in(62 downto 31)) then
+ a_lt_hi := '1';
+ end if;
+ if l = '1' then
+ -- 64-bit comparison
+ msb_a := a_in(63);
+ msb_b := b_in(63);
+ a_lt := a_lt_hi or (zerohi and (a_in(31) xnor b_in(31)) and a_lt_lo);
+ else
+ -- 32-bit comparison
+ msb_a := a_in(31);
+ msb_b := b_in(31);
+ a_lt := a_lt_lo;
+ end if;
+ if msb_a /= msb_b then
+ -- Comparison is clear from MSB difference.
+ -- for signed, 0 is greater; for unsigned, 1 is greater
+ trapval <= msb_a & msb_b & '0' & msb_b & msb_a;
+ else
+ -- MSBs are equal, so signed and unsigned comparisons give the
+ -- same answer.
+ trapval <= a_lt & not a_lt & '0' & a_lt & not a_lt;
+ end if;
+ end if;
+
+ -- CR result mux
+ bf := insn_bf(e_in.insn);
+ crnum := to_integer(unsigned(bf));
+ newcrf := (others => '0');
+ case current.sub_select is
+ when "000" =>
+ -- CMP and CMPL instructions
+ if e_in.is_signed = '1' then
+ newcrf := trapval(4 downto 2) & xerc_in.so;
+ else
+ newcrf := trapval(1 downto 0) & trapval(2) & xerc_in.so;
+ end if;
+ when "001" =>
+ newcrf := ppc_cmprb(a_in, b_in, insn_l(e_in.insn));
+ when "010" =>
+ newcrf := ppc_cmpeqb(a_in, b_in);
+ when "011" =>
+ if current.insn(1) = '1' then
+ -- CR logical instructions
+ j := (7 - crnum) * 4;
+ newcrf := cr_in(j + 3 downto j);
+ bt := insn_bt(e_in.insn);
+ ba := insn_ba(e_in.insn);
+ bb := insn_bb(e_in.insn);
+ btnum := 3 - to_integer(unsigned(bt(1 downto 0)));
+ banum := 31 - to_integer(unsigned(ba));
+ bbnum := 31 - to_integer(unsigned(bb));
+ -- Bits 6-9 of the instruction word give the truth table
+ -- of the requested logical operation
+ cr_operands := cr_in(banum) & cr_in(bbnum);
+ crresult := e_in.insn(6 + to_integer(unsigned(cr_operands)));
+ for i in 0 to 3 loop
+ if i = btnum then
+ newcrf(i) := crresult;
+ end if;
+ end loop;
+ else
+ -- MCRF
+ bfa := insn_bfa(e_in.insn);
+ scrnum := to_integer(unsigned(bfa));
+ j := (7 - scrnum) * 4;
+ newcrf := cr_in(j + 3 downto j);
+ end if;
+ when "100" =>
+ -- MCRXRX
+ newcrf := xerc_in.ov & xerc_in.ca & xerc_in.ov32 & xerc_in.ca32;
+ when others =>
+ end case;
+ if current.insn_type = OP_MTCRF then
+ if e_in.insn(20) = '0' then
+ -- mtcrf
+ write_cr_mask <= insn_fxm(e_in.insn);
+ else
+ -- mtocrf: We require one hot priority encoding here
+ crnum := fxm_to_num(insn_fxm(e_in.insn));
+ write_cr_mask <= num_to_fxm(crnum);
+ end if;
+ write_cr_data <= c_in(31 downto 0);
+ else
+ write_cr_mask <= num_to_fxm(crnum);
+ write_cr_data <= newcrf & newcrf & newcrf & newcrf &
+ newcrf & newcrf & newcrf & newcrf;
+ end if;
+
+ end process;
+
+ execute1_1: process(all)
+ variable v : reg_type;
+ variable lo, hi : integer;
+ variable sh, mb, me : std_ulogic_vector(5 downto 0);
+ variable bo, bi : std_ulogic_vector(4 downto 0);
+ variable overflow : std_ulogic;
+ variable lv : Execute1ToLoadstore1Type;
+ variable irq_valid : std_ulogic;
+ variable exception : std_ulogic;
+ variable illegal : std_ulogic;
+ variable is_branch : std_ulogic;
+ variable is_direct_branch : std_ulogic;
+ variable taken_branch : std_ulogic;
+ variable abs_branch : std_ulogic;
+ variable spr_val : std_ulogic_vector(63 downto 0);
+ variable do_trace : std_ulogic;
+ variable hold_wr_data : std_ulogic;
+ variable fv : Execute1ToFPUType;
+ begin
+ is_branch := '0';
+ is_direct_branch := '0';
+ taken_branch := '0';
+ abs_branch := '0';
+ hold_wr_data := '0';
+
+ v := r;
+ v.e := Execute1ToWritebackInit;
+ v.e.redir_mode := ctrl.msr(MSR_IR) & not ctrl.msr(MSR_PR) &
+ not ctrl.msr(MSR_LE) & not ctrl.msr(MSR_SF);
+ v.e.xerc := xerc_in;
+
+ lv := Execute1ToLoadstore1Init;
+ fv := Execute1ToFPUInit;
+
+ x_to_multiply.valid <= '0';
+ x_to_divider.valid <= '0';
+ v.mul_in_progress := '0';
+ v.div_in_progress := '0';
+ v.cntz_in_progress := '0';
+ v.mul_finish := '0';
+
+ spr_result <= (others => '0');
+ spr_val := (others => '0');
+