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

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [rtl/] [cpu/] [rf6809_pic.sv] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2013-2022  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch@finitron.ca
7
//       ||
8
//
9
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//
35
//
36
//              Encodes discrete interrupt request signals into five
37
//      bit code using a priority encoder.
38
//
39
//      reg
40
//      0x00    - encoded request number (read / write)
41
//                      This register contains the number identifying
42
//                      the current requester in bits 0 to 4
43
//                      If there is no
44
//                      active request, then this number will be
45
//                      zero.
46
//          bits 8 to 15 set the base number for the vector
47
//
48
//      0x04    - request enable (read / write)
49
//                      this register contains request enable bits
50
//                      for each request line. 1 = request
51
//                      enabled, 0 = request disabled. On reset this
52
//                      register is set to zero (disable all ints).
53
//                      bit zero is specially reserved for nmi
54
//
55
//      0x08   - write only
56
//                      this register disables the interrupt indicated
57
//                      by the low order five bits of the input data
58
//
59
//      0x0C    - write only
60
//                      this register enables the interrupt indicated
61
//                      by the low order five bits of the input data
62
//
63
//      0x10    - write only
64
//                      this register indicates which interrupt inputs are
65
//                      edge sensitive
66
//
67
//  0x14        - write only
68
//                      This register resets the edge sense circuitry
69
//                      indicated by the low order five bits of the input data.
70
//
71
//  0x18  - write only
72
//      This register triggers the interrupt indicated by the low
73
//      order five bits of the input data.
74
//
75
//  0x80    - irq control for irq #0
76
//  0x84    - irq control for irq #1
77
//            bits 0 to 7  = cause code to issue
78
//            bits 8 to 11 = irq level to issue
79
//            bit 16 = irq enable
80
//            bit 17 = edge sensitivity
81
//=============================================================================
82
 
83
import rf6809_pkg::*;
84
 
85
module rf6809_pic
86
(
87
        input rst_i,            // reset
88
        input clk_i,            // system clock
89
        input cs_i,
90
        input cyc_i,
91
        input stb_i,
92
        output ack_o,       // controller is ready
93
        input wr_i,                     // write
94
        input [7:0] adr_i,      // address
95
        input [BPB:0] dat_i,
96
        output reg [BPB:0] dat_o,
97
        output vol_o,           // volatile register selected
98
        input i1, i2, i3, i4, i5, i6, i7,
99
                i8, i9, i10, i11, i12, i13, i14, i15,
100
                i16, i17, i18, i19, i20, i21, i22, i23,
101
                i24, i25, i26, i27, i28, i29, i30, i31,
102
        output reg [3:0] irqo,  // normally connected to the processor irq
103
        input nmii,             // nmi input connected to nmi requester
104
        output reg nmio,        // normally connected to the nmi of cpu
105
        output reg [BPB:0] causeo,
106
        output reg [5:0] server_o
107
);
108
 
109
wire clk;
110
reg [31:0] trig;
111
reg [31:0] ie;          // interrupt enable register
112
reg rdy1;
113
reg [4:0] irqenc;
114
wire [31:0] i = {   i31,i30,i29,i28,i27,i26,i25,i24,i23,i22,i21,i20,i19,i18,i17,i16,
115
                    i15,i14,i13,i12,i11,i10,i9,i8,i7,i6,i5,i4,i3,i2,i1,nmii};
116
reg [31:0] ib;
117
reg [31:0] iedge;
118
reg [31:0] rste;
119
reg [31:0] es;
120 21 robfinch
reg [31:0] irq_active;
121 2 robfinch
reg [3:0] irq [0:31];
122
reg [BPB:0] cause [0:31];
123
reg [5:0] server [0:31];
124
integer n;
125
 
126
initial begin
127
        ie <= 32'h0;
128
        es <= 32'hFFFFFFFF;
129
        rste <= 32'h0;
130
        for (n = 0; n < 32; n = n + 1) begin
