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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * motcomp_recon.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
 * motcomp_recon.v - Motion Compensation: pixel reconstruction.
21
 */
22
 
23
`include "timescale.v"
24
 
25
`undef DEBUG
26
//`define DEBUG 1
27
 
28
 /*
29
  Block reconstruction summary:
30
   - read work to be done from dst fifo.
31
   - combine forward prediction (fwd_rd_dta) and backward prediction (bwd_rd_dta) (p[y][x] in Figure 7-5)
32
   - add idct coefficients (f[y][x] in Figure 7-5)
33
   - clip and saturate to 0..255 range
34
   - write reconstructed pixels to frame store (recon_wr_dta, recon_wr_addr)
35
 
36
  Can produce one 8-pixel row every two clock cycles. In practice this means speed is limited by how fast
37
  the memory subsystem can feed it with pixels.
38
 
39
  In detail:
40
   - from dst fifo, read work to be done. This includes write_address_0, the address where the reconstructed pixels have to be written
41
     if write_recon_0 is high.
42
 
43
   - Compute forward prediction: (prediction_fwd_row)
44
     if motion_forward_0 is high, read  a row of 16 pixels from forward motion compensation data fifo (fwd_row_0).
45
     Shift the double row left by fwd_hor_offset_0 pixels.
46
     If fwd_hor_halfpixel_0, do linear interpolation between two adjacent pixels on same horizontal.
47
     If fwd_ver_halfpixel_0, do linear interpolation between two adjacent pixels on fwd_row_0 and the previous row, prev_fwd_2.
48
 
49
     If motion_forward_0 is low, forward prediction is not used (is zero).
50
 
51
   - Compute forward prediction: (prediction_bwd_row)
52
     if motion_backward_0 is high, read  a row of 16 pixels from backward motion compensation data fifo (bwd_row_0).
53
     Shift the double row left by bwd_hor_offset_0 pixels.
54
     If bwd_hor_halfpixel_0, do linear interpolation between two adjacent pixels on same horizontal.
55
     If bwd_ver_halfpixel_0, do linear interpolation between two adjacent pixels on bwd_row_0 and the previous row, prev_bwd_2.
56
 
57
     If motion_backward_0 is low, backward prediction is not used (is zero).
58
 
59
   - Obtain idct coefficients
60
     - If write_recon_0 is high, read  a row of eight idct coefficients from idct_row_0.
61
     - If write_recon_0 is low, idct coefficients are not used.
62
 
63
   - Combine predictions (combine_row)
64
     - If motion_forward_0 is asserted but motion_backward_0 is not asserted, prediction is forward prediction.
65
     - If motion_backward_0 is asserted but motion_forward_0 is not asserted, prediction is backward prediction.
66
     - If both motion_forward_0 and motion_backward_0 are asserted, prediction is the average of forward and backward prediction.
67
     - If neither motion_forward_0 nor motion_backward_0 are asserted, prediction is all zeroes.
68
     - add idct coefficients to the prediction.
69
     - clip and saturate each pixel to 0..255 range.
70
     This produces the reconstructed block row.
71
 
72
   - If write_recon_0 is high, write the reconstructed block row to frame store at address write_address_0.
73
     If write_recon_0 is low, no action is taken.
74
 
75
  Use of write_recon_0:
76
     In vertical halfpixel calculations we need the value of the pixels above the current pixel (the previous row)
77
     to do vertical interpolation. By setting write_recon_0 low, the fwd/bwd pixels of the first row are loaded into the appropriate
78
     registers, but do not produce a write to the frame store. A write would be inappropriate: since it's the first row,
79
     there's no previous row and vertical halfpixel calculations would fail.
80
 
81
     As an example, consider motion compensation of an 8x8 block. dst_rd_write_recon is low during the first row of fwd/bwd pixels,
82
     and high during the eight following rows. Then comes the next 8x8 block: again dst_rd_write_recon is low during the first row,
83
     and high during the next eight rows.
84
 
85
  Note motcomp_recon reconstructs a row of 8 pixels in parallel.
86
 
87
  The pixels are stored in the frame store as signed 8-bit values, with values between -128 and 127.
88
  One can obtain the unsigned pixel values by adding 128.
89
  Thus, -128 corresponding to 0 and 127 corresponding to 255.
90
  Storing the pixels as signed 8-bit values has the advantage that one can average two frames without the dc level going up.
91
  The 128 gets added at the end, in the yuv to rgb conversion.
92
  */
93
 
94
module motcomp_recon(
95
  clk, clk_en, rst,
96
  dst_rd_dta_empty, dst_rd_dta_en, dst_rd_dta, dst_rd_dta_valid,
97
  idct_rd_dta_empty, idct_rd_dta_en, idct_rd_dta, idct_rd_dta_valid,
98
  fwd_rd_dta_empty, fwd_rd_dta_en, fwd_rd_dta, fwd_rd_dta_valid,
99
  bwd_rd_dta_empty, bwd_rd_dta_en, bwd_rd_dta, bwd_rd_dta_valid,
100
  recon_wr_full, recon_wr_almost_full, recon_wr_en, recon_wr_addr, recon_wr_dta
101
  );
102
 
103
  input              clk;                      // clock
104
  input              clk_en;                   // clock enable
105
  input              rst;                      // synchronous active low reset
106
 
107
  /* reading block address and recon parameters */
108
  input             dst_rd_dta_empty;          // low if dst fifo is not empty
109
  input             dst_rd_dta_valid;          // high if dst fifo read successful
110
  output            dst_rd_dta_en;             // assert to read dst fifo
111
  input       [34:0]dst_rd_dta;                // reconstruction parameters: address to write reconstructed block row to, whether to use forward or backward motion compensation, ...
112
 
113
  /* reading idct data */
114
  input       [71:0]idct_rd_dta;               // fifo of idct coefficients. Each idct_rd_dta is a row of 8 idct coefficients. Each idct coefficient is 9-bit signed.
115
  output            idct_rd_dta_en;            // assert to read next idct coefficients
116
  input             idct_rd_dta_empty;         // low if idct_rd_dta fifo not empty
117
  input             idct_rd_dta_valid;         // asserted if idct_rd_dta valid
118
 
119
  /* reading forward reference frame: reading data */
120
  input             fwd_rd_dta_empty;          // low if fwd_rd_dta fifo not empty
121
  output            fwd_rd_dta_en;             // assert to read next fwd_rd_dta
122
  input       [63:0]fwd_rd_dta;                // fifo of forward block rows
123
  input             fwd_rd_dta_valid;
124
 
125
  /* reading backward reference frame: reading data */
126
  input             bwd_rd_dta_empty;          // low if bwd_rd_dta fifo not empty
127
  output            bwd_rd_dta_en;             // assert to read next bwd_rd_dta
128
  input       [63:0]bwd_rd_dta;                // fifo of backward block rows
129
  input             bwd_rd_dta_valid;
130
 
131
  /* writing reconstructed frame: writing address and data */
132
  input             recon_wr_full;             // high if recon_wr_dta/recon_wr_addr fifo full.
