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

Subversion Repositories mpeg2fpga

[/] [mpeg2fpga/] [trunk/] [rtl/] [mpeg2/] [framestore_response.v] - Rev 2

Compare with Previous | Blame | View Log

/* 
 * framestore_response.v
 * 
 * Copyright (c) 2007 Koen De Vleeschauwer. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 * SUCH DAMAGE.
 */
 
/*
 * Frame Store Response. Read response from memory controller.
 *
 * Receives data read from the memory controller; 
 * passes data read on to motion compensation or display.
 */
 
`include "timescale.v"
 
`undef DEBUG
//`define DEBUG 1
 
`undef CHECK
//`define CHECK 1
 
`ifdef __IVERILOG__
`define CHECK 1
`endif
 
//`define SIMULATION_ONLY
`ifdef __IVERILOG__
`define SIMULATION_ONLY 1
`endif
 
module framestore_response(rst, clk, 
                  fwd_wr_dta_full, fwd_wr_dta_en, fwd_wr_dta_ack, fwd_wr_dta, fwd_wr_dta_almost_full,
                  bwd_wr_dta_full, bwd_wr_dta_en, bwd_wr_dta_ack, bwd_wr_dta, bwd_wr_dta_almost_full,
                  disp_wr_dta_full, disp_wr_dta_en, disp_wr_dta_ack, disp_wr_dta, disp_wr_dta_almost_full,
                  vbr_wr_full, vbr_wr_en, vbr_wr_ack, vbr_wr_dta, vbr_wr_almost_full, 
                  mem_res_rd_dta, mem_res_rd_en, mem_res_rd_empty, mem_res_rd_valid, 
                  tag_rd_dta, tag_rd_empty, tag_rd_en, tag_rd_valid
                  );
 
  input            rst;
  input            clk;
  /* motion compensation: reading forward reference frame */
  input             fwd_wr_dta_full;
  input             fwd_wr_dta_almost_full;
  output reg        fwd_wr_dta_en;
  input             fwd_wr_dta_ack;
  output reg     [63:0]fwd_wr_dta;
  /* motion compensation: reading backward reference frame */
  input             bwd_wr_dta_full;
  input             bwd_wr_dta_almost_full;
  output reg        bwd_wr_dta_en;
  input             bwd_wr_dta_ack;
  output reg  [63:0]bwd_wr_dta;
  /* display: reading reconstructed frame */
  input             disp_wr_dta_full;
  input             disp_wr_dta_almost_full;
  output reg        disp_wr_dta_en;
  input             disp_wr_dta_ack;
  output reg  [63:0]disp_wr_dta;
  /* video buffer: reading from circular buffer */
  input             vbr_wr_full;
  input             vbr_wr_almost_full;
  output reg        vbr_wr_en;
  input             vbr_wr_ack;
  output reg  [63:0]vbr_wr_dta;
 
  /* memory response fifo */
  input       [63:0]mem_res_rd_dta;
  output reg        mem_res_rd_en;
  input             mem_res_rd_empty;
  input             mem_res_rd_valid;
 
  /* tag fifo */
  input        [2:0]tag_rd_dta;
  input             tag_rd_empty;
  output reg        tag_rd_en;
  input             tag_rd_valid;
 
`include "mem_codes.v"
 
  parameter [2:0] 
    STATE_INIT        = 4'h0,      
    STATE_FLUSH       = 4'h1,
    STATE_WAIT        = 4'h2,
    STATE_READ        = 4'h3,      
    STATE_WRITE       = 4'h4;      
 
  reg         [2:0]state;
  reg         [2:0]next;
 
  reg        [15:0]flush_counter;
 
  always @(posedge clk)
    if (~rst) flush_counter <= 0;
    else if (state == STATE_FLUSH) flush_counter <= flush_counter + 16'd1;
    else flush_counter <= flush_counter;
 
  wire             fifos_not_ready = fwd_wr_dta_full || bwd_wr_dta_full || disp_wr_dta_full || vbr_wr_full || tag_rd_empty || mem_res_rd_empty;
  wire             fifos_ready = ~fifos_not_ready;
 
  /* next state logic */
  always @*
    case (state)
`ifdef SIMULATION_ONLY
      STATE_INIT:         next = STATE_WAIT;
`else
      STATE_INIT:         next = STATE_FLUSH;
