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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * motcomp_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
`include "timescale.v"
20
 
21
`undef DEBUG
22
//`define DEBUG 1
23
 
24
/*
25
 * motcomp_addrgen - Motion compensation address generator. Handles 4:2:0 only.
26
 */
27
 
28
 /*
29
  par. 7.6.4, Forming Predictions:
30
   A positive value of the horizontal component of a motion vector indicates that the prediction is made from samples (in the reference field/frame) that lie to the right of the samples being predicted.
31
   A positive value of the vertical component of a motion vector indicates that the prediction is made from samples (in the reference field/frame) that lie below the samples being predicted.
32
   All motion vectors are specified to an accuracy of one half sample.
33
   Thus, if a component of the motion vector is odd, the samples will be read from mid-way between the actual samples in the reference field/frame.
34
   These half-samples are calculated by simple linear interpolation from the actual samples.
35
 */
36
 
37
module motcomp_addrgen(
38
  clk, clk_en, rst,
39
  mvec_rd_en, mvec_rd_valid,
40
  picture_coding_type, picture_structure, motion_type, dct_type,
41
  macroblock_address, macroblock_motion_forward, macroblock_motion_backward, macroblock_intra,
42
  mb_width, mb_height, horizontal_size, vertical_size, chroma_format,
43
  pmv_0_0_0, pmv_0_0_1, pmv_1_0_0, pmv_1_0_1, pmv_0_1_0, pmv_0_1_1, pmv_1_1_0, pmv_1_1_1,
44
  dmv_0_0, dmv_0_1, dmv_1_0, dmv_1_1,
45
  motion_vert_field_select_0_0, motion_vert_field_select_0_1, motion_vert_field_select_1_0, motion_vert_field_select_1_1,
46
  second_field, progressive_sequence, progressive_frame, top_field_first, repeat_first_field, last_frame, update_picture_buffers, motion_vector_valid,
47
  source_select,
48
  fwd_wr_addr_en, fwd_wr_addr, fwd_wr_addr_almost_full,
49
  bwd_wr_addr_en, bwd_wr_addr, bwd_wr_addr_almost_full,
50
  dst_wr_en, dst_wr_write_recon, dst_wr_write_address, dst_wr_almost_full,
51
  dst_wr_motion_forward, dst_wr_fwd_hor_offset, dst_wr_fwd_hor_halfpixel, dst_wr_fwd_ver_halfpixel,
52
  dst_wr_motion_backward, dst_wr_bwd_hor_offset, dst_wr_bwd_hor_halfpixel, dst_wr_bwd_ver_halfpixel,
53
  output_frame, output_frame_valid, output_frame_rd, output_progressive_sequence, output_progressive_frame, output_top_field_first, output_repeat_first_field, picbuf_busy,
54
  dct_block_cmd, dct_block_en, dct_block_wr_almost_full
55
  );
56
 
