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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * motcomp_dcttype.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_dcttype - Motion compensation dct type
21
 */
22
 
23
`include "timescale.v"
24
 
25
`undef DEBUG
26
//`define DEBUG 1
27
 
28
`undef CHECK
29
`ifdef __IVERILOG__
30
`define CHECK 1
31
`endif
32
 
33
/*
34
  This module converts blocks between different dct types.
35
  dct_type is a flag indicating whether the macroblock is frame DCT coded or field DCT coded. If this is set to '1', the macroblock is field DCT coded. (par. 6.3.17.1 Macroblock modes)
36
  See par. 6.1.4, Figure 6-13 and 6-14.
37
 */
38
 
39
module motcomp_dcttype (
40
  clk, clk_en, rst,
41
  dct_block_empty, dct_block_cmd, dct_block_en, dct_block_valid,
42
  idct_rd_dta_empty, idct_rd_dta, idct_rd_dta_en, idct_rd_dta_valid,
43
  frame_idct_rd_dta_empty, frame_idct_rd_dta, frame_idct_rd_dta_en, frame_idct_rd_dta_valid,
44
  frame_idct_wr_overflow
45
  );
46
 
47
`include "motcomp_dctcodes.v"
48
 
49
  input              clk;                          // clock
50
  input              clk_en;                       // clock enable
51
  input              rst;                          // synchronous active low reset
52
 
53
  /* input dct field->frame conversion commands */
54
  input              dct_block_empty;              // asserted if no dct_block_type/dct_block_count available.
55
  input         [2:0]dct_block_cmd;                // code which indicates number of blocks to transpose and how to transpose them.
56
  output reg         dct_block_en;                 // assert to read dct_block_type and dct_block_count.
57
  input              dct_block_valid;              // asserted if dct_block_type/dct_block_count valid
58
 
59
  /* input field/frame idct coefficients fifo */
60
  input              idct_rd_dta_empty;
61
  input        [71:0]idct_rd_dta;
62
  output reg         idct_rd_dta_en;
63
  input              idct_rd_dta_valid;
64
 
65
  /* output frame idct coefficients fifo */
66
  output              frame_idct_rd_dta_empty;
67
  output        [71:0]frame_idct_rd_dta;
68
  input               frame_idct_rd_dta_en;
69
  output              frame_idct_rd_dta_valid;
70
 
71
  wire                frame_idct_wr_dta_full;
72
  wire                frame_idct_wr_dta_almost_full;
73
  wire          [71:0]frame_idct_wr_dta;
74
  reg                 frame_idct_wr_dta_en;
75
  reg                 frame_idct_wr_dta_en_0;
76
  output              frame_idct_wr_overflow;
77
 
78
  /* ram address register */
79
  reg           [4:0]wr_addr;
80
  reg           [4:0]coeff;
81
  reg           [4:0]dct_count;
82
  reg           [2:0]dct_cmd;
83
 
84
  parameter [2:0]
85
    STATE_INIT       = 3'd0,
86
    STATE_DCT_RD_EN  = 3'd1,
87
    STATE_DCT_READ   = 3'd2,
88
    STATE_WAIT_IDCT  = 3'd3,
89
    STATE_IDCT_RD_EN = 3'd4,
90
    STATE_READ_IDCT  = 3'd5,
91
    STATE_WRITE_IDCT = 3'd6,
92
    STATE_WAIT_WRITE = 3'd7;
93
 
94
  reg           [2:0]state;
95
  reg           [2:0]next;
96
 
97
  /* next state logic */
98
  always @*
99
    case (state)
100
      STATE_INIT:         if (dct_block_empty || frame_idct_wr_dta_almost_full) next = STATE_INIT; // wait for dct_type fifo (=command input) not empty and frame_idct (=output) not full
101
                          else next = STATE_DCT_RD_EN;
102
 
103
      STATE_DCT_RD_EN:    next = STATE_DCT_READ; // assert dct_block_en
104
 
105
      STATE_DCT_READ:     next = STATE_WAIT_IDCT; // read dct_block_cmd
106
 
107
      STATE_WAIT_IDCT:    if (idct_rd_dta_empty) next = STATE_WAIT_IDCT; // wait for idct fifo not empty
108
                          else next = STATE_IDCT_RD_EN;
109
 
110
      STATE_IDCT_RD_EN:   next = STATE_READ_IDCT; // assert idct_rd_dta_en
111
 
112
      STATE_READ_IDCT:    if (wr_addr == dct_count) next = STATE_WRITE_IDCT; // read idct_rd_dta; if last idct coefficient write re-arranged coefficients to frame idct fifo,
113
                          else next = STATE_WAIT_IDCT;                       // else read next idct coefficient
114
 
115
      STATE_WRITE_IDCT:   if (coeff == dct_count) next = STATE_WAIT_WRITE;   // write idct coefficients to frame idct fifo
116
                          else next = STATE_WRITE_IDCT;
117
 
118
      STATE_WAIT_WRITE:   if (frame_idct_wr_dta_en) next = STATE_WAIT_WRITE;
119
                          else next = STATE_INIT;
120
 
121
      default             next = STATE_INIT;
122
 
123
    endcase
124
 
125
  /* state */
126
  always @(posedge clk)
127
    if (~rst) state <= STATE_INIT;
128
    else if (clk_en) state <= next;
129
    else state <= state;
130
 
131
  /* registers */
132
  /* read from dct_type fifo */
133
  always @(posedge clk)
134
    if (~rst) dct_block_en <= 1'b0;
135
    else if (clk_en) dct_block_en <= next == STATE_DCT_RD_EN;
136
    else  dct_block_en <= 1'b0;
137
 
138
  always @(posedge clk)
139
    if (~rst) dct_cmd <= 1'b0;
140
    else if (clk_en && dct_block_valid) dct_cmd <= dct_block_cmd;
141
    else  dct_cmd <= dct_cmd;
142
 
143
  always @(posedge clk)
144
    if (~rst) dct_count <= 5'b0;
145
    else if (clk_en && dct_block_valid)
146
      case (dct_block_cmd)
147
        DCT_C1_PASS,
148
        DCT_C1_FRAME_TO_TOP_FIELD:    dct_count <= 5'd7;   // 1 block, 8 rows
149
        DCT_L4_PASS,
150
        DCT_L4_TOP_FIELD_TO_FRAME,
151
        DCT_L4_FRAME_TO_TOP_FIELD:    dct_count <= 5'd31;  // 4 blocks, 32 rows
152
        default                       dct_count <= 5'd0;   // Should never occur
153
      endcase
154
    else  dct_count <= dct_count;
155
 
156
  /* read from idct_dta fifo */
157
  always @(posedge clk)
158
    if (~rst) idct_rd_dta_en <= 1'b0;
159
    else if (clk_en) idct_rd_dta_en <= next == STATE_IDCT_RD_EN;
160
    else  idct_rd_dta_en <= 1'b0;
161
 
162
  always @(posedge clk)
163
    if (~rst) wr_addr <= 5'b0;
164
    else if (clk_en && (state == STATE_INIT)) wr_addr <= 5'b0;
165
    else if (clk_en && (state == STATE_READ_IDCT)) wr_addr <= wr_addr + 5'b1;
166
    else  wr_addr <= wr_addr;
167
 
168
  always @(posedge clk)
169
    if (~rst) coeff <= 5'b0;
170
    else if (clk_en && (state == STATE_INIT)) coeff <= 5'b0;
171
    else if (clk_en && (state == STATE_WRITE_IDCT)) coeff <= coeff + 5'b1;
172
    else  coeff <= coeff;
173
 
174
  /* write to idct_dta_ram */
175
  wire idct_ram_wr_en = idct_rd_dta_valid;
176
  wire [71:0]idct_ram_wr_dta = idct_rd_dta;
177
 
178
  /* write to frame_idct fifo */
179
  always @(posedge clk)
180
    if (~rst) frame_idct_wr_dta_en_0 <= 1'b0;
181
    else if (clk_en) frame_idct_wr_dta_en_0 <= (state == STATE_WRITE_IDCT);
182
    else  frame_idct_wr_dta_en_0 <= 1'b0;
183
 
184
  always @(posedge clk)
185
    if (~rst) frame_idct_wr_dta_en <= 1'b0;
186
    else if (clk_en) frame_idct_wr_dta_en <= frame_idct_wr_dta_en_0;
187
    else  frame_idct_wr_dta_en <= 1'b0;
188
 
189
  /* address transposition for reading */
190
  reg           [4:0]rd_addr;
191
  reg                idct_ram_rd_en;
192
 
193
  always @(posedge clk)
194
    if (~rst) idct_ram_rd_en <= 1'b0;
195
    else if (clk_en) idct_ram_rd_en <= (state == STATE_WRITE_IDCT);
196
    else  idct_ram_rd_en <= 1'b0;
197
 
198
  /* convert address from field to frame coding, or the other way round */
199
  always @(posedge clk)
200
    case (dct_cmd)
201
      /* chrominance pass-through */
202
      DCT_C1_PASS:
203
        rd_addr <= coeff;
204
      /* rearrange chrominance from frame to field. output top 4 rows are top field, bottom 4 rows are bottom field */
205
      DCT_C1_FRAME_TO_TOP_FIELD:
206
        case (coeff)
207
          5'd0:   rd_addr <= 5'd0;
208
          5'd1:   rd_addr <= 5'd2;
209
          5'd2:   rd_addr <= 5'd4;
210
          5'd3:   rd_addr <= 5'd6;
211
          5'd4:   rd_addr <= 5'd1;
212
          5'd5:   rd_addr <= 5'd3;
213
          5'd6:   rd_addr <= 5'd5;
214
          5'd7:   rd_addr <= 5'd7;
215
          default rd_addr <= 5'd0;
216
        endcase
217
      /* luminance pass-through */
218
      DCT_L4_PASS:
219
        rd_addr <= coeff;
220
      /* rearrange luminance from field to frame. input top 8 rows are top field, bottom 8 rows are bottom field */
221
      DCT_L4_TOP_FIELD_TO_FRAME:
222
        case (coeff)
223
          5'd0:   rd_addr <= 5'd0;
224
          5'd1:   rd_addr <= 5'd16;
225
          5'd2:   rd_addr <= 5'd1;
226
          5'd3:   rd_addr <= 5'd17;
227
          5'd4:   rd_addr <= 5'd2;
228
          5'd5:   rd_addr <= 5'd18;
229
          5'd6:   rd_addr <= 5'd3;
230
          5'd7:   rd_addr <= 5'd19;
231
          5'd8:   rd_addr <= 5'd8;
232
          5'd9:   rd_addr <= 5'd24;
233
          5'd10:  rd_addr <= 5'd9;
234
          5'd11:  rd_addr <= 5'd25;
235
          5'd12:  rd_addr <= 5'd10;
236
          5'd13:  rd_addr <= 5'd26;
237
          5'd14:  rd_addr <= 5'd11;
238
          5'd15:  rd_addr <= 5'd27;
239
          5'd16:  rd_addr <= 5'd4;
240
          5'd17:  rd_addr <= 5'd20;
241
          5'd18:  rd_addr <= 5'd5;
242
          5'd19:  rd_addr <= 5'd21;
243
          5'd20:  rd_addr <= 5'd6;
244
          5'd21:  rd_addr <= 5'd22;
245
          5'd22:  rd_addr <= 5'd7;
246
          5'd23:  rd_addr <= 5'd23;
247
          5'd24:  rd_addr <= 5'd12;
248
          5'd25:  rd_addr <= 5'd28;
249
          5'd26:  rd_addr <= 5'd13;
250
          5'd27:  rd_addr <= 5'd29;
251
          5'd28:  rd_addr <= 5'd14;
252
          5'd29:  rd_addr <= 5'd30;
253
          5'd30:  rd_addr <= 5'd15;
254
          5'd31:  rd_addr <= 5'd31;
255
          default rd_addr <= 5'd0;
256
        endcase
257
      /* rearrange luminance from frame to field. output top 8 rows are top field, bottom 8 rows are bottom field */
258
      DCT_L4_FRAME_TO_TOP_FIELD:
259
        case (coeff)
260
          5'd0:   rd_addr <= 5'd0;
261
          5'd1:   rd_addr <= 5'd2;
262
          5'd2:   rd_addr <= 5'd4;
263
          5'd3:   rd_addr <= 5'd6;
264
          5'd4:   rd_addr <= 5'd16;
265
          5'd5:   rd_addr <= 5'd18;
266
          5'd6:   rd_addr <= 5'd20;
267
          5'd7:   rd_addr <= 5'd22;
268
          5'd8:   rd_addr <= 5'd8;
269
          5'd9:   rd_addr <= 5'd10;
270
          5'd10:  rd_addr <= 5'd12;
271
          5'd11:  rd_addr <= 5'd14;
272
          5'd12:  rd_addr <= 5'd24;
273
          5'd13:  rd_addr <= 5'd26;
274
          5'd14:  rd_addr <= 5'd28;
275
          5'd15:  rd_addr <= 5'd30;
276
          5'd16:  rd_addr <= 5'd1;
277
          5'd17:  rd_addr <= 5'd3;
278
          5'd18:  rd_addr <= 5'd5;
279
          5'd19:  rd_addr <= 5'd7;
280
          5'd20:  rd_addr <= 5'd17;
281
          5'd21:  rd_addr <= 5'd19;
282
          5'd22:  rd_addr <= 5'd21;
283
          5'd23:  rd_addr <= 5'd23;
284
          5'd24:  rd_addr <= 5'd9;
285
          5'd25:  rd_addr <= 5'd11;
286
          5'd26:  rd_addr <= 5'd13;
287
          5'd27:  rd_addr <= 5'd15;
288
          5'd28:  rd_addr <= 5'd25;
289
          5'd29:  rd_addr <= 5'd27;
290
          5'd30:  rd_addr <= 5'd29;
291
          5'd31:  rd_addr <= 5'd31;
292
          default rd_addr <= 5'd0;
293
        endcase
294
      default
295
        rd_addr <= 5'd0;
296
    endcase
297
 
298
  /* storage for re-ordering idct coefficients */
299
 
300
  dpram_sc
301
    #(.addr_width(5),                                         // number of bits in address bus
302
    .dta_width(72))                                           // number of bits in data bus
303
    idct_dta_ram (
304
    .rst(rst),                                                // reset, active low
305
    .clk(clk),                                                // clock, rising edge trigger
306
    .wr_en(idct_ram_wr_en),                                   // write enable, active high
307
    .wr_addr(wr_addr),                                        // write address
308
    .din(idct_ram_wr_dta),                                    // data input
309
    .rd_en(idct_ram_rd_en),                                   // read enable, active high
310
    .rd_addr(rd_addr),                                        // read address
311
    .dout(frame_idct_wr_dta)                                  // data output
312
    );
313
 
314
  /* output fifo for idct coefficients */
315
 
316
  fifo_sc
317
    #(.addr_width(9'd6), // stores twice 4 blocks
318
    .dta_width(9'd72),
319
    .prog_thresh(9'd32))  // almost_full low indicates enough room for writing 4 blocks
320
    frame_idct_fifo (
321
    .rst(rst),
322
    .clk(clk),
323
    .din(frame_idct_wr_dta),
324
    .wr_en(frame_idct_wr_dta_en && clk_en),
325
    .full(frame_idct_wr_dta_full),
326
    .wr_ack(),
327
    .overflow(frame_idct_wr_overflow),
328
    .prog_full(frame_idct_wr_dta_almost_full),
329
    .dout(frame_idct_rd_dta),
330
    .rd_en(frame_idct_rd_dta_en),
331
    .empty(frame_idct_rd_dta_empty),
332
    .valid(frame_idct_rd_dta_valid),
333
    .underflow(),
334
    .prog_empty()
335
    );
336
 
337
`ifdef CHECK
338
  always @(posedge clk)
