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

Subversion Repositories genesys_ddr2

[/] [genesys_ddr2/] [trunk/] [rtl/] [ipcore_dir/] [MEMCtrl/] [user_design/] [sim/] [ddr2_tb_test_cmp.v] - Rev 3

Compare with Previous | Blame | View Log

//*****************************************************************************
// DISCLAIMER OF LIABILITY
//
// This file contains proprietary and confidential information of
// Xilinx, Inc. ("Xilinx"), that is distributed under a license
// from Xilinx, and may be used, copied and/or disclosed only
// pursuant to the terms of a valid license agreement with Xilinx.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT,
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx
// does not warrant that functions included in the Materials will
// meet the requirements of Licensee, or that the operation of the
// Materials will be uninterrupted or error-free, or that defects
// in the Materials will be corrected. Furthermore, Xilinx does
// not warrant or make any representations regarding use, or the
// results of the use, of the Materials in terms of correctness,
// accuracy, reliability or otherwise.
//
// Xilinx products are not designed or intended to be fail-safe,
// or for use in any application requiring fail-safe performance,
// such as life-support or safety devices or systems, Class III
// medical devices, nuclear facilities, applications related to
// the deployment of airbags, or any other applications that could
// lead to death, personal injury or severe property or
// environmental damage (individually and collectively, "critical
// applications"). Customer assumes the sole risk and liability
// of any use of Xilinx products in critical applications,
// subject only to applicable laws and regulations governing
// limitations on product liability.
//
// Copyright 2006, 2007, 2008 Xilinx, Inc.
// All rights reserved.
//
// This disclaimer and copyright notice must be retained as part
// of this file at all times.
//*****************************************************************************
//   ____  ____
//  /   /\/   /
// /___/  \  /    Vendor: Xilinx
// \   \   \/     Version: 3.6.1
//  \   \         Application: MIG
//  /   /         Filename: ddr2_tb_test_cmp.v
// /___/   /\     Date Last Modified: $Date: 2010/11/26 18:26:02 $
// \   \  /  \    Date Created: Fri Sep 01 2006
//  \___\/\___\
//
//Device: Virtex-5
//Design Name: DDR2
//Purpose:
//   This module generates the error signal in case of bit errors. It compares
//   the read data with expected data value.
//Reference:
//Revision History:
//*****************************************************************************
 
