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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * regfile.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
 * regfile - Register file. Provides a set of registers software can read from and write to.
21
 *
22
 * Note: two reset signals are available, hard_rst and rst.
23
 * hard_rst is a reset signal, synchronous to clk, which goes low when the "rst" input pin goes low.
24
 * rst is a reset signal, synchronous to clk, which goes low when either the "rst" input pin goes low or when the watchdog timer expires.
25
 *
26
 * The register file is reset when the "rst" input pin goes low.
27
 * With the exception of the On-Screen-Display, the register file keeps its contents if the watchdog timer expires.
28
 * In particular, the registers with the video condiguration (horizontal_resolution, vertical_resolution, etc.)
29
 * keep their value if the watchdog timer expires. Hence the video modeline does not change if the watchdog timer expires.
30
 *
31
 * If the watchdog timer expires, the decoder is reset and the memory controller initializes external memory to zero.
32
 * External memory includes the On-Screen Display.
33
 * Because the On-Screen Display memory is zeroed out when the watchdog timer expires,
34
 * any On-Screen Display shown when the watchdog timer expires is lost.
35
 * As the On-Screen Display loses its contents when the watchdog timer expires,
36
 * the On-Screen Display is disabled (osd_enable <= 0) when the watchdog timer expires.
37
 * This is the only configuration register which changes value when the watchdog timer expires.
38
 */
39
 
40
`include "timescale.v"
41
 
42
`undef DEBUG
43
//`define DEBUG 1
44
 