339
    if (frame_idct_wr_overflow)
340
      begin
341
        #0 $display("%m\t*** error: frame_idct_fifo overflow. **");
342
        $stop;
343
      end
344
`endif
345
 
346
`ifdef DEBUG
347
  /* debugging */
348
 
349
  always @(posedge clk)
350
    if (clk_en)
351
      case (state)
352
        STATE_INIT:                               #0 $display("%m         STATE_INIT");
353
        STATE_DCT_RD_EN:                          #0 $display("%m         STATE_DCT_RD_EN");
354
        STATE_DCT_READ:                           #0 $display("%m         STATE_DCT_READ");
355
        STATE_WAIT_IDCT:                          #0 $display("%m         STATE_WAIT_IDCT");
356
        STATE_IDCT_RD_EN:                         #0 $display("%m         STATE_IDCT_RD_EN");
357
        STATE_READ_IDCT:                          #0 $display("%m         STATE_READ_IDCT");
358
        STATE_WRITE_IDCT:                         #0 $display("%m         STATE_WRITE_IDCT");
359
        STATE_WAIT_WRITE:                         #0 $display("%m         STATE_WAIT_WRITE");
360
        default                                   #0 $display("%m         *** Error: unknown state %d", state);
361
      endcase
362
 
363
  always @(posedge clk)
