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

Subversion Repositories simple_pic

[/] [simple_pic/] [trunk/] [rtl/] [simple_pic.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rherveille
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  OpenCores         Simple Programmable Interrupt Controller ////
4
////                                                             ////
5
////  Author: Richard Herveille                                  ////
6
////          richard@asics.ws                                   ////
7
////          www.asics.ws                                       ////
8
////                                                             ////
9
/////////////////////////////////////////////////////////////////////
10
////                                                             ////
11
//// Copyright (C) 2002 Richard Herveille                        ////
12
////                    richard@asics.ws                         ////
13
////                                                             ////
14
//// This source file may be used and distributed without        ////
15
//// restriction provided that this copyright statement is not   ////
16
//// removed from the file and that any derivative work contains ////
17
//// the original copyright notice and the associated disclaimer.////
18
////                                                             ////
19
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
20
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
21
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
22
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
23
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
24
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
25
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
26
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
27
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
28
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
29
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
30
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
31
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
32
////                                                             ////
33
/////////////////////////////////////////////////////////////////////
34
 
35
//  CVS Log
36
//
37 5 rherveille
//  $Id: simple_pic.v,v 1.3 2002-12-24 10:26:51 rherveille Exp $
38 2 rherveille
//
39 5 rherveille
//  $Date: 2002-12-24 10:26:51 $
40
//  $Revision: 1.3 $
41 2 rherveille
//  $Author: rherveille $
42
//  $Locker:  $
43
//  $State: Exp $
44
//
45 4 rherveille
// Change History:
46
//               $Log: not supported by cvs2svn $
47 5 rherveille
//               Revision 1.2  2002/12/22 16:11:03  rherveille
48
//               *** empty log message ***
49 4 rherveille
//
50 5 rherveille
//
51 2 rherveille
 
52
 
53
 
54
//
55
// This is a simple Programmable Interrupt Controller.
56
// The number of interrupts is depending on the databus size.
57
// There's one interrupt input per databit (i.e. 16 interrupts for a 16
58
// bit databus).
59
// All attached devices share the same CPU priority level.
60
//
61
//
62
//
63
// Registers:
64
//
65
// 0x00: EdgeEnable Register
66
//       bits 7:0 R/W  Edge Enable '1' = edge triggered interrupt source
67
//                                 '0' = level triggered interrupt source
68 5 rherveille
// 0x01: PolarityRegister
69 2 rherveille
//       bits 7:0 R/W Polarity     '1' = high level / rising edge
70
//                                 '0' = low level / falling edge
71 5 rherveille
// 0x02: MaskRegister
72 2 rherveille
//       bits 7:0 R/W Mask         '1' = interrupt masked (disabled)
73
//                                 '0' = interrupt not masked (enabled)
74 5 rherveille
// 0x03: PendingRegister
75 2 rherveille
//       bits 7:0 R/W Pending      '1' = interrupt pending
76
//                                 '0' = no interrupt pending
77
//
78
// A CPU interrupt is generated when an interrupt is pending and its
79
// MASK bit is cleared.
80
//
81
//
82
//
83
// HOWTO:
84
//
85
// Clearing pending interrupts:
86
// Writing a '1' to a bit in the interrupt pending register clears the
87
// interrupt. Make sure to clear the interrupt at the source before
88
// writing to the interrupt pending register. Otherwise the interrupt
89
// will be set again.
90
//
91
// Priority based interrupts:
92
// Upon reception of an interrupt, check the interrupt register and
93
// determine the highest priority interrupt. Mask all interrupts from the
94
// current level to the lowest level. This negates the interrupt line, and
95
// makes sure only interrupts with a higher level are triggered. After
96
// completion of the interrupt service routine, clear the interrupt source,
97
// the interrupt bit in the pending register, and restore the MASK register
98
// to it's previous state.
99
//
100
// Addapt the core for fewer interrupt sources:
101
// If less than 8 interrupt sources are required, than the 'is' parameter
102
// can be set to the amount of required interrupts. Interrupts are mapped
103
// starting at the LSBs. So only the 'is' LSBs per register are valid. All
104
// other bits (i.e. the 8-'is' MSBs) are set to zero '0'.
105
// Codesize is approximately linear to the amount of interrupts. I.e. using
106
// 4 instead of 8 interrupt sources reduces the size by approx. half.
107
//
108
 
109
 
110
// synopsys translate_off
111
`include "timescale.v"
112
// synopsys translate_on
113
 
114
module simple_pic(
115
  clk_i, rst_i, cyc_i, stb_i, adr_i, we_i, dat_i, dat_o, ack_o, int_o,
116
  irq
117
);
118
 
119
  parameter is = 8;            // Number of interrupt sources
120
 
121
  //
122
  // Inputs & outputs
123
  //
124
 
125
  // 8bit WISHBONE bus slave interface
126
  input         clk_i;         // clock
127
  input         rst_i;         // reset (asynchronous active low)
128
  input         cyc_i;         // cycle
129
  input         stb_i;         // strobe  (cycle and strobe are the same signal)
130
  input  [ 2:1] adr_i;         // address
131
  input         we_i;          // write enable
132
  input  [ 7:0] dat_i;         // data output
133
  output [ 7:0] dat_o;         // data input
134
  output        ack_o;         // normal bus termination
135
 
136
  output        int_o;         // interrupt output
137
 
138
  //
139
  // Interrupt sources
140
  //
141
  input  [is:1] irq;           // interrupt request inputs
142
 
143
 
144
  //
145
  //  Module body
146
  //
147
  reg  [is:1] pol, edgen, pending, mask;   // register bank
148
  reg  [is:1] lirq, dirq;                  // latched irqs, delayed latched irqs
149
 
150
 
151
  //
152
  // perform parameter checks
153
  //
154
  // synopsys translate_off
155
  initial
156
  begin
157
      if(is > 8)
158
        $display("simple_pic: max. 8 interrupt sources supported.");
159
  end
160
  // synopsys translate_on
161
 
162
  //
163
  // latch interrupt inputs
164
  always @(posedge clk_i)
165
    lirq <= #1 irq;
166
 
167
  //
168
  // generate delayed latched irqs
169
  always @(posedge clk_i)
170
    dirq <= #1 lirq;
171
 
172
 
173
  //
174
  // generate actual triggers
175
  function trigger;
176
    input edgen, pol, lirq, dirq;
177
 
178
    reg   edge_irq, level_irq;
179
  begin
180
      edge_irq  = pol ? (lirq & ~dirq) : (dirq & ~lirq);
181
      level_irq = pol ? lirq : ~lirq;
182
 
183
      trigger = edgen ? edge_irq : level_irq;
184
  end
185
  endfunction
186
 
187
  reg  [is:1] irq_event;
188
  integer n;
189
  always @(posedge clk_i)
190
    for(n=1; n<=is; n=n+1)
191
      irq_event[n] <= #1 trigger(edgen[n], pol[n], lirq[n], dirq[n]);
192
 
193
  //
194
  // generate wishbone register bank writes
195
  wire wb_acc = cyc_i & stb_i;                   // WISHBONE access
196
  wire wb_wr  = wb_acc & we_i;                   // WISHBONE write access
197
 
198
  always @(posedge clk_i or negedge rst_i)
199
    if (~rst_i)
200
      begin
201
          pol   <= #1 {{is}{1'b0}};              // clear polarity register
202
          edgen <= #1 {{is}{1'b0}};              // clear edge enable register
203
          mask  <= #1 {{is}{1'b1}};              // mask all interrupts
204
      end
205
    else if(wb_wr)                               // wishbone write cycle??
206
      case (adr_i) // synopsys full_case parallel_case
207
        2'b00: edgen <= #1 dat_i[is-1:0];        // EDGE-ENABLE register
208
        2'b01: pol   <= #1 dat_i[is-1:0];        // POLARITY register
209
        2'b10: mask  <= #1 dat_i[is-1:0];        // MASK register
210
        2'b11: ;                                 // PENDING register is a special case (see below)
211
      endcase
212
 
213
 
214
    // pending register is a special case
215
    always @(posedge clk_i or negedge rst_i)
216
      if (~rst_i)
217
          pending <= #1 {{is}{1'b0}};            // clear all pending interrupts
218 4 rherveille
      else if ( wb_wr & (&adr_i) )
219 2 rherveille
          pending <= #1 (pending & ~dat_i[is-1:0]) | irq_event;
220
      else
221
          pending <= #1 pending | irq_event;
222
 
223
    //
224
    // generate dat_o
225
    reg [7:0] dat_o;
226
    always @(posedge clk_i)
227
      case (adr_i) // synopsys full_case parallel_case
228
        2'b00: dat_o <= #1 { {{8-is}{1'b0}}, edgen};
229
        2'b01: dat_o <= #1 { {{8-is}{1'b0}}, pol};
230
        2'b10: dat_o <= #1 { {{8-is}{1'b0}}, mask};
231
        2'b11: dat_o <= #1 { {{8-is}{1'b0}}, pending};
232
      endcase
233
 
234
   //
235
   // generate ack_o
236
   reg ack_o;
237
   always @(posedge clk_i)
238
     ack_o <= #1 wb_acc & !ack_o;
239
 
240
  //
241
  // generate CPU interrupt signal
242
  reg int_o;
243
  always @(posedge clk_i)
244
    int_o <= #1 |(pending & ~mask);
245
 
246
endmodule
247
 

powered by: WebSVN 2.1.0

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