57
`include "motcomp_dctcodes.v"
58
 
59
  input              clk;                          // clock
60
  input              clk_en;                       // clock enable
61
  input              rst;                          // synchronous active low reset
62
  output reg         mvec_rd_en;                   // motion vector fifo read enable
63
  input              mvec_rd_valid;                // motion vector fifo read valid
64
 
65
  input         [2:0]picture_coding_type;          // identifies whether a picture is an I, P or B picture.
66
  input         [1:0]picture_structure;            // one of FRAME_PICTURE, TOP_FIELD or BOTTOM_FIELD
67
  input         [1:0]motion_type;                  // one of MC_FIELD, MC_FRAME, MC_16X8 or MC_DMV
68
  input              dct_type;                     // dct_type == 1 : field dct coded; dct_type == 0 : frame dct coded
69
  input        [12:0]macroblock_address;           // absolute position of the current macroblock. top-left macroblock has macroblock_address zero.
70
  input              macroblock_motion_forward;
71
  input              macroblock_motion_backward;
72
  input              macroblock_intra;
73
  input         [7:0]mb_width;                     // par. 6.3.3. width of the encoded luminance component of pictures in macroblocks
74
  input         [7:0]mb_height;                    // par. 6.3.3. height of the encoded luminance component of frame pictures in macroblocks
75
  input        [13:0]horizontal_size;              // par. 6.2.2.1, par. 6.3.3
76
  input        [13:0]vertical_size;                // par. 6.2.2.1, par. 6.3.3 
77
  input         [1:0]chroma_format;
78
  input              motion_vert_field_select_0_0; // motion_vertical_field_select. Indicates which reference field shall be used to form the prediction.
79
                                                   // If motion_vertical_field_select[r][s] is zero, then the top reference field shall be used,
80
                                                   // if it is one then the bottom reference field shall be used.
81
  input              motion_vert_field_select_0_1;
82
  input              motion_vert_field_select_1_0;
83
  input              motion_vert_field_select_1_1;
84
  input              second_field;
85
  input signed [12:0]pmv_0_0_0;                    // predicted motion vector
86
  input signed [12:0]pmv_0_0_1;                    // predicted motion vector
87
  input signed [12:0]pmv_1_0_0;                    // predicted motion vector
88
  input signed [12:0]pmv_1_0_1;                    // predicted motion vector
89
  input signed [12:0]pmv_0_1_0;                    // predicted motion vector
90
  input signed [12:0]pmv_0_1_1;                    // predicted motion vector
91
  input signed [12:0]pmv_1_1_0;                    // predicted motion vector
92
  input signed [12:0]pmv_1_1_1;                    // predicted motion vector
93
  input signed [12:0]dmv_0_0;                      // dual-prime motion vector.
94
  input signed [12:0]dmv_0_1;                      // dual-prime motion vector.
95
  input signed [12:0]dmv_1_0;                      // dual-prime motion vector.
96
  input signed [12:0]dmv_1_1;                      // dual-prime motion vector.
97
  input              progressive_sequence;
98
  input              progressive_frame;
99
  input              top_field_first;
100
  input              repeat_first_field;
101
 
102
  input              last_frame;
103
  input              update_picture_buffers;
104
  input              motion_vector_valid;
105
  /* trick modes */
106
  input         [2:0]source_select;                 /* select video out source */
107
 
108
`include "mem_codes.v"
109
`include "vld_codes.v"
110
 
111
  /* picture buffers */
112
  reg               do_update_picture_buffers;
113
  wire         [2:0]forward_reference_frame;      /* forward reference frame. Has value 2'd0 or 2'd1 */
114
  wire         [2:0]backward_reference_frame;     /* backward reference frame. Has value 2'd0 or 2'd1 */
115
  wire         [2:0]current_frame;                /* current frame */
116
  output       [2:0]output_frame;                 /* frame to be displayed */
117
  output            output_frame_valid;           /* asserted when output_frame valid */
118
  input             output_frame_rd;              /* asserted to read next output_frame */
119
  output            output_progressive_sequence;
120
  output            output_progressive_frame;
121
  output            output_top_field_first;
122
  output            output_repeat_first_field;
123
  output            picbuf_busy;
124
 
125
  /* reading forward reference frame: writing address */
126
  input             fwd_wr_addr_almost_full;
127
  output            fwd_wr_addr_en;
128
  output      [21:0]fwd_wr_addr;
129
 
130
  /* reading backward reference frame: writing address */
131
  input             bwd_wr_addr_almost_full;
132
  output            bwd_wr_addr_en;
133
  output      [21:0]bwd_wr_addr;
134
 
135
  /* writing block reconstruction fifo */
136
  input             dst_wr_almost_full;
137
  output            dst_wr_en;
138
  output            dst_wr_write_recon;
139
  output      [21:0]dst_wr_write_address;
140
  output            dst_wr_motion_forward;
141
  output       [2:0]dst_wr_fwd_hor_offset;
142
  output            dst_wr_fwd_hor_halfpixel;
143
  output            dst_wr_fwd_ver_halfpixel;
144
  output            dst_wr_motion_backward;
145
  output       [2:0]dst_wr_bwd_hor_offset;
146
  output            dst_wr_bwd_hor_halfpixel;
147
  output            dst_wr_bwd_ver_halfpixel;
148
 
149
  /* field/frame dct decoding */
150
  input            dct_block_wr_almost_full;
151
  output      [2:0]dct_block_cmd;
152
  output           dct_block_en;
153
 
154
  /* motvec output */
155
  wire              frame_picture_0;
156
  wire              field_in_frame_0;
157
  wire        [12:0]macroblock_address_0;
158
  wire         [1:0]comp_0;
159
  wire signed [12:0]delta_x_0;
160
  wire signed [12:0]delta_y_0;
161
  wire         [2:0]fwd_src_frame_0;
162
  wire              fwd_src_field_0;
163
  wire signed [12:0]fwd_mv_x_0;
164
  wire signed [12:0]fwd_mv_y_0;
165
  wire              fwd_valid_0;
166
  wire         [2:0]bwd_src_frame_0;
167
  wire              bwd_src_field_0;
168
  wire signed [12:0]bwd_mv_x_0;
169
  wire signed [12:0]bwd_mv_y_0;
170
  wire              bwd_valid_0;
171
  wire         [2:0]recon_dst_frame_0;
172
  wire              recon_dst_field_0;
173
  wire signed [12:0]recon_delta_x_0;
174
  wire signed [12:0]recon_delta_y_0;
175
  wire              write_recon_0;
176
  wire              recon_valid_0;
177
 
178
  /* ripple counter */
179
  reg              column;
180
  reg signed  [3:0]row;
181
  reg signed  [3:0]last_row;
182
  reg         [1:0]block;
183
  reg         [1:0]comp;          /* COMP_Y, COMP_CR or COMP_CB */
184
  reg              mb_end;
185
  reg              motvec_update;
186
  reg              next_column;
187
  reg signed  [3:0]next_row;
188
  reg         [1:0]next_block;
189
  reg         [1:0]next_comp;
190
  reg              next_mb_end;
191
 
192
  /* basic motion compensation state machine  */
193
 
194
  parameter [2:0]
195
    STATE_INIT        = 4'h0,
196
    STATE_READ        = 4'h1,
197
    STATE_UPDATE      = 4'h2,
198
    STATE_MOTVEC      = 4'h3,
199
    STATE_NEXT        = 4'h4;
200
 
201
  reg         [2:0]state;
202
  reg         [2:0]next;
203
 
204
  /* next state logic */
205
  always @*
206
    case (state)
207
      STATE_INIT:         if (~mvec_rd_valid || fwd_wr_addr_almost_full || bwd_wr_addr_almost_full || dst_wr_almost_full || dct_block_wr_almost_full) next = STATE_INIT; // wait until mvec_rd_valid
208
                          else next = STATE_READ;
209
 
210
      STATE_READ:         if (mvec_rd_valid && update_picture_buffers) next = STATE_UPDATE; // update picture buffers
211
                          else if (mvec_rd_valid && motion_vector_valid) next = STATE_MOTVEC; // motion vector valid: process macroblock
212
                          else next = STATE_INIT;
213
 
214
      STATE_MOTVEC:       if (mb_end) next = STATE_NEXT;
215
                          else next = STATE_MOTVEC; // reconstruct pixels from predictions
216
 
217
      STATE_UPDATE:       next = STATE_NEXT; // perform picture buffer update
218
 
219
      STATE_NEXT:         next = STATE_INIT; // wait for clk_en; 
220
 
221
      default             next = STATE_INIT;
222
 
223
    endcase
224
 
225
  /* state */
226
  always @(posedge clk)
227
    if(~rst) state <= STATE_INIT;
228
    else if (clk_en) state <= next;
229
    else  state <= state;
230
 
231
  always @(posedge clk)
232
    if (~rst) mvec_rd_en <= 1'b0;
233
    else if (clk_en && (state == STATE_NEXT)) mvec_rd_en <= 1'b1;
234
    else if (clk_en) mvec_rd_en <= 1'b0;
235
    else mvec_rd_en <= 1'b0;
236
 
237
  always @(posedge clk)
238
    if(~rst) motvec_update <= 1'b0;
239
    else if (clk_en) motvec_update <= (next == STATE_MOTVEC);
240
    else  motvec_update <= motvec_update;
241
 
242
  /*
243
   This represents a "ripple counter" which cycles through all possible component/block/row/column combinations.
244
 
245
     4:2:0
246
     Component   Block      Row    Column
247
         Y       0..3       -1..7   0..1
248
         Cr      0..1       -1..3   0..1
249
         Cb      0..1       -1..3   0..1
250
 
251
    Luminance is reconstructed in blocks of 8x8 pixels.
252
 
253
    For horizontal halfpixel calculations, we need the pixel to the right of the current pixel.
254
    For vertical halfpixel calculations, we need the pixel below the current pixel.
255
    Hence, for reconstructing a 8x8 pixel block we need 9x9 pixels.
256
    As we retrieve pixels from memory 8 at a time, this means we need to retrieve 9x16 pixels from memory.
257
 
258
           | column 0               | column 1
259
    -------|------------------------+------------------------
260
     row -1| 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b0. block: 0..3
261
     row 0 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
262
     row 1 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
263
     row 2 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
264
     row 3 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
265
     row 4 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
266
     row 5 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
267
     row 6 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
268
     row 7 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
269
    -------|------------------------+------------------------
270
 
271
    The first row (16 pixels) is sent to motcomp_recon with dst_wr_write_recon <= 1'b0;
272
    causing recon to just load the row but not to write any reconstructed pixels to memory.
273
    The remaining 8 rows are sent to motcomp_recon with dst_wr_write_recon <= 1'b1.
274
    This causes recon not only to load the row, but also to write the reconstructed pixels to memory.
275
 
276
    For chrominance, reconstruction happens in "blocks" of 8x4 pixels.
277
 
278
           | column 0               | column 1
279
    -------|------------------------+------------------------
280
     row -1| 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b0. block: 0..1
281
     row 0 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
282
     row 1 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
283
     row 2 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
284
     row 3 | 0  1  2  3  4  5  6  7 |  0  1  2  3  4  5  6  7          dst_wr_write_recon <= 1'b1.
285
    -------|------------------------+------------------------
286
 */
287
 
288
  always @(posedge  clk)
289
    if (~rst) last_row <= 4'd0;
290
    else if (clk_en && (state == STATE_INIT)) last_row <= 4'sd7;
291
    else if (clk_en && (state == STATE_MOTVEC) && (comp == COMP_Y)) last_row <= 4'sd7;
292
    else if (clk_en && (state == STATE_MOTVEC)) last_row <= 4'sd3;
293
    else last_row <= last_row;
294
 
295
  always @*
296
    next_column = ~column;
297
 
298
  always @*
299
    if ((row == last_row) && (column == 1'd1)) next_row = -4'sd1;
300
    else if (column == 1'd1) next_row = row + 4'sd1;
301
    else next_row = row;
302
 
303
  always @*
304
    if ((row == last_row) && (column == 1'd1) && (comp == COMP_Y)) next_block = block + 2'd1; // COMP_Y: 0 1 2 3 0
305
    else if ((row == last_row) && (column == 1'd1) && (block == 2'd0)) next_block = block + 2'd1; // COMP_CR/CB: 0 1 0
306
    else if ((row == last_row) && (column == 1'd1)) next_block = 2'd0;
307
    else next_block = block;
308
 
309
  always @*
310
    if ((row == last_row) && (column == 1'd1))
311
      case (comp)
312
        COMP_Y:     if (block == 2'd3) next_comp = COMP_CR;
313
                    else next_comp = COMP_Y;
314
        COMP_CR:    if (block == 2'd1) next_comp = COMP_CB;
315
                    else next_comp = COMP_CR;
316
        COMP_CB:    if (block == 2'd1) next_comp = COMP_Y;
317
                    else next_comp = COMP_CB;
318
        default     next_comp = COMP_Y;
319
      endcase
320
    else next_comp = comp;
321
 
322
  always @*
323
    if ((block == 2'd1) && (row == last_row) && (column == 1'd0) && (next_comp == COMP_CB)) next_mb_end = 1'b1;
324
    else next_mb_end = 1'b0;
325
 
326
  always @(posedge  clk)
327
    if (~rst) column <= 1'b0;
328
    else if (clk_en && (state == STATE_INIT)) column <= 1'b0;
329
    else if (clk_en && (state == STATE_MOTVEC)) column <= next_column;
330
    else column <= column;
331
 
332
  always @(posedge  clk)
333
    if (~rst) row <= -4'sd1;
334
    else if (clk_en && (state == STATE_INIT)) row <= -4'sd1;
335
    else if (clk_en && (state == STATE_MOTVEC)) row <= next_row;
336
    else row <= row;
337
 
338
  always @(posedge  clk)
339
    if (~rst) block <= 2'b0;
340
    else if (clk_en && (state == STATE_INIT)) block <= 2'b0;
341
    else if (clk_en && (state == STATE_MOTVEC)) block <= next_block;
342
    else block <= block;
343
 
344
  always @(posedge  clk)
345
    if (~rst) comp <= COMP_Y;
346
    else if (clk_en && (state == STATE_INIT)) comp <= COMP_Y;
347
    else if (clk_en && (state == STATE_MOTVEC)) comp <= next_comp;
348
    else comp <= comp;
349
 
350
  always @(posedge  clk)
351
    if (~rst) mb_end <= 1'b0;
352
    else if (clk_en && (state == STATE_INIT)) mb_end <= 1'b0;
353
    else if (clk_en && (state == STATE_MOTVEC)) mb_end <= next_mb_end;
354
    else mb_end <= mb_end;
355
 
356
  /* picture buffers */
357
  always @(posedge clk)
358
    if (~rst) do_update_picture_buffers <= 1'b0;
359
    else if (clk_en) do_update_picture_buffers <= (next == STATE_UPDATE);
360
    else do_update_picture_buffers <= do_update_picture_buffers;
361
 
362
  motcomp_picbuf picbuf (
363
    .clk(clk),
364
    .clk_en(clk_en),
365
    .rst(rst),
366
    .source_select(source_select),                           // from regfile
367
    .picture_coding_type(picture_coding_type),
368
    .progressive_sequence(progressive_sequence),             // from vld
369
    .progressive_frame(progressive_frame),                   // from vld
370
    .top_field_first(top_field_first),                       // from vld
371
    .repeat_first_field(repeat_first_field),                 // from vld
372
    .last_frame(last_frame),
373
    .update_picture_buffers(do_update_picture_buffers),
374
    .forward_reference_frame(forward_reference_frame),
375
    .backward_reference_frame(backward_reference_frame),
376
    .current_frame(current_frame),
377
    .output_frame(output_frame),
378
    .output_frame_valid(output_frame_valid),
379
    .output_frame_rd(output_frame_rd),
380
    .output_progressive_sequence(output_progressive_sequence),// to resample
381
    .output_progressive_frame(output_progressive_frame),     // to resample
382
    .output_top_field_first(output_top_field_first),         // to resample
383
    .output_repeat_first_field(output_repeat_first_field),   // to resample
384
    .picbuf_busy(picbuf_busy)
385
    );
386
 
387
  /* motion vector selection */
388
  /*
389
     Note motion vector is not constant for a macroblock.
390
     Some motion types have different motion vectors for the upper two blocks and the lower two blocks.
391
   */
392
  motcomp_motvec motvec (
393
    .clk(clk),
394
    .clk_en(clk_en),
395
    .rst(rst),
396
    /* in */
397
    .picture_coding_type(picture_coding_type),
398
    .picture_structure(picture_structure),
399
    .motion_type(motion_type),
400
    .dct_type(dct_type),
401
    .macroblock_motion_forward(macroblock_motion_forward),
402
    .macroblock_motion_backward(macroblock_motion_backward),
403
    .macroblock_intra(macroblock_intra),
404
    .macroblock_address_in(macroblock_address),
405
    .pmv_0_0_0(pmv_0_0_0),
406
    .pmv_0_0_1(pmv_0_0_1),
407
    .pmv_1_0_0(pmv_1_0_0),
408
    .pmv_1_0_1(pmv_1_0_1),
409
    .pmv_0_1_0(pmv_0_1_0),
410
    .pmv_0_1_1(pmv_0_1_1),
411
    .pmv_1_1_0(pmv_1_1_0),
412
    .pmv_1_1_1(pmv_1_1_1),
413
    .dmv_0_0(dmv_0_0),
414
    .dmv_0_1(dmv_0_1),
415
    .dmv_1_0(dmv_1_0),
416
    .dmv_1_1(dmv_1_1),
417
    .motion_vert_field_select_0_0(motion_vert_field_select_0_0),
418
    .motion_vert_field_select_0_1(motion_vert_field_select_0_1),
419
    .motion_vert_field_select_1_0(motion_vert_field_select_1_0),
420
    .motion_vert_field_select_1_1(motion_vert_field_select_1_1),
421
    .second_field(second_field),
422
    .forward_reference_frame(forward_reference_frame),
423
    .backward_reference_frame(backward_reference_frame),
424
    .current_frame(current_frame),
425
    .column(column),
426
    .row(row),
427
    .block(block),
428
    .comp(comp),
429
    .motvec_update(motvec_update),
430
    /* out */
431
    .frame_picture(frame_picture_0),
432
    .field_in_frame(field_in_frame_0),
433
    .comp_out(comp_0),
434
    .macroblock_address_out(macroblock_address_0),
435
    .delta_x(delta_x_0),
436
    .delta_y(delta_y_0),
437
    .fwd_src_frame(fwd_src_frame_0),
438
    .fwd_src_field(fwd_src_field_0),
439
    .fwd_mv_x(fwd_mv_x_0),
440
    .fwd_mv_y(fwd_mv_y_0),
441
    .fwd_valid(fwd_valid_0),
442
    .bwd_src_frame(bwd_src_frame_0),
443
    .bwd_src_field(bwd_src_field_0),
444
    .bwd_mv_x(bwd_mv_x_0),
445
    .bwd_mv_y(bwd_mv_y_0),
446
    .bwd_valid(bwd_valid_0),
447
    .write_recon(write_recon_0),
448
    .recon_delta_x(recon_delta_x_0),
449
    .recon_delta_y(recon_delta_y_0),
450
    .recon_valid(recon_valid_0),
451
    .recon_dst_frame(recon_dst_frame_0),
452
    .recon_dst_field(recon_dst_field_0),
453
    .dct_block_cmd(dct_block_cmd),
454
    .dct_block_en(dct_block_en)
455
    );
456
 
457
  /* forward */
458
  memory_address
459
    #(.dta_width(1))
460
    fwd_mem_addr (
461
    .clk(clk),
462
    .clk_en(clk_en),
463
    .rst(rst),
464
    /* in */
465
    .frame(fwd_src_frame_0),
466
    .frame_picture(frame_picture_0),
467
    .field_in_frame(field_in_frame_0),
468
    .field(fwd_src_field_0),
469
    .component(comp_0),
470
    .mb_width(mb_width),
471
    .horizontal_size(horizontal_size),
472
    .vertical_size(vertical_size),
473
    .macroblock_address(macroblock_address_0),
474
    .delta_x(delta_x_0),
475
    .delta_y(delta_y_0),
476
    .mv_x(fwd_mv_x_0),
477
    .mv_y(fwd_mv_y_0),
478
    .dta_in(1'b0),
479
    .valid_in(fwd_valid_0),
480
    /* out */
481
    .address(fwd_wr_addr),
482
    .offset_x(dst_wr_fwd_hor_offset),
483
    .halfpixel_x(dst_wr_fwd_hor_halfpixel),
484
    .halfpixel_y(dst_wr_fwd_ver_halfpixel),
485
    .dta_out(),
486
    .valid_out(fwd_wr_addr_en)
487
    );
488
 
489
  /* backward */
490
  memory_address
491
    #(.dta_width(1))
492
    bwd_mem_addr (
493
    .clk(clk),
494
    .clk_en(clk_en),
495
    .rst(rst),
496
    /* in */
497
    .frame(bwd_src_frame_0),
498
    .frame_picture(frame_picture_0),
499
    .field_in_frame(field_in_frame_0),
500
    .field(bwd_src_field_0),
501
    .component(comp_0),
502
    .mb_width(mb_width),
503
    .horizontal_size(horizontal_size),
504
    .vertical_size(vertical_size),
505
    .macroblock_address(macroblock_address_0),
506
    .delta_x(delta_x_0),
507
    .delta_y(delta_y_0),
508
    .mv_x(bwd_mv_x_0),
509
    .mv_y(bwd_mv_y_0),
510
    .dta_in(1'b0),
511
    .valid_in(bwd_valid_0),
512
    /* out */
513
    .address(bwd_wr_addr),
514
    .offset_x(dst_wr_bwd_hor_offset),
515
    .halfpixel_x(dst_wr_bwd_hor_halfpixel),
516
    .halfpixel_y(dst_wr_bwd_ver_halfpixel),
517
    .dta_out(),
518
    .valid_out(bwd_wr_addr_en)
519
    );
520
 
521
  /* reconstruction */
522
  memory_address
523
    #(.dta_width(3))
524
    recon_mem_addr (
525
    .clk(clk),
526
    .clk_en(clk_en),
527
    .rst(rst),
528
    /* in */
529
    .frame(recon_dst_frame_0),
530
    .frame_picture(frame_picture_0),
531
    .field_in_frame(field_in_frame_0),
532
    .field(recon_dst_field_0),
533
    .component(comp_0),
534
    .mb_width(mb_width),
535
    .horizontal_size(horizontal_size),
536
    .vertical_size(vertical_size),
537
    .macroblock_address(macroblock_address_0),
538
    .delta_x(recon_delta_x_0),
539
    .delta_y(recon_delta_y_0),
540
    .mv_x(13'sd0),
541
    .mv_y(13'sd0),
542
    .dta_in({fwd_valid_0, bwd_valid_0, write_recon_0}),
543
    .valid_in(recon_valid_0),
544
    /* out */
545
    .address(dst_wr_write_address),
546
    .offset_x(),
547
    .halfpixel_x(),
548
    .halfpixel_y(),
549
    .dta_out({dst_wr_motion_forward, dst_wr_motion_backward, dst_wr_write_recon}),
550
    .valid_out(dst_wr_en)
551
    );
552
 
553
`ifdef DEBUG
554
  /* debugging */