45
/* allows software to read version number. eg. VERSION 12 = version 1.2 */
46
`define VERSION 'd12
47
 
48
module regfile    (clk, clk_en, hard_rst, rst,
49
                   reg_addr, reg_wr_en, reg_dta_in, reg_rd_en, reg_dta_out,
50
                   progressive_sequence, horizontal_size, vertical_size, display_horizontal_size, display_vertical_size,
51
                   frame_rate_code, frame_rate_extension_n, frame_rate_extension_d, aspect_ratio_information, mb_width,
52
                   matrix_coefficients, update_picture_buffers,
53
                   horizontal_resolution, horizontal_sync_start, horizontal_sync_end, horizontal_length,
54
                   vertical_resolution, vertical_sync_start, vertical_sync_end, horizontal_halfline, vertical_length,
55
                   interlaced, pixel_repetition, clip_display_size, syncgen_rst,
56
                   watchdog_interval_wr, watchdog_interval, watchdog_status_rd, watchdog_status,
57
                   osd_clt_wr_en, osd_clt_wr_addr, osd_clt_wr_dta,
58
                   osd_enable,
59
                   osd_wr_full, osd_wr_en, osd_wr_ack, osd_wr_addr, osd_wr_dta,
60
                   error, vld_err, interrupt, v_sync,
61
                   deinterlace, repeat_frame, persistence, source_select, flush_vbuf,
62
                   testpoint_sel, testpoint);
63
 
64
  input            clk;
65
  input            clk_en;
66
  input            hard_rst;
67
  input            rst;
68
 
69
  input       [3:0]reg_addr;
70
  input      [31:0]reg_dta_in;
71
  input            reg_wr_en;
72
  output reg [31:0]reg_dta_out;
73
  input            reg_rd_en;
74
 
75
  output reg       error;
76
  input            vld_err;
77
  input            v_sync;
78
  output reg       interrupt;
79
 
80
  input            progressive_sequence;          /* par. 6.3.5 */
81
  input      [13:0]horizontal_size;               /* par. 6.2.2.1, par. 6.3.3 */
82
  input      [13:0]vertical_size;                 /* par. 6.2.2.1, par. 6.3.3 */
83
  input      [13:0]display_horizontal_size;       /* par. 6.2.2.4, par. 6.3.6 */
84
  input      [13:0]display_vertical_size;         /* par. 6.2.2.4, par. 6.3.6 */
85
  input       [3:0]aspect_ratio_information;      /* par. 6.3.3 */
86
  input       [3:0]frame_rate_code;               /* par. 6.3.3, Table 6-4 */
87
  input       [1:0]frame_rate_extension_n;        /* par. 6.3.3, par. 6.3.5 */
88
  input       [4:0]frame_rate_extension_d;        /* par. 6.3.3, par. 6.3.5 */
89
  input       [7:0]mb_width;                      /* par. 6.3.3 */
90
  input       [7:0]matrix_coefficients;           /* par. 6.3.6 */
91
  input            update_picture_buffers;        /* asserted when picture header encountered in bitstream */
92
 
93
  output reg [11:0]horizontal_resolution;         /* horizontal resolution. number of dots per line, minus one  */
94
  output reg [11:0]horizontal_sync_start;         /* the dot the horizontal sync pulse begins. */
95
  output reg [11:0]horizontal_sync_end;           /* the dot the horizontal sync pulse ends. */
96
  output reg [11:0]horizontal_length;             /* total horizontal length */
97
 
98
  output reg [11:0]vertical_resolution;           /* vertical resolution. number of visible lines per frame (progressive) or field (interlaced), minus one */
99
  output reg [11:0]vertical_sync_start;           /* the line number within the frame (progressive) or field (interlaced) the vertical sync pulse begins. */
100
  output reg [11:0]vertical_sync_end;             /* the line number within the frame (progressive) or field (interlaced) the vertical sync pulse ends. */
101
  output reg [11:0]horizontal_halfline;           /* the dot the vertical sync begins on odd frames of interlaced video. Not used in progressive mode. */
102
  output reg [11:0]vertical_length;               /* total number of lines of a vertical frame (progressive) or field (interlaced) */
103
 
104
  output reg       clip_display_size;             /* assert to clip image to (display_horizontal_size, display_vertical_size) */
105
  output reg       interlaced;                    /* assert if interlaced output required. */
106
  output reg       pixel_repetition;              /* assert for dot clock rates < 25 MHz, repeats each pixel once */
107
  output reg       syncgen_rst;                   /* reset sync generator whenever modeline parameter is changed */
108
 
109
  output reg  [7:0]watchdog_interval;             /* watchdog interval. 255 = never expire; 0 = expire immediate. */
110
  output reg       watchdog_interval_wr;          /* asserted when the watchdog interval is written */
111
  output reg       watchdog_status_rd;            /* asserted when the watchdog status is read */
112
  input            watchdog_status;               /* high if watchdog expired */
113
 
114
                                                  /* On-Screen Display Color Lookup Table */
115
  output reg       osd_clt_wr_en;                 /* assert when updating clt */
116
  output reg  [7:0]osd_clt_wr_addr;               /* color lookup table address, 8 bits */
117
  output reg [31:0]osd_clt_wr_dta;                /* color lookup table entry, 32 bits: 8 bits y, 8 bits u, 8 bits v, 8 bits mode. See matrix_coefficients for yuv coding details */
118
  output reg       osd_enable;                    /* assert to show osd */
119
 
120
                                                  /* On-Screen Display framestore_writer */
121
  input            osd_wr_full;                   /* high when osd framestore_writer fifo full */
122
  input            osd_wr_ack;                    /* asserted if previous clocks' osd write successful */
123
  output           osd_wr_en;                     /* assert to write osd_wr_dta to osd_wr_addr */
124
  output     [21:0]osd_wr_addr;                   /* osd address */
125
  output     [63:0]osd_wr_dta;                    /* osd data */
126
 
127
  reg        [31:0]osd_wr_dta_high;
128
  reg        [31:0]osd_wr_dta_low;
129
  reg              osd_wr_en_in;
130
  reg         [2:0]osd_frame;                     /* frame of line to be written. Always OSD_FRAME for OSD writes.  */
131
  reg         [1:0]osd_comp;                      /* component of line to be written. Always COMP_Y for OSD writes.  */
132
  reg         [7:0]osd_x;                         /* x coordinate of line to be written, divided by 8 */
133
  reg        [10:0]osd_y;                         /* y coordinate of line to be written */
134
 
135
  reg              osd_wr_en_0;
136
  reg              osd_wr_en_sav;                 /* set when osd write registered; cleared when status register read */
137
  reg              osd_wr_ack_sav;                /* set when osd write successful; cleared when status register read */
138
  reg              picture_hdr;                   /* set when picture header encountered in bitstream; cleared when status register read */
139
  reg              frame_end;                     /* set when displaying pixel 0 of line 0; cleared when status register read */
140
  reg              video_ch;                      /* set when video resolution or frame rate changes; cleared when status register read */
141
 
142
  reg              video_ch_intr_en;              /* normally low; assert to generate interrupts when video resolution/frame rate changes */
143
  reg              frame_end_intr_en;             /* normally low; assert to generate interrupts when vertical sync begins */
144
  reg              picture_hdr_intr_en;           /* normally low; assert to generate interrupts when picture header encountered */
145
 
146
  output reg       deinterlace;                   /* assert if video has to be deinterlaced */
147
  output reg  [4:0]repeat_frame;                  /* repeat decoded images */
148
  output reg       persistence;                   /* last decoded image persists */
149
  output reg  [2:0]source_select;                 /* select video out source */
150
  output reg       flush_vbuf;                    /* flush video buffer */
151
 
152
  output reg  [3:0]testpoint_sel;                 /* selects one of up to 16 internal test points to be muxed to the logical analyzer probe testpoint */
153
  input      [31:0]testpoint;                     /* bits 31..0 of test point, synchronized  to clk */
154
 
155
`include "modeline.v"
156
`include "mem_codes.v"
157
`include "vld_codes.v"
158
 
