Line 72... |
Line 72... |
-- Revision History
|
-- Revision History
|
-- Author Date Change
|
-- Author Date Change
|
------------------ -------- ---------------------------------------------------
|
------------------ -------- ---------------------------------------------------
|
-- Seth Henry 07/19/06 Design Start
|
-- Seth Henry 07/19/06 Design Start
|
-- Seth Henry 01/18/11 Fixed BTT instruction to match V8
|
-- Seth Henry 01/18/11 Fixed BTT instruction to match V8
|
-- Seth Henry 06/14/11 Fixed STO instruction to avoid register corruption
|
|
-- Fixed interrupt logic to avoid address corruption
|
|
-- when interrupt coincides with branch instruction
|
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
Line 582... |
Line 579... |
|
|
signal i_Ints : INTERRUPT_BUNDLE := (others => '0');
|
signal i_Ints : INTERRUPT_BUNDLE := (others => '0');
|
signal Pending_D : INTERRUPT_BUNDLE := (others => '0');
|
signal Pending_D : INTERRUPT_BUNDLE := (others => '0');
|
signal Pending : INTERRUPT_BUNDLE := (others => '0');
|
signal Pending : INTERRUPT_BUNDLE := (others => '0');
|
signal Wait_for_FSM : std_logic := '0';
|
signal Wait_for_FSM : std_logic := '0';
|
signal Mask : std_logic_vector(6 downto 0) := (others => '0');
|
|
signal ISR_D, ISR_Q : ADDRESS_TYPE := (others => '0');
|
signal ISR_D, ISR_Q : ADDRESS_TYPE := (others => '0');
|
|
|
type INT_HIST is array (0 to 8) of integer range 0 to 7;
|
type INT_HIST is array (0 to 8) of integer range 0 to 7;
|
signal History : INT_HIST := (others => 0);
|
signal History : INT_HIST := (others => 0);
|
signal Int_Trig : std_logic := '0';
|
signal Int_Trig : std_logic := '0';
|
signal Hist_Level : integer range 0 to 7 := 0;
|
signal Hist_Level : integer range 0 to 7 := 0;
|
signal Hist_Ptr : integer range 0 to 8 := 0;
|
signal Hist_Ptr : integer range 0 to 8 := 0;
|
|
|
begin
|
begin
|
Int_Mask <= Mask & '1';
|
|
ISR <= ISR_Q;
|
ISR <= ISR_Q;
|
|
|
Int_Mask_proc: process( Mask, Interrupts, INT_Ctrl )
|
Int_Mask_proc: process( Int_Mask, Interrupts, INT_Ctrl )
|
variable S_Mask : std_logic_vector(7 downto 0);
|
variable S_Mask : std_logic_vector(7 downto 0);
|
begin
|
begin
|
S_Mask := Mask & '1';
|
S_Mask := Int_Mask;
|
for i in 0 to 7 loop
|
for i in 0 to 7 loop
|
i_Ints(i) <= (Interrupts(i) or INT_Ctrl.Soft_Ints(i))
|
i_Ints(i) <= (Interrupts(i) or INT_Ctrl.Soft_Ints(i))
|
and S_Mask(i);
|
and S_Mask(i);
|
end loop;
|
end loop;
|
end process;
|
end process;
|
Line 677... |
Line 673... |
begin
|
begin
|
if( Reset = Reset_Level )then
|
if( Reset = Reset_Level )then
|
Int_Req <= '0';
|
Int_Req <= '0';
|
Pending <= x"00";
|
Pending <= x"00";
|
Wait_for_FSM <= '0';
|
Wait_for_FSM <= '0';
|
Mask <= Default_Interrupt_Mask(7 downto 1);
|
Int_Mask <= Default_Interrupt_Mask(7 downto 1) & '1';
|
ISR_Q <= INT_VECTOR_0;
|
ISR_Q <= INT_VECTOR_0;
|
for i in 0 to 8 loop
|
for i in 0 to 8 loop
|
History(i) <= 0;
|
History(i) <= 0;
|
end loop;
|
end loop;
|
Hist_Ptr <= 0;
|
Hist_Ptr <= 0;
|
Line 695... |
Line 691... |
-- Set the Wait_for_FSM flag on Int_Trig
|
-- Set the Wait_for_FSM flag on Int_Trig
|
elsif( Int_Trig = '1' )then
|
elsif( Int_Trig = '1' )then
|
Wait_for_FSM <= '1';
|
Wait_for_FSM <= '1';
|
end if;
|
end if;
|
if( INT_Ctrl.Mask_Set = '1' )then
|
if( INT_Ctrl.Mask_Set = '1' )then
|
Mask <= INT_Ctrl.Mask_Data(7 downto 1);
|
Int_Mask <= INT_Ctrl.Mask_Data(7 downto 1) & '1';
|
end if;
|
end if;
|
ISR_Q <= ISR_D;
|
ISR_Q <= ISR_D;
|
if( Int_Trig = '1' )then
|
if( Int_Trig = '1' )then
|
History(Hist_Ptr+1) <= Hist_Level;
|
History(Hist_Ptr+1) <= Hist_Level;
|
Hist_Ptr <= Hist_Ptr + 1;
|
Hist_Ptr <= Hist_Ptr + 1;
|
Line 1332... |
Line 1328... |
|
|
-- Interrupt service routines can only begin during the decode and wait
|
-- Interrupt service routines can only begin during the decode and wait
|
-- states to avoid corruption due to incomplete instruction execution
|
-- states to avoid corruption due to incomplete instruction execution
|
if( Int_Req = '1' )then
|
if( Int_Req = '1' )then
|
if( CPU_State = INSTR_DECODE or CPU_State = WAIT_FOR_INT )then
|
if( CPU_State = INSTR_DECODE or CPU_State = WAIT_FOR_INT )then
|
CPU_Next_State <= ISR_C1;
|
-- Reset all of the sub-block controls to IDLE, to avoid unintended
|
PC_Ctrl.Oper <= PC_INCR;
|
-- operation due to the current instruction
|
|
ALU_Ctrl.Oper <= ALU_IDLE;
|
|
Cache_Ctrl <= CACHE_IDLE;
|
|
SP_Ctrl.Oper <= SP_IDLE;
|
-- Rewind the PC by 3 to compensate for the pipeline registers
|
-- Rewind the PC by 3 to compensate for the pipeline registers
|
|
PC_Ctrl.Oper <= PC_INCR;
|
PC_Ctrl.Offset <= x"FF";
|
PC_Ctrl.Offset <= x"FF";
|
|
CPU_Next_State <= ISR_C1;
|
|
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
end process;
|
end process;
|
|
|