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

Subversion Repositories pic

[/] [pic/] [trunk/] [vhdl codes/] [PIC.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 lal87
----------------------------------------------------------------------------
2
---- Create Date:    00:12:45 10/23/2010                                                                                
3
---- Design Name: pic                                                                                                                                                           
4
---- Project Name: PIC                                                                                          
5
Description:
6
----  A Programmable Interrupt Controller which can handle upto 8       ----
7
---- level triggered interrupts.The operating modes available are       ----
8
---- polling fixed priority modes.                                                      ----                                                                                                                                                                                                                            ----    
9
----------------------------------------------------------------------------
10
----                                                                    ----
11
---- This file is a part of the pic project at                 ----
12
---- http://www.opencores.org/                                                ----
13
----                                                                    ----
14
---- Author(s):                                                         ----
15
----   Vipin Lal, lalnitt@gmail.com                                     ----
16
----                                                                    ----
17
----------------------------------------------------------------------------
18
----                                                                    ----
19
---- Copyright (C) 2010 Authors and OPENCORES.ORG                       ----
20
----                                                                    ----
21
---- This source file may be used and distributed without               ----
22
---- restriction provided that this copyright statement is not          ----
23
---- removed from the file and that any derivative work contains        ----
24
---- the original copyright notice and the associated disclaimer.       ----
25
----                                                                    ----
26
---- This source file is free software; you can redistribute it         ----
27
---- and/or modify it under the terms of the GNU Lesser General         ----
28
---- Public License as published by the Free Software Foundation;       ----
29
---- either version 2.1 of the License, or (at your option) any         ----
30
---- later version.                                                     ----
31
----                                                                    ----
32
---- This source is distributed in the hope that it will be             ----
33
---- useful, but WITHOUT ANY WARRANTY; without even the implied         ----
34
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR            ----
35
---- PURPOSE. See the GNU Lesser General Public License for more        ----
36
---- details.                                                           ----
37
----                                                                    ----
38
---- You should have received a copy of the GNU Lesser General          ----
39
---- Public License along with this source; if not, download it         ----
40
---- from http://www.opencores.org/lgpl.shtml                           ----
41
----                                                                    ----
42
----------------------------------------------------------------------------
43
 
44
library IEEE;
45
use IEEE.STD_LOGIC_1164.ALL;
46
use IEEE.NUMERIC_STD.ALL;
47
 
48
entity PIC is
49
port(   CLK_I : in std_logic;   --Clock.
50
                RST_I : in std_logic;  --Reset
51
                IR : in unsigned(7 downto 0);   --Interrupt requests from peripherals.
52
                DataBus : inout unsigned(7 downto 0);   --Data bus between processor PIC.
53
                INTR_O : out std_logic;  --Interrupt Request pin of processor.
54
                INTA_I : in std_logic  --Interrupt ack.
55
                );
56
end PIC;
57
 
58
architecture Behavioral of PIC is
59
 
60
type state_type is (reset_s,get_commands,jump_int_method,start_polling,tx_int_info_polling,ack_ISR_done,
61
                                                        ack_txinfo_rxd,start_priority_check,tx_int_info_priority,ack_txinfo_rxd_priority,ack_ISR_done_pt);
62
signal next_s : state_type :=reset_s;
63
signal int_type : unsigned(1 downto 0):="01";
64
signal int_index,count_cmd : integer := 0;
65
type prior_table is array (0 to 7) of unsigned(2 downto 0);
66
signal pt : prior_table := (others => (others => '0'));
67
signal int_pt : unsigned(2 downto 0):="000";
68
signal flag,flag1 : std_logic := '0';  --These flags are used for timing purposes.
69
 
70
begin
71
 
72
process(CLK_I,RST_I)
73
begin
74
if( RST_I = '1') then
75
        next_s <= reset_s;
76
elsif( rising_edge(CLK_I) ) then
77
        flag <= INTA_I;
78
        case next_s is
79
                when reset_s =>
80
                        --initialze signals to zero.
81
                        flag <= '0';
82
                        flag1 <= '0';
83
                        int_type <= "00";
84
                        int_index <= 0;
85
                        count_cmd <= 0;
86
                        int_pt <= "000";
87
                        pt <= (others => (others => '0'));
88
                        if( RST_I = '0' ) then
89
                                next_s <= get_commands;
90
                        else
91
                                next_s <= reset_s;
92
                        end if;
93
                        DataBus <= (others => 'Z');
94
                when get_commands =>     --Get commands and operating mode from the processor.
95
                        if( DataBus(1 downto 0) = "01" ) then
96
                                int_type <= "01";
97
                                next_s <= jump_int_method;
98
                        elsif( DataBus(1 downto 0) = "10" and count_cmd = 0) then
99
                                pt(0) <= DataBus(7 downto 5);
100
                                pt(1) <= DataBus(4 downto 2);
101
                                count_cmd <= count_cmd + 1;
102
                                next_s <= get_commands;
103
                        elsif( DataBus(1 downto 0) = "10" and count_cmd = 1) then
104
                                pt(2) <= DataBus(7 downto 5);
105
                                pt(3) <= DataBus(4 downto 2);
106
                                count_cmd <= count_cmd + 1;
107
                                next_s <= get_commands;
108
                        elsif( DataBus(1 downto 0) = "10" and count_cmd = 2) then
109
                                pt(4) <= DataBus(7 downto 5);
110
                                pt(5) <= DataBus(4 downto 2);
111
                                count_cmd <= count_cmd + 1;
112
                                next_s <= get_commands;
113
                        elsif( DataBus(1 downto 0) = "10" and count_cmd = 3) then
114
                                pt(6) <= DataBus(7 downto 5);
115
                                pt(7) <= DataBus(4 downto 2);
116
                                count_cmd <= 0;
117
                                int_type <= "10";
118
                                next_s <= jump_int_method;
119
                        else
120
                                next_s <= get_commands;
121
                        end if;
122
                when jump_int_method =>  --Check which method is used to determine the interrupts.
123
                        flag <= '0';
124
                        flag1 <= '0';
125
                        int_index <= 0;
126
                        count_cmd <= 0;
127
                        int_pt <= "000";
128
                        if( int_type = "01" ) then
129
                                next_s <= start_polling;   --Polling method for checking the interrupts.
130
                        elsif( int_type = "10" ) then
131
                                next_s <= start_priority_check;  --Fixed priority scheme.
132
                        else
133
                                next_s <= reset_s;  --Error if no method is specified.
134
                        end if;
135
                        DataBus <= (others => 'Z');
136
                when start_polling =>     --Check for interrupts(one by one) using polling method.
137
                        if( IR(int_index) = '1' ) then
138
                                INTR_O <= '1';
139
                                next_s <= tx_int_info_polling;
140
                        else
141
                                INTR_O <= '0';
142
                        end if;
143
                        if( int_index = 7 ) then
144
                                int_index <= 0;
145
                        else
146
                                int_index <= int_index+1;
147
                        end if;
148
                        DataBus <= (others => 'Z');
149
                when tx_int_info_polling =>      --Transmit interrupt information if an interrupt is found.
150
                        if( INTA_I = '0' ) then
151
                                INTR_O <= '0';
152
                        end if;
153
                        if( flag = '0' ) then
154
                                DataBus <= "01011" & to_unsigned( (int_index-1),3);  --MSB "01011" is for matching purpose.
155
                                flag1 <= '1';
156
                        else
157
                                flag1 <= '0';
158
                        end if;
159
                        if ( flag1 = '1' ) then
160
                                next_s <= ack_txinfo_rxd;
161
                                if( INTA_I = '0' ) then
162
                                        DataBus <= (others => 'Z');
163
                                end if;
164
                        end if;
165
                when ack_txinfo_rxd =>   --ACK send by processor to tell PIC that interrupt info is received correctly.
166
                        if( INTA_I <= '0' ) then
167
                                next_s <= ack_ISR_done;
168
                                DataBus <= (others => 'Z');
169
                        end if;
170
                when ack_ISR_done =>  --Wait for the ISR for the particular interrupt to get over.
171
                        if( INTA_I = '0' and DataBus(7 downto 3) = "10100" and DataBus(2 downto 0) = to_unsigned(int_index-1,3) ) then
172
                                next_s <= start_polling;
173
                        else
174
                                next_s <= ack_ISR_done;
175
                        end if;
176
                when start_priority_check =>   --Fixed priority method for interrupt handling.
177
                --Interrupts are checked based on their priority.
178
                        if( IR(to_integer(pt(0))) = '1' ) then
179
                                int_pt <= pt(0);
180
                                INTR_O <= '1';
181
                                next_s <= tx_int_info_priority;
182
                        elsif( IR(to_integer(pt(1))) = '1' ) then
183
                                int_pt <= pt(1);
184
                                INTR_O <= '1';
185
                                next_s <= tx_int_info_priority;
186
                        elsif( IR(to_integer(pt(2))) = '1' ) then
187
                                int_pt <= pt(2);
188
                                INTR_O <= '1';
189
                                next_s <= tx_int_info_priority;
190
                        elsif( IR(to_integer(pt(3))) = '1' ) then
191
                                int_pt <= pt(3);
192
                                INTR_O <= '1';
193
                                next_s <= tx_int_info_priority;
194
                        elsif( IR(to_integer(pt(4))) = '1' ) then
195
                                int_pt <= pt(4);
196
                                INTR_O <= '1';
197
                                next_s <= tx_int_info_priority;
198
                        elsif( IR(to_integer(pt(5))) = '1' ) then
199
                                int_pt <= pt(5);
200
                                INTR_O <= '1';
201
                                next_s <= tx_int_info_priority;
202
                        elsif( IR(to_integer(pt(6))) = '1' ) then
203
                                int_pt <= pt(6);
204
                                INTR_O <= '1';
205
                                next_s <= tx_int_info_priority;
206
                        elsif( IR(to_integer(pt(7))) = '1' ) then
207
                                int_pt <= pt(7);
208
                                INTR_O <= '1';
209
                                next_s <= tx_int_info_priority;
210
                        else
211
                                next_s <= start_priority_check;
212
                        end if;
213
                        DataBus <= (others => 'Z');
214
                when tx_int_info_priority =>      --Transmit interrupt information if an interrupt is found.
215
                        if( INTA_I = '0' ) then
216
                                INTR_O <= '0';
217
                        end if;
218
                        if( flag = '0' ) then
219
                                DataBus <= "10011" & int_pt;  --MSB "10011" is for matching purpose.
220
                                flag1 <= '1';
221
                        else
222
                                flag1 <= '0';
223
                        end if;
224
                        if ( flag1 = '1' ) then
225
                                next_s <= ack_txinfo_rxd_priority;
226
                                if( INTA_I = '0' ) then
227
                                        DataBus <= (others => 'Z');
228
                                end if;
229
                        end if;
230
                when ack_txinfo_rxd_priority =>   --ACK send by processor to tell PIC that interrupt info is received correctly.
231
                        if( INTA_I <= '0' ) then
232
                                next_s <= ack_ISR_done_pt;
233
                                DataBus <= (others => 'Z');
234
                        end if;
235
                when ack_ISR_done_pt =>   --Wait for the ISR for the particular interrupt to get over.
236
                        if( INTA_I = '0' and DataBus(7 downto 3) = "01100" and DataBus(2 downto 0) = int_pt ) then
237
                                next_s <= start_priority_check;
238
                        elsif( DataBus(7 downto 3) /= "01100" or DataBus(2 downto 0) /= int_pt ) then
239
                                next_s <= reset_s;   --Error.
240
                        else
241
                                next_s <= ack_ISR_done_pt;
242
                        end if;
243
                when others =>
244
                        DataBus <= (others => 'Z');
245
        end case;
246
end if;
247
end process;
248
 
249
end Behavioral;
250
 

powered by: WebSVN 2.1.0

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