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

Subversion Repositories rtfbitmapcontroller

[/] [rtfbitmapcontroller/] [trunk/] [rtl/] [verilog/] [pci64_config.sv] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2023  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//
35
// 370 LUTs / 176 FFs
36
// ============================================================================
37
//
38
 
39
module pci64_config(rst_i, clk_i, irq_i, irq_o, cs_config_i,
40
        we_i, sel_i, adr_i, dat_i, dat_o,
41
        cs_bar0_o, cs_bar1_o, cs_bar2_o, irq_en_o);
42
input rst_i;
43
input clk_i;
44
input irq_i;
45
output reg [31:0] irq_o;
46
input cs_config_i;
47
input we_i;
48
input [7:0] sel_i;
49
input [31:0] adr_i;
50
input [63:0] dat_i;
51
output reg [63:0] dat_o;
52
output reg irq_en_o;
53
output reg cs_bar0_o;
54
output reg cs_bar1_o;
55
output reg cs_bar2_o;
56
 
57
parameter CFG_BUS = 8'd0;
58
parameter CFG_DEVICE = 5'd0;
59
parameter CFG_FUNC = 3'd0;
60
parameter CFG_VENDOR_ID =       16'h0;
61
parameter CFG_DEVICE_ID =       16'h0;
62
parameter CFG_SUBSYSTEM_VENDOR_ID       = 16'h0;
63
parameter CFG_SUBSYSTEM_ID = 16'h0;
64
parameter CFG_BAR0 = 32'h1;
65
parameter CFG_BAR1 = 32'h1;
66
parameter CFG_BAR2 = 32'h1;
67
parameter CFG_BAR0_MASK = 32'h0;
68
parameter CFG_BAR1_MASK = 32'h0;
69
parameter CFG_BAR2_MASK = 32'h0;
70
parameter CFG_ROM_ADDR = 32'hFFFFFFF0;
71
 
72
parameter CFG_REVISION_ID = 8'd0;
73
parameter CFG_PROGIF = 8'd1;
74
parameter CFG_SUBCLASS = 8'h80;                                 // 80 = Other
75
parameter CFG_CLASS = 8'h03;                                            // 03 = display controller
76
parameter CFG_CACHE_LINE_SIZE = 8'd8;           // 32-bit units
77
parameter CFG_MIN_GRANT = 8'h00;
78
parameter CFG_MAX_LATENCY = 8'h00;
79
parameter CFG_IRQ_LINE = 8'hFF;
80
 
81
localparam CFG_HEADER_TYPE = 8'h00;                     // 00 = a general device
82
 
83
parameter MSIX = 1'b0;
84
 
85
integer n1;
86
reg [31:0] bar0;
87
reg [31:0] bar1;
88
reg [31:0] bar2;
89
reg [15:0] cmd_reg;
90
reg [15:0] cmdo_reg;
91
reg memory_space, io_space;
92
reg bus_master;
93
reg parity_err_resp;
94
reg serr_enable;
95
reg int_disable;
96
reg [7:0] latency_timer = 8'h00;
97
 
98
always_comb
99
begin
100
        cmdo_reg = cmd_reg;
101
        cmdo_reg[3] = 1'b0;                     // no special cycles
102
        cmdo_reg[4] = 1'b0;                     // memory write and invalidate supported
103
        cmdo_reg[5] = 1'b0;                     // VGA palette snoop
104
        cmdo_reg[7] = 1'b0;                     // reserved bit
105
        cmdo_reg[9] = 1'b1;                     // fast back-to-back enable
106
        cmdo_reg[15:11] = 5'd0; // reserved
107
end
108
 
109
reg [15:0] stat_reg;
110
reg [15:0] stato_reg;
111
always_comb
112
begin
113
        stato_reg = stat_reg;
114
        stato_reg[2:0] = 3'b0;  // reserved
115
        stato_reg[3] = irq_i;           // interrupt status
116
        stato_reg[4] = 1'b0;            // capabilities list
117
        stato_reg[5] = 1'b1;            // 66 MHz enable (N/A)
118
        stato_reg[6] = 1'b0;            // reserved
119
        stato_reg[7] = 1'b1;            // fast back-to-back capable
120
        stato_reg[10:9] = 2'b01;        // medium DEVSEL timing
121
end
122
 
123
reg [63:0] cfg_dat [0:31];
124
reg [7:0] irq_line;
125
 
126
initial begin
127
        for (n1 = 0; n1 < 32; n1 = n1 + 1)
128
                cfg_dat[n1] = 'd0;
129
end
130
 
131
wire cs = cs_config_i &&
132
        adr_i[27:20]==CFG_BUS &&
133
        adr_i[19:15]==CFG_DEVICE &&
134
        adr_i[14:12]==CFG_FUNC;
135
 
136
always_ff @(posedge clk_i)
137
if (rst_i) begin
138
        bar0 <= CFG_BAR0;
139
        bar1 <= CFG_BAR1;
140
        bar2 <= CFG_BAR2;
141
        cmd_reg <= 16'h4003;
142
        stat_reg <= 16'h0000;
143
        irq_line <= CFG_IRQ_LINE;
144
end
145
else begin
146
        io_space <= cmdo_reg[0];
147
        memory_space <= cmdo_reg[1];
148
        bus_master <= cmdo_reg[2];
149
        parity_err_resp <= cmdo_reg[6];
150
        serr_enable <= cmdo_reg[8];
151
        int_disable <= cmdo_reg[10];
152
        irq_en_o <= ~cmdo_reg[10];
153
 
154
        if (cs) begin