159
  /*
160
   * Verify all changes to REG_RD_STATUS (watchdog_status) and REG_WR_STREAM (watchdog_interval) with watchdog.v
161
   */
162
 
163
`include "regfile_codes.v"
164
 
165
  /*
166
   * watchdog timer setting at power-up. Setting the watchdog timer to 8'd255
167
   * will turn the watchdog circuit off.
168
   */
169
 
170
  parameter [7:0]
171
    DEFAULT_WATCHDOG_TIMER= 8'd127;
172
//    DEFAULT_WATCHDOG_TIMER= 8'd255; // watchdog disable
173
 
174
  /*
175
   * reading registers
176
   */
177
 
178
  always @(posedge clk)
179
    if (~hard_rst) reg_dta_out <= 32'b0;
180
    else if (clk_en && reg_rd_en)
181
      case (reg_addr)
182
        REG_RD_VERSION:               reg_dta_out <= {16'd0, 16`VERSION};
183
        REG_RD_STATUS:                reg_dta_out <= {16'd0, matrix_coefficients, watchdog_status, osd_wr_en_sav, osd_wr_ack_sav, osd_wr_full, picture_hdr, frame_end, video_ch, error};
184
        REG_RD_SIZE:                  reg_dta_out <= {2'b0, horizontal_size, 2'b0, vertical_size};
185
        REG_RD_DISP_SIZE:             reg_dta_out <= {2'b0, display_horizontal_size, 2'b0, display_vertical_size};
186
        REG_RD_FRAME_RATE:            reg_dta_out <= {16'b0, aspect_ratio_information, progressive_sequence, frame_rate_extension_d, frame_rate_extension_n, frame_rate_code};
187
        REG_RD_TESTPOINT:             reg_dta_out <= testpoint;
188
        default:                      reg_dta_out <= 32'b0;
189
      endcase
190
    else reg_dta_out <= reg_dta_out;
191
 
192
  /*
193
   * REG_RD_STATUS
194
   */
195
 
196
  always @(posedge clk)
197
    if (~hard_rst) watchdog_status_rd <= 1'b0;
198
    else if (clk_en) watchdog_status_rd <= (reg_rd_en && (reg_addr == REG_RD_STATUS)); // assert when status register read
199
    else watchdog_status_rd <= watchdog_status_rd;
200
 
201
  always @(posedge clk)
202
    if (~hard_rst) osd_wr_en_0 <= 1'b0;
203
    else if (clk_en) osd_wr_en_0 <= osd_wr_en;
204
    else osd_wr_en_0 <= osd_wr_en_0;
205
 
206
  always @(posedge clk)
207
    if (~hard_rst) osd_wr_ack_sav <= 1'b0;
208
    else if (clk_en && osd_wr_en_0) osd_wr_ack_sav <= osd_wr_ack;
209
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) osd_wr_ack_sav <= 1'b0;
210
    else osd_wr_ack_sav <= osd_wr_ack_sav;
211
 
212
  always @(posedge clk)
213
    if (~hard_rst) osd_wr_en_sav <= 1'b0;
214
    else if (clk_en && osd_wr_en_0) osd_wr_en_sav <= 1'b1;
215
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) osd_wr_en_sav <= 1'b0;
216
    else osd_wr_en_sav <= osd_wr_en_sav;
217
 