133
  input             recon_wr_almost_full;      // high if recon_wr_dta/recon_wr_addr fifo is almost full (8 free slots left) XXX
134
  output reg        recon_wr_en;               // assert to write recon_wr_addr/recon_wr_dta to fifo.
135
  output reg  [21:0]recon_wr_addr;             // address to write reconstructed block row to
136
  output reg  [63:0]recon_wr_dta;              // reconstructed block row
137
 
138
  /*
139
   To reconstruct a row
140
    - if dst_rd_motion_forward is asserted, fwd_rd_dta_empty should be low: forward prediction data is needed (~fwd_rd_dta_empty)
141
    - if dst_rd_motion_backward is asserted, bwd_rd_dta_empty should be low: backward prediction data is needed (~bwd_rd_dta_empty)
142
    - idct_rd_dta_empty is not asserted: eight idct coefficients are available in the fifo pipeline. (~idct_rd_dta_empty)
143
      (For skipped macroblocks and uncoded blocks , the inverse discrete cosine transform data are all zeroes.)
144
    - recon_wr_full is not asserted: there is room to write the reconstructed block row.
145
   */
146
 
147
  parameter [1:0]
148
    STATE_WAIT       = 3'b001, // wait for data ready
149
    STATE_RUN        = 3'b010; // start pipeline and read next data
150
 
151
  reg           [1:0]state;
152
  reg           [1:0]next;
153
 
154
  /* stage 0 variables */
155
  reg                dst_rd_en;
156
  wire               dst_valid_0;
157
 
158
  wire               valid_0;
159
  wire        [127:0]fwd_row_0; // one row of 16 pixels, each pixel an 8 bit unsigned reg. 
160
  wire               fwd_row_0_valid;
161
  reg                fwd_row_0_rd_en;
162
  wire        [127:0]bwd_row_0; // one row of 16 pixels, each pixel an 8 bit unsigned reg.
163
  wire               bwd_row_0_valid;
164
  reg                bwd_row_0_rd_en;
165
  wire         [71:0]idct_row_0; // one row of 8 idct coefficients; each idct coefficient a 9 bit signed reg.
166
  wire               idct_row_0_valid;
167
  reg                idct_row_0_rd_en;
168
  wire               write_recon_0;
169
  wire         [21:0]write_address_0;
170
  wire               motion_forward_0;
171
  wire          [2:0]fwd_hor_offset_0;
172
  wire               fwd_hor_halfpixel_0;
173
  wire               fwd_ver_halfpixel_0;
174
  wire               motion_backward_0;
175
  wire          [2:0]bwd_hor_offset_0;
176
  wire               bwd_hor_halfpixel_0;
177
  wire               bwd_ver_halfpixel_0;
178
 
179
  /* next state */
180
 
181
  always @*
182
    case (state)
183
                     /*
184
                      * If recon_wr_almost_full is low, we're sure there will be enough room in the reconstruction fifo to write the reconstructed pixels and their address,
185
                      * If recon_wr_almost_full is high, wait until the framestore has written reconstruction write requests already in the queue.
186
                      *
187
                      * If dst_valid_0 is low, we have no work to do. Wait.
188
                      */
189
      STATE_WAIT:    if (recon_wr_almost_full || ~dst_valid_0) next = STATE_WAIT;
190
                     /*
191
                      * If write_recon_0 is high, the reconstructed pixels will be written to write_address_0.
192
                      * Reconstructing the pixels will need the idct values, hence idct_row_0_valid has to be high.
193
                      * If write_recon_0 is low, the reconstructed pixels are thrown away. We just want to load values in prev_fwd_row_0 and prev_bwd_row_0.
194
                      * As the reconstructed pixels are thrown away, there's no need for idct_row_0_valid to be high.
195
                      *
196
                      * If motion_forward_0 is high, we will use forward motion compensation, and fwd_row_0_valid has to be high.
197
                      *
198
                      * If motion_backward_0 is high, we will use backward motion compensation, and bwd_row_0_valid has to be high.
199
                      */
200
                     else if ((~write_recon_0 || idct_row_0_valid) && (~motion_forward_0 || fwd_row_0_valid) && (~motion_backward_0 || bwd_row_0_valid)) next = STATE_RUN;
201
                     else next = STATE_WAIT;
202
      STATE_RUN:     next = STATE_WAIT;
203
      default        next = STATE_WAIT;
204
    endcase
205
 
206
  always @(posedge clk)
207
    if (~rst) state <= STATE_WAIT;
208
    else if (clk_en) state <= next;
209
    else state <= state;
210
 
211
  /* fifo read enables */
212
  always @(posedge clk)
213
    if (~rst) dst_rd_en <= 1'b0;
214
    else if (clk_en) dst_rd_en <= (next == STATE_RUN);
215
    else dst_rd_en <= dst_rd_en;
216
 
217
  always @(posedge clk)
218
    if (~rst) idct_row_0_rd_en <= 1'b0;
219
    // If reconstructed pixels are written to the framestore, read next idct values.
220
    else if (clk_en) idct_row_0_rd_en <= write_recon_0 && (next == STATE_RUN);
221
    else idct_row_0_rd_en <= idct_row_0_rd_en;
222
 
223
  always @(posedge clk)
224
    if (~rst) fwd_row_0_rd_en <= 1'b0;
225
    // If we used forward motion compensation, read next row of forward motion compensation pixels.
226
    else if (clk_en) fwd_row_0_rd_en <= motion_forward_0 && (next == STATE_RUN);
227
    else fwd_row_0_rd_en <= fwd_row_0_rd_en;
228
 
229
  always @(posedge clk)
230
    if (~rst) bwd_row_0_rd_en <= 1'b0;
231
    // If we used backward motion compensation, read next row of backward motion compensation pixels.
232
    else if (clk_en) bwd_row_0_rd_en <= motion_backward_0 && (next == STATE_RUN);
233
    else bwd_row_0_rd_en <= bwd_row_0_rd_en;
234
 
235
  /* stage 0 */
236
  assign valid_0 = dst_rd_en;
237
 
238
  fwft_reader #(.dta_width(9'd35)) dst_fwft_reader (
239
    .rst(rst),
240
    .clk(clk),
241
    .clk_en(clk_en),
242
    .fifo_rd_en(dst_rd_dta_en),
243
    .fifo_valid(dst_rd_dta_valid),
244
    .fifo_dout(dst_rd_dta),
245
    .valid(dst_valid_0),
246
    .dout({write_recon_0, write_address_0, motion_forward_0, fwd_hor_offset_0, fwd_hor_halfpixel_0, fwd_ver_halfpixel_0, motion_backward_0, bwd_hor_offset_0, bwd_hor_halfpixel_0, bwd_ver_halfpixel_0}),
247
    .rd_en(dst_rd_en)
248
    );
249
 
250
  fwft_reader #(.dta_width(9'd72)) idct_fwft_reader (
251
    .rst(rst),
252
    .clk(clk),
253
    .clk_en(clk_en),
254
    .fifo_rd_en(idct_rd_dta_en),
255
    .fifo_valid(idct_rd_dta_valid),
