Commit 35164028 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

VME_IRQ_Controller: made IRQ line level-sensitive.

There are two reasons for doing so:
- compatibility with Wishbone and the VIC interrupt controller
- possibility of losing an edge-triggered IRQ and hanging interrupts when
  different cores trigger interrupts very close to each other.
The modified interrupter implements a retry mechanism, that is, if the IRQ line
gets stuck for longer than certain period (g_retry_timeout), an IRQ cycle
is repeated on the VME bus.
parent 2eb96983
......@@ -235,7 +235,6 @@ architecture RTL of VME64xCore_Top is
signal s_BAR : std_logic_vector(4 downto 0);
signal s_time : std_logic_vector(39 downto 0);
signal s_bytes : std_logic_vector(12 downto 0);
signal s_IRQ : std_logic;
-- Oversampled input signals
signal VME_RST_n_oversampled : std_logic;
......@@ -317,13 +316,8 @@ begin
clk_i => clk_i
);
IrqrisingEdge : RisEdgeDetection
port map (
sig_i => IRQ_i,
clk_i => clk_i,
RisEdge_o => s_IRQ
);
Inst_VME_bus : VME_bus
generic map(
g_clock => g_clock,
......@@ -431,7 +425,7 @@ begin
VME_ADDR_123_i => VME_ADDR_i(3 downto 1),
INT_Level_i => s_INT_Level,
INT_Vector_i => s_INT_Vector ,
INT_Req_i => s_IRQ,
INT_Req_i => irq_i,
VME_IRQ_n_o => s_VME_IRQ_n_o,
VME_IACKOUT_n_o => VME_IACKOUT_n_o,
VME_DTACK_n_o => s_VME_DTACK_IRQ,
......
......@@ -106,6 +106,8 @@ use work.vme64x_pack.all;
-- Entity declaration
--===========================================================================
entity VME_IRQ_Controller is
generic (
g_retry_timeout : integer range 1024 to 16777215 := 62500);
port (
clk_i : in std_logic;
reset_n_i : in std_logic;
......@@ -130,7 +132,12 @@ end VME_IRQ_Controller;
--===========================================================================
architecture Behavioral of VME_IRQ_Controller is
--input signals
signal s_INT_Req_sample : std_logic;
signal int_trigger_p : std_logic;
signal retry_count : unsigned(23 downto 0);
type t_retry_state is (R_IDLE, R_IRQ, R_WAIT_RETRY);
signal retry_state : t_retry_state;
--output signals
signal s_DTACK_OE_o : std_logic;
signal s_enable : std_logic;
......@@ -166,13 +173,42 @@ begin
FallEdge_o => s_AS_FallingEdge
);
INT_ReqinputSample : process(clk_i)
p_int_retry : process(clk_i)
begin
if rising_edge(clk_i) then
s_INT_Req_sample <= INT_Req_i;
if reset_n_i = '0' then
int_trigger_p <= '0';
retry_count <= (others => '0');
retry_state <= R_IDLE;
else
case retry_state is
when R_IDLE =>
if(INT_Req_i = '1') then
retry_state <= R_IRQ;
end if;
when R_IRQ =>
retry_count <= (others => '0');
int_trigger_p <= '1';
retry_state <= R_WAIT_RETRY;
when R_WAIT_RETRY =>
int_trigger_p <= '0';
if(INT_Req_i = '1') then
retry_count <= retry_count + 1;
if(retry_count = g_retry_timeout) then
retry_state <= R_IRQ;
end if;
else
retry_state <= R_IDLE;
end if;
end case;
end if;
end if;
end process;
--Output registers:
DTACKOutputSample : process(clk_i)
begin
......@@ -225,11 +261,11 @@ begin
end if;
end process;
-- Update next state
process(s_currs, s_INT_Req_sample, VME_AS_n_i, VME_DS_n_i, s_ack_int, VME_IACKIN_n_i, s_AS_RisingEdge)
process(s_currs, int_trigger_p, VME_AS_n_i, VME_DS_n_i, s_ack_int, VME_IACKIN_n_i, s_AS_RisingEdge)
begin
case s_currs is
when IDLE =>
if s_INT_Req_sample = '1' and VME_IACKIN_n_i = '1' then
if int_trigger_p = '1' and VME_IACKIN_n_i = '1' then
s_nexts <= IRQ;
elsif VME_IACKIN_n_i = '0' then
s_nexts <= IACKOUT2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment