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

Subversion Repositories mpeg2fpga

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * framestore_request.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
 * Frame Store Requests. Write requests to memory controller.
21
 *
22
 * Receives memory read and write requests from motion compensation and display;
23
 * passes the read and write requests on to the memory controller.
24
 */
25
 
26
`include "timescale.v"
27
 
28
`undef DEBUG
29
//`define DEBUG 1
30
 
31
`undef DEBUG_2
32
//`define DEBUG_2
33
 
34
`undef CHECK
35
`ifdef __IVERILOG__
36
`define CHECK 1
37
`endif
38
 
39
//`define SIMULATION_ONLY
40
`ifdef __IVERILOG__
41
`define SIMULATION_ONLY 1
42
`endif
43
 
44
module framestore_request(rst, clk,
45
                  fwd_rd_addr_empty, fwd_rd_addr_en, fwd_rd_addr_valid, fwd_rd_addr, fwd_wr_dta_full, fwd_wr_dta_almost_full, fwd_rd_dta_almost_empty,
46
                  bwd_rd_addr_empty, bwd_rd_addr_en, bwd_rd_addr_valid, bwd_rd_addr, bwd_wr_dta_full, bwd_wr_dta_almost_full, bwd_rd_dta_almost_empty,
47
                  recon_rd_empty, recon_rd_almost_empty, recon_rd_en, recon_rd_valid, recon_rd_addr, recon_rd_dta, recon_wr_almost_full,
48
                  disp_rd_addr_empty, disp_rd_addr_en, disp_rd_addr_valid, disp_rd_addr, disp_wr_dta_full, disp_wr_dta_almost_full, disp_rd_dta_almost_empty,
49
                  osd_rd_empty, osd_rd_almost_empty, osd_rd_en, osd_rd_valid, osd_rd_addr, osd_rd_dta, osd_wr_almost_full,
50
                  vbw_rd_empty, vbw_rd_almost_empty, vbw_rd_en, vbw_rd_valid, vbw_rd_dta, vbw_wr_almost_full,
51
                  vbr_wr_full, vbr_wr_almost_full, vbr_rd_almost_empty,
52
                  vb_flush,
53
                  mem_req_wr_cmd, mem_req_wr_addr, mem_req_wr_dta, mem_req_wr_en, mem_req_wr_almost_full,
54
                  tag_wr_dta, tag_wr_en, tag_wr_almost_full
55
                  );
56
 
57
  input            rst;
58
  input            clk;
59
  /* motion compensation: reading forward reference frame */
60
  input             fwd_rd_addr_empty;
61
  output reg        fwd_rd_addr_en;
62
  input             fwd_rd_addr_valid;
63
  input       [21:0]fwd_rd_addr;
64
  input             fwd_wr_dta_full;
65
  input             fwd_wr_dta_almost_full;
66
  input             fwd_rd_dta_almost_empty;
67
  /* motion compensation: reading backward reference frame */
68
  input             bwd_rd_addr_empty;
69
  output reg        bwd_rd_addr_en;
70
  input             bwd_rd_addr_valid;
71
  input       [21:0]bwd_rd_addr;
72
  input             bwd_wr_dta_full;
73
  input             bwd_wr_dta_almost_full;
74
  input             bwd_rd_dta_almost_empty;
75
  /*  motion compensation: writing reconstructed frame */
76
  input             recon_rd_empty;
77
  input             recon_rd_almost_empty;
78
  output reg        recon_rd_en;
79
  input             recon_rd_valid;
80
  input       [21:0]recon_rd_addr;
81
  input       [63:0]recon_rd_dta;
82
  input             recon_wr_almost_full;
83
  /* display: reading reconstructed frame */
84
  input             disp_rd_addr_empty;
85
  output reg        disp_rd_addr_en;
86
  input             disp_rd_addr_valid;
87
  input       [21:0]disp_rd_addr;
88
  input             disp_wr_dta_full;
89
  input             disp_wr_dta_almost_full;
90
  input             disp_rd_dta_almost_empty;
91
  /* video buffer: writing to circular buffer */
92
  input       [63:0]vbw_rd_dta;
93
  output reg        vbw_rd_en;
94
  input             vbw_rd_valid;
95
  input             vbw_rd_empty;
96
  input             vbw_rd_almost_empty;
97
  input             vbw_wr_almost_full;
98
  /* video buffer: reading from circular buffer */
99
  input             vbr_wr_full;
100
  input             vbr_wr_almost_full;
101
  input             vbr_rd_almost_empty;
102
  /* video buffer: flushing circular buffer */
103
  input             vb_flush;
104
  /*  register file: writing on-screen display */
105
  input             osd_rd_empty;
106
  input             osd_rd_almost_empty;
107
  output reg        osd_rd_en;
108
  input             osd_rd_valid;
109
  input       [21:0]osd_rd_addr;
110
  input       [63:0]osd_rd_dta;
111
  input             osd_wr_almost_full;
112
  /* memory request fifo */
113
  output reg   [1:0]mem_req_wr_cmd;
114
  output reg  [21:0]mem_req_wr_addr;
115
  output reg  [63:0]mem_req_wr_dta;
116
  output reg        mem_req_wr_en;
117
  input             mem_req_wr_almost_full;
118
  /* memory tag fifo */
119
  output reg   [2:0]tag_wr_dta;
120
  output reg        tag_wr_en;
121
  input             tag_wr_almost_full;
122
 
123
 parameter [15:0]
124
   REFRESH_CYCLES = 16'd1024; /* number of mem_clk clock cycles between memory refreshes. */
125
 
126
 parameter
127
   REFRESH_EN = 1'b0; /* 1 if needs to issue REFRESH; 0 if no need to issue refresh commands, eg. sram */
128
 
129
 /*
130
  * memory controller commands.
131
  */
132
 
133
`include "mem_codes.v"
134
 