256
    .fifo_dout(idct_rd_dta),
257
    .valid(idct_row_0_valid),
258
    .dout(idct_row_0),
259
    .rd_en(idct_row_0_rd_en)
260
    );
261
 
262
  fwft2_reader #(.dta_width(9'd64)) fwd_fwft2_reader (
263
    .rst(rst),
264
    .clk(clk),
265
    .clk_en(clk_en),
266
    .fifo_rd_en(fwd_rd_dta_en),
267
    .fifo_valid(fwd_rd_dta_valid),
268
    .fifo_dout(fwd_rd_dta),
269
    .valid(fwd_row_0_valid),
270
    .dout(fwd_row_0),
271
    .rd_en(fwd_row_0_rd_en)
272
    );
273
 
274
  fwft2_reader #(.dta_width(9'd64)) bwd_fwft2_reader (
275
    .rst(rst),
276
    .clk(clk),
277
    .clk_en(clk_en),
278
    .fifo_rd_en(bwd_rd_dta_en),
279
    .fifo_valid(bwd_rd_dta_valid),
280
    .fifo_dout(bwd_rd_dta),
281
    .valid(bwd_row_0_valid),
282
    .dout(bwd_row_0),
283
    .rd_en(bwd_row_0_rd_en)
284
    );
285
 
286
  /* horizontal offset, including horizontal halfpixel */
287
  wire               valid_2;
288
  wire               write_recon_2;
289
  wire         [71:0]idct_row_2;
290
  wire         [21:0]write_address_2;
291
  wire               motion_forward_2;
292
  wire               fwd_hor_halfpixel_2;
293
  wire               fwd_ver_halfpixel_2;
294
  wire               motion_backward_2;
295
  wire               bwd_hor_halfpixel_2;
296
  wire               bwd_ver_halfpixel_2;
297
 
298
  wire signed   [7:0]fwd_2_pixel_0;
299
  wire signed   [7:0]fwd_2_pixel_1;
300
  wire signed   [7:0]fwd_2_pixel_2;
301
  wire signed   [7:0]fwd_2_pixel_3;
302
  wire signed   [7:0]fwd_2_pixel_4;
303
  wire signed   [7:0]fwd_2_pixel_5;
304
  wire signed   [7:0]fwd_2_pixel_6;
305
  wire signed   [7:0]fwd_2_pixel_7;
306
  wire signed   [7:0]fwd_2_pixel_8;
307
 
308
  wire signed   [7:0]bwd_2_pixel_0;
309
  wire signed   [7:0]bwd_2_pixel_1;
310
  wire signed   [7:0]bwd_2_pixel_2;
311
  wire signed   [7:0]bwd_2_pixel_3;
312
  wire signed   [7:0]bwd_2_pixel_4;
313
  wire signed   [7:0]bwd_2_pixel_5;
314
  wire signed   [7:0]bwd_2_pixel_6;
315
  wire signed   [7:0]bwd_2_pixel_7;
316
  wire signed   [7:0]bwd_2_pixel_8;
317
 
318
  wire signed   [8:0]idct_2_pixel_0;
319
  wire signed   [8:0]idct_2_pixel_1;
320
  wire signed   [8:0]idct_2_pixel_2;
321
  wire signed   [8:0]idct_2_pixel_3;
322
  wire signed   [8:0]idct_2_pixel_4;
323
  wire signed   [8:0]idct_2_pixel_5;
324
  wire signed   [8:0]idct_2_pixel_6;
325
  wire signed   [8:0]idct_2_pixel_7;
326
 
327
  assign {idct_2_pixel_0, idct_2_pixel_1, idct_2_pixel_2, idct_2_pixel_3, idct_2_pixel_4, idct_2_pixel_5, idct_2_pixel_6, idct_2_pixel_7} = idct_row_2;
328
 
329
  wire signed   [7:0]prev_fwd_2_pixel_0;
330
  wire signed   [7:0]prev_fwd_2_pixel_1;
331
  wire signed   [7:0]prev_fwd_2_pixel_2;
332
  wire signed   [7:0]prev_fwd_2_pixel_3;
333
  wire signed   [7:0]prev_fwd_2_pixel_4;
334
  wire signed   [7:0]prev_fwd_2_pixel_5;
335
  wire signed   [7:0]prev_fwd_2_pixel_6;
336
  wire signed   [7:0]prev_fwd_2_pixel_7;
337
  wire signed   [7:0]prev_fwd_2_pixel_8;
338
 
339
  wire signed   [7:0]prev_bwd_2_pixel_0;
340
  wire signed   [7:0]prev_bwd_2_pixel_1;
341
  wire signed   [7:0]prev_bwd_2_pixel_2;
342
  wire signed   [7:0]prev_bwd_2_pixel_3;
343
  wire signed   [7:0]prev_bwd_2_pixel_4;
344
  wire signed   [7:0]prev_bwd_2_pixel_5;
345
  wire signed   [7:0]prev_bwd_2_pixel_6;
346
  wire signed   [7:0]prev_bwd_2_pixel_7;
347
  wire signed   [7:0]prev_bwd_2_pixel_8;
348
 
349
  reg [71:0]prev_fwd_2;
350
 
351
  assign {prev_fwd_2_pixel_0, prev_fwd_2_pixel_1, prev_fwd_2_pixel_2, prev_fwd_2_pixel_3, prev_fwd_2_pixel_4,
352
          prev_fwd_2_pixel_5, prev_fwd_2_pixel_6, prev_fwd_2_pixel_7, prev_fwd_2_pixel_8} = prev_fwd_2;
353
 
354
  always @(posedge clk)
355
    if (~rst) prev_fwd_2 <= 72'b0;
356
    else if (clk_en && valid_2) prev_fwd_2 <= {fwd_2_pixel_0, fwd_2_pixel_1, fwd_2_pixel_2, fwd_2_pixel_3, fwd_2_pixel_4, fwd_2_pixel_5, fwd_2_pixel_6, fwd_2_pixel_7, fwd_2_pixel_8};
357
    else prev_fwd_2 <= prev_fwd_2;
358
 
359
  reg [71:0]prev_bwd_2;
360
 
361
  assign {prev_bwd_2_pixel_0, prev_bwd_2_pixel_1, prev_bwd_2_pixel_2, prev_bwd_2_pixel_3, prev_bwd_2_pixel_4,
362
          prev_bwd_2_pixel_5, prev_bwd_2_pixel_6, prev_bwd_2_pixel_7, prev_bwd_2_pixel_8} = prev_bwd_2;
363
 
364
  always @(posedge clk)
365
    if (~rst) prev_bwd_2 <= 72'b0;
366
    else if (clk_en && valid_2) prev_bwd_2 <= {bwd_2_pixel_0, bwd_2_pixel_1, bwd_2_pixel_2, bwd_2_pixel_3, bwd_2_pixel_4, bwd_2_pixel_5, bwd_2_pixel_6, bwd_2_pixel_7, bwd_2_pixel_8};
367
    else prev_bwd_2 <= prev_bwd_2;
368
 
369
  prediction_horizontal_offset #(.dta_width(8'd101)) prediction_fwd_row (
