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

Subversion Repositories mpeg2fpga

[/] [mpeg2fpga/] [trunk/] [rtl/] [mpeg2/] [syncgen.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * syncgen.v
3
 *
4
 * Copyright (c) 2007 Koen De Vleeschauwer.
5
 *
6
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
7
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
10
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16
 * SUCH DAMAGE.
17
 */
18
 
19
/*
20
 * sync_gen - Sync generator.
21
 */
22
 
23
`include "timescale.v"
24
 
25
`undef DEBUG
26
//`define DEBUG 1
27
 
28
/*
29
 * Generates horizontal and vertical synchronisation and timing.
30
 *
31
 * Inputs:
32
 *
33
 * horizontal_size, vertical_size, display_horizontal_size, and display_vertical_size
34
 * are parameters extracted from the MPEG2 bitstream.
35
 * horizontal_size and vertical_size determine the size of the reconstructed bitmap in frame memory;
36
 * display_horizontal_size and display_vertical_size - if non-zero - are the displayable part of this bitmap.
37
 *
38
 * horizontal_resolution, horizontal_sync_start, horizontal_sync_end, horizontal_length,
39
 * vertical_resolution, vertical_sync_start, vertical_sync_end, horizontal_halfline and vertical_length determine video timing.
40
 *
41
 * The timing parameters can be deduced from the X11 modeline for the display.
42
 * See "XFree86 Video Timings HOWTO".
43
 *
44
 * Note vertical_resolution, vertical_sync_start, vertical_sync_end and vertical_length refer to a frame if
45
 * progressive, and to a field if interlaced.
46
 *
47
 * For instance, vertical_resolution is number of visible lines per frame if progressive,
48
 * and number of visible lines per field if interlaced.
49
 *
50
 * If 'interlaced' is asserted, vertical sync is delayed one-half scan line at the end of odd frames.
51
 * This is similar to "interlace sync and video mode" of the mc6845 crtc.
52
 *
53
 * Outputs:
54
 * h_pos and v_pos are the coordinates of the current pixel.
55
 * pixel_en is not asserted if blanking is required.
56
 * h_sync and v_sync are horizontal and vertical synchronisation,
57
 * respectively.
58
 *
59
 */
60
 
61
module sync_gen    (clk, clk_en, rst,
62
                   horizontal_size, vertical_size, display_horizontal_size, display_vertical_size,
63
                   horizontal_resolution, horizontal_sync_start, horizontal_sync_end, horizontal_length,
64
                   vertical_resolution, vertical_sync_start, vertical_sync_end, horizontal_halfline, vertical_length,
65
                   interlaced, clip_display_size,
66
                   h_pos, v_pos, pixel_en, h_sync, v_sync, c_sync, h_blank, v_blank);
67
 
68
  input            clk;
69
  input            clk_en;
70
  input            rst;
71
 
72
  input      [13:0]horizontal_size;               /* par. 6.2.2.1, par. 6.3.3 */
73
  input      [13:0]vertical_size;                 /* par. 6.2.2.1, par. 6.3.3 */
74
  input      [13:0]display_horizontal_size;       /* par. 6.2.2.4, par. 6.3.6 */
75
  input      [13:0]display_vertical_size;         /* par. 6.2.2.4, par. 6.3.6 */
76
 
77
  input      [11:0]horizontal_resolution;         /* horizontal resolution. number of dots per line */
78
  input      [11:0]horizontal_sync_start;         /* the dot the horizontal sync pulse begins. */
79
  input      [11:0]horizontal_sync_end;           /* the dot the horizontal sync pulse ends. */
80
  input      [11:0]horizontal_length;             /* total horizontal length */
81
  input      [11:0]vertical_resolution;           /* vertical resolution. number of visible lines per frame (progressive) or field (interlaced) */
82
  input      [11:0]vertical_sync_start;           /* the line number within the frame (progressive) or field (interlaced) the vertical sync pulse begins. */
83
  input      [11:0]vertical_sync_end;             /* the line number within the frame (progressive) or field (interlaced) the vertical sync pulse ends. */
84
  input      [11:0]horizontal_halfline;           /* the dot the vertical sync begins on odd frames of interlaced video. Not used in progressive mode. */
85
  input      [11:0]vertical_length;               /* total number of lines of a vertical frame (progressive) or field (interlaced) */
86
  input            interlaced;                    /* asserted if interlaced output required. */
87
  input            clip_display_size;             /* assert to clip image to (display_horizontal_size, display_vertical_size) */
88
 
89
  output reg [11:0]h_pos;                         /* horizontal position */
90
  output reg [11:0]v_pos;                         /* vertical position */
91
  output reg       pixel_en;                      /* pixel enable, asserted when pixel drawn */
92
  output reg       h_sync;                        /* horizontal sync */
93
  output reg       v_sync;                        /* vertical sync */
94
  output reg       c_sync;                        /* complex sync */
95
  output reg       h_blank;                       /* horizontal blanking */
96
  output reg       v_blank;                       /* vertical blanking */
97
 
98
  /*
99
   * general registers
100
   */
101
 
102
  reg        [11:0]h_size;
103
  reg        [11:0]h_display_size;
104
  reg        [11:0]v_size;
105
  reg        [11:0]v_display_size;
106
  reg        [11:0]v_sync_h_pos;
107
  reg              odd_field;
108
 
109
  /*
110
   * v_sync_h_pos: horizontal position of vertical sync.
111
   * In progressive video,  the vertical sync begins at horizontal position 0,
112
   * In interlaced video:
113
   *  - in even fields, vertical sync begins at horizontal position 0
114
   *  - in odd fields,  vertical sync is delayed horizontal_halfline dots.
115
   *  A common value for horizontal_halfline is horizontal_length/2.
116
   */
117
 
118
  always @(posedge clk)
119
    if (~rst) v_sync_h_pos <= 12'd0;
120
    else if (clk_en) v_sync_h_pos <= (interlaced && odd_field) ? horizontal_halfline : 12'd0;
121
    else v_sync_h_pos <= v_sync_h_pos;
122
 
123
  /*
124
   * for h_display_size and v_display_size:
125
   * display_horizontal_size and display_vertical_size are optional mpeg2 parameters.
126
   * If display_horizontal_size and display_vertical_size are  zero, the whole frame is displayable; use horizontal_size and vertical_size instead.
127
   * If display_horizontal_size and display_vertical_size are non-zero, only display_horizontal_size by display_vertical_size of the frame is displayable.
128
   */
129
 
130
  always @(posedge clk)
131
    if (~rst) h_display_size <= 12'd0;
132
    else if (clk_en) h_display_size <= ((display_horizontal_size != 0) && clip_display_size) ? display_horizontal_size[11:0] : ((horizontal_size != 0) ? horizontal_size[11:0] : horizontal_resolution);
133
    else h_display_size <= h_display_size;
134
 
135
  always @(posedge clk)
136
    if (~rst) v_display_size <= 12'd0;
137
    else if (clk_en && interlaced) v_display_size <= ((display_vertical_size != 0) && clip_display_size) ? display_vertical_size[11:1] : ((vertical_size != 0) ? vertical_size[11:1] : vertical_resolution[11:1]); // interlacing; one field contains half the visible lines.
138
    else if (clk_en) v_display_size <= ((display_vertical_size != 0) && clip_display_size) ? display_vertical_size[11:0] : ((vertical_size != 0) ? vertical_size[11:0] : vertical_resolution); // no interlacing; one frame contains all visible lines.
139
    else v_display_size <= v_display_size;
140
 
141
  always @(posedge clk)
142
    if (~rst) h_size <= 12'd0;
143
    else if (clk_en) h_size <= (horizontal_size != 0) ? horizontal_size[11:0] : horizontal_resolution;
144
    else h_size <= h_size;
145
 
146
  always @(posedge clk)
147
    if (~rst) v_size <= 12'd0;
148
    else if (clk_en && interlaced) v_size <= (vertical_size != 0) ? vertical_size[11:1] : vertical_resolution[11:1];
149
    else if (clk_en) v_size <= (vertical_size != 0) ? vertical_size[11:0] : vertical_resolution;
150
    else v_size <= v_size;
151
 
152
  /*
153
   * Stage 0
154
   */
155
 
156
  reg        [11:0]h_cntr;
157
  reg        [11:0]v_cntr;
158
 
159
  /* horizontal counter */
160
  always @(posedge clk)
161
    if (~rst) h_cntr <= 12'd0;
162
    else if (clk_en) h_cntr <= (h_cntr >= horizontal_length) ? 12'd0 : (h_cntr + 1);
163
    else h_cntr <= h_cntr;
164
 
165
  /* vertical counter */
166
  always @(posedge clk)
167
    if (~rst) v_cntr <= 12'd0;
168
    else if (clk_en && (h_cntr >= horizontal_length)) v_cntr <= (v_cntr >= vertical_length) ? 12'd0 : (v_cntr + 1);
169
    else v_cntr <= v_cntr;
170
 
171
  /*
172
   * Stage 1
173
   */
174
 
175
  reg        [11:0]h_cntr_1;
176
  reg        [11:0]v_cntr_1;
177
  reg              h_blank_1;
178
  reg              v_blank_1;
179
  reg              h_sync_1;
180
  reg              v_sync_1;
181
 
182
  always @(posedge clk)
183
    if (~rst) h_cntr_1 <= 12'd0;
184
    else if (clk_en) h_cntr_1 <= h_cntr;
185
    else h_cntr_1 <= h_cntr_1;
186
 
187
  always @(posedge clk)
188
    if (~rst) v_cntr_1 <= 12'd0;
189
    else if (clk_en) v_cntr_1 <= v_cntr;
190
    else v_cntr_1 <= v_cntr_1;
191
 
192
  /* horizontal synchronisation */
193
  always @(posedge clk)
194
    if (~rst) h_sync_1 <= 1'b0;
195
    else if (clk_en) h_sync_1 <= (h_cntr >= horizontal_sync_start) && (h_cntr <= horizontal_sync_end);
196
    else h_sync_1 <= h_sync_1;
197
 
198
  /* horizontal blanking */
199
  always @(posedge clk)
200
    if (~rst) h_blank_1 <= 1'b1;
201
    else if (clk_en) h_blank_1 <= (h_cntr >= horizontal_resolution) || (h_cntr >= h_size) || (h_cntr >= h_display_size);
202
    else h_blank_1 <= h_blank_1;
203
 
204
  /* vertical synchronisation */
205
  always @(posedge clk)
206
    if (~rst) v_sync_1 <= 1'b0;
207
    else if (clk_en) v_sync_1 <= ((v_cntr == vertical_sync_start) && (h_cntr >= v_sync_h_pos))
208
                              || ((v_cntr > vertical_sync_start) && (v_cntr < vertical_sync_end))
209
                              || ((v_cntr == vertical_sync_end) && (h_cntr < v_sync_h_pos));
210
    else v_sync_1 <= v_sync_1;
211
 
212
  /* vertical blanking */
213
  always @(posedge clk)
214
    if (~rst) v_blank_1 <= 1'b1;
215
    else if (clk_en) v_blank_1 <= (v_cntr >= vertical_resolution) || (v_cntr >= v_size) || (v_cntr >= v_display_size);
216
    else v_blank_1 <= v_blank_1;
217
 
218
  /*
219
   * odd_field is asserted during odd fields of interlaced pictures.
220
   * odd_field is not asserted when video is not interlaced.
221
   */
222
 
223
  always @(posedge clk)
224
    if (~rst) odd_field <= 1'b0;
225
    else if (clk_en && ~interlaced) odd_field <= 1'b0;
226
    else if (clk_en && interlaced && (h_cntr == 12'b0) && (v_cntr == 12'b0)) odd_field <= ~odd_field; // when interlaced, toggle 
227
    else odd_field <= odd_field;
228
 
229
  /*
230
   * Stage 2
231
   */
232
 
233
  reg        [11:0]h_cntr_2;
234
  reg        [11:0]v_cntr_2;
235
  reg              h_blank_2;
236
  reg              v_blank_2;
237
  reg              h_sync_2;
238
  reg              v_sync_2;
239
 
240
  always @(posedge clk)
241
    if (~rst) h_cntr_2 <= 12'd0;
242
    else if (clk_en) h_cntr_2 <= h_cntr_1;
243
    else h_cntr_2 <= h_cntr_2;
244
 
245
  always @(posedge clk)
246
    if (~rst) v_cntr_2 <= 12'd0;
247
    else if (clk_en) v_cntr_2 <= v_cntr_1;
248
    else v_cntr_2 <= v_cntr_2;
249
 
250
  always @(posedge clk)
251
    if (~rst) h_blank_2 <= 1'b1;
252
    else if (clk_en) h_blank_2 <= h_blank_1;
253
    else h_blank_2 <= h_blank_2;
254
 
255
  always @(posedge clk)
256
    if (~rst) v_blank_2 <= 1'b1;
257
    else if (clk_en) v_blank_2 <= v_blank_1;
258
    else v_blank_2 <= v_blank_2;
259
 
260
  always @(posedge clk)
261
    if (~rst) h_sync_2 <= 1'b0;
262
    else if (clk_en) h_sync_2 <= h_sync_1;
263
    else h_sync_2 <= h_sync_2;
264
 
265
  always @(posedge clk)
266
    if (~rst) v_sync_2 <= 1'b0;
267
    else if (clk_en) v_sync_2 <= v_sync_1;
268
    else v_sync_2 <= v_sync_2;
269
 
270
  /*
271
   * horizontal coordinate
272
   */
273
 
274
  always @(posedge clk)
275
    if (~rst) h_pos <= 12'd0;
276
    else if (clk_en) h_pos <= h_cntr_2;
277
    else h_pos <= h_pos;
278
 
279
  /*
280
   * vertical coordinate: line number.
281
   * If progressive, v_pos sequences through the line number 0, 1, 2, 3, 4, 5, ...
282
   * If interlaced, v_pos sequences through even numbers on odd fields 0, 2, 4, ...
283
   * and through odd numbers on even fields 1, 3, 5, ...
284
   * (This is because tv people start counting from 1, not 0.)
285
   */
286
 
287
  always @(posedge clk)
288
    if (~rst) v_pos <= 12'd0;
289
    else if (clk_en) v_pos <= interlaced ? { v_cntr_2[10:0], ~odd_field } : v_cntr_2;
290
    else v_pos <= v_pos;
291
 
292
  always @(posedge clk)
293
    if (~rst) h_sync <= 1'b0;
294
    else if (clk_en) h_sync <= h_sync_2;
295
    else h_sync <= h_sync;
296
 
297
  always @(posedge clk)
298
    if (~rst) v_sync <= 1'b0;
299
    else if (clk_en) v_sync <= v_sync_2;
300
    else v_sync <= v_sync;
301
 
302
  always @(posedge clk)
303
    if (~rst) h_blank <= 1'b1;
304
    else if (clk_en) h_blank <= h_blank_2;
305
    else h_blank <= h_blank;
306
 
307
  always @(posedge clk)
308
    if (~rst) v_blank <= 1'b1;
309
    else if (clk_en) v_blank <= v_blank_2;
310
    else v_blank <= v_blank;
311
 
312
  /*
313
   * pixel enable
314
   */
315
 
316
  always @(posedge clk)
317
    if (~rst) pixel_en <= 1'd0;
318
    else if (clk_en) pixel_en <= ~h_blank_2 && ~v_blank_2;
319
    else pixel_en <= pixel_en;
320
 
321
  /*
322
   * composite sync
323
   */
324
 
325
  always @(posedge clk)
326
    if (~rst) c_sync <= 1'b0;
327
    else if (clk_en) c_sync <= ~(h_sync_2 ^ v_sync_2);
328
    else c_sync <= c_sync;
329
 
330
`ifdef DEBUG
331
  always @(posedge clk)
332
      begin
333
            $strobe("%m\th_pos: %4d v_pos: %4d h_cntr: %4d v_cntr: %4d h_sync: %d v_sync: %d h_blank: %d v_blank: %d pixel_en: %d odd_field: %d v_sync_h_pos: %d h_display_size: %d v_display_size: %d h_size: %d v_size: %d",
334
                          h_pos, v_pos, h_cntr, v_cntr, h_sync, v_sync, h_blank, v_blank, pixel_en, odd_field, v_sync_h_pos, h_display_size, v_display_size, h_size, v_size);
335
 
336
            $strobe("%m\thorizontal_size: %d vertical_size: %d display_horizontal_size: %d display_vertical_size: %d horizontal_resolution: %d horizontal_sync_start: %d horizontal_sync_end: %d horizontal_length: %d",
337
                         horizontal_size, vertical_size, display_horizontal_size, display_vertical_size, horizontal_resolution, horizontal_sync_start, horizontal_sync_end, horizontal_length);
338
 
339
            $strobe("%m\tvertical_resolution: %d vertical_sync_start: %d vertical_sync_end: %d horizontal_halfline: %d vertical_length: %d interlaced: %d",
340
                        vertical_resolution, vertical_sync_start, vertical_sync_end, horizontal_halfline, vertical_length, interlaced);
341
 
342
            $strobe("%m\t%4d.%4d h_sync: %0d v_sync: %0d h_blank: %0d v_blank: %0d pixel_en: %0d", h_pos, v_pos, h_sync, v_sync, h_blank, v_blank, pixel_en);
343
 
344
            $strobe("sync2graph %0d %0d %d %d %d", h_pos, v_pos, h_sync, v_sync, pixel_en); // for sync2graph testbench
345
      end
346
`endif
347
endmodule
348
/* not truncated */

powered by: WebSVN 2.1.0

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