218
  always @(posedge clk)
219
    if (~hard_rst) picture_hdr <= 1'b0;
220
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) picture_hdr <= 1'b0;
221
    else if (clk_en) picture_hdr <= picture_hdr || update_picture_buffers;
222
    else picture_hdr <= picture_hdr;
223
 
224
  /* video frame end indicator, set at vertical sync start */
225
  reg              v_sync_0;
226
 
227
  always @(posedge clk)
228
    if (~hard_rst) v_sync_0 <= 1'b0;
229
    else if (clk_en) v_sync_0 <= v_sync;
230
    else v_sync_0 <= v_sync_0;
231
 
232
  always @(posedge clk)
233
    if (~hard_rst) frame_end <= 1'b0;
234
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) frame_end <= 1'b0;
235
    else if (clk_en) frame_end <= frame_end || (v_sync && ~v_sync_0);
236
    else frame_end <= frame_end;
237
 
238
  /* video modeline change indicator */
239
 
240
  wire       [71:0]current_vid_params = {horizontal_size, vertical_size, display_horizontal_size, display_vertical_size, progressive_sequence, aspect_ratio_information, frame_rate_code, frame_rate_extension_n, frame_rate_extension_d};
241
  reg        [71:0]previous_vid_params;
242
  wire             video_params_changed = update_picture_buffers && (previous_vid_params != current_vid_params);
243
 
244
  always @(posedge clk)
245
    if (~hard_rst) previous_vid_params <= 72'b0;
246
    else if (clk_en && update_picture_buffers) previous_vid_params <= current_vid_params;
247
    else previous_vid_params <= previous_vid_params;
248
 
249
  always @(posedge clk)
250
    if (~hard_rst) video_ch <= 1'b0;
251
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) video_ch <= video_params_changed;
252
    else if (clk_en) video_ch <= video_ch || video_params_changed;
253
    else video_ch <= video_ch;
254
 
255
  /* error flag is set when vld error occurs; cleared whenever status register is read */
256
 
257
  always @(posedge clk)
258
    if (~hard_rst) error <= 1'b0;
259
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) error <= 1'b0;
260
    else if (clk_en) error <= error || vld_err;
261
    else error <= error;
262
 
263
  /*
264
   * REG_WR_STREAM
265
   */
266
 
267
  always @(posedge clk)
268
    if (~hard_rst) watchdog_interval_wr <= 1'b0;
269
    else if (clk_en) watchdog_interval_wr <= (reg_wr_en && (reg_addr == REG_WR_STREAM)); // assert when new watchdog_interval written
270
    else watchdog_interval_wr <= watchdog_interval_wr;
271
 
272
  always @(posedge clk)
273
    if (~hard_rst) watchdog_interval <= DEFAULT_WATCHDOG_TIMER;
274
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_STREAM)) watchdog_interval <= reg_dta_in[15:8]; // new watchdog_interval 
275
    else watchdog_interval <= watchdog_interval;
276
 
277
  always @(posedge clk)
278
    if (~hard_rst) osd_enable <= 1'b0;
279
    else if (~rst) osd_enable <= 1'b0; // switch off OSD if watchdog timer expires
280
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_STREAM)) osd_enable <= reg_dta_in[3];
281
    else osd_enable <= osd_enable;
282
 
283
  always @(posedge clk)
284
    if (~hard_rst) picture_hdr_intr_en <= 1'b0;
285
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_STREAM)) picture_hdr_intr_en <= reg_dta_in[2];
286
    else picture_hdr_intr_en <= picture_hdr_intr_en;
287
 
288
  always @(posedge clk)
289
    if (~hard_rst) frame_end_intr_en <= 1'b0;
290
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_STREAM)) frame_end_intr_en <= reg_dta_in[1];
291
    else frame_end_intr_en <= frame_end_intr_en;
292
 
293
  always @(posedge clk)
294
    if (~hard_rst) video_ch_intr_en <= 1'b0;
295
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_STREAM)) video_ch_intr_en <= reg_dta_in[0];
296
    else video_ch_intr_en <= video_ch_intr_en;
297
 
298
  /*
299
   * REG_WR_HOR
300
   */
301
 
302
  always @(posedge clk)
303
    if (~hard_rst) horizontal_resolution <= HORZ_RES;