131
                cause[n] <= {BPB{1'b0}};
132
                irq[n] <= 4'h8;
133
                server[n] <= 6'd2;
134
        end
135
end
136
 
137
wire cs = cyc_i && stb_i && cs_i;
138
assign vol_o = cs;
139
 
140
assign clk = clk_i;
141
//BUFH ucb1 (.I(clk_i), .O(clk));
142
 
143
always @(posedge clk)
144
        rdy1 <= cs;
145
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
146
 
147
// write registers
148
always @(posedge clk)
149
        if (rst_i) begin
150
                ie <= 32'h0;
151
                rste <= 32'h0;
152
                trig <= 32'h0;
153
        end
154
        else begin
155
                rste <= 32'h0;
156
                trig <= 32'h0;
157
                if (cs & wr_i) begin
158
                        casez (adr_i[7:0])
159
                        8'd0: ;
160
                        8'd4:   ie[31:24] <= dat_i;
161
                        8'd5:   ie[23:16] <= dat_i;
162
                        8'd6:   ie[15: 8] <= dat_i;
163
                        8'd7:   ie[ 7: 0] <= dat_i;
164
                        8'd8,8'd9:
165
                                ie[dat_i[4:0]] <= adr_i[0];
166
                        8'd12:  es[31:24] <= dat_i;
167
                        8'd13:  es[23:16] <= dat_i;
168
                        8'd14:  es[15: 8] <= dat_i;
169
                        8'd15:  es[ 7: 0] <= dat_i;
170
                        8'd16:  rste[dat_i[4:0]] <= 1'b1;
171
                        8'd17:  trig[dat_i[4:0]] <= 1'b1;
172
                        8'b1?????00:
173
                 cause[adr_i[6:2]] <= dat_i;
174
                        8'b1?????01:
175
                             begin
176
                                 irq[adr_i[6:2]] <= dat_i[3:0];
177
                                 ie[adr_i[6:2]] <= dat_i[6];
178
                                 es[adr_i[6:2]] <= dat_i[7];
179
                             end
180
                        8'b1?????10:
181
                                server[adr_i[6:2]] <= dat_i[5:0];
182
                        default:        ;
183
                        endcase
184
                end
185
        end
186
 
187
// read registers
188
always @(posedge clk)
189
begin
190
        if (irqenc!=5'd0)
191
                $display("PIC: %d",irqenc);
192
        if (cs)
193
                casez (adr_i[7:0])
194
                8'd0:   dat_o <= cause[irqenc];
195
                8'd4:   dat_o <= ie[31:24];
196
                8'd5:   dat_o <= ie[23:16];
197
                8'd6:   dat_o <= ie[15: 8];
198
                8'd7:   dat_o <= ie[ 7: 0];
199
                8'b1?????00: dat_o <= cause[adr_i[6:2]];
200
                8'b1?????01: dat_o <= {es[adr_i[6:2]],ie[adr_i[6:2]],2'b0,irq[adr_i[6:2]]};
201
                8'b1?????10:    dat_o <= {2'b0,server[adr_i[6:2]]};
202 21 robfinch
                8'b1?????11:    dat_o <= irq_active[adr_i[6:2]];
203 2 robfinch
                default:        dat_o <= 12'h00;
204
                endcase
205
        else
206
                dat_o <= 12'h00;
207
end
208
 
209
always @(posedge clk)
210
  irqo <= (irqenc == 5'h0) ? 4'd0 : irq[irqenc] & {4{ie[irqenc]}};
211
always @(posedge clk)
212
  causeo <= (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
213
always @(posedge clk)
214
  server_o <= (irqenc == 5'h0) ? 6'd0 : server[irqenc];
215
always @(posedge clk)
216
  nmio <= nmii & ie[0];
217
 
218
// Edge detect circuit
219
always @(posedge clk)
220
begin
221
        for (n = 1; n < 32; n = n + 1)
222
        begin
223
                ib[n] <= i[n];
224
                if (trig[n]) iedge[n] <= 1'b1;
225
                if (i[n] & !ib[n]) iedge[n] <= 1'b1;
226
                if (rste[n]) iedge[n] <= 1'b0;
227
        end
228
end
229
 
230
// irq requests are latched on every rising clock edge to prevent
231
// misreads
232
// nmi is not encoded
233
always @(posedge clk)
234 21 robfinch
if (rst_i)
235
        irq_active <= 32'd0;
236
else begin
237 2 robfinch
        irqenc <= 5'd0;
238 21 robfinch
        for (n = 31; n > 0; n = n - 1) begin
239 2 robfinch
                if ((es[n] ? iedge[n] : i[n])) irqenc <= n;
240 21 robfinch
                if ((es[n] ? iedge[n] : i[n])) irq_active[n] <= 1'b1;
241
        end
242
        if (cs && wr_i && adr_i[7] && &adr_i[1:0])
243
                irq_active[adr_i[6:2]] <= dat_i[0];
244 2 robfinch
end
245
 
246
endmodule

powered by: WebSVN 2.1.0

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