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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * resample_addrgen.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
 * resample_addrgen - chroma resampling: address generation
21
 */
22
 
23
`include "timescale.v"
24
 
25
`undef DEBUG
26
//`define DEBUG 1
27
 
28
module resample_addrgen (
29
  clk, clk_en, rst,
30
  output_frame, output_frame_valid, output_frame_rd,
31
  progressive_sequence, progressive_frame, top_field_first, repeat_first_field, mb_width, mb_height, horizontal_size, vertical_size,
32
  interlaced, deinterlace, persistence, repeat_frame,
33
  disp_wr_addr_full, disp_wr_addr_en, disp_wr_addr_ack, disp_wr_addr,
34
  resample_wr_dta, resample_wr_en,
35
  disp_wr_addr_almost_full, resample_wr_almost_full,
36
  busy
37
  );
38
 
39
  input              clk;                      // clock
40
  input              clk_en;                   // clock enable
41
  input              rst;                      // synchronous active low reset
42
 
43
  input        [2:0]output_frame;              /* frame to be displayed */
44
  input             output_frame_valid;        /* asserted when output_frame valid */
45
  output reg        output_frame_rd;
46
 
47
  input             progressive_sequence;
48
  input             progressive_frame;
49
  input             top_field_first;
50
  input             repeat_first_field;
51
  input         [7:0]mb_width;                 // par. 6.3.3. width of the encoded luminance component of pictures in macroblocks
52
  input         [7:0]mb_height;                // par. 6.3.3. height of the encoded luminance component of frame pictures in macroblocks
53
  input        [13:0]horizontal_size;          // par. 6.2.2.1, par. 6.3.3 
54
  input        [13:0]vertical_size;            // par. 6.2.2.1, par. 6.3.3
55
 
56
  input              interlaced;               // asserted if display modeline is interlaced
57
  input              deinterlace;              // asserted if video has to be deinterlaced
58
  input              persistence;              // asserted if last shown image persists
59
  input         [4:0]repeat_frame;             // repeat frame if non-zero
60
 
61
  /* reading reconstructed frame: writing address */
62
  input              disp_wr_addr_full;
63
  output             disp_wr_addr_en;
64
  input              disp_wr_addr_ack;
65
  output       [21:0]disp_wr_addr;
66
 
67
  output reg    [2:0]resample_wr_dta;
68
  output reg         resample_wr_en;
69
 
70
  input              disp_wr_addr_almost_full;
71
  input              resample_wr_almost_full;
72
  output reg         busy;                     // asserted when generating addresses
73
 
