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

Subversion Repositories thor

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

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
//   \\__/ o\    (C) 2013-2018  Robert Finch, Waterloo
5
//    \  __ /    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
//  0x80    - irq control for irq #0
59
//  0x84    - irq control for irq #1
60
//            bits 0 to 7  = cause code to issue
61
//            bits 8 to 11 = irq level to issue
62
//            bit 16 = irq enable
63
//            bit 17 = edge sensitivity
64
//=============================================================================
65
 
66
module FT64_pic
67
(
68
        input rst_i,            // reset
69
        input clk_i,            // system clock
70
        input cyc_i,
71
        input stb_i,
72
        output ack_o,       // controller is ready
73
        input wr_i,                     // write
74
        input [31:0] adr_i,      // address
75
        input [31:0] dat_i,
76
        output reg [31:0] dat_o,
77
        output vol_o,           // volatile register selected
78
        input i1, i2, i3, i4, i5, i6, i7,
79
                i8, i9, i10, i11, i12, i13, i14, i15,
80
                i16, i17, i18, i19, i20, i21, i22, i23,
81
                i24, i25, i26, i27, i28, i29, i30, i31,
82
        output [3:0] irqo,       // normally connected to the processor irq
83
        input nmii,             // nmi input connected to nmi requester
84
        output nmio,    // normally connected to the nmi of cpu
85
        output [6:0] causeo
86
);
87
parameter pIOAddress = 32'hFFDC_0F00;
88
 
89
reg [31:0] ie;           // interrupt enable register
90
reg rdy1;
91
reg [4:0] irqenc;
92
wire [31:0] i = {   i31,i30,i29,i28,i27,i26,i25,i24,i23,i22,i21,i20,i19,i18,i17,i16,
93
                    i15,i14,i13,i12,i11,i10,i9,i8,i7,i6,i5,i4,i3,i2,i1,nmii};
94
reg [31:0] ib;
95
reg [31:0] iedge;
96
reg [31:0] rste;
97
reg [31:0] es;
98
reg [3:0] irq [0:31];
99
reg [7:0] cause [0:31];
100
integer n;
101
 
102
initial begin
103
        ie <= 32'h0;
104
        es <= 32'hFFFFFFFF;
105
        rste <= 32'h0;
106
        for (n = 0; n < 32; n = n + 1) begin
107
                cause[n] <= 8'h00;
108
                irq[n] <= 4'h8;
109
        end
110
end
111
 
112
wire cs = cyc_i && stb_i && adr_i[31:8]==pIOAddress[31:8];
113
assign vol_o = cs;
114
 
115
always @(posedge clk_i)
116
        rdy1 <= cs;
117
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
118
 
119
// write registers      
120
always @(posedge clk_i)
121
        if (rst_i) begin
122
                ie <= 32'h0;
123
                rste <= 32'h0;
124
        end
125
        else begin
126
                rste <= 32'h0;
127
                if (cs & wr_i) begin
128
                        casez (adr_i[7:2])
129
                        6'd0: ;
130
                        6'd1:
131
                                begin
132
                                        ie[31:0] <= dat_i[31:0];
133
                                end
134
                        6'd2,6'd3:
135
                                ie[dat_i[4:0]] <= adr_i[2];
136
                        6'd4:   es <= dat_i[31:0];
137
                        6'd5:   rste[dat_i[4:0]] <= 1'b1;
138
                        6'b1?????:
139
                             begin
140
                                 cause[adr_i[6:2]] <= dat_i[7:0];
141
                                 irq[adr_i[6:2]] <= dat_i[11:8];
142
                                 ie[adr_i[6:2]] <= dat_i[16];
143
                                 es[adr_i[6:2]] <= dat_i[17];
144
                             end
145
                        endcase
146
                end
147
        end
148
 
149
// read registers
150
always @(posedge clk_i)
151
begin
152
        if (irqenc!=5'd0)
153
                $display("PIC: %d",irqenc);
154
        if (cs)
155
                casez (adr_i[7:2])
156
                6'd0:   dat_o <= cause[irqenc];
157
                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]]};
158
                default:        dat_o <= ie;
159
                endcase
160
        else
161
                dat_o <= 32'h0000;
162
end
163
 
164
assign irqo = (irqenc == 5'h0) ? 4'd0 : irq[irqenc];
165
assign causeo = (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
166
assign nmio = nmii & ie[0];
167
 
168
// Edge detect circuit
169
always @(posedge clk_i)
170
begin
171
        for (n = 1; n < 32; n = n + 1)
172
        begin
173
                ib[n] <= i[n];
174
                if (i[n] & !ib[n]) iedge[n] <= 1'b1;
175
                if (rste[n]) iedge[n] <= 1'b0;
176
        end
177
end
178
 
179
// irq requests are latched on every rising clock edge to prevent
180
// misreads
181
// nmi is not encoded
182
always @(posedge clk_i)
183
begin
184
        irqenc <= 5'd0;
185
        for (n = 31; n > 0; n = n - 1)
186
                if (ie[n] & (es[n] ? iedge[n] : i[n])) irqenc <= n;
187
end
188
 
189
endmodule

powered by: WebSVN 2.1.0

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