From d8083946f36dafa37c8ab21c2e2b1fba1d756e01 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 17 Oct 2009 17:19:41 +0000 Subject: [PATCH] - changed NMI/RST behavior: reset exception entered after NMI/RST transition 1 => 0. - BEV = 1 after NMI/RST (like hard reset) - status not KUc,IEc not saved to KUp, IEp at NMI/RST (like hard reset) Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@523 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/src/core/mips_cop.vhd | 101 +++++++++++++++++----------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/lib/CPUs/MIPS/src/core/mips_cop.vhd b/lib/CPUs/MIPS/src/core/mips_cop.vhd index e25970d..79c95d3 100644 --- a/lib/CPUs/MIPS/src/core/mips_cop.vhd +++ b/lib/CPUs/MIPS/src/core/mips_cop.vhd @@ -82,6 +82,8 @@ architecture Behavioral of cop is signal reg_wptr : reg_ptr_t; signal inject_exc : STD_LOGIC; signal latch_vect_en : STD_LOGIC; + signal int_nmi : STD_LOGIC; + signal nmi_asserted : std_logic; type cop_pipe_t is record opc : opcode_t; @@ -147,7 +149,28 @@ begin eflags.RI <= ctrl_in.events.illegal; eflags.Int <= ctrl_in.events.int; -exception_state: +proc_nmi_state_next: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + int_nmi <= '0'; + nmi_asserted <= '0'; + elsif latch_vect_en = '1' then + int_nmi <= '0'; + elsif nmi_asserted = '1' then + if nmi = '0' then + nmi_asserted <= '0'; + int_nmi <= '1'; + end if; + elsif nmi = '1' then + nmi_asserted <= '1'; + end if; + end if; + end process; + + +proc_exc_state: process(exc_state, ctrl_in, cop_pipe_ID) begin @@ -219,6 +242,18 @@ exception_state: end case; end process; +proc_exc_state_next: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + exc_state <= exc_idle; + else + exc_state <= exc_staten; + end if; + end if; + end process; + sample_endian: process(clk) begin @@ -239,25 +274,13 @@ exception_last_imem_addr: end if; end process; -exception_state_next: - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - exc_state <= exc_idle; - else - exc_state <= exc_staten; - end if; - end if; - end process; - cop_exception_epc_write: process(clk) begin if rising_edge(clk) then if rst = '1' then - bd <= '0'; - epc <= (others => '0'); + bd <= '0'; + epc <= (others => '0'); elsif epc_reg_we = '1' then bd <= '0'; epc <= ctrl_in.epc_mem; @@ -349,7 +372,7 @@ cop_ip_reg_write: ipm_v := ip_v and im; ip <= ip_v; ctrl_out.int <= (eval_int(ipm_v) and status(0)); - ctrl_out.NMI <= nmi; + ctrl_out.NMI <= int_nmi; end if; end process; @@ -476,30 +499,32 @@ cop_status_reg_write: if rising_edge(clk) then if rst = '1' then status <= X"00600000"; - else - if status_save = '1' then + elsif status_save = '1' then + if ctrl_in.events.nmi = '0' then status(5 downto 4) <= status(3 downto 2); status(3 downto 2) <= status(1 downto 0); - status(1 downto 0) <= "00"; - elsif status_rest = '1' then - status(1 downto 0) <= status(3 downto 2); - status(3 downto 2) <= status(5 downto 4); - elsif ctrl_in.sdu.WB_nop = '0' then - if stat_reg_we = '1' then - if status(1) = '0' then - status(0) <= din(0); -- IEc - status(1) <= din(1); -- KUc - status(2) <= din(2); -- IEp - status(3) <= din(3); -- KUp - status(4) <= din(4); -- IEo - status(5) <= din(5); -- KUo - end if; - status(15 downto 8) <= din(15 downto 8); -- IM - status(22) <= din(22); -- BEV - status(25) <= din(25); -- RE - end if; - end if; - end if; + else + status(22) <= '1'; + end if; + status(1 downto 0) <= "00"; + elsif status_rest = '1' then + status(1 downto 0) <= status(3 downto 2); + status(3 downto 2) <= status(5 downto 4); + elsif ctrl_in.sdu.WB_nop = '0' then + if stat_reg_we = '1' then + if status(1) = '0' then + status(0) <= din(0); -- IEc + status(1) <= din(1); -- KUc + status(2) <= din(2); -- IEp + status(3) <= din(3); -- KUp + status(4) <= din(4); -- IEo + status(5) <= din(5); -- KUo + end if; + status(15 downto 8) <= din(15 downto 8); -- IM + status(22) <= din(22); -- BEV + status(25) <= din(25); -- RE + end if; + end if; end if; end process;