304
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_HOR)) horizontal_resolution <= reg_dta_in[27:16];
305
    else horizontal_resolution <= horizontal_resolution;
306
 
307
  always @(posedge clk)
308
    if (~hard_rst) horizontal_length <= HORZ_LEN;
309
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_HOR)) horizontal_length <= reg_dta_in[11:0];
310
    else horizontal_length <= horizontal_length;
311
 
312
  /*
313
   * REG_WR_HOR_SYNC
314
   */
315
 
316
  always @(posedge clk)
317
    if (~hard_rst) horizontal_sync_start <= HORZ_SYNC_STRT;
318
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_HOR_SYNC)) horizontal_sync_start <= reg_dta_in[27:16];
319
    else horizontal_sync_start <= horizontal_sync_start;
320
 
321
  always @(posedge clk)
322
    if (~hard_rst) horizontal_sync_end <= HORZ_SYNC_END;
323
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_HOR_SYNC)) horizontal_sync_end <= reg_dta_in[11:0];
324
    else horizontal_sync_end <= horizontal_sync_end;
325
 
326
  /*
327
   * REG_WR_VER
328
   */
329
 
330
  always @(posedge clk)
331
    if (~hard_rst) vertical_resolution <= VERT_RES;
332
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_VER)) vertical_resolution <= reg_dta_in[27:16];
333
    else vertical_resolution <= vertical_resolution;
334
 
335
  always @(posedge clk)
336
    if (~hard_rst) vertical_length <= VERT_LEN;
337
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_VER)) vertical_length <= reg_dta_in[11:0];
338
    else vertical_length <= vertical_length;
339
 
340
  /*
341
   * REG_WR_VER_SYNC
342
   */
343
 
344
  always @(posedge clk)
345
    if (~hard_rst) vertical_sync_start <= VERT_SYNC_STRT;
346
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_VER_SYNC)) vertical_sync_start <= reg_dta_in[27:16];
347
    else vertical_sync_start <= vertical_sync_start;
348
 
349
  always @(posedge clk)
350
    if (~hard_rst) vertical_sync_end <= VERT_SYNC_END;
351
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_VER_SYNC)) vertical_sync_end <= reg_dta_in[11:0];
352
    else vertical_sync_end <= vertical_sync_end;
353
 
354
  /*
355
   * REG_WR_VID_MODE
356
   */
357
 
358
  always @(posedge clk)
359
    if (~hard_rst) horizontal_halfline <= HALFLINE;
360
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_VID_MODE)) horizontal_halfline <= reg_dta_in[27:16];
361
    else horizontal_halfline <= horizontal_halfline;
362
 
363
  /*
364
   * If pixel_repetition is asserted, each pixel is output twice.
365
   * This can be used if the original dotclock is too low for the transmitter.
366
   * As an example, DVI and HDMI may require a dot clock of 25...165 MHz.
367
   * An SDTV image may have a dotclock of 13.5 MHz; asserting pixel_repetition
368
   * and doubling dotclock results in a dotclock of 27 MHz and
369
   * allows video to be transmitted across the link.
370
   */
371
 
372
  always @(posedge clk)
373
    if (~hard_rst) {clip_display_size, pixel_repetition, interlaced} <= VID_MODE;
374
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_VID_MODE)) {clip_display_size, pixel_repetition, interlaced} <= reg_dta_in[2:0];
375
    else {clip_display_size, pixel_repetition, interlaced} <= {clip_display_size, pixel_repetition, interlaced};
376
 
377
  /*
378
   * REG_WR_CLT_YUVM
379
   */
380
 
381
  always @(posedge clk)
382
    if (~hard_rst) osd_clt_wr_dta <= 32'b0;
383
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_CLT_YUVM)) osd_clt_wr_dta <= reg_dta_in;
384
    else osd_clt_wr_dta <= osd_clt_wr_dta;
385
 
386
  /*
387
   * REG_WR_CLT_ADDR
388
   */
389
 
390
  always @(posedge clk)
391
    if (~hard_rst) osd_clt_wr_addr <= 8'b0;
392
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_CLT_ADDR)) osd_clt_wr_addr <= reg_dta_in[7:0];
393
    else osd_clt_wr_addr <= osd_clt_wr_addr;
394
 
395
  always @(posedge clk)
396
    if (~hard_rst) osd_clt_wr_en <= 1'b0;