370
    .rst(rst),
371
    .clk(clk),
372
    .clk_en(clk_en),
373
    .valid_in(valid_0),
374
    .row_in(fwd_row_0),
375
    .motion_compensation_in(motion_forward_0),
376
    .hor_offset_in(fwd_hor_offset_0),
377
    .dta_in({write_recon_0, idct_row_0, write_address_0, motion_forward_0, fwd_hor_halfpixel_0, fwd_ver_halfpixel_0, motion_backward_0, bwd_hor_halfpixel_0, bwd_ver_halfpixel_0}),
378
    .valid_out(valid_2),
379
    .pixel_0_out(fwd_2_pixel_0),
380
    .pixel_1_out(fwd_2_pixel_1),
381
    .pixel_2_out(fwd_2_pixel_2),
382
    .pixel_3_out(fwd_2_pixel_3),
383
    .pixel_4_out(fwd_2_pixel_4),
384
    .pixel_5_out(fwd_2_pixel_5),
385
    .pixel_6_out(fwd_2_pixel_6),
386
    .pixel_7_out(fwd_2_pixel_7),
387
    .pixel_8_out(fwd_2_pixel_8),
388
    .dta_out({write_recon_2, idct_row_2, write_address_2, motion_forward_2, fwd_hor_halfpixel_2, fwd_ver_halfpixel_2, motion_backward_2, bwd_hor_halfpixel_2, bwd_ver_halfpixel_2})
389
    );
390
 
391
  prediction_horizontal_offset #(.dta_width(8'd1)) prediction_bwd_row (
392
    .rst(rst),
393
    .clk(clk),
394
    .clk_en(clk_en),
395
    .valid_in(valid_0),
396
    .row_in(bwd_row_0),
397
    .motion_compensation_in(motion_backward_0),
398
    .hor_offset_in(bwd_hor_offset_0),
399
    .dta_in(1'b0),
400
    .valid_out(),
401
    .pixel_0_out(bwd_2_pixel_0),
402
    .pixel_1_out(bwd_2_pixel_1),
403
    .pixel_2_out(bwd_2_pixel_2),
404
    .pixel_3_out(bwd_2_pixel_3),
405
    .pixel_4_out(bwd_2_pixel_4),
406
    .pixel_5_out(bwd_2_pixel_5),
407
    .pixel_6_out(bwd_2_pixel_6),
408
    .pixel_7_out(bwd_2_pixel_7),
409
    .pixel_8_out(bwd_2_pixel_8),
410
    .dta_out()
411
    );
412
 
413
  /* vertical halfpixel, and prediction error */
414
 
415
  wire               valid_out;
416
  wire               write_recon_out;
417
  wire         [21:0]write_address_out;
418
  wire          [7:0]pixel_out_0;
419
  wire          [7:0]pixel_out_1;
420
  wire          [7:0]pixel_out_2;
421
  wire          [7:0]pixel_out_3;
422
  wire          [7:0]pixel_out_4;
423
  wire          [7:0]pixel_out_5;
424
  wire          [7:0]pixel_out_6;
425
  wire          [7:0]pixel_out_7;
426
 
427
  combine_predictions combine_predictions_0 (
428
    .rst(rst),
429
    .clk(clk),
430
    .clk_en(clk_en),
431
    .valid_in(valid_2),
432
    .write_recon_in(write_recon_2),
433
    .write_address_in(write_address_2),
434
    .motion_forward_in(motion_forward_2),
435
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
436
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
437
    .motion_backward_in(motion_backward_2),
438
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
439
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
440
    .fwd_left_pixel_in(fwd_2_pixel_0),
441
    .fwd_rght_pixel_in(fwd_2_pixel_1),
442
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_0),
443
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_1),
444
    .bwd_left_pixel_in(bwd_2_pixel_0),
445
    .bwd_rght_pixel_in(bwd_2_pixel_1),
446
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_0),
447
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_1),
448
    .idct_pixel_in(idct_2_pixel_0),
449
    .valid_out(valid_out),
450
    .write_recon_out(write_recon_out),
451
    .write_address_out(write_address_out),
452
    .pixel_out(pixel_out_0)
453
    );
454
 
455
  combine_predictions combine_predictions_1 (
456
    .rst(rst),
457
    .clk(clk),
458
    .clk_en(clk_en),
459
    .valid_in(valid_2),
460
    .write_recon_in(write_recon_2),
461
    .write_address_in(write_address_2),
462
    .motion_forward_in(motion_forward_2),
463
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
464
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
465
    .motion_backward_in(motion_backward_2),
466
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
467
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
468
    .fwd_left_pixel_in(fwd_2_pixel_1),
469
    .fwd_rght_pixel_in(fwd_2_pixel_2),
470
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_1),
471
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_2),
472
    .bwd_left_pixel_in(bwd_2_pixel_1),
473
    .bwd_rght_pixel_in(bwd_2_pixel_2),
474
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_1),
475
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_2),
476
    .idct_pixel_in(idct_2_pixel_1),
477
    .valid_out(),
478
    .write_recon_out(),
479
    .write_address_out(),
480
    .pixel_out(pixel_out_1)
481
    );
482
 
483
  combine_predictions combine_predictions_2 (
484
    .rst(rst),
485
    .clk(clk),
486
    .clk_en(clk_en),
487
    .valid_in(valid_2),
488
    .write_recon_in(write_recon_2),
489
    .write_address_in(write_address_2),
490
    .motion_forward_in(motion_forward_2),
491
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
492
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
493
    .motion_backward_in(motion_backward_2),
494
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
495
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
496
    .fwd_left_pixel_in(fwd_2_pixel_2),
497
    .fwd_rght_pixel_in(fwd_2_pixel_3),
498
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_2),
499
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_3),
500
    .bwd_left_pixel_in(bwd_2_pixel_2),
501
    .bwd_rght_pixel_in(bwd_2_pixel_3),
502
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_2),
503
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_3),
504
    .idct_pixel_in(idct_2_pixel_2),
505
    .valid_out(),
506
    .write_recon_out(),
507
    .write_address_out(),
508
    .pixel_out(pixel_out_2)
509
    );
510
 
511
  combine_predictions combine_predictions_3 (
512
    .rst(rst),
513
    .clk(clk),
514
    .clk_en(clk_en),
515
    .valid_in(valid_2),
516
    .write_recon_in(write_recon_2),
517
    .write_address_in(write_address_2),
518
    .motion_forward_in(motion_forward_2),
519
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
520
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
521
    .motion_backward_in(motion_backward_2),
522
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
523
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
524
    .fwd_left_pixel_in(fwd_2_pixel_3),
525
    .fwd_rght_pixel_in(fwd_2_pixel_4),
526
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_3),
527
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_4),
528
    .bwd_left_pixel_in(bwd_2_pixel_3),
529
    .bwd_rght_pixel_in(bwd_2_pixel_4),
530
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_3),
531
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_4),
532
    .idct_pixel_in(idct_2_pixel_3),
533
    .valid_out(),
534
    .write_recon_out(),