135
  wire do_refresh;
136
  wire do_disp;
137
  wire do_vbr;
138
  wire do_fwd;
139
  wire do_bwd;
140
  wire do_recon;
141
  wire do_osd;
142
  wire do_vbw;
143
 
144
  /*
145
   * memory clear address
146
   */
147
 
148
  reg [21:0]mem_clr_addr;
149
  reg [21:0]mem_clr_addr_0;
150
 
151
  /*
152
   * circular video buffer addresses
153
   */
154
 
155
  reg [21:0]vbuf_wr_addr;
156
  reg [21:0]vbuf_rd_addr;
157
 
158
  reg       vbuf_full;
159
  reg       vbuf_empty;
160
 
161
  /*
162
   * State machine
163
   * Implements priority scheme.
164
   * From highest to lowest priority:
165
   * - disp  display read
166
   * - vbr   video buffer read
167
   * - fwd   forward motion compensation read
168
   * - bwd   backward motion compensation read
169
   * - vbw   video buffer write
170
   * - recon motion compensation write
171
   * - osd   on-screen display write
172
   * Roughly modeled after the priority scheme in
173
   * "Architecture and Bus-Arbitration Schemes for MPEG-2 Video Decoder",
174
   * Jui-Hua Li and Nam Ling,
175
   * IEEE Transactions on Circuits and Systems for Video Technology, Vol. 9, No. 5, August 1999, p.727-736.
176
   */
177
 
178
 
179
  parameter [10:0]
180
    STATE_INIT        = 11'b00000000001,
181
    STATE_CLEAR       = 11'b00000000010,
182
    STATE_IDLE        = 11'b00000000100,
183
    STATE_REFRESH     = 11'b00000001000,
184
    STATE_DISP        = 11'b00000010000,
185
    STATE_VBR         = 11'b00000100000,
186
    STATE_FWD         = 11'b00001000000,
187
    STATE_BWD         = 11'b00010000000,
188
    STATE_VBW         = 11'b00100000000,
189
    STATE_RECON       = 11'b01000000000,
190
    STATE_OSD         = 11'b10000000000;
191
 
192
  reg  [10:0]state;
193
  reg  [10:0]next;
194
  reg  [10:0]previous;
195
 
196
  /* next state logic */
197
  always @*
198
    case (state)
199
      STATE_INIT:       next = STATE_CLEAR;
200
      STATE_CLEAR:      if ((mem_clr_addr == VBUF_END) && ~mem_req_wr_almost_full) next = STATE_IDLE; // initialize memory
201
                        else next = STATE_CLEAR;
