diff --git a/Makefile b/Makefile index 13d245e..8075439 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ crhelpers.o: common.o decode1.o: common.o decode_types.o decode2.o: decode_types.o common.o helpers.o insn_helpers.o decode_types.o: -execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o +execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o insn_helpers.o execute2.o: common.o crhelpers.o ppc_fx_insns.o fetch1.o: common.o fetch2.o: common.o wishbone_types.o diff --git a/common.vhdl b/common.vhdl index 694e20c..8b1d4cf 100644 --- a/common.vhdl +++ b/common.vhdl @@ -58,13 +58,13 @@ package common is cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; - aa: std_ulogic; input_carry: std_ulogic; output_carry: std_ulogic; input_cr: std_ulogic; output_cr: std_ulogic; + insn: std_ulogic_vector(31 downto 0); end record; - constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', aa => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0')); + constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0')); type Decode2ToMultiplyType is record valid: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index c003739..98f6d35 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -125,12 +125,8 @@ architecture behaviour of decode1 is --PPC_MCRXRX PPC_MFCR => (ALU, OP_MFCR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MFOCRF => (ALU, OP_MFOCRF, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFCTR => (ALU, OP_MFCTR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFLR => (ALU, OP_MFLR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFTB => (ALU, OP_MFTB, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTCTR => (ALU, OP_MTCTR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTLR => (ALU, OP_MTLR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_MFSPR + PPC_MFSPR => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + PPC_MTSPR => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MOD => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_MTCRF => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MTOCRF => (ALU, OP_MTOCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), @@ -527,22 +523,6 @@ begin elsif std_match(f_in.insn, "011111-----1---------0000010011-") then report "PPC_mfocrf"; ppc_insn := PPC_MFOCRF; - -- Specific MF/MT SPR encodings first - elsif std_match(f_in.insn, "011111-----01001000000101010011-") then - report "PPC_mfctr"; - ppc_insn := PPC_MFCTR; - elsif std_match(f_in.insn, "011111-----01000000000101010011-") then - report "PPC_mflr"; - ppc_insn := PPC_MFLR; - elsif std_match(f_in.insn, "011111-----01100010000101010011-") then - report "PPC_mftb"; - ppc_insn := PPC_MFTB; - elsif std_match(f_in.insn, "011111-----01001000000111010011-") then - report "PPC_mtctr"; - ppc_insn := PPC_MTCTR; - elsif std_match(f_in.insn, "011111-----01000000000111010011-") then - report "PPC_mtlr"; - ppc_insn := PPC_MTLR; elsif std_match(f_in.insn, "011111---------------0101010011-") then report "PPC_mfspr"; ppc_insn := PPC_MFSPR; diff --git a/decode2.vhdl b/decode2.vhdl index c1c6e6b..2b816a7 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -264,13 +264,13 @@ begin v.e.cr := c_in.read_cr_data; v.e.input_carry := d_in.decode.input_carry; v.e.output_carry := d_in.decode.output_carry; - v.e.aa := insn_aa(d_in.insn); if d_in.decode.lr = '1' then v.e.lr := insn_lk(d_in.insn); end if; v.e.const1 := decode_const_a(d_in.decode.const_a, d_in.insn); v.e.const2 := decode_const_b(d_in.decode.const_b, d_in.insn); v.e.const3 := decode_const_c(d_in.decode.const_c, d_in.insn); + v.e.insn := d_in.insn; -- multiply unit v.m.insn_type := d_in.decode.insn_type; diff --git a/decode_types.vhdl b/decode_types.vhdl index 63e78c0..1437bf0 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -48,9 +48,8 @@ package decode_types is OP_DCBZ, OP_DIV, OP_EQV, OP_EXTSB, OP_EXTSH, OP_EXTSW, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC, OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF, - OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFCTR, OP_MFLR, - OP_MFTB, OP_MFSPR, OP_MOD, - OP_MTCRF, OP_MTOCRF, OP_MTCTR, OP_MTLR, OP_MTSPR, OP_MUL_L64, + OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFSPR, OP_MOD, + OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD, OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR, diff --git a/execute1.vhdl b/execute1.vhdl index e75fac7..0d85e71 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -7,6 +7,7 @@ use work.decode_types.all; use work.common.all; use work.helpers.all; use work.crhelpers.all; +use work.insn_helpers.all; use work.ppc_fx_insns.all; entity execute1 is @@ -102,7 +103,7 @@ begin result_en := 1; when OP_B => f_out.redirect <= '1'; - if (e_in.aa) then + if (insn_aa(e_in.insn)) then f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); else f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); @@ -113,7 +114,7 @@ begin end if; if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then f_out.redirect <= '1'; - if (e_in.aa) then + if (insn_aa(e_in.insn)) then f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); else f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); @@ -202,19 +203,17 @@ begin hi := lo + 3; v.e.write_cr_data(hi downto lo) := newcrf; end loop; - when OP_MFCTR => - result := ctrl.ctr; - result_en := 1; - when OP_MFLR => - result := ctrl.lr; - result_en := 1; - when OP_MFTB => - result := ctrl.tb; - result_en := 1; - when OP_MTCTR => - ctrl_tmp.ctr <= e_in.read_data1; - when OP_MTLR => - ctrl_tmp.lr <= e_in.read_data1; + when OP_MFSPR => + if std_match(e_in.insn(20 downto 11), "0100100000") then + result := ctrl.ctr; + result_en := 1; + elsif std_match(e_in.insn(20 downto 11), "0100000000") then + result := ctrl.lr; + result_en := 1; + elsif std_match(e_in.insn(20 downto 11), "0110001000") then + result := ctrl.tb; + result_en := 1; + end if; when OP_MFCR => result := x"00000000" & e_in.cr; result_en := 1; @@ -239,6 +238,12 @@ begin crnum := fxm_to_num(e_in.const1(7 downto 0)); v.e.write_cr_mask := num_to_fxm(crnum); v.e.write_cr_data := e_in.read_data1(31 downto 0); + when OP_MTSPR => + if std_match(e_in.insn(20 downto 11), "0100100000") then + ctrl_tmp.ctr <= e_in.read_data1; + elsif std_match(e_in.insn(20 downto 11), "0100000000") then + ctrl_tmp.lr <= e_in.read_data1; + end if; when OP_NAND => result := ppc_nand(e_in.read_data1, e_in.read_data2); result_en := 1;