555
 
556
  always @(posedge clk)
557
    if (clk_en && (state == STATE_READ) && motion_vector_valid)
558
      begin
559
        case (chroma_format)
560
          CHROMA420:     #0 $display("%m         CHROMA420");
561
          CHROMA422:     #0 $display("%m         CHROMA422");
562
          CHROMA444:     #0 $display("%m         CHROMA444");
563
          default        #0 $display("%m         chroma_format %h", chroma_format);
564
        endcase
565
        case (picture_coding_type)
566
          P_TYPE:        #0 $display("%m         P_TYPE");
567
          I_TYPE:        #0 $display("%m         I_TYPE");
568
          B_TYPE:        #0 $display("%m         B_TYPE");
569
          D_TYPE:        #0 $display("%m         D_TYPE"); // mpeg1 only; mpeg2 does not have D pictures
570
        endcase
571
        case (picture_structure)
572
          FRAME_PICTURE: #0 $display("%m         FRAME_PICTURE");
573
          TOP_FIELD:     #0 $display("%m         TOP_FIELD");
574
          BOTTOM_FIELD:  #0 $display("%m         BOTTOM_FIELD");
575
          default        #0 $display("%m         picture_structure %h", picture_structure);
576
        endcase
577
 
578
        /*
579
           MC_FRAME and MC_16X8 share the same code; which one is used depends upon picture_structure.
580
           In a FRAME_PICTURE you can have MC_FRAME, but never MC_16X8.
581
           In a field picture (TOP_FIELD, BOTTOM_FIELD) you can have MC_16X8, but never MC_FRAME.
582
         */
