diff --git a/common.vhdl b/common.vhdl index 9f6e96d..9041d32 100644 --- a/common.vhdl +++ b/common.vhdl @@ -7,6 +7,15 @@ use work.decode_types.all; package common is + -- MSR bit numbers + constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode + constant MSR_EE : integer := (63 - 48); -- External interrupt Enable + constant MSR_PR : integer := (63 - 49); -- PRoblem state + constant MSR_IR : integer := (63 - 58); -- Instruction Relocation + constant MSR_DR : integer := (63 - 59); -- Data Relocation + constant MSR_RI : integer := (63 - 62); -- Recoverable Interrupt + constant MSR_LE : integer := (63 - 63); -- Little Endian + -- SPR numbers subtype spr_num_t is integer range 0 to 1023; diff --git a/execute1.vhdl b/execute1.vhdl index 2c0a558..0f4eea9 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -48,6 +48,11 @@ architecture behaviour of execute1 is slow_op_oe : std_ulogic; slow_op_xerc : xer_common_t; end record; + constant reg_type_init : reg_type := + (e => Execute1ToWritebackInit, lr_update => '0', + mul_in_progress => '0', div_in_progress => '0', cntz_in_progress => '0', + slow_op_rc => '0', slow_op_oe => '0', slow_op_xerc => xerc_init, + others => (others => '0')); signal r, rin : reg_type; @@ -124,11 +129,11 @@ architecture behaviour of execute1 is -- tion MSR bits are not saved or restored. -- Full function MSR bits lie in the range 0:32, 37:41, and -- 48:63, and partial function MSR bits lie in the range - -- 33:36 and 42:47. + -- 33:36 and 42:47. (Note this is IBM bit numbering). msr_out := (others => '0'); - msr_out(32 downto 0) := msr(32 downto 0); - msr_out(41 downto 37) := msr(41 downto 37); - msr_out(63 downto 48) := msr(63 downto 48); + msr_out(63 downto 31) := msr(63 downto 31); + msr_out(26 downto 22) := msr(26 downto 22); + msr_out(15 downto 0) := msr(15 downto 0); return msr_out; end; @@ -193,14 +198,20 @@ begin execute1_0: process(clk) begin if rising_edge(clk) then - r <= rin; - ctrl <= ctrl_tmp; - assert not (r.lr_update = '1' and e_in.valid = '1') - report "LR update collision with valid in EX1" - severity failure; - if r.lr_update = '1' then - report "LR update to " & to_hstring(r.next_lr); - end if; + if rst = '1' then + r <= reg_type_init; + ctrl.msr <= (MSR_SF => '1', MSR_LE => '1', others => '0'); + ctrl.irq_state <= WRITE_SRR0; + else + r <= rin; + ctrl <= ctrl_tmp; + assert not (r.lr_update = '1' and e_in.valid = '1') + report "LR update collision with valid in EX1" + severity failure; + if r.lr_update = '1' then + report "LR update to " & to_hstring(r.next_lr); + end if; + end if; end if; end process; @@ -370,7 +381,7 @@ begin ctrl_tmp.dec <= std_ulogic_vector(unsigned(ctrl.dec) - 1); irq_valid := '0'; - if ctrl.msr(63 - 48) = '1' and ctrl.dec(63) = '1' then + if ctrl.msr(MSR_EE) = '1' and ctrl.dec(63) = '1' then report "IRQ valid"; irq_valid := '1'; end if; @@ -400,7 +411,13 @@ begin v.e.exc_write_reg := fast_spr_num(SPR_SRR1); v.e.exc_write_data := ctrl.srr1; v.e.exc_write_enable := '1'; - ctrl_tmp.msr(63 - 48) <= '0'; -- clear EE + ctrl_tmp.msr(MSR_SF) <= '1'; + ctrl_tmp.msr(MSR_EE) <= '0'; + ctrl_tmp.msr(MSR_PR) <= '0'; + ctrl_tmp.msr(MSR_IR) <= '0'; + ctrl_tmp.msr(MSR_DR) <= '0'; + ctrl_tmp.msr(MSR_RI) <= '0'; + ctrl_tmp.msr(MSR_LE) <= '1'; f_out.redirect <= '1'; f_out.redirect_nia <= ctrl.irq_nia; v.e.valid := e_in.valid; @@ -545,7 +562,7 @@ begin when OP_B => f_out.redirect <= '1'; if (insn_aa(e_in.insn)) then - f_out.redirect_nia <= std_ulogic_vector(signed(b_in)); + f_out.redirect_nia <= b_in; else f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in)); end if; @@ -561,7 +578,7 @@ begin if ppc_bc_taken(bo, bi, e_in.cr, a_in) = 1 then f_out.redirect <= '1'; if (insn_aa(e_in.insn)) then - f_out.redirect_nia <= std_ulogic_vector(signed(b_in)); + f_out.redirect_nia <= b_in; else f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in)); end if; @@ -584,7 +601,17 @@ begin when OP_RFID => f_out.redirect <= '1'; f_out.redirect_nia <= a_in(63 downto 2) & "00"; -- srr0 - ctrl_tmp.msr <= msr_copy(std_ulogic_vector(signed(b_in))); -- srr1 + -- Can't use msr_copy here because the partial function MSR + -- bits should be left unchanged, not zeroed. + ctrl_tmp.msr(63 downto 31) <= b_in(63 downto 31); + ctrl_tmp.msr(26 downto 22) <= b_in(26 downto 22); + ctrl_tmp.msr(15 downto 0) <= b_in(15 downto 0); + if b_in(MSR_PR) = '1' then + ctrl_tmp.msr(MSR_EE) <= '1'; + ctrl_tmp.msr(MSR_IR) <= '1'; + ctrl_tmp.msr(MSR_DR) <= '1'; + end if; + when OP_CMPB => result := ppc_cmpb(c_in, b_in); result_en := '1'; @@ -658,7 +685,7 @@ begin end loop; end if; when OP_MFMSR => - result := msr_copy(ctrl.msr); + result := ctrl.msr; result_en := '1'; when OP_MFSPR => report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & @@ -714,9 +741,23 @@ begin v.e.write_cr_mask := num_to_fxm(crnum); end if; v.e.write_cr_data := c_in(31 downto 0); - when OP_MTMSRD => - -- FIXME handle just the bits we need to. - ctrl_tmp.msr <= msr_copy(c_in); + when OP_MTMSRD => + if e_in.insn(16) = '1' then + -- just update EE and RI + ctrl_tmp.msr(MSR_EE) <= c_in(MSR_EE); + ctrl_tmp.msr(MSR_RI) <= c_in(MSR_RI); + else + -- Architecture says to leave out bits 3 (HV), 51 (ME) + -- and 63 (LE) (IBM bit numbering) + ctrl_tmp.msr(63 downto 61) <= c_in(63 downto 61); + ctrl_tmp.msr(59 downto 13) <= c_in(59 downto 13); + ctrl_tmp.msr(11 downto 1) <= c_in(11 downto 1); + if c_in(MSR_PR) = '1' then + ctrl_tmp.msr(MSR_EE) <= '1'; + ctrl_tmp.msr(MSR_IR) <= '1'; + ctrl_tmp.msr(MSR_DR) <= '1'; + end if; + end if; when OP_MTSPR => report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(c_in);