74
`include "vld_codes.v"
75
`include "mem_codes.v"
76
`include "resample_codes.v"
77
 
78
  /*
79
    progressive_sequence == 1: progressive video, no interlacing. use progressive chroma upsampling.
80
      repeat_first_field == 0: show frame once.
81
      repeat_first_field == 1:
82
        top_field_first == 0: show frame twice.
83
        top_field_first == 1: show frame three times.
84
 
85
    progressive_sequence == 0: interlacing.
86
      progressive_frame == 0: use interlaced chroma upsampling.
87
        top_field_first == 1: show top field, then show bottom field.
88
        top_field_first == 0: show bottom field, then show top field.
89
      progressive_frame == 1: use progressive chroma upsampling.
90
        repeat_first_field == 0:
91
          top_field_first == 1: show top field, then show bottom field.
92
          top_field_first == 0: show bottom field, then show top field.
93
        repeat_first_field == 1:
94
          top_field_first == 1: show top field, then show bottom field, then show top field.
95
          top_field_first == 0: show bottom field, then show top field, then show bottom field.
96
 
97
    See par. 7.12, Output of the decoding process
98
 
99
    A slight complication: as a workaround for popular mpeg2 encoder bug,
100
    if the current frame's progressive_frame flag is "true"
101
      use progressive chroma upsampling
102
    else
103
      if the previous frame's progressive_frame AND repeat_first_field flags are "true"
104
        use progressive chroma upsampling
105
       else
106
        use interlaced chroma upsampling
107
    ( From: http://www.hometheaterhifi.com/volume_8_2/dvd-benchmark-special-report-chroma-bug-4-2001.html )
108
  */
109
 
110
  parameter [1:0]
111
    NO_OUTPUT         = 3'h0,      // No output
112
    FRAME             = 3'h1,      // Output frame, progressive chroma upsampling.
113
    TOP               = 3'h2,      // Output top field, progressive or interlaced chroma upsampling.
114
    BOTTOM            = 3'h3;      // Output bottom field, progressive or interlaced chroma upsampling.ç
115
 
116
  reg               encoder_bug_workaround;
117
  reg          [1:0]last_image;
118
  reg          [1:0]image;
119
  reg          [1:0]image_0;
120
  reg          [1:0]image_1;
121
  reg          [1:0]image_2;
122
  reg          [1:0]image_3;
123
  reg          [1:0]image_4;
124
  reg          [1:0]image_5;
125
  reg          [4:0]repeat_cnt;
126
 
127
  wire          [7:0]mb_height_minus_one = mb_height - 8'd1;
128
  wire          [7:0]mb_width_minus_one = mb_width - 8'd1;
129
 
130
  reg          [2:0]output_frame_sav;        /* saved 'output_frame' value */
131
  reg          [2:0]disp_frame;              /* frame to be fetched from memory. May be OSD_FRAME */
132
  reg          [1:0]disp_comp;               /* Component to be fetched from memory. If frame, has value COMP_Y, COMP_CR or COMP_CB. If osd, has value COMP_Y */
133
 /*
134
  disp_mb counts left to right, one macroblock at a time.
135
  disp_y counts top to bottom, one (frame) or two (field) lines at a time.
136
  */
137
  reg          [7:0]disp_mb;                 /* horizontal macroblock counter */
138
  wire        [11:0]disp_x = {disp_mb, 4'b0};/* horizontal coordinate */
139
  reg         [11:0]disp_y;                  /* vertical line counter */
140
  reg signed  [12:0]disp_delta_x;            /* address generator input */
141
  reg signed  [12:0]disp_delta_y;            /* address generator input */
142
  reg signed  [12:0]disp_mv_x;               /* address generator input */
143
  reg signed  [12:0]disp_mv_y;               /* address generator input */
144
  reg               disp_valid_in;
145
 
146
  reg               progressive_upscaling;   /* asserted if progressive upscaling, low if interlaced upscaling */
147
  wire        [11:0]disp_height = {mb_height, 4'b0}; // height in lines
148
  wire              last_mb = (disp_mb + 1) == mb_width; // asserted in rightmost macroblock of line
149
  wire              last_y = (disp_y[11:4] == mb_height_minus_one) && (disp_y[3:0] == ((image == TOP) ? 4'd14 : 4'd15));
150
 
151
  parameter [3:0]
152
    STATE_INIT        = 4'h0,
153
    STATE_NEXT_IMG    = 4'h1,
154
    STATE_REPEAT      = 4'h2,
155
    STATE_NEXT_MB     = 4'h3,
156
    STATE_WAIT        = 4'h4,
157
    STATE_WR_OSD_MSB  = 4'h5,
158
    STATE_WR_OSD_LSB  = 4'h6,
159
    STATE_WR_Y_MSB    = 4'h7,
160
    STATE_WR_Y_LSB    = 4'h8,
161
    STATE_WR_U_UPPER  = 4'h9,
162
    STATE_WR_U_LOWER  = 4'ha,
163
    STATE_WR_V_UPPER  = 4'hb,
164
    STATE_WR_V_LOWER  = 4'hc;
165
 
166
  reg         [3:0]state;
167
  reg         [3:0]next;
168
 
169
  /* next state logic */
170
  always @*
171
    case (state)
172
      STATE_INIT:         if (output_frame_valid) next = STATE_NEXT_IMG; // wait for next output frame
173
                          else next = STATE_INIT;
174
 
175
      STATE_NEXT_IMG:     if ((image_0 == NO_OUTPUT) && (image_1 == NO_OUTPUT) && (image_2 == NO_OUTPUT) &&
176
                              (image_3 == NO_OUTPUT) && (image_4 == NO_OUTPUT) && (image_5 == NO_OUTPUT)) next = STATE_REPEAT;
177
                          else next = STATE_WR_OSD_MSB;
178
 
179
      STATE_REPEAT:       if (repeat_cnt != 5'd0) next = STATE_NEXT_IMG; // repeat frame 
180
                          else if (~output_frame_valid && persistence && (last_image != NO_OUTPUT)) next = STATE_NEXT_IMG; // persistence: repeat last image until next image decoded
181
                          else next = STATE_INIT;
182
 
183
      STATE_NEXT_MB:      if (last_mb && last_y) next = STATE_NEXT_IMG;
184
                          else next = STATE_WAIT;
185
 
186
      STATE_WAIT:         if (disp_wr_addr_almost_full || resample_wr_almost_full) next = STATE_WAIT;
187
                          else next = STATE_WR_OSD_MSB;
188
 
189
      STATE_WR_OSD_MSB:   next = STATE_WR_OSD_LSB; // output osd read requests - 16 pixels
190
 
191
      STATE_WR_OSD_LSB:   next = STATE_WR_Y_MSB;
192
 
193
      STATE_WR_Y_MSB:     next = STATE_WR_Y_LSB; // output luminance read requests - 16 pixels
194
 
195
      STATE_WR_Y_LSB:     next = STATE_WR_U_UPPER;
196
 
197
      STATE_WR_U_UPPER:   next = STATE_WR_U_LOWER; // output chroma read requests - 2 rows of 8 
198
 
199
      STATE_WR_U_LOWER:   next = STATE_WR_V_UPPER;
200
 
201
      STATE_WR_V_UPPER:   next = STATE_WR_V_LOWER; // output chroma read requests - 2 rows of 8
202
 
203
      STATE_WR_V_LOWER:   next = STATE_NEXT_MB;
204
 
205
      default             next = STATE_INIT;
206
 
207
    endcase
208
 
209
  /* state */
210
  always @(posedge clk)
211
    if(~rst) state <= STATE_INIT;
212
    else if (clk_en) state <= next;
213
    else state <= state;
214
 
215
  always @(posedge clk)
216
    if (~rst) busy <= 1'd0;
217
    else if (clk_en) busy <= (next != STATE_INIT);
218
    else busy <= busy;
219
 
220
  always @(posedge clk)
221
    if (~rst) output_frame_rd <= 1'd0;
222
    else if (clk_en) output_frame_rd <= (state == STATE_INIT) && output_frame_valid;
223
    else output_frame_rd <= output_frame_rd;
224
 
225
  /*
226
   * repeat frame counter
227
   */
228
 
229
  always @(posedge clk)
230
    if (~rst) repeat_cnt <= 5'd0;
231
    else if (clk_en && (state == STATE_INIT)) repeat_cnt <= repeat_frame;
232
    else if (clk_en && (state == STATE_REPEAT) && (repeat_cnt == 5'd31)) repeat_cnt <= repeat_frame;
233
    else if (clk_en && (state == STATE_REPEAT) && (repeat_cnt != 5'd0)) repeat_cnt <= repeat_cnt - 5'd1;
234
    else repeat_cnt <= repeat_cnt;
235
 
236
  /* counters */
237
 
238
  always @(posedge clk)
239
    if (~rst) disp_mb <= 8'd0;
240
    else if (clk_en && (state == STATE_NEXT_IMG)) disp_mb <= 8'd0;
241
    else if (clk_en && (state == STATE_NEXT_MB) && last_mb) disp_mb <= 8'd0;
242
    else if (clk_en && (state == STATE_NEXT_MB)) disp_mb <= disp_mb + 8'd1;
243
    else disp_mb <= disp_mb;
244
 
245
  always @(posedge clk)
246
    if (~rst) disp_y <= 12'd0;
247
    else if (clk_en && (state == STATE_NEXT_IMG)) disp_y <= (image_0 == BOTTOM) ? 12'd1 : 12'd0;
248
    else if (clk_en && (state == STATE_NEXT_MB) && last_mb) disp_y <= (image == FRAME) ? disp_y + 12'd1 : disp_y + 12'd2;
249
    else disp_y <= disp_y;
250
 
251
  /* one output frame may have to be shown up to three times (par. 7.12) */
252
  always @(posedge clk)
253
    if (~rst)
254
      begin
255
        image   <= NO_OUTPUT;
256
        image_0 <= NO_OUTPUT;
257
        image_1 <= NO_OUTPUT;
258
        image_2 <= NO_OUTPUT;
259
        image_3 <= NO_OUTPUT;
260
        image_4 <= NO_OUTPUT;
261
        image_5 <= NO_OUTPUT;
262
        progressive_upscaling <= 1'b0;
263
      end
264
    else if (clk_en && (state == STATE_INIT) && output_frame_valid)
265
      begin
266
        /*
267
         * display progressive sequence on progressive display. Display frames.
268
         */
269
        if (progressive_sequence && ~interlaced)
270
          begin
271
            image   <= NO_OUTPUT;
272
            image_0 <= FRAME;
273
            image_1 <= (repeat_first_field) ? FRAME : NO_OUTPUT;
274
            image_2 <= (repeat_first_field && top_field_first) ? FRAME : NO_OUTPUT;
275
            image_3 <= NO_OUTPUT;
276
            image_4 <= NO_OUTPUT;
277
            image_5 <= NO_OUTPUT;
278
            progressive_upscaling <= 1'b1;
279
          end
280
        /*
281
         * Interlacing: display progressive sequence on interlaced display. Display fields.
282
         */
283
        else if (progressive_sequence && interlaced)
284
          begin
285
            image   <= NO_OUTPUT;
286
            image_0 <= TOP;
287
            image_1 <= BOTTOM;
288
            image_2 <= (repeat_first_field) ? TOP : NO_OUTPUT;
289
            image_3 <= (repeat_first_field) ? BOTTOM : NO_OUTPUT;
290
            image_4 <= (repeat_first_field && top_field_first) ? TOP : NO_OUTPUT;
291
            image_5 <= (repeat_first_field && top_field_first) ? BOTTOM : NO_OUTPUT;
292
            progressive_upscaling <= 1'b1;
293
          end
294
        /*
295
         * XXX Deinterlacing: display is progressive and deinterlacing is requested. Display frame.
296
         */
297
        else if (deinterlace && ~interlaced)
298
          begin
299
            image   <= NO_OUTPUT;
300
            image_0 <= FRAME;
301
            image_1 <= NO_OUTPUT;
302
            image_2 <= NO_OUTPUT;
303
            image_3 <= NO_OUTPUT;
304
            image_4 <= NO_OUTPUT;
305
            image_5 <= NO_OUTPUT;
306
            progressive_upscaling <= (progressive_frame || encoder_bug_workaround);
307
          end
308
         /*
309
          * Interlaced display, progressive frame.
310
          */
311
        else if (progressive_frame)
312
          begin
313
            image   <= NO_OUTPUT;
314
            image_0 <= (top_field_first) ? TOP : BOTTOM;
315
            image_1 <= (top_field_first) ? BOTTOM : TOP;
316
            image_2 <= (repeat_first_field) ? ((top_field_first) ? TOP : BOTTOM) : NO_OUTPUT;
317
            image_3 <= NO_OUTPUT;
318
            image_4 <= NO_OUTPUT;
319
            image_5 <= NO_OUTPUT;
320
            progressive_upscaling <= 1'b1;
321
          end
322
        else
323
         /*
324
          * Interlaced display, interlaced frame.
325
          */
326
          begin
327
            image   <= NO_OUTPUT;
328
            image_0 <= (top_field_first) ? TOP : BOTTOM;
329
            image_1 <= (top_field_first) ? BOTTOM : TOP;
330
            image_2 <= NO_OUTPUT;
331
            image_3 <= NO_OUTPUT;
332
            image_4 <= NO_OUTPUT;
333
            image_5 <= NO_OUTPUT;
334
            progressive_upscaling <= encoder_bug_workaround;
335
          end
336
      end
337
    else if (clk_en && (state == STATE_REPEAT) && (next == STATE_NEXT_IMG))
338
      /*
339
       * Repeat last shown image.
340
       * If last shown image was a frame, show frame.
341
       * If last shown image was a field image, show both fields.
342
       */
343
      begin
344
        image   <= NO_OUTPUT;
345
        case (last_image)
346
          FRAME:
347
            begin
348
              image_0 <= FRAME;
349
              image_1 <= NO_OUTPUT;
350
            end
351
          TOP:
352
            begin
353
              image_0 <= BOTTOM;
354
              image_1 <= TOP;
355
            end
356
          BOTTOM:
357
            begin
358
              image_0 <= TOP;
359
              image_1 <= BOTTOM;
360
            end
361
          NO_OUTPUT:
362
            begin
363
              image_0 <= NO_OUTPUT;
364
              image_1 <= NO_OUTPUT;
365
            end
366
          default
367
            begin
368
              image_0 <= NO_OUTPUT;
369
              image_1 <= NO_OUTPUT;
370
            end
371
        endcase
372
        image_2 <= NO_OUTPUT;
373
        image_3 <= NO_OUTPUT;
374
        image_4 <= NO_OUTPUT;
375
        image_5 <= NO_OUTPUT;
376
        progressive_upscaling <= progressive_upscaling;
377
      end
378
    else if (clk_en && (state == STATE_NEXT_IMG))
379
      begin
380
        image   <= image_0;
381
        image_0 <= image_1;
382
        image_1 <= image_2;
383
        image_2 <= image_3;
384
        image_3 <= image_4;
385
        image_4 <= image_5;
386
        image_5 <= NO_OUTPUT;
387
        progressive_upscaling <= progressive_upscaling;
388
      end
389
    else
390
      begin
391
        image   <= image;
392
        image_0 <= image_0;
393
        image_1 <= image_1;
394
        image_2 <= image_2;
395
        image_3 <= image_3;
396
        image_4 <= image_4;
397
        image_5 <= image_5;
398
        progressive_upscaling <= progressive_upscaling;
399
      end
400
 
401
  always @(posedge clk)
402
    if (~rst) last_image <= NO_OUTPUT;
403
    else if (clk_en && (state == STATE_INIT) && ~persistence) last_image <= NO_OUTPUT;
404
    else if (clk_en && (state == STATE_NEXT_IMG)) last_image <= image;
405
    else last_image <= last_image;
406
 
407
  /* registers */
408
  /* save output_frame */
409
  always @(posedge clk)
410
    if (~rst) output_frame_sav <= 3'b0;
411
    else if (clk_en && (state == STATE_INIT) && output_frame_valid) output_frame_sav <= output_frame;
412
    else output_frame_sav <= output_frame_sav;
413
 
414
  /* determine frame, top, bottom sequence */
415
  always @(posedge clk)
416
    if (~rst) encoder_bug_workaround <= 1'b0;
417
    else if (clk_en && (state == STATE_INIT) && output_frame_valid) encoder_bug_workaround <= progressive_frame && repeat_first_field;
418
    else encoder_bug_workaround <= encoder_bug_workaround;
419
 
420
  always @(posedge clk)
421
    if (~rst) disp_frame <= 3'b0;
422
    else if (clk_en)
423
      case (state)
424
        STATE_INIT,
425
        STATE_NEXT_IMG,
426
        STATE_REPEAT,
427
        STATE_NEXT_MB,
428
        STATE_WAIT:       disp_frame <= output_frame_sav;
429
        STATE_WR_OSD_MSB,
430
        STATE_WR_OSD_LSB: disp_frame <= OSD_FRAME; /* osd frame */
431
        STATE_WR_Y_MSB,
432
        STATE_WR_Y_LSB,
433
        STATE_WR_U_UPPER,
434
        STATE_WR_U_LOWER,
435
        STATE_WR_V_UPPER,
436
        STATE_WR_V_LOWER: disp_frame <= output_frame_sav;
437
        default           disp_frame <= output_frame_sav;
438
      endcase
439
    else disp_frame <= disp_frame;
440
 
441
  always @(posedge clk)
442
    if (~rst) disp_comp <= 2'b0;
443
    else if (clk_en)
444
      case (state)
445
        STATE_INIT,
446
        STATE_NEXT_IMG,
447
        STATE_REPEAT,
448
        STATE_NEXT_MB,
449
        STATE_WAIT,
450
        STATE_WR_OSD_MSB,
451
        STATE_WR_OSD_LSB,
452
        STATE_WR_Y_MSB,
453
        STATE_WR_Y_LSB:   disp_comp <= COMP_Y;
454
        STATE_WR_U_UPPER,
455
        STATE_WR_U_LOWER: disp_comp <= COMP_CR;
456
        STATE_WR_V_UPPER,
457
        STATE_WR_V_LOWER: disp_comp <= COMP_CB;
458
        default           disp_comp <= COMP_Y;
459
      endcase
460
    else disp_comp <= disp_comp;
461
 
462
  always @(posedge clk)
463
    if (~rst) disp_delta_x <= 13'sd0;
464
    else if (clk_en)
465
      case (state)
466
        STATE_INIT,
467
        STATE_NEXT_IMG,
468
        STATE_REPEAT,
469
        STATE_NEXT_MB,
470
        STATE_WAIT,
471
        STATE_WR_OSD_MSB,
472
        STATE_WR_OSD_LSB,
473
        STATE_WR_Y_MSB,
474
        STATE_WR_Y_LSB:   disp_delta_x <= {1'b0, disp_x};
475
        STATE_WR_U_UPPER,
476
        STATE_WR_U_LOWER,
477
        STATE_WR_V_UPPER,
478
        STATE_WR_V_LOWER: disp_delta_x <= {2'b0, disp_x[11:1]};
479
        default           disp_delta_x <= 13'sd0;
480
      endcase
481
    else disp_delta_x <= disp_delta_x;
482
 
483
  always @(posedge clk)
484
    if (~rst) disp_delta_y <= 13'sd0;
485
    else if (clk_en)
486
      case (state)
487
        STATE_INIT,
488
        STATE_NEXT_IMG,
489
        STATE_REPEAT,
490
        STATE_NEXT_MB,
491
        STATE_WAIT,
492
        STATE_WR_OSD_MSB,
493
        STATE_WR_OSD_LSB,
494
        STATE_WR_Y_MSB,
495
        STATE_WR_Y_LSB:   disp_delta_y <= {1'b0, disp_y};
496
        STATE_WR_U_UPPER,
497
        STATE_WR_U_LOWER,
498
        STATE_WR_V_UPPER,
499
        STATE_WR_V_LOWER: if (progressive_upscaling) disp_delta_y <= {2'b0, disp_y[11:1]};
500
                          else disp_delta_y <= {2'b0, disp_y[11:2], disp_y[0]};
501
        default           disp_delta_y <= 13'sd0;
502
      endcase
503
    else disp_delta_y <= disp_delta_y;
504
 
505
  always @(posedge clk)
506
    if (~rst) disp_mv_x <= 2'b0;
507
    else if (clk_en)
508
      case (state)
509
        STATE_INIT,
510
        STATE_NEXT_IMG,
511
        STATE_REPEAT,
512
        STATE_NEXT_MB,
513
        STATE_WAIT,
514
        STATE_WR_OSD_MSB: disp_mv_x <= 13'sd0;
515
        STATE_WR_OSD_LSB: disp_mv_x <= 13'sd16; // 16 halfpixels
516
        STATE_WR_Y_MSB:   disp_mv_x <= 13'sd0;
517
        STATE_WR_Y_LSB:   disp_mv_x <= 13'sd16; // 16 halfpixels
518
        STATE_WR_U_UPPER,
519
        STATE_WR_U_LOWER,
520
        STATE_WR_V_UPPER,
521
        STATE_WR_V_LOWER: disp_mv_x <= 13'sd0;
522
        default           disp_mv_x <= 13'sd0;
523
      endcase
524
    else disp_mv_x <= disp_mv_x;
525
 
526
  /* border cases */
527
  wire signed [12:0]disp_mv_y_minus_4 =  (disp_y[11:2] == 10'b0)                                            ? 13'sd0 : -13'sd4;
528
  wire signed [12:0]disp_mv_y_minus_2 =  (disp_y[11:1] == 11'b0)                                            ? 13'sd0 : -13'sd2;
529
  wire signed [12:0]disp_mv_y_plus_2  =  ((disp_y[11:4] == mb_height_minus_one) && (disp_y[3:1] == 3'b111)) ? 13'sd0 : 13'sd2;
530
  wire signed [12:0]disp_mv_y_plus_4  =  ((disp_y[11:4] == mb_height_minus_one) && (disp_y[3:2] == 2'b11))  ? 13'sd0 : 13'sd4;
531
 
532
  /* bilinear chroma upsampling; see text file 'bilinear.txt' */
533
  always @(posedge clk)
534
    if (~rst) disp_mv_y <= 2'b0;
535
    else if (clk_en)
536
      case (state)
537
        STATE_INIT,
538
        STATE_NEXT_IMG,
539
        STATE_REPEAT,
540
        STATE_NEXT_MB,
541
        STATE_WAIT:       disp_mv_y <= 13'sd0;
542
        STATE_WR_OSD_MSB,
543
        STATE_WR_OSD_LSB,
544
        STATE_WR_Y_MSB,
545
        STATE_WR_Y_LSB,
546
        STATE_WR_U_UPPER,
547
        STATE_WR_V_UPPER: disp_mv_y <= 13'sd0;
548
        STATE_WR_U_LOWER,
549
        STATE_WR_V_LOWER: if (progressive_upscaling) disp_mv_y <= disp_y[0] ? disp_mv_y_plus_2 : disp_mv_y_minus_2;
550
                          else disp_mv_y <= disp_y[1] ? disp_mv_y_plus_4 : disp_mv_y_minus_4;
551
        default           disp_mv_y <= 13'sd0;
552
      endcase
553
    else disp_mv_y <= disp_mv_y;
554
 
555
  always @(posedge clk)
556
    if (~rst) disp_valid_in <= 1'b0;
557
    else if (clk_en)
558
      case (state)
559
        STATE_INIT,
560
        STATE_NEXT_IMG,
561
        STATE_REPEAT,
562
        STATE_NEXT_MB,
563
        STATE_WAIT:       disp_valid_in <= 1'b0;
564
        STATE_WR_OSD_MSB,
565
        STATE_WR_OSD_LSB,
566
        STATE_WR_Y_MSB,
567
        STATE_WR_Y_LSB,
568
        STATE_WR_U_UPPER,
569
        STATE_WR_U_LOWER,
570
        STATE_WR_V_UPPER,
571
        STATE_WR_V_LOWER: disp_valid_in <= 1'b1;
572
        default           disp_valid_in <= 1'b0;
573
      endcase
574
    else disp_valid_in <= disp_valid_in;
575
 
576
  /*
577
   Write to resample fifo.
578
   */
579
 
580
  always @(posedge clk)
581
    if (~rst) resample_wr_dta <= 2'b0;
582
    else if (clk_en && (state == STATE_WR_OSD_MSB) && (disp_mb == 8'd0) && (disp_y == 12'd0)) resample_wr_dta <= ROW_0_COL_0;
583
    else if (clk_en && (state == STATE_WR_OSD_MSB) && (disp_mb == 8'd0) && (disp_y == 12'd1)) resample_wr_dta <= ROW_1_COL_0;
584
    else if (clk_en && (state == STATE_WR_OSD_MSB) && (disp_mb == 8'd0)) resample_wr_dta <= ROW_X_COL_0;
585
    else if (clk_en && (state == STATE_WR_OSD_MSB) && (disp_mb == mb_width_minus_one)) resample_wr_dta <= ROW_X_COL_LAST;
586
    else if (clk_en && (state == STATE_WR_OSD_MSB)) resample_wr_dta <= ROW_X_COL_X;
587
    else resample_wr_dta <= resample_wr_dta;
588
 
589
  always @(posedge clk)
590
    if (~rst) resample_wr_en <= 1'b0;
591
    else if (clk_en) resample_wr_en <= (state == STATE_WR_OSD_MSB);
592
    else resample_wr_en <= resample_wr_en;
593
 
594
  /* display address generator */
595
  memory_address
596
    #(.dta_width(1))
597
    disp_mem_addr (
598
    .clk(clk),
599
    .clk_en(clk_en),
600
    .rst(rst),
601
    /* in */
602
    .frame(disp_frame),
603
    .frame_picture(1'b1),
604
    .field_in_frame(1'b0),
605
    .field(1'b0),
606
    .component(disp_comp),
607
    .mb_width(mb_width),
608
    .horizontal_size(horizontal_size),
609
    .vertical_size(vertical_size),
610
    .macroblock_address(13'd0),
611
    .delta_x(disp_delta_x),
612
    .delta_y(disp_delta_y),
613
    .mv_x(disp_mv_x),
614
    .mv_y(disp_mv_y),
615
    .dta_in(1'b0),
616
    .valid_in(disp_valid_in),
617
    /* out */
618
    .address(disp_wr_addr),
619
    .offset_x(),
620
    .halfpixel_x(),
621
    .halfpixel_y(),
622
    .dta_out(),
623
    .valid_out(disp_wr_addr_en)
624
    );
625
 
626
`ifdef DEBUG
627
  always @(posedge clk)