535
    .write_address_out(),
536
    .pixel_out(pixel_out_3)
537
    );
538
 
539
  combine_predictions combine_predictions_4 (
540
    .rst(rst),
541
    .clk(clk),
542
    .clk_en(clk_en),
543
    .valid_in(valid_2),
544
    .write_recon_in(write_recon_2),
545
    .write_address_in(write_address_2),
546
    .motion_forward_in(motion_forward_2),
547
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
548
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
549
    .motion_backward_in(motion_backward_2),
550
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
551
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
552
    .fwd_left_pixel_in(fwd_2_pixel_4),
553
    .fwd_rght_pixel_in(fwd_2_pixel_5),
554
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_4),
555
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_5),
556
    .bwd_left_pixel_in(bwd_2_pixel_4),
557
    .bwd_rght_pixel_in(bwd_2_pixel_5),
558
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_4),
559
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_5),
560
    .idct_pixel_in(idct_2_pixel_4),
561
    .valid_out(),
562
    .write_recon_out(),
563
    .write_address_out(),
564
    .pixel_out(pixel_out_4)
565
    );
566
 
567
  combine_predictions combine_predictions_5 (
568
    .rst(rst),
569
    .clk(clk),
570
    .clk_en(clk_en),
571
    .valid_in(valid_2),
572
    .write_recon_in(write_recon_2),
573
    .write_address_in(write_address_2),
574
    .motion_forward_in(motion_forward_2),
575
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
576
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
577
    .motion_backward_in(motion_backward_2),
578
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
579
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
580
    .fwd_left_pixel_in(fwd_2_pixel_5),
581
    .fwd_rght_pixel_in(fwd_2_pixel_6),
582
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_5),
583
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_6),
584
    .bwd_left_pixel_in(bwd_2_pixel_5),
585
    .bwd_rght_pixel_in(bwd_2_pixel_6),
586
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_5),
587
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_6),
588
    .idct_pixel_in(idct_2_pixel_5),
589
    .valid_out(),
590
    .write_recon_out(),
591
    .write_address_out(),
592
    .pixel_out(pixel_out_5)
593
    );
594
 
595
  combine_predictions combine_predictions_6 (
596
    .rst(rst),
597
    .clk(clk),
598
    .clk_en(clk_en),
599
    .valid_in(valid_2),
600
    .write_recon_in(write_recon_2),
601
    .write_address_in(write_address_2),
602
    .motion_forward_in(motion_forward_2),
603
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
604
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
605
    .motion_backward_in(motion_backward_2),
606
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
607
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
608
    .fwd_left_pixel_in(fwd_2_pixel_6),
609
    .fwd_rght_pixel_in(fwd_2_pixel_7),
610
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_6),
611
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_7),
612
    .bwd_left_pixel_in(bwd_2_pixel_6),
613
    .bwd_rght_pixel_in(bwd_2_pixel_7),
614
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_6),
615
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_7),
616
    .idct_pixel_in(idct_2_pixel_6),
617
    .valid_out(),
618
    .write_recon_out(),
619
    .write_address_out(),
620
    .pixel_out(pixel_out_6)
621
    );
622
 
623
  combine_predictions combine_predictions_7 (
624
    .rst(rst),
625
    .clk(clk),
626
    .clk_en(clk_en),
627
    .valid_in(valid_2),
628
    .write_recon_in(write_recon_2),
629
    .write_address_in(write_address_2),
630
    .motion_forward_in(motion_forward_2),
631
    .fwd_hor_halfpixel_in(fwd_hor_halfpixel_2),
632
    .fwd_ver_halfpixel_in(fwd_ver_halfpixel_2),
633
    .motion_backward_in(motion_backward_2),
634
    .bwd_hor_halfpixel_in(bwd_hor_halfpixel_2),
635
    .bwd_ver_halfpixel_in(bwd_ver_halfpixel_2),
636
    .fwd_left_pixel_in(fwd_2_pixel_7),
637
    .fwd_rght_pixel_in(fwd_2_pixel_8),
638
    .prev_fwd_left_pixel_in(prev_fwd_2_pixel_7),
639
    .prev_fwd_rght_pixel_in(prev_fwd_2_pixel_8),
640
    .bwd_left_pixel_in(bwd_2_pixel_7),
641
    .bwd_rght_pixel_in(bwd_2_pixel_8),
642
    .prev_bwd_left_pixel_in(prev_bwd_2_pixel_7),
643
    .prev_bwd_rght_pixel_in(prev_bwd_2_pixel_8),
644
    .idct_pixel_in(idct_2_pixel_7),
645
    .valid_out(),
646
    .write_recon_out(),
647
    .write_address_out(),
648
    .pixel_out(pixel_out_7)
649
    );
650
 
651
  always @(posedge clk)
652
    if (~rst) recon_wr_en <= 1'b0;
653
    else if (clk_en) recon_wr_en <= write_recon_out && valid_out;
654
    else recon_wr_en <= recon_wr_en;
655
 
656
  always @(posedge clk)
657
    if (~rst) recon_wr_addr <= 22'b0;
658
    else if (clk_en && valid_out) recon_wr_addr <= write_address_out;
659
    else recon_wr_addr <= recon_wr_addr;
660
 
661
  always @(posedge clk)
662
    if (~rst) recon_wr_dta <= 64'b0;
663
    else if (clk_en && valid_out) recon_wr_dta <= {pixel_out_0, pixel_out_1, pixel_out_2, pixel_out_3, pixel_out_4, pixel_out_5, pixel_out_6, pixel_out_7};
664
    else recon_wr_dta <= recon_wr_dta;
665
 
666
`ifdef DEBUG
667
   always @(posedge clk)
668
     if (clk_en)
669
       begin
670
         $strobe("%m\tvalid_0: %h  write_recon_0: %h  write_address_0: %h",
671
                  valid_0, write_recon_0, write_address_0);
672
         $strobe("%m\tmotion_forward_0: %h  fwd_hor_offset_0: %h  fwd_hor_halfpixel_0: %h  fwd_ver_halfpixel_0: %h",
673
                  motion_forward_0, fwd_hor_offset_0, fwd_hor_halfpixel_0, fwd_ver_halfpixel_0);
674
         $strobe("%m\tmotion_backward_0: %h  bwd_hor_offset_0: %h  bwd_hor_halfpixel_0: %h  bwd_ver_halfpixel_0: %h",
675
                  motion_backward_0, bwd_hor_offset_0, bwd_hor_halfpixel_0, bwd_ver_halfpixel_0);
676
         $strobe("%m\tfwd_row_0_valid: %h  fwd_row_0: %h",
677
                  fwd_row_0_valid, fwd_row_0);
678
         $strobe("%m\tbwd_row_0_valid: %h  bwd_row_0: %h",
679
                  bwd_row_0_valid, bwd_row_0);
680
         $strobe("%m\tidct_row_0: %h  idct_row_0_valid: %h",
681
                  idct_row_0, idct_row_0_valid);
682
 
683
         $strobe("%m\trecon_wr_en: %h recon_wr_addr: %h recon_wr_dta: %h",
684
                      recon_wr_en, recon_wr_addr, recon_wr_dta);
685
       end
686
`endif
687
 
