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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [verilog/] [rtl/] [intr_ctrl.v] - Blame information for rev 67

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 66 motilito
//---------------------------------------------------------------------------------------
2
//      Project:                        light8080 SOC           WiCores Solutions 
3
//
4
//      File name:                      intr_ctrl.v             (March 02, 2012)
5
//
6
//      Writer:                         Moti Litochevski 
7
//
8
//      Description:
9
//              This file contains the light8080 SOC interrupt controller. The controller 
10
//              supports 4 external interrupt requests with fixed interrupt vector addresses. 
11
//              The interrupt vectors code is implemented in the "intr_vec.h" file included in 
12
//              the projects C directory. 
13
//              Note that the controller clears the interrupt request after the CPU read the 
14
//              interrupt vector. 
15
//
16
//      Revision History:
17
//
18
//      Rev <revnumber>                 <Date>                  <owner> 
19
//              <comment>
20
// 
21
//---------------------------------------------------------------------------------------
22
// 
23
//      Copyright (C) 2012 Moti Litochevski 
24
// 
25
//      This source file may be used and distributed without restriction provided that this 
26
//      copyright statement is not removed from the file and that any derivative work 
27
//      contains the original copyright notice and the associated disclaimer.
28
//
29
//      THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 
30
//      INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND 
31
//      FITNESS FOR A PARTICULAR PURPOSE. 
32
// 
33
//---------------------------------------------------------------------------------------
34
 
35
module intr_ctrl
36
(
37
        clock, reset,
38
        ext_intr, cpu_intr,
39
        cpu_inte, cpu_inta,
40
        cpu_rd, cpu_inst,
41
        intr_ena
42
);
43
//---------------------------------------------------------------------------------------
44
// module interfaces 
45
// global signals 
46
input                   clock;          // global clock input 
47
input                   reset;          // global reset input 
48
// external interrupt sources 
49
// least significant bit has the highest priority, most significant bit has the lowest 
50
// priority. 
51
input   [3:0]    ext_intr;       // active high 
52
// CPU interface 
53
output                  cpu_intr;       // CPU interrupt request 
54
input                   cpu_inte;       // CPU interrupt enable - just to mask 
55
input                   cpu_inta;       // CPU interrupt acknowledge 
56
input                   cpu_rd;         // CPU read signal 
57
output  [7:0]    cpu_inst;       // interrupt calling instruction 
58
 
59
// interrupt enable register 
60
input   [3:0]    intr_ena;       // set high to enable respective interrupt 
61
 
62
//---------------------------------------------------------------------------------------
63
// 8080 assembly code constants 
64
// call instruction opcode used to call interrupt routine 
65
`define CALL_INST                       8'hcd
66
// interrupt vectors fixed addresses - high address byte is 0 
67
`define INT0_VEC                        8'h08
68
`define INT1_VEC                        8'h18
69
`define INT2_VEC                        8'h28
70
`define INT3_VEC                        8'h38
71
 
72
//---------------------------------------------------------------------------------------
73
// internal declarations 
74
// registered output 
75
reg [7:0] cpu_inst;
76
 
77
// internals 
78
reg [1:0] intSq, intSel;
79
reg [3:0] act_int, int_clr;
80
reg [7:0] int_vec;
81
 
82
//---------------------------------------------------------------------------------------
83
// module implementation 
84
// main interrupt controller control process 
85
always @ (posedge reset or posedge clock)
86
begin
87
        if (reset)
88
        begin
89
                intSq <= 2'b0;
90
                intSel <= 2'b0;
91
                cpu_inst <= 8'b0;
92
        end
93
        else
94
        begin
95
                // interrupt controller state machine 
96
                case (intSq)
97
                        2'd0:           // idle state - wait for active interrupt 
98
                                if ((act_int != 4'b0) && cpu_inte)
99
                                begin
100
                                        // latch the index of the active interrupt according to priority 
101
                                        if (act_int[0])          intSel <= 2'd0;
102
                                        else if (act_int[2])    intSel <= 2'd1;
103
                                        else if (act_int[3])    intSel <= 2'd2;
104
                                        else                                    intSel <= 2'd3;
105
                                        // switch to next state 
106
                                        intSq <= 2'd1;
107
                                end
108
                        default:        // all other states increment the state register on inta read 
109
                                if (cpu_inta && cpu_rd)
110
                                begin
111
                                        // update state 
112
                                        intSq <= intSq + 1;
113
 
114
                                        // update instruction opcode for each byte read during inta 
115
                                        case (intSq)
116
                                                2'd1:           cpu_inst <= `CALL_INST;
117
                                                2'd2:           cpu_inst <= int_vec;
118
                                                default:        cpu_inst <= 8'd0;
119
                                        endcase
120
                                end
121
                                else if (!cpu_inta)
122
                                begin
123
                                        intSq <= 2'd0;
124
                                        cpu_inst <= 8'd0;
125
                                end
126
                endcase
127
        end
128
end
129
 
130
// assign interrupt vector address according to selected interrupt 
131
always @ (intSel)
132
begin
133
        case (intSel)
134
                2'd0:   int_vec <= `INT0_VEC;
135
                2'd1:   int_vec <= `INT1_VEC;
136
                2'd2:   int_vec <= `INT2_VEC;
137
                2'd3:   int_vec <= `INT3_VEC;
138
        endcase
139
end
140
 
141
// latch active interrupt on rising edge 
142
always @ (posedge reset or posedge clock)
143
begin
144
        if (reset)
145
                act_int <= 4'b0;
146
        else
147
                act_int <= (act_int & ~int_clr) | (ext_intr & intr_ena);
148
end
149
// CPU interrupt is asserted when at least one interrupt is active 
150
assign cpu_intr = |act_int;
151
 
152
// clear serviced interrupt 
153
always @ (cpu_inta or cpu_rd or intSq or intSel)
154
begin
155
        if (cpu_inta && cpu_rd && (intSq == 2'd3))
156
        begin
157
                case (intSel)
158
                        2'd0:   int_clr <= 4'b0001;
159
                        2'd1:   int_clr <= 4'b0010;
160
                        2'd2:   int_clr <= 4'b0100;
161
                        2'd3:   int_clr <= 4'b1000;
162
                endcase
163
        end
164
        else
165
                int_clr <= 4'b0;
166
end
167
 
168
endmodule
169
//---------------------------------------------------------------------------------------
170
//                                              Th.. Th.. Th.. Thats all folks !!!
171
//---------------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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