583
        case (picture_structure)
584
          FRAME_PICTURE:
585
            case (motion_type)
586
              MC_FIELD:      #0 $display("%m         MC_FIELD");
587
              MC_FRAME:      #0 $display("%m         MC_FRAME");
588
              MC_DMV:        #0 $display("%m         MC_DMV");
589
              MC_NONE:       #0 $display("%m         MC_NONE");
590
              default        #0 $display("%m         *** unknown motion_type %h ***", motion_type);
591
            endcase
592
          TOP_FIELD,
593
          BOTTOM_FIELD:
594
            case (motion_type)
595
              MC_FIELD:      #0 $display("%m         MC_FIELD");
596
              MC_16X8:       #0 $display("%m         MC_16X8");
597
              MC_DMV:        #0 $display("%m         MC_DMV");
598
              MC_NONE:       #0 $display("%m         MC_NONE");
599
              default        #0 $display("%m         *** unknown motion_type %h ***", motion_type);
600
            endcase
601
        endcase
602
        #0 $display("%m         macroblock_address: %d", macroblock_address);
603
        if (macroblock_intra)           #0 $display("%m         macroblock_intra");
604
        if (macroblock_motion_forward && macroblock_motion_backward)  #0 $display("%m         macroblock_motion_forward, macroblock_motion_backward");
