OpenCores
URL https://opencores.org/ocsvn/lxp32/lxp32/trunk

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [rtl/] [lxp32_interrupt_mux.vhd] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 ring0_mipt
---------------------------------------------------------------------
2
-- Interrupt multiplexer
3
--
4
-- Part of the LXP32 CPU
5
--
6
-- Copyright (c) 2016 by Alex I. Kuznetsov
7
--
8
-- Manages LXP32 interrupts. Interrupts with lower numbers have
9
-- higher priority.
10
---------------------------------------------------------------------
11
 
12
library ieee;
13
use ieee.std_logic_1164.all;
14
use ieee.numeric_std.all;
15
 
16
entity lxp32_interrupt_mux is
17
        port(
18
                clk_i: in std_logic;
19
                rst_i: in std_logic;
20
 
21
                irq_i: in std_logic_vector(7 downto 0);
22
 
23
                interrupt_valid_o: out std_logic;
24
                interrupt_vector_o: out std_logic_vector(2 downto 0);
25
                interrupt_ready_i: in std_logic;
26
                interrupt_return_i: in std_logic;
27 12 ring0_mipt
 
28
                wakeup_o: out std_logic;
29 9 ring0_mipt
 
30
                sp_waddr_i: in std_logic_vector(7 downto 0);
31
                sp_we_i: in std_logic;
32
                sp_wdata_i: in std_logic_vector(31 downto 0)
33
        );
34
end entity;
35
 
36
architecture rtl of lxp32_interrupt_mux is
37
 
38
signal irq_reg: std_logic_vector(irq_i'range):=(others=>'0');
39
 
40
type state_type is (Ready,Requested,WaitForExit);
41
signal state: state_type:=Ready;
42
 
43
signal pending_interrupts: std_logic_vector(irq_i'range):=(others=>'0');
44
 
45
signal interrupt_valid: std_logic:='0';
46
 
47
signal interrupts_enabled: std_logic_vector(7 downto 0):=(others=>'0');
48 12 ring0_mipt
signal interrupts_wakeup: std_logic_vector(7 downto 0):=(others=>'0');
49 9 ring0_mipt
 
50
begin
51
 
52
-- Note: "disabled" interrupts (i.e. for which interrupts_enabled_i(i)='0')
53
-- are ignored completely, meaning that the interrupt handler won't be
54 12 ring0_mipt
-- called even if the interrupt is enabled later.
55 9 ring0_mipt
 
56
process (clk_i) is
57
begin
58
        if rising_edge(clk_i) then
59
                if rst_i='1' then
60
                        irq_reg<=(others=>'0');
61
                        pending_interrupts<=(others=>'0');
62
                        state<=Ready;
63
                        interrupt_valid<='0';
64
                        interrupt_vector_o<=(others=>'-');
65 12 ring0_mipt
                        wakeup_o<='0';
66 9 ring0_mipt
                else
67
                        irq_reg<=irq_i;
68
 
69
                        pending_interrupts<=(pending_interrupts or
70
                                (irq_i and not irq_reg)) and
71 12 ring0_mipt
                                interrupts_enabled and not interrupts_wakeup;
72 9 ring0_mipt
 
73
                        case state is
74
                        when Ready =>
75
                                for i in pending_interrupts'reverse_range loop -- lower interrupts have priority
76 12 ring0_mipt
                                        if pending_interrupts(i)='1' then
77 9 ring0_mipt
                                                pending_interrupts(i)<='0';
78
                                                interrupt_valid<='1';
79
                                                interrupt_vector_o<=std_logic_vector(to_unsigned(i,3));
80
                                                state<=Requested;
81
                                                exit;
82
                                        end if;
83
                                end loop;
84
                        when Requested =>
85
                                if interrupt_ready_i='1' then
86
                                        interrupt_valid<='0';
87
                                        state<=WaitForExit;
88
                                end if;
89
                        when WaitForExit =>
90
                                if interrupt_return_i='1' then
91
                                        state<=Ready;
92
                                end if;
93
                        end case;
94 12 ring0_mipt
 
95
                        if (irq_i and (not irq_reg) and interrupts_enabled and interrupts_wakeup)/=X"00" then
96
                                wakeup_o<='1';
97
                        else
98
                                wakeup_o<='0';
99
                        end if;
100 9 ring0_mipt
                end if;
101
        end if;
102
end process;
103
 
104
interrupt_valid_o<=interrupt_valid;
105
 
106
process (clk_i) is
107
begin
108
        if rising_edge(clk_i) then
109
                if rst_i='1' then
110
                        interrupts_enabled<=(others=>'0');
111 12 ring0_mipt
                        interrupts_wakeup<=(others=>'0');
112 9 ring0_mipt
                elsif sp_we_i='1' and sp_waddr_i=X"FC" then
113
                        interrupts_enabled<=sp_wdata_i(7 downto 0);
114 12 ring0_mipt
                        interrupts_wakeup<=sp_wdata_i(15 downto 8);
115 9 ring0_mipt
                end if;
116
        end if;
117
end process;
118
 
119
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.