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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [rtl/] [common/] [FT64_pic.v] - Blame information for rev 56

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

Line No. Rev Author Line
1 48 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 13 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 52 robfinch
//            bits 0 to 7  = cause code to issue
61
//            bits 8 to 11 = irq level to issue
62 48 robfinch
//            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 49 robfinch
        output [3:0] irqo,       // normally connected to the processor irq
83 48 robfinch
        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 [5:0] cause_base;
99 49 robfinch
reg [3:0] irq [0:31];
100 52 robfinch
reg [7:0] cause [0:31];
101 51 robfinch
integer n;
102 48 robfinch
 
103 51 robfinch
initial begin
104
        ie <= 32'h0;
105
        es <= 32'hFFFFFFFF;
106
        rste <= 32'h0;
107
        for (n = 0; n < 32; n = n + 1) begin
108 52 robfinch
                cause[n] <= 8'h00;
109 51 robfinch
                irq[n] <= 4'h8;
110
        end
111
end
112
 
113 48 robfinch
wire cs = cyc_i && stb_i && adr_i[31:8]==pIOAddress[31:8];
114
assign vol_o = cs;
115
 
116
always @(posedge clk_i)
117
        rdy1 <= cs;
118
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
119
 
120
// write registers      
121
always @(posedge clk_i)
122
        if (rst_i) begin
123
                ie <= 32'h0;
124
                rste <= 32'h0;
125
        end
126
        else begin
127
                rste <= 32'h0;
128
                if (cs & wr_i) begin
129 51 robfinch
                        casez (adr_i[7:2])
130 48 robfinch
                        6'd0:    ;
131
                        6'd1:
132
                                begin
133
                                        ie[31:0] <= dat_i[31:0];
134
                                end
135
                        6'd2,6'd3:
136
                                ie[dat_i[4:0]] <= adr_i[2];
137
                        6'd4:   es <= dat_i[31:0];
138
                        6'd5:   rste[dat_i[4:0]] <= 1'b1;
139 51 robfinch
                        6'b1?????:
140 48 robfinch
                             begin
141 52 robfinch
                                 cause[adr_i[6:2]] <= dat_i[7:0];
142 49 robfinch
                                 irq[adr_i[6:2]] <= dat_i[11:8];
143 48 robfinch
                                 ie[adr_i[6:2]] <= dat_i[16];
144
                                 es[adr_i[6:2]] <= dat_i[17];
145
                             end
146
                        endcase
147
                end
148
        end
149
 
150
// read registers
151
always @(posedge clk_i)
152
begin
153
        if (irqenc!=5'd0)
154
                $display("PIC: %d",irqenc);
155
        if (cs)
156 51 robfinch
                casez (adr_i[7:2])
157 48 robfinch
                6'd0:   dat_o <= {cause_base,3'd0} + irqenc;
158 52 robfinch
                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]]};
159 48 robfinch
                default:        dat_o <= ie;
160
                endcase
161
        else
162
                dat_o <= 32'h0000;
163
end
164
 
165 49 robfinch
assign irqo = (irqenc == 5'h0) ? 4'd0 : irq[irqenc];
166 52 robfinch
assign causeo = (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
167 48 robfinch
assign nmio = nmii & ie[0];
168
 
169
// Edge detect circuit
170
always @(posedge clk_i)
171
begin
172
        for (n = 1; n < 32; n = n + 1)
173
        begin
174
                ib[n] <= i[n];
175
                if (i[n] & !ib[n]) iedge[n] <= 1'b1;
176
                if (rste[n]) iedge[n] <= 1'b0;
177
        end
178
end
179
 
180
// irq requests are latched on every rising clock edge to prevent
181
// misreads
182
// nmi is not encoded
183
always @(posedge clk_i)
184
begin
185
        irqenc <= 5'd0;
186
        for (n = 31; n > 0; n = n - 1)
187
                if (ie[n] & (es[n] ? iedge[n] : i[n])) irqenc <= n;
188
end
189
 
190
endmodule

powered by: WebSVN 2.1.0

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