397
    else if (clk_en) osd_clt_wr_en <= (reg_addr == REG_WR_CLT_ADDR) && reg_wr_en;
398
    else osd_clt_wr_en <= osd_clt_wr_en;
399
 
400
  /*
401
   * REG_WR_OSD_DTA_HIGH
402
   */
403
 
404
  always @(posedge clk)
405
    if (~hard_rst) osd_wr_dta_high <= 32'b0;
406
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_OSD_DTA_HIGH)) osd_wr_dta_high <= reg_dta_in;
407
    else osd_wr_dta_high <= osd_wr_dta_high;
408
 
409
  /*
410
   * REG_WR_OSD_DTA_LOW
411
   */
412
 
413
  always @(posedge clk)
414
    if (~hard_rst) osd_wr_dta_low <= 32'b0;
415
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_OSD_DTA_LOW)) osd_wr_dta_low <= reg_dta_in;
416
    else osd_wr_dta_low <= osd_wr_dta_low;
417
 
418
  /*
419
   * REG_WR_OSD_ADDR
420
   */
421
 
422
  always @(posedge clk)
423
    if (~hard_rst) osd_frame <= 3'b0;
424
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_OSD_ADDR)) osd_frame <= reg_dta_in[31:29]; // Always OSD_FRAME for OSD writes
425
    else osd_frame <= osd_frame;
426
 
427
  always @(posedge clk)
428
    if (~hard_rst) osd_comp <= 2'b0;
429
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_OSD_ADDR)) osd_comp <= reg_dta_in[28:27]; // Always COMP_Y for OSD writes
430
    else osd_comp <= osd_comp;
431
 
432
  always @(posedge clk)
433
    if (~hard_rst) osd_x <= 8'b0;
434
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_OSD_ADDR)) osd_x <= reg_dta_in[26:19]; // reg_dta_in[18:16] has to be 3'b0, as osd_addr_x has to be a multiple of 8
435
    else osd_x <= osd_x;
436
 
437
  always @(posedge clk)
438
    if (~hard_rst) osd_y <= 11'b0;
439
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_OSD_ADDR)) osd_y <= reg_dta_in[10:0];
440
    else osd_y <= osd_y;
441
 
442
  always @(posedge clk)
443
    if (~hard_rst) osd_wr_en_in <= 1'b0;
444
    else if (clk_en && reg_wr_en) osd_wr_en_in <= (reg_addr == REG_WR_OSD_ADDR) && ~osd_wr_full;
445
    else if (clk_en) osd_wr_en_in <= 1'b0;
446
    else osd_wr_en_in <= osd_wr_en_in;
447
 
448
  /*
449
   * REG_WR_TRICK
450
   */
451
 
452
  always @(posedge clk)
453
    if (~hard_rst) deinterlace <= 1'b1;
454
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_TRICK)) deinterlace <= reg_dta_in[10];
455
    else deinterlace <= deinterlace;
456
 
457
  always @(posedge clk)
458
    if (~hard_rst) repeat_frame <= 5'd0;
459
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_TRICK)) repeat_frame <= reg_dta_in[9:5];
460
    else repeat_frame <= repeat_frame;
461
 
462
  always @(posedge clk)
463
    if (~hard_rst) persistence <= 1'b1;
464
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_TRICK)) persistence <= reg_dta_in[4];
465
    else persistence <= persistence;
466
 
467
  always @(posedge clk)
468
    if (~hard_rst) source_select <= 3'b0;
469
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_TRICK)) source_select <= reg_dta_in[3:1];
470
    else source_select <= source_select;
471
 
472
  /*
473
   * Signal used to clear circular video buffer.
474
   * This includes resetting FIFO's. For  Xilinx FIFO18/FIFO36 primitives:
475
   * "The reset signal must be high for at least three read clock and three write clock cycles."
476
   */
477
 
478
  always @(posedge clk)
479
    if (~hard_rst) flush_vbuf <= 1'b1;
480
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_TRICK)) flush_vbuf <= reg_dta_in[0];
481
    else if (clk_en) flush_vbuf <= 1'b0;
482
    else flush_vbuf <= flush_vbuf;
483
 
484
  /*
485
   * REG_WR_TESTPOINT
486
   */
487
 
488
  always @(posedge clk)
489
    if (~hard_rst) testpoint_sel <= 4'b0;