688
endmodule
689
 
690
module prediction_horizontal_offset (rst, clk, clk_en,
691
  valid_in, row_in, motion_compensation_in, hor_offset_in, dta_in,
692
  valid_out, pixel_0_out, pixel_1_out, pixel_2_out, pixel_3_out, pixel_4_out, pixel_5_out, pixel_6_out, pixel_7_out, pixel_8_out, dta_out);
693
 
694
  parameter [8:0]dta_width=9'd8;
695
 
696
  input              clk;                      // clock
697
  input              clk_en;                   // clock enable
698
  input              rst;                      // synchronous active low reset
699
  input              valid_in;
700
  input       [127:0]row_in;                   // one row of 16 pixels, each pixel an 8 bit unsigned reg.
701
  input              motion_compensation_in;
702
  input         [2:0]hor_offset_in;
703
  input [dta_width-1:0]dta_in;
704
  output reg         valid_out;
705
  output signed [7:0]pixel_0_out;
706
  output signed [7:0]pixel_1_out;
707
  output signed [7:0]pixel_2_out;
708
  output signed [7:0]pixel_3_out;
709
  output signed [7:0]pixel_4_out;
710
  output signed [7:0]pixel_5_out;
711
  output signed [7:0]pixel_6_out;
712
  output signed [7:0]pixel_7_out;
713
  output signed [7:0]pixel_8_out;
714
  output reg [dta_width-1:0]dta_out;
715
 
716
  /* stage 1 */
717
  reg                valid_1;
718
  reg         [127:0]row_1;
719
  reg           [2:0]hor_offset_1;
720
  reg [dta_width-1:0]dta_1;
721
 
722
  always @(posedge clk)
723
    if (~rst) valid_1 <= 1'b0;
724
    else if (clk_en) valid_1 <= valid_in;
725
    else valid_1 <= valid_1;
726
 
727
  always @(posedge clk)
728
    if (~rst) row_1 <= 128'b0;
729
    else if (clk_en && motion_compensation_in) row_1 <= row_in;
730
    else if (clk_en) row_1 <= 128'b0;
731
    else row_1 <= row_1;
732
 
733
  always @(posedge clk)
734
    if (~rst) hor_offset_1 <= 3'd0;
735
    else if (clk_en && motion_compensation_in) hor_offset_1 <= hor_offset_in;
736
    else if (clk_en) hor_offset_1 <= 3'd0;
737
    else hor_offset_1 <= hor_offset_1;
738
 
739
  always @(posedge clk)
740
    if (~rst) dta_1 <= 1'b0;
741
    else if (clk_en) dta_1 <= dta_in;
742
    else dta_1 <= dta_1;
743
 
744
  /* stage 2 */
745
  reg          [71:0]row_2;
746
 
747
  always @(posedge clk)
748
    if (~rst) valid_out <= 1'b0;
749
    else if (clk_en) valid_out <= valid_1;
750
    else valid_out <= valid_out;
751
 
752
  /* shift by horizontal offset */
753
  always @(posedge clk)
754
    if (~rst) row_2 <= 72'b0;
755
    else if (clk_en)
756
      case (hor_offset_1)
757
        3'd0: row_2 <= row_1[127:56];
758
        3'd1: row_2 <= row_1[119:48];
759
        3'd2: row_2 <= row_1[111:40];
760
        3'd3: row_2 <= row_1[103:32];
761
        3'd4: row_2 <= row_1[95:24];
762
        3'd5: row_2 <= row_1[87:16];
763
        3'd6: row_2 <= row_1[79:8];
764
        3'd7: row_2 <= row_1[71:0];
765
      endcase
766
    else row_2 <= row_2;
767
 
768
  always @(posedge clk)
769
    if (~rst) dta_out <= 1'b0;
770
    else if (clk_en) dta_out <= dta_1;
771
    else dta_out <= dta_out;
772
 
773
  /* individual pixels within the row */
774
  assign pixel_0_out = row_2[71:64];
775
  assign pixel_1_out = row_2[63:56];
776
  assign pixel_2_out = row_2[55:48];
777
  assign pixel_3_out = row_2[47:40];
778
  assign pixel_4_out = row_2[39:32];
779
  assign pixel_5_out = row_2[31:24];
780
  assign pixel_6_out = row_2[23:16];
781
  assign pixel_7_out = row_2[15:8];
782
  assign pixel_8_out = row_2[7:0];
783
 
784
endmodule
785
 
786
module combine_predictions (rst, clk, clk_en,
787
  valid_in, write_recon_in, write_address_in, fwd_hor_halfpixel_in, fwd_ver_halfpixel_in, bwd_hor_halfpixel_in, bwd_ver_halfpixel_in,
788
  motion_forward_in, fwd_left_pixel_in, fwd_rght_pixel_in, prev_fwd_left_pixel_in, prev_fwd_rght_pixel_in,
789
  motion_backward_in, bwd_left_pixel_in, bwd_rght_pixel_in, prev_bwd_left_pixel_in, prev_bwd_rght_pixel_in,
790
  idct_pixel_in,
791
  valid_out, write_recon_out, write_address_out, pixel_out);
792
 
793
  input              clk;                      // clock
794
  input              clk_en;                   // clock enable
795
  input              rst;                      // synchronous active low reset
796
  input              valid_in;
797
  input              write_recon_in;
798
  input        [21:0]write_address_in;
799
  input              fwd_hor_halfpixel_in;
800
  input              fwd_ver_halfpixel_in;
801
  input              bwd_hor_halfpixel_in;
802
  input              bwd_ver_halfpixel_in;
803
  input              motion_forward_in;
804
  input signed  [7:0]fwd_left_pixel_in;
805
  input signed  [7:0]fwd_rght_pixel_in;
806
  input signed  [7:0]prev_fwd_left_pixel_in;
807
  input signed  [7:0]prev_fwd_rght_pixel_in;
808
  input              motion_backward_in;
809
  input signed  [7:0]bwd_left_pixel_in;
810
  input signed  [7:0]bwd_rght_pixel_in;
811
  input signed  [7:0]prev_bwd_left_pixel_in;
812
  input signed  [7:0]prev_bwd_rght_pixel_in;
813
  input signed  [8:0]idct_pixel_in;
814
  output reg         valid_out;
815
  output reg         write_recon_out;
816
  output reg   [21:0]write_address_out;
817
  output reg signed [7:0]pixel_out;
818
 
819
  /* stage 1 */
820
  wire               valid_4;
821
  wire               write_recon_4;
822
  wire         [21:0]write_address_4;
823
  wire               motion_forward_4;
824
  wire               motion_backward_4;
825
  wire signed   [8:0]idct_pixel_4;
826
  wire signed   [9:0]fwd_prediction_pixel_4;
827
  wire signed   [9:0]bwd_prediction_pixel_4;
828
 
829
  pixel_prediction #(.dta_width(8'd35)) forward_prediction (
830
    .rst(rst),
831
    .clk(clk),
832
    .clk_en(clk_en),
