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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v7/] [rtl/] [common/] [FT64_pic.v] - Blame information for rev 61

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

Line No. Rev Author Line
1 60 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4 61 robfinch
//   \\__/ o\    (C) 2013-2019  Robert Finch, Waterloo
5 60 robfinch
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//
9
// This source file is free software: you can redistribute it and/or modify 
10
// it under the terms of the GNU Lesser General Public License as published 
11
// by the Free Software Foundation, either version 3 of the License, or     
12
// (at your option) any later version.                                      
13
//                                                                          
14
// This source file is distributed in the hope that it will be useful,      
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
17
// GNU General Public License for more details.                             
18
//                                                                          
19
// You should have received a copy of the GNU General Public License        
20
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
21
//                                                                          
22
//
23
//              Encodes discrete interrupt request signals into five
24
//      bit code using a priority encoder.
25
//      
26
//      reg
27
//      0x00    - encoded request number (read / write)
28
//                      This register contains the number identifying
29
//                      the current requester in bits 0 to 4
30
//                      If there is no
31
//                      active request, then this number will be 
32
//                      zero.
33
//          bits 8 to 15 set the base number for the vector
34
//
35
//      0x04    - request enable (read / write)
36
//                      this register contains request enable bits
37
//                      for each request line. 1 = request
38
//                      enabled, 0 = request disabled. On reset this
39
//                      register is set to zero (disable all ints).
40
//                      bit zero is specially reserved for nmi
41
//
42
//      0x08   - write only
43
//                      this register disables the interrupt indicated
44
//                      by the low order five bits of the input data
45
//                      
46
//      0x0C    - write only
47
//                      this register enables the interrupt indicated
48
//                      by the low order five bits of the input data
49
//
50
//      0x10    - write only
51
//                      this register indicates which interrupt inputs are
52
//                      edge sensitive
53
//
54
//  0x14        - write only
55
//                      This register resets the edge sense circuitry
56
//                      indicated by the low order five bits of the input data.
57
//
58 61 robfinch
//  0x18  - write only
59
//      This register triggers the interrupt indicated by the low
60
//      order five bits of the input data.
61
//
62 60 robfinch
//  0x80    - irq control for irq #0
63
//  0x84    - irq control for irq #1
64
//            bits 0 to 7  = cause code to issue
65
//            bits 8 to 11 = irq level to issue
66
//            bit 16 = irq enable
67
//            bit 17 = edge sensitivity
68
//=============================================================================
69
 
70
module FT64_pic
71
(
72
        input rst_i,            // reset
73
        input clk_i,            // system clock
74
        input cyc_i,
75
        input stb_i,
76
        output ack_o,       // controller is ready
77
        input wr_i,                     // write
78
        input [31:0] adr_i,      // address
79
        input [31:0] dat_i,
80
        output reg [31:0] dat_o,
81
        output vol_o,           // volatile register selected
82
        input i1, i2, i3, i4, i5, i6, i7,
83
                i8, i9, i10, i11, i12, i13, i14, i15,
84
                i16, i17, i18, i19, i20, i21, i22, i23,
85
                i24, i25, i26, i27, i28, i29, i30, i31,
86
        output [3:0] irqo,       // normally connected to the processor irq
87
        input nmii,             // nmi input connected to nmi requester
88
        output nmio,    // normally connected to the nmi of cpu
89 61 robfinch
        output [7:0] causeo
90 60 robfinch
);
91
parameter pIOAddress = 32'hFFDC_0F00;
92
 
93 61 robfinch
reg [31:0] trig;
94 60 robfinch
reg [31:0] ie;           // interrupt enable register
95
reg rdy1;
96
reg [4:0] irqenc;
97
wire [31:0] i = {   i31,i30,i29,i28,i27,i26,i25,i24,i23,i22,i21,i20,i19,i18,i17,i16,
98
                    i15,i14,i13,i12,i11,i10,i9,i8,i7,i6,i5,i4,i3,i2,i1,nmii};
