diff --git a/common.vhdl b/common.vhdl index 321cff1..41623af 100644 --- a/common.vhdl +++ b/common.vhdl @@ -64,6 +64,7 @@ package common is is_32bit: std_ulogic; is_signed: std_ulogic; insn: std_ulogic_vector(31 downto 0); + data_len: std_ulogic_vector(3 downto 0); end record; constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', invert_a => '0', @@ -168,12 +169,14 @@ package common is write_enable : std_ulogic; write_reg: std_ulogic_vector(4 downto 0); write_data: std_ulogic_vector(63 downto 0); + write_len : std_ulogic_vector(3 downto 0); write_cr_enable : std_ulogic; write_cr_mask : std_ulogic_vector(7 downto 0); write_cr_data : std_ulogic_vector(31 downto 0); rc : std_ulogic; + sign_extend: std_ulogic; end record; - constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', others => (others => '0')); + constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', sign_extend => '0', others => (others => '0')); type Execute2ToWritebackType is record valid: std_ulogic; @@ -181,11 +184,13 @@ package common is write_enable : std_ulogic; write_reg: std_ulogic_vector(4 downto 0); write_data: std_ulogic_vector(63 downto 0); + write_len : std_ulogic_vector(3 downto 0); write_cr_enable : std_ulogic; write_cr_mask : std_ulogic_vector(7 downto 0); write_cr_data : std_ulogic_vector(31 downto 0); + sign_extend: std_ulogic; end record; - constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', rc => '0', write_enable => '0', write_cr_enable => '0', others => (others => '0')); + constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', rc => '0', write_enable => '0', write_cr_enable => '0', sign_extend => '0', others => (others => '0')); type MultiplyToWritebackType is record valid: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index 2bdb423..49e37da 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -164,9 +164,9 @@ architecture behaviour of decode1 is 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw 2#0100011100# => (ALU, OP_XOR, NONE, RB, RS, RA, '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- eqv - 2#1110111010# => (ALU, OP_EXTSB, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- extsb - 2#1110011010# => (ALU, OP_EXTSH, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- extsh - 2#1111011010# => (ALU, OP_EXTSW, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- extsw + 2#1110111010# => (ALU, OP_EXTS, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- extsb + 2#1110011010# => (ALU, OP_EXTS, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- extsh + 2#1111011010# => (ALU, OP_EXTS, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- extsw -- 2#110111101-# extswsli 2#1111010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbi 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt diff --git a/decode2.vhdl b/decode2.vhdl index 524943c..c8dee48 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -208,6 +208,7 @@ begin variable decoded_reg_b : decode_input_reg_t; variable decoded_reg_c : decode_input_reg_t; variable signed_division: std_ulogic; + variable length : std_ulogic_vector(3 downto 0); begin v := r; @@ -231,6 +232,19 @@ begin r_out.read2_enable <= decoded_reg_b.reg_valid; r_out.read3_enable <= decoded_reg_c.reg_valid; + case d_in.decode.length is + when is1B => + length := "0001"; + when is2B => + length := "0010"; + when is4B => + length := "0100"; + when is8B => + length := "1000"; + when NONE => + length := "0000"; + end case; + -- execute unit v.e.nia := d_in.nia; v.e.insn_type := d_in.decode.insn_type; @@ -252,6 +266,7 @@ begin v.e.lr := insn_lk(d_in.insn); end if; v.e.insn := d_in.insn; + v.e.data_len := length; -- multiply unit v.m.insn_type := d_in.decode.insn_type; @@ -336,19 +351,7 @@ begin v.l.load := '0'; end if; - case d_in.decode.length is - when is1B => - v.l.length := "0001"; - when is2B => - v.l.length := "0010"; - when is4B => - v.l.length := "0100"; - when is8B => - v.l.length := "1000"; - when NONE => - v.l.length := "0000"; - end case; - + v.l.length := length; v.l.byte_reverse := d_in.decode.byte_reverse; v.l.sign_extend := d_in.decode.sign_extend; v.l.update := d_in.decode.update; diff --git a/decode_types.vhdl b/decode_types.vhdl index 982b172..f6b6ca9 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -8,7 +8,7 @@ package decode_types is OP_CNTZ, OP_CRAND, OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC, OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST, - OP_DCBZ, OP_DIV, OP_EXTSB, OP_EXTSH, OP_EXTSW, + OP_DCBZ, OP_DIV, OP_EXTS, 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_MFSPR, OP_MOD, diff --git a/execute1.vhdl b/execute1.vhdl index d0ff461..85bb5e1 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -143,6 +143,8 @@ begin v.e.valid := '1'; v.e.write_reg := e_in.write_reg; + v.e.write_len := x"8"; + v.e.sign_extend := '0'; case_0: case e_in.insn_type is @@ -230,14 +232,10 @@ begin when OP_CNTZ => result := countzero_result; result_en := 1; - when OP_EXTSB => - result := ppc_extsb(e_in.read_data3); - result_en := 1; - when OP_EXTSH => - result := ppc_extsh(e_in.read_data3); - result_en := 1; - when OP_EXTSW => - result := ppc_extsw(e_in.read_data3); + when OP_EXTS => + v.e.write_len := e_in.data_len; + v.e.sign_extend := '1'; + result := e_in.read_data3; result_en := 1; when OP_ISEL => crnum := to_integer(unsigned(insn_bc(e_in.insn))); diff --git a/execute2.vhdl b/execute2.vhdl index de55310..97b4103 100644 --- a/execute2.vhdl +++ b/execute2.vhdl @@ -40,6 +40,8 @@ begin v.write_cr_mask := e_in.write_cr_mask; v.write_cr_data := e_in.write_cr_data; v.rc := e_in.rc; + v.write_len := e_in.write_len; + v.sign_extend := e_in.sign_extend; -- Update registers rin <= v; diff --git a/writeback.vhdl b/writeback.vhdl index ba88970..4bae8f7 100644 --- a/writeback.vhdl +++ b/writeback.vhdl @@ -100,6 +100,8 @@ begin w_out.write_reg <= e_in.write_reg; data_in <= e_in.write_data; w_out.write_enable <= '1'; + data_len <= unsigned(e_in.write_len); + sign_extend <= e_in.sign_extend; rc <= e_in.rc; end if;