605
        else if (macroblock_motion_forward)  #0 $display("%m         macroblock_motion_forward");
606
        else if (macroblock_motion_backward) #0 $display("%m         macroblock_motion_backward");
607
        else #0 $display("%m         no macroblock_motion_forward, no macroblock_motion_backward");
608
        if (dct_type) #0 $display("%m         dct_type field");
609
        else #0 $display("%m         dct_type frame");
610
        #0 $display("%m\tpmv_0_0_0: %d pmv_0_0_1: %d pmv_1_0_0: %d pmv_1_0_1: %d pmv_0_1_0: %d pmv_0_1_1: %d pmv_1_1_0: %d pmv_1_1_1: %d", pmv_0_0_0, pmv_0_0_1, pmv_1_0_0, pmv_1_0_1, pmv_0_1_0, pmv_0_1_1, pmv_1_1_0, pmv_1_1_1);
611
        #0 $display("%m\tdmv_0_0: %d dmv_0_1: %d dmv_1_0: %d dmv_1_1: %d", dmv_0_0, dmv_0_1, dmv_1_0, dmv_1_1);
612
        #0 $display("%m\tmotion_vert_field_select_0_0: %d motion_vert_field_select_0_1: %d motion_vert_field_select_1_0: %d motion_vert_field_select_1_1: %d", motion_vert_field_select_0_0, motion_vert_field_select_0_1, motion_vert_field_select_1_0, motion_vert_field_select_1_1);