364
    if (clk_en)
365
      begin
366
        $strobe("%m\tdct_block_empty: %d dct_block_cmd: %d dct_block_en: %d dct_block_valid: %d", dct_block_empty, dct_block_cmd, dct_block_en, dct_block_valid);
367
        $strobe("%m\tidct_rd_dta_empty: %d idct_rd_dta: %h idct_rd_dta_en: %d idct_rd_dta_valid: %d wr_addr: %d", idct_rd_dta_empty, idct_rd_dta, idct_rd_dta_en, idct_rd_dta_valid, wr_addr);
368
        $strobe("%m\tframe_idct_wr_dta_almost_full: %d frame_idct_wr_dta: %h frame_idct_wr_dta_en: %d rd_addr: %d", frame_idct_wr_dta_almost_full, frame_idct_wr_dta, frame_idct_wr_dta_en, rd_addr);
369
        $strobe("%m\tframe_idct_rd_dta_empty: %d frame_idct_rd_dta: %h frame_idct_rd_dta_en: %d frame_idct_rd_dta_valid: %d", frame_idct_rd_dta_empty, frame_idct_rd_dta, frame_idct_rd_dta_en, frame_idct_rd_dta_valid);
370
      end
371
 
372
`endif
373
 
374
endmodule
375
/* not truncated */

powered by: WebSVN 2.1.0

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