202
      STATE_IDLE,
203
      STATE_DISP,
204
      STATE_VBR,
205
      STATE_FWD,
206
      STATE_BWD,
207
      STATE_VBW,
208
      STATE_RECON,
209
      STATE_OSD:         if (do_refresh) next = STATE_REFRESH;                                 // schedule a dram refresh
210
                         else if (do_disp) next = STATE_DISP;                                  // schedule a read for the display fifo
211
                         else if (do_vbr) next = STATE_VBR;                                    // schedule a read from circular video buffer
212
                         else if (do_fwd) next = STATE_FWD;                                    // schedule a read for forward motion compensation
213
                         else if (do_bwd) next = STATE_BWD;                                    // schedule a read for backward motion compensation
214
                         else if (do_vbw) next = STATE_VBW;                                    // schedule a write to circular video buffer
215
                         else if (do_recon) next = STATE_RECON;                                // schedule a write for motion compensation to write the reconstructed frame
216
                         else if (do_osd) next = STATE_OSD;                                    // schedule a write for register file to write to the on-screen display
217
                         else next = STATE_IDLE;                                               // nothing to do
218
 
219
      STATE_REFRESH:     if (do_disp) next = STATE_DISP;
220
                         else if (do_vbr) next = STATE_VBR;
221
                         else if (do_fwd) next = STATE_FWD;
222
                         else if (do_bwd) next = STATE_BWD;
223
                         else if (do_vbw) next = STATE_VBW;
224
                         else if (do_recon) next = STATE_RECON;
225
                         else if (do_osd) next = STATE_OSD;
226
                         else next = STATE_IDLE;
227
 
228
      default            next = STATE_IDLE;
229
 
230
    endcase
231
 
232
  always @(posedge clk)
233
    if (~rst) state <= STATE_INIT;
234
    else state <= next;
235
 
236
  always @(posedge clk)
237
    if (~rst) previous <= STATE_INIT;
238
    else previous <= state;
239
 
240
  /*
241
   * Read data from fifo's
242
   */
243
 
244
  always @(posedge clk)
245
    if (~rst) disp_rd_addr_en <= 1'b0;
246
    else disp_rd_addr_en <= (next == STATE_DISP);
247
 
248
  always @(posedge clk)
249
    if (~rst) fwd_rd_addr_en <= 1'b0;
250
    else fwd_rd_addr_en <= (next == STATE_FWD);
251
 
252
  always @(posedge clk)
253
    if (~rst) bwd_rd_addr_en <= 1'b0;
254
    else bwd_rd_addr_en <= (next == STATE_BWD);
255
 
256
  always @(posedge clk)
257
    if (~rst) recon_rd_en <= 1'b0;
258
    else recon_rd_en <= (next == STATE_RECON);
259
 
260
  always @(posedge clk)
261
    if (~rst) vbw_rd_en <= 1'b0;
262
    else vbw_rd_en <= (next == STATE_VBW);
263
 
264
  always @(posedge clk)
265
    if (~rst) osd_rd_en <= 1'b0;
266
    else osd_rd_en <= (next == STATE_OSD);
267
 
268
  /*
269
   * Write address, data, command to memory request fifo.
270
   * Write tag to tag fifo.
271
   */
272
 
273
  always @(posedge clk)
274
    if (~rst) tag_wr_dta <= TAG_CTRL;
275
    else
276
      case (previous)
277
        STATE_INIT:        tag_wr_dta <= TAG_CTRL;
278
        STATE_CLEAR:       tag_wr_dta <= TAG_CTRL;
279
        STATE_IDLE:        tag_wr_dta <= TAG_CTRL;
280
        STATE_REFRESH:     tag_wr_dta <= TAG_CTRL;
281
        STATE_DISP:        tag_wr_dta <= TAG_DISP;
282
        STATE_VBR:         tag_wr_dta <= TAG_VBUF;
283
        STATE_FWD:         tag_wr_dta <= TAG_FWD;
284
        STATE_BWD:         tag_wr_dta <= TAG_BWD;
285
        STATE_RECON:       tag_wr_dta <= TAG_RECON;
286
        STATE_VBW:         tag_wr_dta <= TAG_VBUF;
