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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * mixer.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
 * mixer: synchronize pixels to video h_sync, v_sync
21
 */
22
 
23
 /*
24
  * HDMI Specification 1.0:
25
  *   6.4 Pixel-Repetition
26
  *   Video formats with native pixel rates below 25 Mpixels/sec require pixel-repetition in order to be
27
  *   carried across a TMDS link. 720x480i and 720x576i video format timings shall always be pixel-repeated.
28
  *
29
  * Here: if pixel_repetition repetition is asserted, each pixel is duplicated.
30
  */
31
 
32
`include "timescale.v"
33
 
34
`undef DEBUG
35
//`define DEBUG 1
36
 
37
module mixer(
38
  clk, rst,
39
  pixel_repetition,
40
  y_in, u_in, v_in, osd_in, position_in, pixel_rd_en, pixel_rd_valid, pixel_rd_underflow,
41
  h_pos, v_pos, h_sync_in, v_sync_in, pixel_en_in,
42
  y_out, u_out, v_out, osd_out, h_sync_out, v_sync_out, pixel_en_out
43
  );
44
 
45
  input              clk;                      // clock
46
  input              rst;                      // synchronous active low reset
47
 
48
  input              pixel_repetition;         // if asserted, repeat each pixel once
49
 
50
  /* from pixel_queue fifo */
51
  input         [7:0]y_in;
52
  input         [7:0]u_in;
53
  input         [7:0]v_in;
54
  input         [7:0]osd_in;
55
  input         [2:0]position_in;
56
  output reg         pixel_rd_en;
57
  input              pixel_rd_valid;
58
  input              pixel_rd_underflow; // if pixel_rd_underflow we're outputting pixels faster than we're computing them
59
 
60
  /* from video sync generator */
61
  input        [11:0]h_pos;
62
  input        [11:0]v_pos;
63
  input              h_sync_in;
64
  input              v_sync_in;
65
  input              pixel_en_in;
66
 
67
  /* to dvi transmitter */
68
  output reg    [7:0]y_out;
69
  output reg    [7:0]u_out;
70
  output reg    [7:0]v_out;
71
  output reg    [7:0]osd_out;
72
  output reg         h_sync_out;
73
  output reg         v_sync_out;
74
  output reg         pixel_en_out;
75
 
76
  /* store pixel_queue fifo output */
77
  reg           [7:0]y_0;
78
  reg           [7:0]u_0;
79
  reg           [7:0]v_0;
80
  reg           [7:0]osd_0;
81
  reg           [2:0]position_in_0;
82
  reg                h_sync_0;
83
  reg                v_sync_0;
84
  reg                pixel_en_0;
85
  /* delay h_sync, v_sync, pixel_en by two clocks */
86
  reg                pixel_en_1;
87
  reg                h_sync_1;
88
  reg                v_sync_1;
89
 
90
  reg                pixel_en_2;
91
  reg                h_sync_2;
92
  reg                v_sync_2;
93
 