`endif
 
      STATE_FLUSH:        if (flush_counter == 16'hffff) next = STATE_WAIT; // Flush any data in the memory response fifo's.
                          else next = STATE_FLUSH;
 
      STATE_WAIT:         if (fifos_not_ready) next = STATE_WAIT;  // wait until all fifos available
                          else next = STATE_READ;
 
      STATE_READ:         next = STATE_WRITE;
 
      STATE_WRITE:        next = STATE_WAIT;
 
      default             next = STATE_WAIT;
 
    endcase
 
  /* state */
  always @(posedge clk)
    if(~rst) state <= STATE_INIT;
    else state <= next;
 
  /* 
   * read from memory response and tag fifos
   */
 
  always @(posedge clk)
    if (~rst) mem_res_rd_en <= 1'b0;
    else if (state == STATE_FLUSH) mem_res_rd_en <= 1'b1;
    else if (state == STATE_READ) mem_res_rd_en <= fifos_ready;
    else mem_res_rd_en <= 1'b0;
 
  always @(posedge clk)
    if (~rst) tag_rd_en <= 1'b0;
    else if (state == STATE_READ) tag_rd_en <= fifos_ready;
    else tag_rd_en <= 1'b0;
 
  /*
   * second stage: if successful read from memory response fifo, write memory response data to fifo corresponding to tag (fwd, bwd, disp or vbr).
   */
 
  always @(posedge clk)
    if (~rst) fwd_wr_dta_en <= 1'b0;
    else fwd_wr_dta_en <= (tag_rd_dta == TAG_FWD) && tag_rd_valid;
 
  always @(posedge clk)
    if (~rst) fwd_wr_dta <= 64'b0;
    else if (mem_res_rd_valid) fwd_wr_dta <= mem_res_rd_dta;
    else fwd_wr_dta <= fwd_wr_dta;
 
  always @(posedge clk)
    if (~rst) bwd_wr_dta_en <= 1'b0;
    else bwd_wr_dta_en <= (tag_rd_dta == TAG_BWD) && tag_rd_valid;
 
  always @(posedge clk)
    if (~rst) bwd_wr_dta <= 64'b0;
    else if (mem_res_rd_valid) bwd_wr_dta <= mem_res_rd_dta;
    else bwd_wr_dta <= bwd_wr_dta;
 
  always @(posedge clk)
    if (~rst) disp_wr_dta_en <= 1'b0;
    else disp_wr_dta_en <= (tag_rd_dta == TAG_DISP) && tag_rd_valid;
 
  always @(posedge clk)
    if (~rst) disp_wr_dta <= 64'b0;
    else if (mem_res_rd_valid) disp_wr_dta <= mem_res_rd_dta;
    else disp_wr_dta <= disp_wr_dta;
 
  always @(posedge clk)
    if (~rst) vbr_wr_en <= 1'b0;
    else vbr_wr_en <= (tag_rd_dta == TAG_VBUF) && tag_rd_valid;
 
  always @(posedge clk)
    if (~rst) vbr_wr_dta <= 64'b0;
    else if (mem_res_rd_valid) vbr_wr_dta <= mem_res_rd_dta;
    else vbr_wr_dta <= vbr_wr_dta;
 
`ifdef DEBUG
 
  always @(posedge clk)
    case (state)
      STATE_INIT:                               #0 $display("%m         STATE_INIT");
      STATE_WAIT:                               #0 $display("%m         STATE_WAIT");
      STATE_FLUSH:                              #0 $display("%m         STATE_FLUSH");
      STATE_READ:                               #0 $display("%m         STATE_READ");
      STATE_WRITE:                              #0 $display("%m         STATE_WRITE");
      default                                   #0 $display("%m         *** Error: unknown state %d", state);
    endcase
 
  always @(posedge clk)
    $strobe("%m\tmem_res_rd_dta: %h mem_res_rd_valid: %h tag_rd_dta: %h tag_rd_valid: %h fifos_not_ready: %h mem_res_rd_en: %h", mem_res_rd_dta, mem_res_rd_valid, tag_rd_dta, tag_rd_valid, fifos_not_ready, mem_res_rd_en);
 
  always @(posedge clk)
    begin
      $strobe("%m\tfwd_wr_dta: %h fwd_wr_dta_en: %h", fwd_wr_dta, fwd_wr_dta_en);
      $strobe("%m\tbwd_wr_dta: %h bwd_wr_dta_en: %h", bwd_wr_dta, bwd_wr_dta_en);
      $strobe("%m\tdisp_wr_dta: %h disp_wr_dta_en: %h", disp_wr_dta, disp_wr_dta_en);
      $strobe("%m\tvbr_wr_dta: %h vbr_wr_en: %h", vbr_wr_dta, vbr_wr_en);
    end
 
  always @(posedge clk)
    if (tag_rd_valid)
    case (tag_rd_dta)
      TAG_FWD:  #0 $display ("%m\ttag_rd_dta: fwd");
      TAG_BWD:  #0 $display ("%m\ttag_rd_dta: bwd");
      TAG_DISP: #0 $display ("%m\ttag_rd_dta: disp");
      TAG_VBUF: #0 $display ("%m\ttag_rd_dta: vbuf");
      default:  #0 $display ("%m\t*** error: unknown tag %d ***", tag_rd_dta);
    endcase
 
`endif
 
`ifdef CHECK
  always @(posedge clk)
    if (fwd_wr_dta_full) #0 $display ("%m\t*** warning: memory stall possible: fwd_wr_dta_full ***");
 
  always @(posedge clk)
    if (bwd_wr_dta_full) #0 $display ("%m\t*** warning: memory stall possible: bwd_wr_dta_full ***");
 
  always @(posedge clk)
    if (disp_wr_dta_full) #0 $display ("%m\t*** warning: memory stall possible: disp_wr_dta_full ***");
 
  always @(posedge clk)
    if (vbr_wr_full) #0 $display ("%m\t*** warning: memory stall possible: vbr_wr_full ***");
 
  /*
   * Should never happen, but doesn't hurt to check.
   */
 
  always @(posedge clk)
    if ((state == STATE_READ) && ((tag_rd_valid && ~mem_res_rd_valid) || (mem_res_rd_valid && ~tag_rd_valid)))
      begin
        #0 $display("%m\t*** error: tag and mem_res fifo unsynchronized tag_rd_valid: %d mem_res_rd_valid: %d ***", tag_rd_valid, mem_res_rd_valid);
        $stop;
      end
 
  always @(posedge clk)
    if (tag_rd_valid && (tag_rd_dta != TAG_FWD) && (tag_rd_dta != TAG_BWD) && (tag_rd_dta != TAG_DISP) && (tag_rd_dta != TAG_VBUF)) 
      begin
        #0 $display("%m\t*** error: unknown tag %d ***", tag_rd_dta);
        $stop;
      end
 
`endif
endmodule
/* not truncated */
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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