628
    if (clk_en)
629
      case (state)
630
        STATE_INIT:                               #0 $display("%m         STATE_INIT");
631
        STATE_NEXT_IMG:                           #0 $display("%m         STATE_NEXT_IMG");
632
        STATE_REPEAT:                             #0 $display("%m         STATE_REPEAT");
633
        STATE_NEXT_MB:                            #0 $display("%m         STATE_NEXT_MB");
634
        STATE_WAIT:                               #0 $display("%m         STATE_WAIT");
635
        STATE_WR_OSD_MSB:                         #0 $display("%m         STATE_WR_OSD_MSB");
636
        STATE_WR_OSD_LSB:                         #0 $display("%m         STATE_WR_OSD_LSB");
637
        STATE_WR_Y_MSB:                           #0 $display("%m         STATE_WR_Y_MSB");
638
        STATE_WR_Y_LSB:                           #0 $display("%m         STATE_WR_Y_LSB");
639
        STATE_WR_U_UPPER:                         #0 $display("%m         STATE_WR_U_UPPER");
640
        STATE_WR_U_LOWER:                         #0 $display("%m         STATE_WR_U_LOWER");
641
        STATE_WR_V_UPPER:                         #0 $display("%m         STATE_WR_V_UPPER");
642
        STATE_WR_V_LOWER:                         #0 $display("%m         STATE_WR_V_LOWER");