99
reg [31:0] ib;
100
reg [31:0] iedge;
101
reg [31:0] rste;
102
reg [31:0] es;
103
reg [3:0] irq [0:31];
104
reg [7:0] cause [0:31];
105
integer n;
106
 
107
initial begin
108
        ie <= 32'h0;
109
        es <= 32'hFFFFFFFF;
110
        rste <= 32'h0;
111
        for (n = 0; n < 32; n = n + 1) begin
112
                cause[n] <= 8'h00;
113
                irq[n] <= 4'h8;
114
        end
115
end
116
 
117
wire cs = cyc_i && stb_i && adr_i[31:8]==pIOAddress[31:8];
118
assign vol_o = cs;
119
 
120
always @(posedge clk_i)
121
        rdy1 <= cs;
122
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
123
 
124
// write registers      
125
always @(posedge clk_i)
126
        if (rst_i) begin
127
                ie <= 32'h0;
128
                rste <= 32'h0;
129 61 robfinch
                trig <= 32'h0;
130 60 robfinch
        end
131
        else begin
132
                rste <= 32'h0;
133 61 robfinch
                trig <= 32'h0;
134 60 robfinch
                if (cs & wr_i) begin
135
                        casez (adr_i[7:2])
136
                        6'd0: ;
137
                        6'd1:
138
                                begin
139
                                        ie[31:0] <= dat_i[31:0];
140
                                end
141
                        6'd2,6'd3:
142
                                ie[dat_i[4:0]] <= adr_i[2];
143
                        6'd4:   es <= dat_i[31:0];
144
                        6'd5:   rste[dat_i[4:0]] <= 1'b1;
145 61 robfinch
                        6'd6:   trig[dat_i[4:0]] <= 1'b1;
146 60 robfinch
                        6'b1?????:
147
                             begin
148
                                 cause[adr_i[6:2]] <= dat_i[7:0];
149
                                 irq[adr_i[6:2]] <= dat_i[11:8];
150
                                 ie[adr_i[6:2]] <= dat_i[16];
151
                                 es[adr_i[6:2]] <= dat_i[17];
152
                             end
153
                        endcase
154
                end
155
        end
156
 
157
// read registers
158
always @(posedge clk_i)
159
begin
160
        if (irqenc!=5'd0)
161
                $display("PIC: %d",irqenc);
162
        if (cs)
163
                casez (adr_i[7:2])
164
                6'd0:   dat_o <= cause[irqenc];
165
                6'b1?????: dat_o <= {es[adr_i[6:2]],ie[adr_i[6:2]],4'b0,irq[adr_i[6:2]],cause[adr_i[6:2]]};
166
                default:        dat_o <= ie;
167
                endcase
168
        else
169
                dat_o <= 32'h0000;
170
end
171
 
172 61 robfinch
assign irqo = (irqenc == 5'h0) ? 4'd0 : irq[irqenc] & {4{ie[irqenc]}};
173 60 robfinch
assign causeo = (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
174
assign nmio = nmii & ie[0];
175
 
176
// Edge detect circuit
177
always @(posedge clk_i)
178
begin
179
        for (n = 1; n < 32; n = n + 1)
180
        begin
181
                ib[n] <= i[n];
182 61 robfinch
                if (trig[n]) iedge[n] <= 1'b1;
183 60 robfinch
                if (i[n] & !ib[n]) iedge[n] <= 1'b1;
184
                if (rste[n]) iedge[n] <= 1'b0;
185
        end
186
end
187
 
188
// irq requests are latched on every rising clock edge to prevent
189
// misreads
190
// nmi is not encoded
191
always @(posedge clk_i)
192
begin
193
        irqenc <= 5'd0;
194
        for (n = 31; n > 0; n = n - 1)
195 61 robfinch
                if ((es[n] ? iedge[n] : i[n])) irqenc <= n;
196 60 robfinch
end
197
 
198
endmodule

powered by: WebSVN 2.1.0

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