94
`include "resample_codes.v"
95
 
96
  parameter [2:0]
97
    STATE_INIT               = 3'h0, /* read pixel queue until the first pixel of a line is found */
98
    STATE_WAIT               = 3'h1, /* wait until first pixel of the line will be displayed */
99
    STATE_FIRST_PIXEL        = 3'h2, /* display first pixel of the line */
100
    STATE_REPEAT_FIRST_PIXEL = 3'h3, /* pixel repetition */
101
    STATE_PIXEL              = 3'h4, /* display pixels */
102
    STATE_REPEAT_PIXEL       = 3'h5, /* pixel repetition */
103
    STATE_LAST_PIXEL         = 3'h6, /* display last pixel of the line */
104
    STATE_REPEAT_LAST_PIXEL  = 3'h7; /* pixel repetition */
105
 
106
  reg          [2:0]state;
107
  reg          [2:0]next;
108
 
109
  wire              first_pixel_read    = (pixel_rd_valid && ((position_in == ROW_0_COL_0) || (position_in == ROW_1_COL_0) || (position_in == ROW_X_COL_0)))      // first pixel at fifo output
110
                                                         || ((position_in_0 == ROW_0_COL_0) || (position_in_0 == ROW_1_COL_0) || (position_in_0 == ROW_X_COL_0)); // first pixel already stored
111
  wire              display_first_pixel = (h_pos == 12'd0) && (((position_in_0 == ROW_0_COL_0) && (v_pos == 12'd0)) ||
112
                                                               ((position_in_0 == ROW_1_COL_0) && (v_pos == 12'd1)) ||
113
                                                               ((position_in_0 == ROW_X_COL_0) && (v_pos != 12'd0) && (v_pos != 12'd1)));
114
  wire              last_pixel_read     = pixel_rd_valid && (position_in == ROW_X_COL_LAST);
115
 
116
  /* next state logic */
117
  always @*
118
    case (state)
119
      STATE_INIT:               if (first_pixel_read) next = STATE_WAIT;
120
                                else next = STATE_INIT;
121
 
122
      STATE_WAIT:               if (pixel_en_in && display_first_pixel) next = STATE_FIRST_PIXEL;
123
                                else next = STATE_WAIT;
124
 
125
      STATE_FIRST_PIXEL:        if (pixel_repetition) next = STATE_REPEAT_FIRST_PIXEL;
126
                                else next = STATE_PIXEL;
127
 
128
      STATE_REPEAT_FIRST_PIXEL: next = STATE_PIXEL;
129
 
130
      STATE_PIXEL:              if (pixel_rd_underflow) next = STATE_INIT;
131
                                else if (pixel_repetition) next = STATE_REPEAT_PIXEL;
132
                                else if (last_pixel_read) next = STATE_LAST_PIXEL;
133
                                else next = STATE_PIXEL;
134
 
135
      STATE_REPEAT_PIXEL:       if (pixel_rd_underflow) next = STATE_INIT;
136
                                else if (last_pixel_read) next = STATE_LAST_PIXEL;
137
                                else next = STATE_PIXEL;
138
 
139
      STATE_LAST_PIXEL:         if (pixel_repetition) next = STATE_REPEAT_LAST_PIXEL;
140
                                else next = STATE_INIT;
141
 
142
      STATE_REPEAT_LAST_PIXEL:  next = STATE_INIT;
143
 
144
      default                   next = STATE_INIT;
145
 
146
    endcase
147
 
148
  /* state */
149
  always @(posedge clk)
150
    if(~rst) state <= STATE_INIT;
151
    else state <= next;
152
 
153
  /* registers */
154
  /* store pixel_fifo output */
155
  always @(posedge clk)
156
    if (~rst) y_0 <= 8'd0;
157
    else if (pixel_rd_valid) y_0 <= y_in;
158
    else y_0 <= y_0;
159
 
160
  always @(posedge clk)
161
    if (~rst) u_0 <= 8'd0;
162
    else if (pixel_rd_valid) u_0 <= u_in;
163
    else u_0 <= u_0;
164
 
165
  always @(posedge clk)
166
    if (~rst) v_0 <= 8'd0;
167
    else if (pixel_rd_valid) v_0 <= v_in;
168
    else v_0 <= v_0;
169
 
170
  always @(posedge clk)
171
    if (~rst) osd_0 <= 8'd0;
172
    else if (pixel_rd_valid) osd_0 <= osd_in;
173
    else osd_0 <= osd_0;
174
 
175
  always @(posedge clk)
176
    if (~rst) position_in_0 <= ROW_X_COL_X;
177
    else if (pixel_rd_valid) position_in_0 <= position_in;
178
    else position_in_0 <= position_in_0;
179
 
180
  /* read from pixel_fifo */
181
  always @(posedge clk)
182
    if (~rst) pixel_rd_en <= 1'b0;
183
    else
184
      case (state)
185
        STATE_INIT:               pixel_rd_en <= ~pixel_rd_en && ~first_pixel_read;
186
        STATE_WAIT:               pixel_rd_en <= 1'b0;
187
        STATE_FIRST_PIXEL:        pixel_rd_en <= ~pixel_repetition;
188
        STATE_REPEAT_FIRST_PIXEL: pixel_rd_en <= 1'b1;
189
        STATE_PIXEL:              pixel_rd_en <= ~pixel_repetition && ~last_pixel_read; // stop if last pixel of this line read
190
        STATE_REPEAT_PIXEL:       pixel_rd_en <= ~last_pixel_read;
191
        STATE_LAST_PIXEL:         pixel_rd_en <= 1'b0;
192
        STATE_REPEAT_LAST_PIXEL:  pixel_rd_en <= 1'b0;
193
        default                   pixel_rd_en <= 1'b0;
194
      endcase
195
 
196
  /* delay sync gen output */
197
  always @(posedge clk)
198
    if (~rst) h_sync_0 <= 1'b0;
199
    else h_sync_0 <= h_sync_in;
200
 
201
  always @(posedge clk)
202
    if (~rst) v_sync_0 <= 1'b0;
203
    else v_sync_0 <= v_sync_in;
204
 
205
  always @(posedge clk)
206
    if (~rst) pixel_en_0 <= 1'b0;
207
    else pixel_en_0 <= pixel_en_in;
208
 
209
  /* default values of y_out, u_out and v_out are 16, 128, 128, which maps onto black */
210
 
211
  wire displaying = (state == STATE_FIRST_PIXEL) ||
212
                    (state == STATE_REPEAT_FIRST_PIXEL) ||
213
                    (state == STATE_PIXEL) ||
214
                    (state == STATE_REPEAT_PIXEL) ||
215
                    (state == STATE_LAST_PIXEL) ||
216
                    (state == STATE_REPEAT_LAST_PIXEL);
217
 
218
  always @(posedge clk)
219
    if (~rst) y_out <= 8'b0;
220
    else if (pixel_en_2 && displaying) y_out <= y_0;
221
    else y_out <= 8'd16;
222
 
223
  always @(posedge clk)
224
    if (~rst) u_out <= 8'b0;
225
    else if (pixel_en_2 && displaying) u_out <= u_0;
226
    else u_out <= 8'd128;
227
 
228
  always @(posedge clk)
229
    if (~rst) v_out <= 8'b0;
230
    else if (pixel_en_2 && displaying) v_out <= v_0;
231
    else v_out <= 8'd128;
232
 
233
  always @(posedge clk)
234
    if (~rst) osd_out <= 8'b0;
235
    else if (pixel_en_2 && displaying) osd_out <= osd_0;
236
    else osd_out <= 8'd0;
237
 
238
 /*
239
  * delay h_sync, v_sync, pixel_en_out by two clocks
240
  */
241
 
242
  always @(posedge clk)
243
    if (~rst) pixel_en_1 <= 1'b0;
244
    else pixel_en_1 <= pixel_en_0;
245
 
246
  always @(posedge clk)
247
    if (~rst) h_sync_1 <= 1'b0;
248
    else h_sync_1 <= h_sync_0;
249
 
250
  always @(posedge clk)
251
    if (~rst) v_sync_1 <= 1'b0;
252
    else v_sync_1 <= v_sync_0;
253
 
254
  always @(posedge clk)
255
    if (~rst) pixel_en_2 <= 1'b0;
256
    else pixel_en_2 <= pixel_en_1;
257
 
258
  always @(posedge clk)
259
    if (~rst) h_sync_2 <= 1'b0;
260
    else h_sync_2 <= h_sync_1;
261
 
262
  always @(posedge clk)
263
    if (~rst) v_sync_2 <= 1'b0;
264
    else v_sync_2 <= v_sync_1;
265
 
266
  always @(posedge clk)
267
    if (~rst) pixel_en_out <= 1'b0;
268
    else pixel_en_out <= pixel_en_2;
269
 
270
  always @(posedge clk)
271
    if (~rst) h_sync_out <= 1'b0;
272
    else h_sync_out <= h_sync_2;
273
 
274
  always @(posedge clk)
275
    if (~rst) v_sync_out <= 1'b0;
276
    else v_sync_out <= v_sync_2;
277
 
278
`ifdef DEBUG
279
  always @(posedge clk)
