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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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