287
        STATE_OSD:         tag_wr_dta <= TAG_OSD;
288
        default            tag_wr_dta <= TAG_CTRL;
289
      endcase
290
 
291
  always @(posedge clk)
292
    if (~rst) tag_wr_en <= 1'b0;
293
    else
294
      case (previous)
295
        STATE_INIT:        tag_wr_en <= 1'b0;
296
        STATE_CLEAR:       tag_wr_en <= 1'b0;
297
        STATE_IDLE:        tag_wr_en <= 1'b0;
298
        STATE_REFRESH:     tag_wr_en <= 1'b0;
299
        STATE_DISP:        tag_wr_en <= disp_rd_addr_valid;
300
        STATE_VBR:         tag_wr_en <= ~vbuf_empty;
301
        STATE_FWD:         tag_wr_en <= fwd_rd_addr_valid;
302
        STATE_BWD:         tag_wr_en <= bwd_rd_addr_valid;
303
        STATE_RECON:       tag_wr_en <= 1'b0;
304
        STATE_VBW:         tag_wr_en <= 1'b0;
305
        STATE_OSD:         tag_wr_en <= 1'b0;
306
        default            tag_wr_en <= 1'b0;
307
      endcase
308
 
309
  always @(posedge clk)
310
    if (~rst) mem_req_wr_cmd <= CMD_NOOP;
311
    else
312
      case (previous)
313
        STATE_INIT:        mem_req_wr_cmd <= CMD_NOOP;
314
        STATE_CLEAR:       mem_req_wr_cmd <= CMD_WRITE;
315
        STATE_IDLE:        mem_req_wr_cmd <= CMD_NOOP;
316
        STATE_REFRESH:     mem_req_wr_cmd <= CMD_REFRESH;
317
        STATE_DISP:        mem_req_wr_cmd <= disp_rd_addr_valid  ? CMD_READ  : CMD_NOOP;
318
        STATE_VBR:         mem_req_wr_cmd <= ~vbuf_empty         ? CMD_READ  : CMD_NOOP;
319
        STATE_FWD:         mem_req_wr_cmd <= fwd_rd_addr_valid   ? CMD_READ  : CMD_NOOP;
320
        STATE_BWD:         mem_req_wr_cmd <= bwd_rd_addr_valid   ? CMD_READ  : CMD_NOOP;
321
        STATE_RECON:       mem_req_wr_cmd <= recon_rd_valid      ? CMD_WRITE : CMD_NOOP;
322
        STATE_VBW:         mem_req_wr_cmd <= vbw_rd_valid        ? CMD_WRITE : CMD_NOOP;
323
        STATE_OSD:         mem_req_wr_cmd <= osd_rd_valid        ? CMD_WRITE : CMD_NOOP;
324
        default            mem_req_wr_cmd <= CMD_NOOP;
325
      endcase
326
 
327
  always @(posedge clk)
328
    if (~rst) mem_req_wr_addr <= 22'b0;
329
    else
330
      case (previous)
331
        STATE_INIT:        mem_req_wr_addr <= 22'b0;
332
        STATE_CLEAR:       mem_req_wr_addr <= mem_clr_addr_0;
333
        STATE_IDLE:        mem_req_wr_addr <= 22'b0;
334
        STATE_REFRESH:     mem_req_wr_addr <= 22'b0;
335
        STATE_DISP:        mem_req_wr_addr <= disp_rd_addr_valid  ? disp_rd_addr     : 22'b0;
336
        STATE_VBR:         mem_req_wr_addr <= ~vbuf_empty         ? vbuf_rd_addr     : 22'b0;
337
        STATE_FWD:         mem_req_wr_addr <= fwd_rd_addr_valid   ? fwd_rd_addr      : 22'b0;
338
        STATE_BWD:         mem_req_wr_addr <= bwd_rd_addr_valid   ? bwd_rd_addr      : 22'b0;
339
        STATE_RECON:       mem_req_wr_addr <= recon_rd_valid      ? recon_rd_addr    : 22'b0;
340
        STATE_VBW:         mem_req_wr_addr <= vbw_rd_valid        ? vbuf_wr_addr     : 22'b0;
341
        STATE_OSD:         mem_req_wr_addr <= osd_rd_valid        ? osd_rd_addr      : 22'b0;