833
    .dta_in({valid_in, write_recon_in, write_address_in, motion_forward_in, motion_backward_in, idct_pixel_in}),
834
    .hor_halfpixel_in(fwd_hor_halfpixel_in),
835
    .ver_halfpixel_in(fwd_ver_halfpixel_in),
836
    .left_pixel_in(fwd_left_pixel_in),
837
    .rght_pixel_in(fwd_rght_pixel_in),
838
    .prev_left_pixel_in(prev_fwd_left_pixel_in),
839
    .prev_rght_pixel_in(prev_fwd_rght_pixel_in),
840
    .pixel_out(fwd_prediction_pixel_4),
841
    .dta_out({valid_4, write_recon_4, write_address_4, motion_forward_4, motion_backward_4, idct_pixel_4})
842
    );
843
 
844
  pixel_prediction #(.dta_width(8'd1)) backward_prediction (
845
    .rst(rst),
846
    .clk(clk),
847
    .clk_en(clk_en),
848
    .dta_in(1'b0),
849
    .hor_halfpixel_in(bwd_hor_halfpixel_in),
850
    .ver_halfpixel_in(bwd_ver_halfpixel_in),
851
    .left_pixel_in(bwd_left_pixel_in),
852
    .rght_pixel_in(bwd_rght_pixel_in),
853
    .prev_left_pixel_in(prev_bwd_left_pixel_in),
854
    .prev_rght_pixel_in(prev_bwd_rght_pixel_in),
855
    .pixel_out(bwd_prediction_pixel_4),
856
    .dta_out()
857
    );
858
 
859
  /* stage 5*/
860
 
861
  reg                valid_5;
862
  reg                write_recon_5;
863
  reg          [21:0]write_address_5;
864
  reg                motion_forward_5;
865
  reg                motion_backward_5;
866
  reg signed    [9:0]idct_pixel_5;
867
  reg signed    [9:0]fwd_prediction_pixel_5;
868
  reg signed    [9:0]bwd_prediction_pixel_5;
869
  reg signed    [9:0]fwd_bwd_prediction_pixel_5;