155
                if (we_i)
156
                        case(adr_i[7:3])
157
                        5'h01:
158
                                begin
159
                                        if (sel_i[0]) cmd_reg[7:0] <= dat_i[7:0];
160
                                        if (sel_i[1]) cmd_reg[15:8] <= dat_i[15:8];
161
                                        if (sel_i[3]) begin
162
                                                if (dat_i[8]) stat_reg[8] <= 1'b0;
163
                                                if (dat_i[11]) stat_reg[11] <= 1'b0;
164
                                                if (dat_i[12]) stat_reg[12] <= 1'b0;
165
                                                if (dat_i[13]) stat_reg[13] <= 1'b0;
166
                                                if (dat_i[14]) stat_reg[14] <= 1'b0;
167
                                                if (dat_i[15]) stat_reg[15] <= 1'b0;
168
                                        end
169
                                end
170
                        5'h02:
171
                                begin
172
                                        if (&sel_i[3:0] && dat_i[31:0]==32'hFFFFFFFF)
173
                                                bar0 <= CFG_BAR0_MASK;
174
                                        else begin
175
                                                if (sel_i[0])   bar0[7:0] <= dat_i[7:0];
176
                                                if (sel_i[1])   bar0[15:8] <= dat_i[15:8];
177
                                                if (sel_i[2])   bar0[23:16] <= dat_i[23:16];
178
                                                if (sel_i[3])   bar0[31:24] <= dat_i[31:24];
179
                                        end
180
                                        if (&sel_i[7:4] && dat_i[63:32]==32'hFFFFFFFF)
181
                                                bar1 <= CFG_BAR1_MASK;
182
                                        else begin
183
                                                if (sel_i[4])   bar1[7:0] <= dat_i[39:32];
184
                                                if (sel_i[5])   bar1[15:8] <= dat_i[47:40];
185
                                                if (sel_i[6])   bar1[23:16] <= dat_i[55:48];
186
                                                if (sel_i[7])   bar1[31:24] <= dat_i[63:56];
187
                                        end
188
                                end
189
                        5'h03:
190
                                if (&sel_i[3:0] && dat_i[31:0]==32'hFFFFFFFF)
191
                                        bar2 <= CFG_BAR2_MASK;
192
                                else begin
193
                                        if (sel_i[0])   bar2[7:0] <= dat_i[7:0];
194
                                        if (sel_i[1])   bar2[15:8] <= dat_i[15:8];
195
                                        if (sel_i[2])   bar2[23:16] <= dat_i[23:16];
196
                                        if (sel_i[3])   bar2[31:24] <= dat_i[31:24];
197
                                end
198
                        5'h07:
199
                                if (sel_i[4]) irq_line <= dat_i[39:32];
200
                        default:
201
                                begin
202
                                        if (sel_i[0]) cfg_dat[adr_i[8:4]][7:0] <= dat_i[7:0];
203
                                        if (sel_i[1]) cfg_dat[adr_i[8:4]][15:8] <= dat_i[15:8];
204
                                        if (sel_i[2]) cfg_dat[adr_i[8:4]][23:16] <= dat_i[23:16];
205
                                        if (sel_i[3]) cfg_dat[adr_i[8:4]][31:24] <= dat_i[31:24];
206
                                        if (sel_i[4]) cfg_dat[adr_i[8:4]][39:32] <= dat_i[39:32];
207
                                        if (sel_i[5]) cfg_dat[adr_i[8:4]][47:40] <= dat_i[47:40];
208
                                        if (sel_i[6]) cfg_dat[adr_i[8:4]][55:48] <= dat_i[55:48];
209
                                        if (sel_i[7]) cfg_dat[adr_i[8:4]][63:56] <= dat_i[63:56];
210
                                end
211
                        endcase
212
                else
213
                        case(adr_i[7:3])
214
                        5'h00:  dat_o <= {stato_reg,cmdo_reg,CFG_DEVICE_ID,CFG_VENDOR_ID};
215
                        5'h01:  dat_o <= {8'h00,
216
                                CFG_HEADER_TYPE,latency_timer,CFG_CACHE_LINE_SIZE,
217
                                CFG_CLASS,CFG_SUBCLASS,CFG_PROGIF,CFG_REVISION_ID};
218
                        5'h02:  dat_o <= {bar1,bar0};
219
                        5'h03:  dat_o <= {32'hFFFFFFFF,bar2};
220
                        5'h04:  dat_o <= 64'hFFFFFFFFFFFFFFFF;
221
                        5'h05:  dat_o <= {CFG_SUBSYSTEM_ID,CFG_SUBSYSTEM_VENDOR_ID,32'h0};
222
                        5'h06:  dat_o <= {32'd0,CFG_ROM_ADDR};
223
                        5'h07:  dat_o <= {8'd8,8'd0,8'd0,irq_line,32'd0};
224
                        default:        dat_o <= cfg_dat[adr_i[7:3]];
225
                        endcase
226
        end
227
end
228
 
229
always_comb
230
        irq_o = {31'd0,irq_i & ~int_disable} << irq_line;
231
 
232
always_comb
233
        cs_bar0_o = ((adr_i ^ bar0) & CFG_BAR0_MASK) == 'd0;
234
always_comb
235
        cs_bar1_o = ((adr_i ^ bar1) & CFG_BAR1_MASK) == 'd0;
236
always_comb
237
        cs_bar2_o = ((adr_i ^ bar2) & CFG_BAR2_MASK) == 'd0;
238
 
239
endmodule

powered by: WebSVN 2.1.0

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