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

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [rtl/] [terasic_de2_70/] [drv_eth_vga_capture.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
/*! \file
26
 * \brief DM9000A 10/100 Mbit Ethernet driver for a VGA frame grabber
27
 */
28
 
29
/*! \brief \copybrief drv_eth_vga_capture.v
30
*/
31
module drv_eth_vga_capture(
32
    //% \name Clock and reset
33
    //% @{
34
    input           clk_30,
35
    input           clk_25,
36
    input           reset_n,
37
    //% @}
38
 
39
    //% \name Captured VGA output signals
40
    //% @{
41
    input           display_valid,
42
    input [9:0]     vga_r,
43
    input [9:0]     vga_g,
44
    input [9:0]     vga_b,
45
    //% @}
46
 
47
    //% \name DM9000A Ethernet hardware interface
48
    //% @{
49
    output          enet_clk_25,
50
    output          enet_reset_n,
51
    output          enet_cs_n,
52
    input           enet_irq,
53
 
54
    output reg      enet_ior_n,
55
    output reg      enet_iow_n,
56
    output reg      enet_cmd,
57
    inout [15:0]    enet_data
58
    //% @}
59
);
60
assign enet_clk_25  = clk_25;
61
assign enet_reset_n = reset_n;
62
assign enet_cs_n    = 1'b0;
63
 
64
reg tx_active;
65
 
66
reg enet_data_oe;
67
reg [15:0] enet_data_out;
68
assign enet_data = (enet_data_oe == 1'b1)? enet_data_out : 16'bZ;
69
 
70
//************ packet Ethernet and IP/UDP header contents ROM
71
reg [5:0] ram_addr;
72
wire [15:0] ram_q;
73
 
74
altsyncram ethernet_ram_inst(
75
    .clock0(clk_30),
76
    .address_a(ram_addr),
77
    .q_a(ram_q)
78
);
79
defparam
80
    ethernet_ram_inst.operation_mode = "ROM",
81
    ethernet_ram_inst.width_a = 16,
82
    ethernet_ram_inst.widthad_a = 6,
83
    ethernet_ram_inst.init_file = "drv_eth_vga_capture.mif";
84
 
85
//************ vga burst fifo
86
reg [8:0] vga_line_number;
87
reg last_display_valid;
88
reg [1:0] select_line;
89
reg block_wrreq;
90
always @(posedge clk_30 or negedge reset_n) begin
91
    if(reset_n == 1'b0) begin
92
        vga_line_number <= 9'd0;
93
        last_display_valid <= 1'b0;
94
        select_line <= 2'd0;
95
        block_wrreq <= 1'b0;
96
    end
97
    else begin
98
        last_display_valid <= display_valid;
99
 
100
        if(fifo_empty == 1'b0 && last_display_valid == 1'b0 && display_valid == 1'b1)   block_wrreq <= 1'b1;
101
        else if(display_valid == 1'b0)                                                  block_wrreq <= 1'b0;
102
 
103
        if(display_valid == 1'b0 && last_display_valid == 1'b1) begin
104
            if(vga_line_number == 9'd479)   vga_line_number <= 9'd0;
105
            else                            vga_line_number <= vga_line_number + 9'd1;
106
        end
107
 
108
        if(display_valid == 1'b0 && last_display_valid == 1'b1 && vga_line_number == 9'd479) select_line <= select_line + 2'd1;
109
    end
110
end
111
 
112
wire fifo_wrreq = (fifo_empty == 1'b1 || last_display_valid == 1'b1) && block_wrreq == 1'b0 && display_valid == 1'b1 && select_line == vga_line_number[1:0];
113
wire start_load = fifo_empty == 1'b0;
114
 
115
wire fifo_empty;
116
wire [11:0] fifo_q;
117
 
118
scfifo vga_fifo_inst(
119
    .clock(clk_30),
120
    .data( { vga_r[9:6], vga_g[9:6], vga_b[9:6] } ),
121
    .wrreq(fifo_wrreq),
122
    .rdreq(fifo_rdreq),
123
 
124
    .empty(fifo_empty),
125
    .q(fifo_q)
126
);
127
defparam
128
    vga_fifo_inst.lpm_width = 12,
129
    vga_fifo_inst.lpm_numwords = 1024;
130
 
131
reg fifo_rdreq;
132
reg [1:0] fifo_rd_cnt;
133
reg [11:0] last_fifo_q;
134
 
135
//************
136
 
137
reg [15:0] state_counter;
138
always @(posedge clk_30 or negedge reset_n) begin
139
    if(reset_n == 1'b0) begin
140
        state_counter   <= 16'd0;
141
        tx_active       <= 1'b0;
142
 
143
        enet_iow_n      <= 1'b1;
144
        enet_ior_n      <= 1'b1;
145
        enet_cmd        <= 1'b0;        // low: INDEX, high: DATA
146
        enet_data_oe    <= 1'b0;
147
        enet_data_out   <= 16'd0;
148
 
149
        ram_addr        <= 6'd0;
150
 
151
        fifo_rdreq      <= 1'b0;
152
        fifo_rd_cnt     <= 2'd0;
153
        last_fifo_q     <= 12'd0;
154
    end
155
    else if(state_counter == 16'd50000) begin
156
        enet_iow_n <= 1'b0;
157
        enet_cmd <= 1'b0;
158
        enet_data_oe <= 1'b1;
159
        enet_data_out <= { 8'd0, 8'hFF }; // set IMR(FFh = 0x80)
160
 
161
        state_counter <= state_counter + 16'd1;
162
    end
163
    else if(state_counter == 16'd50002) begin
164
        enet_iow_n <= 1'b0;
165
        enet_cmd <= 1'b1;
166
        enet_data_out <= { 8'd0, 8'h80 };
167
 
168
        state_counter <= state_counter + 16'd1;
169
    end
170
    else if(state_counter == 16'd50005) begin
171
        enet_iow_n <= 1'b0;
172
        enet_cmd <= 1'b0;
173
        enet_data_out <= { 8'd0, 8'h1F }; // power-up PHY (1Fh = 0x00)
174
 
175
        state_counter <= state_counter + 16'd1;
176
    end
177
    else if(state_counter == 16'd50007) begin
178
        enet_iow_n <= 1'b0;
179
        enet_cmd <= 1'b1;
180
        enet_data_out <= { 8'd0, 8'h00 };
181
 
182
        state_counter <= state_counter + 16'd1;
183
    end
184
 
185
    else if(state_counter == 16'd50010) begin
186
        enet_iow_n <= 1'b0;
187
        enet_cmd <= 1'b0;
188
        enet_data_out <= { 8'd0, 8'h31 }; // set checksum reg (31h = 0x05)
189
 
190
        state_counter <= state_counter + 16'd1;
191
    end
192
    else if(state_counter == 16'd50012) begin
193
        enet_iow_n <= 1'b0;
194
        enet_cmd <= 1'b1;
195
        enet_data_out <= { 8'd0, 8'h05 };
196
 
197
        state_counter <= state_counter + 16'd1;
198
    end
199
 
200
 
201
    else if(state_counter == 16'd50018) begin
202
        enet_iow_n <= 1'b0;
203
        enet_cmd <= 1'b0;
204
        enet_data_out <= { 8'd0, 8'hF8 }; // set MWCMD(F8h = 16-bit data) 
205
 
206
        ram_addr <= 6'd0;
207
        state_counter <= state_counter + 16'd1;
208
    end
209
    else if(state_counter >= 16'd50020 && state_counter <= 16'd50060 && state_counter[0] == 1'b0) begin
210
        enet_iow_n <= 1'b0;
211
        enet_cmd <= 1'b1;
212
        enet_data_out <= ram_q;
213
 
214
        ram_addr <= ram_addr + 6'd1;
215
        state_counter <= state_counter + 16'd1;
216
    end
217
    else if(state_counter == 16'd50062) begin
218
        if(start_load == 1'b1) begin
219
            enet_iow_n <= 1'b0;
220
            enet_cmd <= 1'b1;
221
            enet_data_out <= { 7'd0, vga_line_number };
222
 
223
            fifo_rdreq <= 1'b1;
224
            fifo_rd_cnt <= 2'd0;
225
            state_counter <= state_counter + 16'd1;
226
        end
227
    end
228
    else if(state_counter == 16'd50063) begin
229
        enet_iow_n <= 1'b1;
230
        fifo_rdreq <= 1'b1;
231
        last_fifo_q <= fifo_q;
232
        state_counter <= state_counter + 16'd1;
233
    end
234
 
235
 
236
    else if(state_counter >= 16'd50064 && state_counter <= 16'd51022 && state_counter[0] == 1'b0) begin
237
        enet_iow_n <= 1'b0;
238
        enet_cmd <= 1'b1;
239
 
240
        if(fifo_rd_cnt == 2'd0)     enet_data_out <= { fifo_q[3:0], last_fifo_q };
241
        else if(fifo_rd_cnt == 2'd1)enet_data_out <= { fifo_q[7:0], last_fifo_q[11:4] };
242
        else                        enet_data_out <= { fifo_q, last_fifo_q[11:8] };
243
 
244
        if(fifo_rd_cnt == 2'd2) fifo_rdreq <= 1'b1;
245
        else                    fifo_rdreq <= 1'b0;
246
 
247
        fifo_rd_cnt <= fifo_rd_cnt + 2'd1;
248
        last_fifo_q <= fifo_q;
249
 
250
        if(state_counter == 16'd51022)  state_counter <= 16'd60016 - 16'd1;
251
        else                            state_counter <= state_counter + 16'd1;
252
    end
253
    else if(state_counter >= 16'd50064 && state_counter <= 16'd51022 && state_counter[0] == 1'b1 && fifo_rd_cnt == 2'd3) begin
254
        enet_iow_n <= 1'b1;
255
        fifo_rdreq <= 1'b1;
256
        last_fifo_q <= fifo_q;
257
        fifo_rd_cnt <= 2'd0;
258
        state_counter <= state_counter + 16'd1;
259
    end
260
    else if(state_counter >= 16'd50064 && state_counter <= 16'd51022 && state_counter[0] == 1'b1) begin
261
        enet_iow_n <= 1'b1;
262
        fifo_rdreq <= 1'b1;
263
        state_counter <= state_counter + 16'd1;
264
    end
265
 
266
 
267
    else if(state_counter == 16'd60016) begin
268
        enet_iow_n <= 1'b0;
269
        enet_cmd <= 1'b0;
270
        enet_data_oe <= 1'b1;
271
        enet_data_out <= { 8'd0, 8'h02 }; // read TX(02h bit 0 == 0)
272
 
273
        state_counter <= state_counter + 16'd1;
274
    end
275
    else if(state_counter == 16'd60018) begin
276
        enet_ior_n <= 1'b0;
277
        enet_cmd <= 1'b1;
278
        enet_data_oe <= 1'b0;
279
 
280
        state_counter <= state_counter + 16'd1;
281
    end
282
    else if(state_counter == 16'd60020) begin
283
        enet_ior_n <= 1'b1;
284
        tx_active <= enet_data[0];
285
 
286
        state_counter <= state_counter + 16'd1;
287
    end
288
    else if(state_counter == 16'd60022) begin
289
        if(tx_active == 1'b0)   state_counter <= 16'd60118;
290
        else                    state_counter <= 16'd60016;
291
    end
292
 
293
    else if(state_counter == 16'd60118) begin
294
        enet_iow_n <= 1'b0;
295
        enet_cmd <= 1'b0;
296
        enet_data_oe <= 1'b1;
297
        enet_data_out <= { 8'd0, 8'hFC }; // set TXPLL(FCh = low byte)
298
 
299
        state_counter <= state_counter + 16'd1;
300
    end
301
    else if(state_counter == 16'd60120) begin
302
        enet_iow_n <= 1'b0;
303
        enet_cmd <= 1'b1;
304
        enet_data_out <= { 8'h00, 8'hEC };
305
 
306
        state_counter <= state_counter + 16'd1;
307
    end
308
 
309
    else if(state_counter == 16'd60123) begin
310
        enet_iow_n <= 1'b0;
311
        enet_cmd <= 1'b0;
312
        enet_data_out <= { 8'd0, 8'hFD }; // set TXPLH(FDh = high byte)
313
 
314
        state_counter <= state_counter + 16'd1;
315
    end
316
    else if(state_counter == 16'd60125) begin
317
        enet_iow_n <= 1'b0;
318
        enet_cmd <= 1'b1;
319
        enet_data_out <= { 8'h00, 8'h03 };
320
 
321
        state_counter <= state_counter + 16'd1;
322
    end
323
 
324
    else if(state_counter == 16'd60128) begin
325
        enet_iow_n <= 1'b0;
326
        enet_cmd <= 1'b0;
327
        enet_data_out <= { 8'd0, 8'h02 }; // write TX(02h = 0x01)
328
 
329
        state_counter <= state_counter + 16'd1;
330
    end
331
    else if(state_counter == 16'd60130) begin
332
        enet_iow_n <= 1'b0;
333
        enet_cmd <= 1'b1;
334
        enet_data_out <= { 8'h00, 8'h01 };
335
 
336
        state_counter <= state_counter + 16'd1;
337
    end
338
 
339
    else if(state_counter == 16'd60132) begin
340
         state_counter <= 16'd50018;
341
    end
342
 
343
    else if(state_counter <= 16'd60132) begin
344
        enet_iow_n <= 1'b1;
345
        enet_ior_n <= 1'b1;
346
        fifo_rdreq <= 1'b0;
347
        state_counter <= state_counter + 16'd1;
348
    end
349
 
350
end
351
 
352
endmodule

powered by: WebSVN 2.1.0

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