`timescale 1ns/1ps
 
module ddr2_tb_test_cmp #
  (
   // Following parameters are for 72-bit RDIMM design (for ML561 Reference 
   // board design). Actual values may be different. Actual parameters values 
   // are passed from design top module MEMCtrl module. Please refer to
   // the MEMCtrl module for actual values.
   parameter DQ_WIDTH      = 72,
   parameter APPDATA_WIDTH = 144,
   parameter ECC_ENABLE    = 0
   )
  (
   input                     clk,
   input                     rst,
   input                     phy_init_done,
   input                     rd_data_valid,
   input [APPDATA_WIDTH-1:0] app_cmp_data,
   input [APPDATA_WIDTH-1:0] rd_data_fifo_in,
   output reg                error,
   output reg                error_cmp
   );
 
  wire [(APPDATA_WIDTH/16)-1:0] byte_err_fall;
  reg [(APPDATA_WIDTH/16)-1:0]  byte_err_fall_r;
  wire [(APPDATA_WIDTH/16)-1:0] byte_err_rise;
  reg [(APPDATA_WIDTH/16)-1:0]  byte_err_rise_r;
  wire [(APPDATA_WIDTH/2)-1:0]  cmp_data_fall;
  wire [(APPDATA_WIDTH/2)-1:0]  cmp_data_rise;
  wire [APPDATA_WIDTH-1:0]      cmp_data_r;
  reg  [APPDATA_WIDTH-1:0]      cmp_data_r1;
  reg                           cmp_start;
  wire [(APPDATA_WIDTH/2)-1:0]  data_fall_r;
  wire [(APPDATA_WIDTH/2)-1:0]  data_rise_r;
  reg                           err_fall;
  reg                           err_rise;
  reg                           error_tmp_r;
  wire                          error_tmp_r1;
  wire                          error_tmp_r2;
  wire [APPDATA_WIDTH-1:0]      rd_data_r;
  wire [APPDATA_WIDTH-1:0]      rd_data_r1;
  reg [APPDATA_WIDTH-1:0]       rd_data_r2;
  wire                          rd_data_valid_r;
  reg                           rd_data_valid_r1;
  reg                           rd_data_valid_r2;
  reg                           rst_r
                                /* synthesis syn_preserve = 1 */;
  reg                           rst_r1
                                /* synthesis syn_maxfan = 10 */;
 
  // XST attributes for local reset "tree"
  // synthesis attribute shreg_extract of rst_r is "no";
  // synthesis attribute shreg_extract of rst_r1 is "no";
  // synthesis attribute equivalent_register_removal of rst_r is "no"
 
  //***************************************************************************
 
  // local reset "tree" for controller logic only. Create this to ease timing
  // on reset path. Prohibit equivalent register removal on RST_R to prevent
  // "sharing" with other local reset trees (caution: make sure global fanout
  // limit is set to larger than fanout on RST_R, otherwise SLICES will be
  // used for fanout control on RST_R.
  always @(posedge clk) begin
    rst_r  <= rst;
    rst_r1 <= rst_r;
  end
 
  // instantiate discrete flops for better timing
  genvar rd_data_i;
  generate
    for (rd_data_i = 0; rd_data_i < APPDATA_WIDTH;
         rd_data_i = rd_data_i + 1) begin: gen_rd_data
      FDRSE ff_rd_data
        (
         .Q   (rd_data_r[rd_data_i]),
         .C   (clk),
         .CE  (1'b1),
         .D   (rd_data_fifo_in[rd_data_i]),
         .R   (1'b0),
         .S   (1'b0)
         );
 
      FDRSE ff_rd_data_r1
        (
         .Q   (rd_data_r1[rd_data_i]),
         .C   (clk),
         .CE  (1'b1),
         .D   (rd_data_r[rd_data_i]),
         .R   (1'b0),
         .S   (1'b0)
         );
    end
  endgenerate
 
  genvar cmp_data_i;
  generate
    for (cmp_data_i = 0; cmp_data_i < APPDATA_WIDTH;
         cmp_data_i = cmp_data_i + 1) begin: gen_cmp_data
        FDRSE ff_cmp_data
          (
           .Q   (cmp_data_r[cmp_data_i]),
           .C   (clk),
           .CE  (1'b1),
           .D   (app_cmp_data[cmp_data_i]),
           .R   (1'b0),
           .S   (1'b0)
           );
    end
  endgenerate
 
  assign data_fall_r   = rd_data_r2[APPDATA_WIDTH-1:(APPDATA_WIDTH/2)];
  assign data_rise_r   = rd_data_r2[(APPDATA_WIDTH/2)-1:0];
  assign cmp_data_fall = cmp_data_r[APPDATA_WIDTH-1:(APPDATA_WIDTH/2)];
  assign cmp_data_rise = cmp_data_r[(APPDATA_WIDTH/2)-1:0];
 
  // Instantiate ff for timing.
  FDRSE ff_rd_data_valid_r
    (
     .Q   (rd_data_valid_r),
     .C   (clk),
     .CE  (1'b1),
     .D   (rd_data_valid),
     .R   (1'b0),
     .S   (1'b0)
     );
 
  always @(posedge clk) begin
    if (rst_r1) begin
      rd_data_valid_r1 <= 1'd0;
    end else begin
      rd_data_valid_r1 <= rd_data_valid_r & phy_init_done;
    end
  end
 
  always @(posedge clk)begin
     rd_data_r2 <= rd_data_r1;
     cmp_data_r1 <= cmp_data_r;
     rd_data_valid_r2 <= rd_data_valid_r1;
  end
 
  genvar cmp_i;
  generate
    for (cmp_i = 0; cmp_i < APPDATA_WIDTH/16; cmp_i = cmp_i + 1) begin: gen_cmp
      assign byte_err_fall[cmp_i]
               = (rd_data_valid_r2 &&
                  (data_fall_r[8*(cmp_i+1)-1:8*cmp_i] !=
                   cmp_data_fall[8*(cmp_i+1)-1:8*cmp_i]));
      assign byte_err_rise[cmp_i]
               = (rd_data_valid_r2 &&
                  (data_rise_r[8*(cmp_i+1)-1:8*cmp_i] !=
                   cmp_data_rise[8*(cmp_i+1)-1:8*cmp_i]));
    end
  endgenerate
 
  always @(posedge clk) begin
    byte_err_rise_r  <= byte_err_rise;
    byte_err_fall_r  <= byte_err_fall;
  end
 
  always @(posedge clk)
    if (rst_r1) begin
      err_rise    <= 1'bx;
      err_fall    <= 1'bx;
      cmp_start   <= 1'b0;
      error_tmp_r <= 1'b0;
    end else begin
      err_rise <= | byte_err_rise_r;
      err_fall <= | byte_err_fall_r;
      // start comparing when initialization/calibration complete, and we
      // get first valid readback
      if (rd_data_valid_r2)
        cmp_start <= 1'b1;
      if (cmp_start && !error_tmp_r)
        error_tmp_r <= err_rise | err_fall;
      //synthesis translate_off
      if ((err_rise || err_fall) && cmp_start)
        $display ("ERROR at time %t" , $time);
      //synthesis translate_on
    end
 
  // FF inst to force synthesis to infer ff's.
  // Done for timing.
  FDRSE ff_error_1
    (
     .Q   (error_tmp_r1),
     .C   (clk),
     .CE  (1'b1),
     .D   (error_tmp_r),
     .R   (1'b0),
     .S   (1'b0)
     );
 
  FDRSE ff_error_2
    (
     .Q   (error_tmp_r2),
     .C   (clk),
     .CE  (1'b1),
     .D   (error_tmp_r1),
     .R   (1'b0),
     .S   (1'b0)
     );
 
  always @(posedge clk) begin
    error     <= error_tmp_r2;
    error_cmp <= err_rise | err_fall;
  end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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