613
      end
614
 
615
  always @(posedge clk)
616
    if (clk_en && (state == STATE_READ) && update_picture_buffers)
617
      begin
618
        #0 $display("%m\tupdate picture buffers");
619
      end
620
 
621
  always @(posedge clk)
622
    if (clk_en)
623
      case (state)
624
        STATE_INIT:                               #0 $display("%m         STATE_INIT");
625
        STATE_READ:                               #0 $display("%m         STATE_READ");
626
        STATE_UPDATE:                             #0 $display("%m         STATE_UPDATE");
627
        STATE_MOTVEC:                             #0 $display("%m         STATE_MOTVEC");
628
        STATE_NEXT:                               #0 $display("%m         STATE_NEXT");
629
        default                                   #0 $display("%m         *** Error: unknown state %d", state);
630
      endcase
631
 
632
  always @(posedge clk)
633
    begin
634
      $strobe("%m\tclk_en: %d mvec_rd_en: %d mvec_rd_valid: %d", clk_en, mvec_rd_en, mvec_rd_valid);
635
      $strobe("%m\tclk_en: %d mb_end: %d last_row: %d comp: %d block: %d row: %d col:%d motvec_update: %d", clk_en, mb_end, last_row, comp, block, row, column, motvec_update);
636
 
637
      $strobe("%m\tclk_en: %d fwd_src_frame_0: %d frame_picture_0: %d field_in_frame_0: %d fwd_src_field_0: %d comp_0: %d macroblock_address_0: %d delta_x_0: %d delta_y_0: %d fwd_mv_x_0: %d fwd_mv_y_0: %d fwd_valid_0: %d",
638
                   clk_en, fwd_src_frame_0, frame_picture_0, field_in_frame_0, fwd_src_field_0, comp_0, macroblock_address_0, delta_x_0, delta_y_0, fwd_mv_x_0, fwd_mv_y_0, fwd_valid_0);