490
    else if (clk_en && reg_wr_en && (reg_addr == REG_WR_TESTPOINT)) testpoint_sel <= reg_dta_in[31:28];
491
    else testpoint_sel <= testpoint_sel;
492
 
493
  /*
494
   * Reset sync_gen when video modeline changes
495
   */
496
 
497
  always @(posedge clk)
498
    if (~hard_rst) syncgen_rst <= 1'b0;
499
    else if (clk_en) syncgen_rst <= ~(reg_wr_en && ((reg_addr == REG_WR_HOR) || (reg_addr == REG_WR_HOR_SYNC) || (reg_addr == REG_WR_VER) || (reg_addr == REG_WR_VER_SYNC) || (reg_addr == REG_WR_VID_MODE)));
500
    else syncgen_rst <= syncgen_rst;
501
 
502
  /*
503
   * interrupt.
504
   * assert interrupt whenever one of the following signals changes:
505
   * horizontal_size, vertical_size, display_horizontal_size, display_vertical_size, aspect_ratio_information,
506
   * progressive_sequence, aspect_ratio_information, frame_rate_extension_n, frame_rate_extension_d, frame_rate_code.
507
   */
508
 
509
  always @(posedge clk)
510
    if (~hard_rst) interrupt <= 1'b0;
511
    else if (clk_en && reg_rd_en && (reg_addr == REG_RD_STATUS)) interrupt <= 1'b0; // reset when REG_RD_STATUS read
512
    else if (clk_en) interrupt <= interrupt || (video_ch_intr_en && video_ch) || (frame_end_intr_en && frame_end) || (picture_hdr_intr_en && picture_hdr); // set when video modeline changes, vertical sync begins or picture header encountered.
513
    else interrupt <= interrupt;
514
 
515
  /*
516
   * OSD write address generator
517
   */
518
 
519
  wire         [63:0]osd_wr_dta_in = {osd_wr_dta_high, osd_wr_dta_low};
520
  wire signed  [12:0]osd_x_in = {2'b0, osd_x, 3'b0}; // osd_x is x-coordinate, divided by 8.
521
  wire signed  [12:0]osd_y_in = {2'b0, osd_y};
522
 
523
  /* osd address generator */
524
  memory_address
525
    #(.dta_width(64))
526
    osd_mem_addr (
527
    .clk(clk),
528
    .clk_en(clk_en),
529
    .rst(rst),
530
    /* in */
531
    .frame(osd_frame),
532
    .frame_picture(1'b1),
533
    .field_in_frame(1'b0),
534
    .field(1'b0),
535
    .component(osd_comp),
536
    .mb_width(mb_width),
537
    .horizontal_size(horizontal_size),
538
    .vertical_size(vertical_size),
539
    .macroblock_address(13'd0),
540
    .delta_x(osd_x_in),
541
    .delta_y(osd_y_in),
542
    .mv_x(13'sd0),
543
    .mv_y(13'sd0),
544
    .dta_in(osd_wr_dta_in),
545
    .valid_in(osd_wr_en_in),
546
    /* out */
547
    .address(osd_wr_addr),
548
    .offset_x(),
549
    .halfpixel_x(),
550
    .halfpixel_y(),
551
    .dta_out(osd_wr_dta),
552
    .valid_out(osd_wr_en)
553
    );
554
 
555
`ifdef DEBUG
556
  always @(posedge clk)
557
    if (clk_en)
558
      $strobe("%m\treg_addr: %d reg_rd_en: %d reg_wr_en: %d reg_dta_out: %h reg_dta_in: %h", reg_addr, reg_rd_en, reg_wr_en, reg_dta_out, reg_dta_in);
559
 
560
  always @(posedge clk)
561
    if (clk_en)
562
      $strobe("%m\tosd_x_in: %d osd_y_in: %d osd_wr_dta_in: %h osd_wr_en_in: %d mb_width: %d", osd_x_in, osd_y_in, osd_wr_dta_in, osd_wr_en_in, mb_width);
563
 
564
  always @(posedge clk)
565
    if (clk_en)
566
      $strobe("%m\tosd_wr_addr: %h osd_wr_dta: %h osd_wr_en: %d", osd_wr_addr, osd_wr_dta, osd_wr_en);
567
`endif
568
endmodule
569
/* not truncated */

powered by: WebSVN 2.1.0

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