diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd index b03d1a713dce1afe2b618e54211ffe58d7878560..6a1765ab8873b2357b3a22aac50f983737d66844 100644 --- a/cMIPS/vhdl/core.vhd +++ b/cMIPS/vhdl/core.vhd @@ -156,7 +156,7 @@ architecture rtl of core is signal update, not_stalled: std_logic; signal update_reg : reg5; signal status_update,epc_update,compare_update: std_logic; - signal cause_update, disable_count, compare_set, compare_clr: std_logic; + signal disable_count, compare_set, compare_clr: std_logic; signal STATUSinp,STATUS, CAUSEinp,CAUSE, EPCinp,EPC : reg32; signal COUNT, COMPARE : reg32; signal count_eq_compare,count_update,count_enable : std_logic; @@ -2327,31 +2327,31 @@ begin variable newCAUSE : reg32; begin - if STATUS(STATUS_EXL) = '0' then - newCAUSE(CAUSE_BD) := is_delayslot; -- instr is in delay slot + if STATUS(STATUS_EXL) = '0' then -- no exception, update CAUSE + newCAUSE(CAUSE_BD) := is_delayslot; + newCAUSE(CAUSE_TI) := count_eq_compare; + newCAUSE(CAUSE_CE1) := '0'; + newCAUSE(CAUSE_CE0) := '0'; + newCAUSE(CAUSE_DC) := CAUSE(CAUSE_DC); + newCAUSE(CAUSE_PCI) := '0'; + newCAUSE(25 downto 24) := b"00"; + newCAUSE(CAUSE_IV) := CAUSE(CAUSE_IV); + newCAUSE(CAUSE_WP) := '0'; + newCAUSE(21 downto 16) := b"000000"; + newCAUSE(CAUSE_IP7) := MM_int_req(7); + newCAUSE(CAUSE_IP6) := MM_int_req(6); + newCAUSE(CAUSE_IP5) := MM_int_req(5); + newCAUSE(CAUSE_IP4) := MM_int_req(4); + newCAUSE(CAUSE_IP3) := MM_int_req(3); + newCAUSE(CAUSE_IP2) := MM_int_req(2); + newCAUSE(CAUSE_IP1) := CAUSE(CAUSE_IP1); + newCAUSE(CAUSE_IP0) := CAUSE(CAUSE_IP0); + newCAUSE(7) := '0'; + newCAUSE(6 downto 2) := ExcCode; + newCAUSE(1 downto 0) := b"00"; else - newCAUSE(CAUSE_BD) := CAUSE(CAUSE_BD); -- hold it on a double fault + newCAUSE := CAUSE; -- hold it on an exception end if; - newCAUSE(CAUSE_TI) := count_eq_compare; - newCAUSE(CAUSE_CE1) := '0'; - newCAUSE(CAUSE_CE0) := '0'; - newCAUSE(CAUSE_DC) := CAUSE(CAUSE_DC); - newCAUSE(CAUSE_PCI) := '0'; - newCAUSE(25 downto 24) := b"00"; - newCAUSE(CAUSE_IV) := CAUSE(CAUSE_IV); - newCAUSE(CAUSE_WP) := '0'; - newCAUSE(21 downto 16) := b"000000"; - newCAUSE(CAUSE_IP7) := MM_int_req(7); - newCAUSE(CAUSE_IP6) := MM_int_req(6); - newCAUSE(CAUSE_IP5) := MM_int_req(5); - newCAUSE(CAUSE_IP4) := MM_int_req(4); - newCAUSE(CAUSE_IP3) := MM_int_req(3); - newCAUSE(CAUSE_IP2) := MM_int_req(2); - newCAUSE(CAUSE_IP1) := CAUSE(CAUSE_IP1); - newCAUSE(CAUSE_IP0) := CAUSE(CAUSE_IP0); - newCAUSE(7) := '0'; - newCAUSE(6 downto 2) := ExcCode; - newCAUSE(1 downto 0) := b"00"; if (update = '1' and update_reg = cop0reg_CAUSE) then CAUSEinp <= newCAUSE(CAUSE_BD downto CAUSE_CE0) & @@ -2365,22 +2365,9 @@ begin end if; end process COP0_COMPUTE_CAUSE; - COP0_CAUSE_HOLD: process(rst,clk, ExcCode,is_exception, - MM_cop0_reg,not_stalled) - variable state: reg32; - begin - if rst = '0' then -- hold CAUSE until it is read - cause_update <= '0'; - elsif ( rising_edge(clk) and (ExcCode /= cop0code_NULL) ) then - cause_update <= '1'; -- syscall/trap/interrupt/exception - elsif ( rising_edge(clk) and (is_exception = exMFC0) and - MM_cop0_reg = cop0reg_CAUSE and (not_stalled = '1') ) then - cause_update <= '0'; -- CAUSE is being read - end if; - end process COP0_CAUSE_HOLD; - + COP0_CAUSE: register32 generic map (RESET_CAUSE) - port map (clk, rst, cause_update, CAUSEinp, CAUSE); + port map (clk, rst, '0', CAUSEinp, CAUSE); -- EPC -- pg 97 -- cop0_14 ------------------- @@ -2418,8 +2405,7 @@ begin COP0_COUNT_INTERRUPT: FFD port map (clk, rst, '1', compare_set, count_eq_compare); - disable_count <= CAUSE(CAUSE_DC) - when (cause_update='0' and CAUSE(CAUSE_DC) /= count_enable) + disable_count <= CAUSE(CAUSE_DC) when (CAUSE(CAUSE_DC) /= count_enable) else count_enable; -- load new CAUSE(CAUSE_DC) COP0_DISABLE_COUNT: FFD port map (clk,'1',rst, disable_count, count_enable);