639
 
640
      $strobe("%m\tclk_en: %d bwd_src_frame_0: %d frame_picture_0: %d field_in_frame_0: %d bwd_src_field_0: %d comp_0: %d macroblock_address_0: %d delta_x_0: %d delta_y_0: %d bwd_mv_x_0: %d bwd_mv_y_0: %d bwd_valid_0: %d",
641
                   clk_en, bwd_src_frame_0, frame_picture_0, field_in_frame_0, bwd_src_field_0, comp_0, macroblock_address_0, delta_x_0, delta_y_0, bwd_mv_x_0, bwd_mv_y_0, bwd_valid_0);
642
 
643
      $strobe("%m\tclk_en: %d recon_dst_frame_0: %d frame_picture_0: %d field_in_frame_0: %d recon_dst_field_0: %d comp_0: %d macroblock_address_0: %d recon_delta_x_0: %d recon_delta_y_0: %d recon_valid_0: %d write_recon_0: %d",
644
                   clk_en, recon_dst_frame_0, frame_picture_0, field_in_frame_0, recon_dst_field_0, comp_0, macroblock_address_0, recon_delta_x_0, recon_delta_y_0, recon_valid_0, write_recon_0);
645
      $strobe("%m\tclk_en: %d dst_wr_en: %d dst_wr_write_recon: %d dst_wr_write_address: %h dst_wr_motion_forward: %d dst_wr_motion_backward: %d ",
646
                   clk_en, dst_wr_en, dst_wr_write_recon, dst_wr_write_address, dst_wr_motion_forward, dst_wr_motion_backward);
647
      $strobe("%m\tclk_en: %d dst_wr_en: %d dst_wr_fwd_hor_offset: %d dst_wr_fwd_hor_halfpixel: %d dst_wr_fwd_ver_halfpixel: %d dst_wr_bwd_hor_offset: %d dst_wr_bwd_hor_halfpixel: %d dst_wr_bwd_ver_halfpixel: %d",
648
                   clk_en, dst_wr_en, dst_wr_fwd_hor_offset, dst_wr_fwd_hor_halfpixel, dst_wr_fwd_ver_halfpixel, dst_wr_bwd_hor_offset, dst_wr_bwd_hor_halfpixel, dst_wr_bwd_ver_halfpixel);
649
 
650
      $strobe("%m\tclk_en: %d dct_block_cmd: %d dct_block_en: %d",
651
                   clk_en, dct_block_cmd, dct_block_en);
652
    end
653
 
654
`endif
655
 
656
endmodule
657
/* not truncated */

powered by: WebSVN 2.1.0

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