643
        default                                   #0 $display("%m         *** Error: unknown state %d", state);
644
      endcase
645
 
646
  always @(posedge clk)
647
    if (clk_en && (state == STATE_INIT))
648
      $strobe("%m\toutput_frame: %d output_frame_valid: %d progressive_sequence: %d progressive_frame: %d top_field_first: %d repeat_first_field: %d mb_width: %d mb_height: %d", output_frame, output_frame_valid, progressive_sequence, progressive_frame, top_field_first, repeat_first_field, mb_width, mb_height);
649
 
650
  always @(posedge clk)
651
    if (clk_en && (state == STATE_NEXT_IMG))
652
      $strobe("%m\timage: %d image_0: %d image_1: %d image_2: %d image_3: %d image_4: %d image_5: %d", image, image_0, image_1, image_2, image_3, image_4, image_5);
653
 
654
  always @(posedge clk)
655
    if (clk_en)
656
      $strobe("%m\tstate: %d image: %d disp_frame: %d disp_comp: %d disp_mb: %d disp_x: %d disp_y: %d disp_delta_x: %d disp_delta_y: %d disp_mv_x: %d disp_mv_y: %d disp_valid_in: %d resample_wr_dta: %d resample_wr_en: %d",
657
                   state, image, disp_frame, disp_comp, disp_mb, disp_x, disp_y, disp_delta_x, disp_delta_y, disp_mv_x, disp_mv_y, disp_valid_in, resample_wr_dta, resample_wr_en);
658
`endif
659
endmodule
660
/* not truncated */

powered by: WebSVN 2.1.0

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