870
  wire signed   [9:0]fwd_bwd_prediction_pixel_round_5 = {9'b0, ~fwd_bwd_prediction_pixel_5[9]};
871
 
872
  always @(posedge clk)
873
    if (~rst) {valid_5, write_recon_5, write_address_5, motion_forward_5 ,motion_backward_5, fwd_prediction_pixel_5, bwd_prediction_pixel_5} <= 1'b0;
874
    else if (clk_en) {valid_5, write_recon_5, write_address_5, motion_forward_5 ,motion_backward_5, fwd_prediction_pixel_5, bwd_prediction_pixel_5} <= {valid_4, write_recon_4, write_address_4, motion_forward_4 ,motion_backward_4, fwd_prediction_pixel_4, bwd_prediction_pixel_4};
875
    else {valid_5, write_recon_5, write_address_5, motion_forward_5 ,motion_backward_5, fwd_prediction_pixel_5, bwd_prediction_pixel_5} <= {valid_5, write_recon_5, write_address_5, motion_forward_5 ,motion_backward_5, fwd_prediction_pixel_5, bwd_prediction_pixel_5};
876
 
877
  always @(posedge clk)
878
    if (~rst) idct_pixel_5 <= 10'sd0;
879
    else if (clk_en && write_recon_5) idct_pixel_5 <= {idct_pixel_4[8], idct_pixel_4};
880
    else if (clk_en) idct_pixel_5 <= 10'sd0;
881
    else idct_pixel_5 <= idct_pixel_5;
882
 
883
  always @(posedge clk)
884
    if (~rst) fwd_bwd_prediction_pixel_5 <= 10'sd0;
885
    else if (clk_en) fwd_bwd_prediction_pixel_5 <= fwd_prediction_pixel_4 + bwd_prediction_pixel_4;
886
    else fwd_bwd_prediction_pixel_5 <= fwd_bwd_prediction_pixel_5;
887
 
888
  /* stage 6 */
889
 
890
  reg                valid_6;
891
  reg                write_recon_6;
892
  reg          [21:0]write_address_6;
893
  reg signed    [9:0]idct_pixel_6;
894
  reg signed    [9:0]prediction_pixel_6;
895
 
896
  always @(posedge clk)
897
    if (~rst) {valid_6, write_recon_6, write_address_6, idct_pixel_6} <= 1'b0;
898
    else if (clk_en) {valid_6, write_recon_6, write_address_6, idct_pixel_6} <= {valid_5, write_recon_5, write_address_5, idct_pixel_5};
899
    else {valid_6, write_recon_6, write_address_6, idct_pixel_6} <= {valid_6, write_recon_6, write_address_6, idct_pixel_6};
900
 
901
  always @(posedge clk)
902
    if (~rst) prediction_pixel_6 <= 10'sd0;
903
    else if (clk_en)
904
      case ({motion_forward_5, motion_backward_5})
905
        2'b00:   prediction_pixel_6 <= 10'sd0;
906
        2'b01:   prediction_pixel_6 <= bwd_prediction_pixel_5;
907
        2'b10:   prediction_pixel_6 <= fwd_prediction_pixel_5;
908
        2'b11:   prediction_pixel_6 <= (fwd_bwd_prediction_pixel_5 + fwd_bwd_prediction_pixel_round_5) >>> 1;
909
        default  prediction_pixel_6 <= 10'sd0;
910
      endcase
911
    else prediction_pixel_6 <= prediction_pixel_6;
912
 
913
  /* stage 7 */
914
 
915
  reg                valid_7;
916
  reg                write_recon_7;
917
  reg          [21:0]write_address_7;
918
  reg signed    [9:0]pixel_7;
919
 
920
  always @(posedge clk)
921
    if (~rst) {valid_7, write_recon_7, write_address_7} <= 1'b0;
922
    else if (clk_en) {valid_7, write_recon_7, write_address_7} <= {valid_6, write_recon_6, write_address_6};
923
    else {valid_7, write_recon_7, write_address_7} <= {valid_7, write_recon_7, write_address_7};
924
 
925
  always @(posedge clk)
926
    if (~rst) pixel_7 <= 10'sd0;
927
    else if (clk_en) pixel_7 <= idct_pixel_6 + prediction_pixel_6;
928
    else pixel_7 <= pixel_7;
929
 
930
  /* stage 8 */
931
 
932
  always @(posedge clk)
933
    if (~rst) valid_out <= 1'b0;
934
    else if (clk_en) valid_out <= valid_7;
935
    else valid_out <= valid_out;
936
 
937
  always @(posedge clk)
938
    if (~rst) write_recon_out <= 1'b0;
939
    else if (clk_en) write_recon_out <= write_recon_7;
940
    else write_recon_out <= write_recon_out;
941
 
942
  always @(posedge clk)
943
    if (~rst) write_address_out <= 22'd0;
944
    else if (clk_en) write_address_out <= write_address_7;
945
    else write_address_out <= write_address_out;
946
 
947
  always @(posedge clk)
948
    if (~rst) pixel_out <= 8'b0;
949
    else if (clk_en && ((pixel_7[9:7] == 3'b000) || (pixel_7[9:7] == 3'b111))) pixel_out <= pixel_7[7:0]; /* between -128 and 127, copy */
950
    else if (clk_en) pixel_out <= {pixel_7[9], {7{~pixel_7[9]}}}; /* clip to -128 if negative, to 127 if positive */
951
    else pixel_out <= pixel_out;
952
 
953
`ifdef DEBUG
954
   always @(posedge clk)
955
     if (clk_en)
956
       begin
957
         $strobe("%m\tvalid_5: %h write_recon_5: %h write_address_5: %h idct_pixel_5: %d fwd_prediction_pixel_5: %d bwd_prediction_pixel_5: %d", valid_5, write_recon_5, write_address_5, idct_pixel_5, fwd_prediction_pixel_5, bwd_prediction_pixel_5);
958
         $strobe("%m\tvalid_6: %h write_recon_6: %h write_address_6: %h idct_pixel_6: %d prediction_pixel_6: %d", valid_6, write_recon_6, write_address_6, idct_pixel_6, prediction_pixel_6);
959
         $strobe("%m\tvalid_7: %h write_recon_7: %h write_address_7: %h pixel_7: %d", valid_7, write_recon_7, write_address_7, pixel_7);
960
         $strobe("%m\tvalid_out: %h write_recon_out: %h write_address_out: %h pixel_out: %d", valid_out, write_recon_out, write_address_out, pixel_out);
961
       end
962
`endif
963
 
964
endmodule
965
 
966
module pixel_prediction (rst, clk, clk_en, dta_in,
967
  hor_halfpixel_in, ver_halfpixel_in, left_pixel_in, rght_pixel_in, prev_left_pixel_in, prev_rght_pixel_in,
968
  pixel_out, dta_out);
969
 
970
  parameter [8:0]dta_width=9'd8;
971
 
972
  input              clk;                      // clock
973
  input              clk_en;                   // clock enable
974
  input              rst;                      // synchronous active low reset
975
  input [dta_width-1:0]dta_in;
976
  input              hor_halfpixel_in;
977
  input              ver_halfpixel_in;
978
  input signed  [7:0]left_pixel_in;
979
  input signed  [7:0]rght_pixel_in;
980
  input signed  [7:0]prev_left_pixel_in;
981
  input signed  [7:0]prev_rght_pixel_in;
982
  output reg signed [9:0]pixel_out;
983
  output reg [dta_width-1:0]dta_out;
984
 
985
  /* stage 1 */
986
  reg [dta_width-1:0]dta_1;
987
  reg               hor_halfpixel_1;
988
  reg               ver_halfpixel_1;
989
  reg signed   [9:0]prev_left_pixel_in_1;
990
  reg signed   [9:0]sum_prev_left_prev_right_1;
991
  reg signed   [9:0]sum_left_prev_left_1;
992
  reg signed   [9:0]sum_right_prev_right_1;
993
 
994
  wire signed [9:0]left_pixel_in_ext      = {left_pixel_in[7], left_pixel_in[7], left_pixel_in};
995
  wire signed [9:0]rght_pixel_in_ext      = {rght_pixel_in[7], rght_pixel_in[7], rght_pixel_in};
996
  wire signed [9:0]prev_left_pixel_in_ext = {prev_left_pixel_in[7], prev_left_pixel_in[7], prev_left_pixel_in};
997
  wire signed [9:0]prev_rght_pixel_in_ext = {prev_rght_pixel_in[7], prev_rght_pixel_in[7], prev_rght_pixel_in};
998
 
999
  always @(posedge clk)
1000
    if (~rst) dta_1 <= 1'b0;
1001
    else if (clk_en) dta_1 <= dta_in;
1002
    else dta_1 <= dta_1;
1003
 
1004
  always @(posedge clk)
1005
    if (~rst) hor_halfpixel_1 <= 1'b0;
1006
    else if (clk_en) hor_halfpixel_1 <= hor_halfpixel_in;
1007
    else hor_halfpixel_1 <= hor_halfpixel_1;
1008
 
1009
  always @(posedge clk)
1010
    if (~rst) ver_halfpixel_1 <= 1'b0;
1011
    else if (clk_en) ver_halfpixel_1 <= ver_halfpixel_in;
1012
    else ver_halfpixel_1 <= ver_halfpixel_1;
1013
 
1014
  always @(posedge clk)
1015
    if (~rst) prev_left_pixel_in_1 <= 1'b0;
1016
    else if (clk_en) prev_left_pixel_in_1 <= prev_left_pixel_in_ext;
1017
    else prev_left_pixel_in_1 <= prev_left_pixel_in_1;
1018
 
1019
  always @(posedge clk)
1020
    if (~rst) sum_prev_left_prev_right_1 <= 10'sd0;
1021
    else if (clk_en) sum_prev_left_prev_right_1 <= prev_left_pixel_in_ext + prev_rght_pixel_in_ext + 10'sd1;
1022
    else sum_prev_left_prev_right_1 <= sum_prev_left_prev_right_1;
1023
 
1024
  always @(posedge clk)
1025
    if (~rst) sum_left_prev_left_1 <= 10'sd0;
1026
    else if (clk_en) sum_left_prev_left_1 <= left_pixel_in_ext + prev_left_pixel_in_ext + 10'sd1;
1027
    else sum_left_prev_left_1 <= sum_left_prev_left_1;
1028
 
1029
  always @(posedge clk)
1030
    if (~rst) sum_right_prev_right_1 <= 10'sd0;
1031
    else if (clk_en) sum_right_prev_right_1 <= rght_pixel_in_ext + prev_rght_pixel_in_ext + 10'sd1;
1032
    else sum_right_prev_right_1 <= sum_right_prev_right_1;
1033
 
1034
  /* stage 2 */
1035
 
1036
  always @(posedge clk)
1037
    if (~rst) dta_out <= 1'b0;
1038
    else if (clk_en) dta_out <= dta_1;
1039
    else dta_out <= dta_out;
1040
 
1041
  always @(posedge clk)
1042
    if (~rst) pixel_out <= 10'sd0;
1043
    else if (clk_en)
1044
      case ({hor_halfpixel_1, ver_halfpixel_1})
1045
        2'b00:  pixel_out <= prev_left_pixel_in_1;
1046
        2'b01:  pixel_out <= sum_left_prev_left_1 >>> 1;
1047
        2'b10:  pixel_out <= sum_prev_left_prev_right_1 >>> 1;
1048
        2'b11:  pixel_out <= (sum_left_prev_left_1 + sum_right_prev_right_1) >>> 2;
1049
        default pixel_out <= prev_left_pixel_in_1;
1050
      endcase
1051
    else pixel_out <= pixel_out;
1052
 
1053
`ifdef DEBUG
1054
   always @(posedge clk)
1055
     if (clk_en)
1056
       $strobe("%m\tpixel_out: %d", pixel_out);
1057
`endif
1058
 
1059
endmodule
1060
/* not truncated */

powered by: WebSVN 2.1.0

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