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

Subversion Repositories thor

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

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 66 robfinch
wire clk;
94 61 robfinch
reg [31:0] trig;
95 60 robfinch
reg [31:0] ie;           // interrupt enable register
96
reg rdy1;
97
reg [4:0] irqenc;
98
wire [31:0] i = {   i31,i30,i29,i28,i27,i26,i25,i24,i23,i22,i21,i20,i19,i18,i17,i16,
99
                    i15,i14,i13,i12,i11,i10,i9,i8,i7,i6,i5,i4,i3,i2,i1,nmii};
100
reg [31:0] ib;
101
reg [31:0] iedge;
102
reg [31:0] rste;
103
reg [31:0] es;
104
reg [3:0] irq [0:31];
105
reg [7:0] cause [0:31];
106
integer n;
107
 
108
initial begin
109
        ie <= 32'h0;
110
        es <= 32'hFFFFFFFF;
111
        rste <= 32'h0;
112
        for (n = 0; n < 32; n = n + 1) begin
113
                cause[n] <= 8'h00;
114
                irq[n] <= 4'h8;
115
        end
116
end
117
 
118
wire cs = cyc_i && stb_i && adr_i[31:8]==pIOAddress[31:8];
119
assign vol_o = cs;
120
 
121 66 robfinch
assign clk = clk_i;
122
//BUFH ucb1 (.I(clk_i), .O(clk));
123
 
124
always @(posedge clk)
125 60 robfinch
        rdy1 <= cs;
126
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
127
 
128
// write registers      
129 66 robfinch
always @(posedge clk)
130 60 robfinch
        if (rst_i) begin
131
                ie <= 32'h0;
132
                rste <= 32'h0;
133 61 robfinch
                trig <= 32'h0;
134 60 robfinch
        end
135
        else begin
136
                rste <= 32'h0;
137 61 robfinch
                trig <= 32'h0;
138 60 robfinch
                if (cs & wr_i) begin
139
                        casez (adr_i[7:2])
140
                        6'd0: ;
141
                        6'd1:
142
                                begin
143
                                        ie[31:0] <= dat_i[31:0];
144
                                end
145
                        6'd2,6'd3:
146
                                ie[dat_i[4:0]] <= adr_i[2];
147
                        6'd4:   es <= dat_i[31:0];
148
                        6'd5:   rste[dat_i[4:0]] <= 1'b1;
149 61 robfinch
                        6'd6:   trig[dat_i[4:0]] <= 1'b1;
150 60 robfinch
                        6'b1?????:
151
                             begin
152
                                 cause[adr_i[6:2]] <= dat_i[7:0];
153
                                 irq[adr_i[6:2]] <= dat_i[11:8];
154
                                 ie[adr_i[6:2]] <= dat_i[16];
155
                                 es[adr_i[6:2]] <= dat_i[17];
156
                             end
157
                        endcase
158
                end
159
        end
160
 
161
// read registers
162 66 robfinch
always @(posedge clk)
163 60 robfinch
begin
164
        if (irqenc!=5'd0)
165
                $display("PIC: %d",irqenc);
166
        if (cs)
167
                casez (adr_i[7:2])
168
                6'd0:   dat_o <= cause[irqenc];
169
                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]]};
170
                default:        dat_o <= ie;
171
                endcase
172
        else
173
                dat_o <= 32'h0000;
174
end
175
 
176 61 robfinch
assign irqo = (irqenc == 5'h0) ? 4'd0 : irq[irqenc] & {4{ie[irqenc]}};
177 60 robfinch
assign causeo = (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
178
assign nmio = nmii & ie[0];
179
 
180
// Edge detect circuit
181 66 robfinch
always @(posedge clk)
182 60 robfinch
begin
183
        for (n = 1; n < 32; n = n + 1)
184
        begin
185
                ib[n] <= i[n];
186 61 robfinch
                if (trig[n]) iedge[n] <= 1'b1;
187 60 robfinch
                if (i[n] & !ib[n]) iedge[n] <= 1'b1;
188
                if (rste[n]) iedge[n] <= 1'b0;
189
        end
190
end
191
 
192
// irq requests are latched on every rising clock edge to prevent
193
// misreads
194
// nmi is not encoded
195 66 robfinch
always @(posedge clk)
196 60 robfinch
begin
197
        irqenc <= 5'd0;
198
        for (n = 31; n > 0; n = n - 1)
199 61 robfinch
                if ((es[n] ? iedge[n] : i[n])) irqenc <= n;
200 60 robfinch
end
201
 
202
endmodule

powered by: WebSVN 2.1.0

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