280
    case (state)
281
      STATE_INIT:                               #0 $display("%m         STATE_INIT");
282
      STATE_WAIT:                               #0 $display("%m         STATE_WAIT");
283
      STATE_FIRST_PIXEL:                        #0 $display("%m         STATE_FIRST_PIXEL");
284
      STATE_REPEAT_FIRST_PIXEL:                 #0 $display("%m         STATE_REPEAT_FIRST_PIXEL");
285
      STATE_PIXEL:                              #0 $display("%m         STATE_PIXEL");
286
      STATE_REPEAT_PIXEL:                       #0 $display("%m         STATE_REPEAT_PIXEL");
287
      STATE_LAST_PIXEL:                         #0 $display("%m         STATE_LAST_PIXEL");
288
      STATE_REPEAT_LAST_PIXEL:                  #0 $display("%m         STATE_REPEAT_LAST_PIXEL");
289
      default                                   #0 $display("%m         *** Error: unknown state %d", state);
290
    endcase
291
 
292
  always @(posedge clk)
293
    $strobe("%m\tstate: %d y_in %d u_in %d v_in %d osd_in %d position_in %d pixel_rd_en %d pixel_rd_valid %d h_pos %d v_pos %d h_sync_in %d v_sync_in %d pixel_en_in %d y_out %d u_out %d v_out %d osd_out %d h_sync_out %d v_sync_out %d pixel_en_out %d",
294
                 state, y_in, u_in, v_in, osd_in, position_in, pixel_rd_en, pixel_rd_valid, h_pos, v_pos, h_sync_in, v_sync_in, pixel_en_in, y_out, u_out, v_out, osd_out, h_sync_out, v_sync_out, pixel_en_out);
295
 
296
`endif
297
endmodule
298
/* not truncated */

powered by: WebSVN 2.1.0

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