342
        default            mem_req_wr_addr <= 22'b0;
343
      endcase
344
 
345
 
346
  /*
347
   * All y,u and v values are stored in memory with an offset of 128; hence every memory byte is initialized to 8'd128.
348
   * This corresponds to y=u=v=0; a dull green.
349
   */
350
 
351
  always @(posedge clk)
352
    if (~rst) mem_req_wr_dta <= 64'b0;
353
    else
354
      case (previous)
355
        STATE_INIT:        mem_req_wr_dta <= 64'b0;
356
        STATE_CLEAR:       mem_req_wr_dta <= {8{8'd128}}; // initialize memory to all zeroes; all zeroes in yuv is a dull green
357
//        STATE_CLEAR:       mem_req_wr_dta <= {mem_clr_addr_0, 32'hdeadbeef}; // initialize memory so reads from addresses not written to can be easily detected
358
        STATE_IDLE:        mem_req_wr_dta <= 64'b0;
359
        STATE_REFRESH:     mem_req_wr_dta <= 64'b0;
360
        STATE_DISP:        mem_req_wr_dta <= 64'b0;
361
        STATE_VBR:         mem_req_wr_dta <= 64'b0;
362
        STATE_FWD:         mem_req_wr_dta <= 64'b0;
363
        STATE_BWD:         mem_req_wr_dta <= 64'b0;
364
        STATE_RECON:       mem_req_wr_dta <= recon_rd_valid       ? recon_rd_dta : 64'b0;
365
        STATE_VBW:         mem_req_wr_dta <= vbw_rd_valid         ? vbw_rd_dta : 64'b0;
366
        STATE_OSD:         mem_req_wr_dta <= osd_rd_valid         ? osd_rd_dta   : 64'b0;
367
        default            mem_req_wr_dta <= 64'b0;
368
      endcase
369
 
370
  always @(posedge clk)
371
    if (~rst) mem_req_wr_en <= 1'b0;
372
    else
373
      case (previous)
374
        STATE_INIT:        mem_req_wr_en <= 1'b0;
375
        STATE_CLEAR:       mem_req_wr_en <= ~mem_req_wr_almost_full;
376
        STATE_IDLE:        mem_req_wr_en <= 1'b0;
377
        STATE_REFRESH:     mem_req_wr_en <= 1'b1;
378
        STATE_DISP:        mem_req_wr_en <= disp_rd_addr_valid;
379
        STATE_VBR:         mem_req_wr_en <= ~vbuf_empty;
380
        STATE_FWD:         mem_req_wr_en <= fwd_rd_addr_valid;
381
        STATE_BWD:         mem_req_wr_en <= bwd_rd_addr_valid;
382
        STATE_RECON:       mem_req_wr_en <= recon_rd_valid;
383
        STATE_VBW:         mem_req_wr_en <= vbw_rd_valid;
384
        STATE_OSD:         mem_req_wr_en <= osd_rd_valid;
385
        default            mem_req_wr_en <= 1'b0;
386
      endcase
387
 
388
 
389
  /*
390
   * Clearing memory at start-up.
391
   * When we're simulating, SIMULATION_ONLY is defined and we only clear 10 addresses at the end of memory, else simulation takes forever.
392
   * When we're synthesizing, SIMULATION_ONLY is not defined, and we initialize all of memory.
393
   */
394
 
395
  always @(posedge clk)
396
    if (~rst) mem_clr_addr <= 22'd0;
397
`ifdef SIMULATION_ONLY
398
    else if (state == STATE_INIT) mem_clr_addr <= VBUF_END - 22'd10; /* only clear ten last addresses */
399
`else
400
    else if (state == STATE_INIT) mem_clr_addr <= FRAME_0_Y; /* lowest address used */
401
`endif
402
    else if ((state == STATE_CLEAR) && ~mem_req_wr_almost_full) mem_clr_addr <= mem_clr_addr + 22'd1;
403
    else mem_clr_addr <= mem_clr_addr;
404
 
405
  always @(posedge clk)
406
    if (~rst) mem_clr_addr_0 <= FRAME_0_Y;
407
    else if ((state == STATE_CLEAR) && ~mem_req_wr_almost_full) mem_clr_addr_0 <= mem_clr_addr;
408
    else mem_clr_addr_0 <= mem_clr_addr_0;
409
 
410
  /*
411
   * Refresh counter. Refresh at least every REFRESH_CYCLES cycles.
412
   */
413
 
414
  reg [15:0]refresh_cnt;
415
 
416
  always @(posedge clk)
417
    if (~rst) refresh_cnt <= REFRESH_CYCLES;
418
    else if (state == STATE_REFRESH) refresh_cnt <= REFRESH_CYCLES;
419
    else if (refresh_cnt != 0) refresh_cnt <= refresh_cnt - 1;
420
    else refresh_cnt <= refresh_cnt;
421
 
422
  /*
423
   * circular video buffer addresses
424
   */
425
 
426
  reg [21:0]next_vbuf_wr_addr;
427
  reg [21:0]next_vbuf_rd_addr;
428
  reg next_vbuf_full;
429
  reg next_vbuf_empty;
430
 
431
  always @*
432
    if ((previous == STATE_VBW) && vbw_rd_valid) next_vbuf_wr_addr = (vbuf_wr_addr == VBUF_END) ? VBUF : (vbuf_wr_addr + 22'd1);
433
    else next_vbuf_wr_addr = vbuf_wr_addr;
434
 
435
  always @*
436
    if ((previous == STATE_VBR) && ~vbuf_empty) next_vbuf_rd_addr = (vbuf_rd_addr == VBUF_END) ? VBUF : (vbuf_rd_addr + 22'd1);
437
    else next_vbuf_rd_addr = vbuf_rd_addr;
438
 
439
  always @*
440
    next_vbuf_full = ((next_vbuf_wr_addr + 22'd1) == next_vbuf_rd_addr) || ((next_vbuf_wr_addr == VBUF_END) && (next_vbuf_rd_addr == VBUF));
441
 
442
  always @*
443
    next_vbuf_empty = (next_vbuf_wr_addr == next_vbuf_rd_addr);
444
 
445
  always @(posedge clk)
446
    if (~rst) vbuf_wr_addr <= VBUF;
447
    else if (vb_flush) vbuf_wr_addr <= VBUF;
448
    else vbuf_wr_addr <= next_vbuf_wr_addr;
449
 
450
  always @(posedge clk)
451
    if (~rst) vbuf_rd_addr <= VBUF;
452
    else if (vb_flush) vbuf_rd_addr <= VBUF;
453
    else vbuf_rd_addr <= next_vbuf_rd_addr;
454
 
455
  always @(posedge clk)
456
    if (~rst) vbuf_full <= 1'b0;
457
    else if (vb_flush) vbuf_full <= 1'b0;
458
    else vbuf_full <= next_vbuf_full;
459
 
460
  always @(posedge clk)
461
    if (~rst) vbuf_empty <= 1'b1;
462
    else if (vb_flush) vbuf_empty <= 1'b1;
463
    else vbuf_empty <= next_vbuf_empty;
464
 
465
  /*
466
   * Priority scheme:
467
   *  refresh >  display frame read > forward frame read > backward frame read > reconstructed frame write > osd write
468
   *
469
   * Note we do not treat requests for a 'reader' when the data fifo is "almost full".
470
   * this way the data fifo never overflows (hopefully).
471
   *
472
   * Note we do not allow two consecutive vbuf writes.
473
   * The first vbuf write might cause vbuf_full to assert, which would make the second vbuf write overflow the fifo.
474
   * Not allowing two consecutive vbuf writes is not a problem, given program stream bitrates.
475
   */
476
 
477
  wire vbuf_holdoff = (state == STATE_VBW) || (state == STATE_VBR) || (previous == STATE_VBW) || (previous == STATE_VBR);
478
 
479
  assign do_refresh = (refresh_cnt == 0)                    && REFRESH_EN                 && ~mem_req_wr_almost_full;
480
  assign do_disp    = ~disp_rd_addr_empty                   && ~disp_wr_dta_almost_full   && ~mem_req_wr_almost_full && ~tag_wr_almost_full;
481
  assign do_vbr     = ~vbuf_empty          && ~vbuf_holdoff &&  vbr_rd_almost_empty       && ~mem_req_wr_almost_full && ~tag_wr_almost_full;
482
  assign do_fwd     = ~fwd_rd_addr_empty                    && ~fwd_wr_dta_almost_full    && ~mem_req_wr_almost_full && ~tag_wr_almost_full;
483
  assign do_bwd     = ~bwd_rd_addr_empty                    && ~bwd_wr_dta_almost_full    && ~mem_req_wr_almost_full && ~tag_wr_almost_full;
484
  assign do_recon   =                                          ~recon_rd_empty            && ~mem_req_wr_almost_full;
485
  assign do_vbw     = ~vbuf_full           && ~vbuf_holdoff && ~vbw_rd_empty              && ~mem_req_wr_almost_full;
486
  assign do_osd     =                                          ~osd_rd_empty              && ~mem_req_wr_almost_full;
487
 
488
`ifdef DEBUG
489
  always @(posedge clk)
490
    case (state)
491
      STATE_INIT:                                #0 $display("%m\tinit");
492
      STATE_CLEAR:       if (~mem_req_wr_almost_full) #0 $display("%m\tclear %h", mem_clr_addr);
493
      STATE_IDLE:                                #0 $display("%m\tidle");
494
      STATE_DISP:        if (disp_rd_addr_valid) #0 $display("%m\tdisp  read %h", disp_rd_addr);
495
      STATE_VBW:         if (vbw_rd_valid)       #0 $display("%m\tvbw   write %6h = %h", vbuf_wr_addr, vbw_rd_dta);
496
      STATE_FWD:         if (fwd_rd_addr_valid)  #0 $display("%m\tfwd   read %h", fwd_rd_addr);
497
      STATE_BWD:         if (bwd_rd_addr_valid)  #0 $display("%m\tbwd   read %h", bwd_rd_addr);
498
      STATE_RECON:       if (recon_rd_valid)     #0 $display("%m\trecon write %6h = %h", recon_rd_addr, recon_rd_dta);
499
      STATE_VBR:                                 #0 $display("%m\tvbr   read %h", vbuf_rd_addr);
500
      STATE_OSD:         if (osd_rd_valid)       #0 $display("%m\tosd   write %6h = %h", osd_rd_addr, osd_rd_dta);
501
      default            #0 $display("%m\t** Error: unknown state %d **", state);
502
    endcase
503
 
504
`endif
505
 
506
`ifdef CHECK
507
  always @(posedge clk)
508
    if (vbw_rd_valid && vbr_wr_full)
509
      begin
510
        $display("%m\t***error*** vbw_rd_valid && vbr_wr_full");
511
        $finish();
512
      end
513
 
514
  always @(posedge clk)
515
    if ((state == STATE_VBW) && vbw_rd_valid && ((vbuf_wr_addr < VBUF) || (vbuf_wr_addr > VBUF_END)))
516
      begin
517
        $display("%m\t***error*** vbuf_wr_addr out of range: %h", vbuf_wr_addr);
518
        $finish();
519
      end
520
 
521
  always @(posedge clk)
522
    if ((state == STATE_VBR) && ~vbuf_empty && ((vbuf_rd_addr < VBUF) || (vbuf_rd_addr > VBUF_END)))
523
      begin
524
        $display("%m\t***error*** vbuf_rd_addr out of range: %h", vbuf_rd_addr);
525
        $finish();
526
      end
527
`endif
528
 
529
`ifdef DEBUG_2
530
  always @(posedge clk)
531
    case (state)
532
      STATE_INIT:        #0 $display("%m\tSTATE_INIT");
533
      STATE_CLEAR:       #0 $display("%m\tSTATE_CLEAR");
534
      STATE_IDLE:        #0 $display("%m\tSTATE_IDLE");
535
      STATE_REFRESH:     #0 $display("%m\tSTATE_REFRESH");
536
      STATE_DISP:        #0 $display("%m\tSTATE_DISP");
537
      STATE_VBR:         #0 $display("%m\tSTATE_VBR");
538
      STATE_FWD:         #0 $display("%m\tSTATE_FWD");
539
      STATE_BWD:         #0 $display("%m\tSTATE_BWD");
540
      STATE_RECON:       #0 $display("%m\tSTATE_RECON");
541
      STATE_VBW:         #0 $display("%m\tSTATE_VBW");
542
      STATE_OSD:         #0 $display("%m\tSTATE_OSD");
543
      default            #0 $display("%m\t** Error: unknown state %d **", state);
544
    endcase
545
 
546
 
547
  always @(posedge clk)
548
    begin
549
      $strobe("%m\tstate: %h  fwd_rd_addr_empty: %h  fwd_rd_addr_en: %h  fwd_rd_addr_valid: %h  fwd_rd_addr: %h  fwd_wr_dta_full: %h",
550
                   state, fwd_rd_addr_empty, fwd_rd_addr_en, fwd_rd_addr_valid, fwd_rd_addr, fwd_wr_dta_full);
551
      $strobe("%m\tbwd_rd_addr_empty: %h  bwd_rd_addr_en: %h  bwd_rd_addr_valid: %h  bwd_rd_addr: %h  bwd_wr_dta_full: %h",
552
                   bwd_rd_addr_empty, bwd_rd_addr_en, bwd_rd_addr_valid, bwd_rd_addr, bwd_wr_dta_full);
553
      $strobe("%m\trecon_rd_empty: %h  recon_rd_en: %h  recon_rd_valid: %h  recon_rd_addr: %h  recon_rd_dta: %h",
554
                   recon_rd_empty, recon_rd_en, recon_rd_valid, recon_rd_addr, recon_rd_dta);
555
      $strobe("%m\tdisp_rd_addr_empty: %h  disp_rd_addr_en: %h  disp_rd_addr_valid: %h  disp_rd_addr: %h  disp_wr_dta_full: %h",
556
                   disp_rd_addr_empty, disp_rd_addr_en, disp_rd_addr_valid, disp_rd_addr, disp_wr_dta_full);
557
      $strobe("%m\tosd_rd_empty: %h  osd_rd_en: %h  osd_rd_valid: %h  osd_rd_addr: %h  osd_rd_dta: %h",
558
                   osd_rd_empty, osd_rd_en, osd_rd_valid, osd_rd_addr, osd_rd_dta);
559
      $strobe("%m\tvbw_rd_empty: %h  vbw_rd_en: %h  vbw_rd_valid: %h  vbw_rd_dta: %h vbr_wr_full: %h  vbr_wr_almost_full: %h",
560
                   vbw_rd_empty, vbw_rd_en, vbw_rd_valid, vbw_rd_dta, vbr_wr_full, vbr_wr_almost_full);
561
      $strobe("%m\tvbuf_wr_addr: %h  vbuf_rd_addr: %h  vbuf_full: %h  vbuf_empty: %h next_vbuf_wr_addr: %h next_vbuf_rd_addr: %h",
562
                   vbuf_wr_addr, vbuf_rd_addr, vbuf_full, vbuf_empty, next_vbuf_wr_addr, next_vbuf_rd_addr);
563
      $strobe("%m\tvbw_rd_empty: %h  vbw_rd_en: %h  vbw_rd_valid: %h  vbw_rd_dta: %h  vbuf_wr_addr: %h  vbuf_rd_addr: %h  vbuf_full: %h  vbuf_empty: %h  vbr_wr_full: %h  vbr_wr_almost_full: %h",
564
                   vbw_rd_empty, vbw_rd_en, vbw_rd_valid, vbw_rd_dta, vbuf_wr_addr, vbuf_rd_addr, vbuf_full, vbuf_empty, vbr_wr_full, vbr_wr_almost_full);
565
      $strobe("%m\tmem_req_wr_cmd: %h  mem_req_wr_addr: %h  mem_req_wr_dta: %h  mem_req_wr_en: %h  mem_req_wr_almost_full: %h",
566
                   mem_req_wr_cmd, mem_req_wr_addr, mem_req_wr_dta, mem_req_wr_en, mem_req_wr_almost_full);
567
      $strobe("%m\ttag_wr_dta: %h  tag_wr_en: %h  tag_wr_almost_full: %h",
568
                   tag_wr_dta, tag_wr_en, tag_wr_almost_full);
569
    end
570
`endif
571
endmodule
572
 
573
/* not truncated */

powered by: WebSVN 2.1.0

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