⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem_interface_top_phy_calib_0.v

📁 sata_device_model,对做硬盘控制器的朋友有帮助
💻 V
📖 第 1 页 / 共 4 页
字号:
//*****************************************************************************
// Copyright (c) 2006 Xilinx, Inc.
// This design is confidential and proprietary of Xilinx, Inc.
// All Rights Reserved
//*****************************************************************************
//   ____  ____
//  /   /\/   /
// /___/  \  /    Vendor: Xilinx
// \   \   \/     Version: $Name: i+IP+125372 $
//  \   \         Application: MIG
//  /   /         Filename: mem_interface_top_phy_calib_0.v
// /___/   /\     Date Last Modified: $Date: 2007/04/18 13:49:32 $
// \   \  /  \    Date Created: Thu Aug 10 2006
//  \___\/\___\
//
//Device: Virtex-5
//Design Name: DDR2
//Purpose:
//   This module handles calibration after memory initialization.
//Reference:
//Revision History:
//*****************************************************************************

`timescale 1ns/1ps

//*****************************************************************************
// Port descriptions:
//   Inputs:
//     clk: CLK0 (some initialization logic interfacing to this module is
//       clocked off CLK0, so require CLK0 <-> CLK90 synchronization)
//     clk90, rst90: 90 degrees shift from CLK0, and reset sync'ed to CLK90
//     calib_start: Assert to begin each stage of calibration. [0] = stg1,
//       [3] = stg4. [0] should be asserted only once memory initialization
//       complete, calibration training patterns have been written to memory,
//       and continuous read to generate training pattern for stage 1 begun.
//       The others should only be asserted once the previous stage is
//       complete, and training pattern continuous read for that stage has
//       begun.
//     din_capture: Raw capture data from ISERDES. rising data = lower half
//       of din_capture (i.e. [WIDTH-1:0]), falling data = upper half
//     bit_time_taps: Number of taps that a bit time spans (e.g. clk = 333MHz,
//       then bit time = 1.5ns, or 20 taps; for 100MHz, taps = 63 (max))
//   Outputs:
//     calib_done[3:0]: Asserted when the corresponding stage of calibration
//     invert_dqs[]: Inverts internal gated DQS, and controls ISERDES data MUX
//       successfully completed. [0] = stg1, [3] = stg 4
//     dlyrst_dq[]: Tap reset for DQ IDELAYs
//     dlyce_dq[]: Control enable for DQ IDELAYs
//     dlyinc_dq[]: Increment/decrement for DQ IDELAYs
//     dlyrst_dqs[]: Tap reset for DQS IDELAYs
//     dlyce_dqs[]: Control enable for DQS IDELAYs
//     dlyinc_dqs[]: Increment/decrement for DQS IDELAYs
//*****************************************************************************

module mem_interface_top_phy_calib_0 #
  (
   parameter DQ_WIDTH      = 72,
   parameter DQ_BITS       = 7,
   parameter DQ_PER_DQS    = 8,
   parameter DQS_WIDTH     = 9,
   parameter DQS_BITS      = 4,
   parameter ADDITIVE_LAT  = 0,
   parameter CAS_LAT       = 3,
   parameter ECC_ENABLE    = 0,
   parameter REG_ENABLE    = 1,
   parameter SIM_ONLY      = 0,
   parameter CLK_PERIOD    = 5000
   )
  (
   input                                   clk0,
   input                                   clk90,
   input                                   rst90,
   input [3:0]                             calib_start_0,
   input                                   ctrl_rden_0,
   input                                   phy_init_rden_0,
   input [DQ_WIDTH-1:0]                    rd_data_rise,
   input [DQ_WIDTH-1:0]                    rd_data_fall,
   output reg [3:0]                        calib_done_0,
   output reg [DQS_WIDTH-1:0]              calib_rden
                                           /* synthesis syn_maxfan = 1 */,
   output reg [DQ_WIDTH-1:0]               dlyrst_dq,
   output reg [DQ_WIDTH-1:0]               dlyce_dq,
   output reg [DQ_WIDTH-1:0]               dlyinc_dq,
   output reg                              dlyrst_dqs,
   output reg [DQS_WIDTH-1:0]              dlyce_dqs,
   output reg [DQS_WIDTH-1:0]              dlyinc_dqs
   );

  // minimum time (in IDELAY taps) for which capture data must be stable for
  // algorithm to consider
  // higher for lower frequencies. Lower frequencies more taps will be used.
  localparam MIN_WIN_SIZE = (CLK_PERIOD < 3800)?10:14;
  // minimum # of cycles to wait after changing IDELAY value
  localparam IDEL_SET_VAL = 4'b1001;
  localparam MAX_TAPS = 63;
  localparam BIT_PERIOD_TAPS = CLK_PERIOD/150;
  // fix minimum value of DQS to be 1 to handle the case where's there's only
  // one DQS group. We could also enforce that user always inputs minimum
  // value of 1 for DQS_BITS (even when DQS_WIDTH=1). Leave this as safeguard
  // Assume we don't have to do this for DQ, DQ_WIDTH always > 1
  localparam DQS_BITS_FIX = (DQS_BITS == 0) ? 1 : DQS_BITS;

  localparam CAL1_IDLE                   = 4'h0;
  localparam CAL1_INIT                   = 4'h1;
  localparam CAL1_EDGE_DETECT            = 4'h2;
  localparam CAL1_EDGE_DETECT_WAIT       = 4'h3;
  localparam CAL1_DQS_INC                = 4'h4;
  localparam CAL1_DQ_RESET               = 4'h5;
  localparam CAL1_DQ_RESET1              = 4'h6;
  localparam CAL1_DQ_DESKEW              = 4'h7;
  localparam CAL1_DONE                   = 4'h8;

  localparam CAL2_IDLE                   = 4'h0;
  localparam CAL2_INIT                   = 4'h1;
  localparam CAL2_EDGE_DETECT            = 4'h2;
  localparam CAL2_EDGE_DETECT_WAIT       = 4'h3;
  localparam CAL2_CASE1                  = 4'h4;
  localparam CAL2_CASE2                  = 4'h5;
  localparam CAL2_CASE3                  = 4'h6;
  localparam CAL2_TAP_DEC                = 4'h7;
  localparam CAL2_DONE                   = 4'h8;

  integer                                i;

  reg [(DQS_WIDTH*6)-1:0]       dqs_tap_count
                                /* synthesis syn_maxfan = 5 */;
  reg [(DQS_WIDTH*6)-1:0]       dqs_tap_count_r1
                                /* synthesis syn_maxfan = 5 */;
  wire [(2*DQ_PER_DQS)-1:0]     cal1_data_chk;
  reg [(2*DQ_PER_DQS)-1:0]      cal1_data_chk_last;
  reg [(2*DQ_PER_DQS)-1:0]      cal1_data_chk_r;
  reg [DQ_PER_DQS-1:0]          cal1_dlyce_dq;
  reg [DQ_PER_DQS-1:0]          cal1_dlyinc_dq;
  reg [DQ_PER_DQS-1:0]          cal1_dlyce_dq_cp1;
  reg [DQ_PER_DQS-1:0]          cal1_dlyinc_dq_cp1;
  reg [DQ_PER_DQS-1:0]          cal1_dlyce_dq_cp3;
  reg [DQ_PER_DQS-1:0]          cal1_dlyinc_dq_cp3;
  reg                           cal1_dlyrst_dq;
  reg                           cal1_dlyce_dqs;
  reg                           cal1_dlyinc_dqs;
  wire [DQ_PER_DQS-1:0]         cal1_detect_stable;
  reg  [DQ_PER_DQS-1:0]         cal1_detect_stable_r
                                /* synthesis syn_maxfan = 1 */;
  reg [(DQ_PER_DQS*5)-1:0]      cal1_dq_count
                                /* synthesis syn_maxfan = 5 */;
  reg [(DQ_PER_DQS*5)-1:0]      cal1_dq_count_cp1
                                /* synthesis syn_maxfan = 5 */;
  reg [(DQ_PER_DQS*5)-1:0]      cal1_dq_count_cp2
                                /* synthesis syn_maxfan = 5 */;
  reg [(DQ_PER_DQS*5)-1:0]      cal1_dq_count_cp3
                                /* synthesis syn_maxfan = 5 */;
  reg [(DQS_BITS_FIX)-1:0]      cal1_dqs_count
                                /* synthesis syn_maxfan = 1 */;
  reg [(DQS_BITS_FIX)-1:0]      cal1_dqs_count_r1
                                /* synthesis syn_maxfan = 3 */;
  reg                           cal1_dqs_count_check;
  reg [5:0]                     cal1_dqs_inc_count
                                /* synthesis syn_maxfan = 5 */;
  reg [5:0]                     cal1_dq_inc_count
                                /* synthesis syn_maxfan = 5 */;
  reg [5:0]                     cal1_dq_deskew_count
                                /* synthesis syn_maxfan = 2 */;
  reg [5:0]                     cal1_dq_deskew_count_cp
                                /* synthesis syn_maxfan = 2 */;
  reg [5:0]                     cal1_tp_count
                                /* synthesis syn_maxfan = 5 */;
  reg [3:0]                     cal1_state
                                /* synthesis syn_maxfan = 5 */;
  reg [3:0]                     cal1_state_r1
                                /* synthesis syn_maxfan = 5 */;
  reg [3:0]                     cal1_state_r2
                                /* synthesis syn_maxfan = 5 */;
  reg [5:0]                     cal1_window_cnt
                                /* synthesis syn_maxfan = 2 */;
  reg [5:0]                     cal1_window_cnt_r1
                                /* synthesis syn_maxfan = 2 */;
  reg                           cal1_stable_flag;

  reg [5:0]                     cal2_tap_count
                                /* synthesis syn_dspstyle = "logic" */
                                /* synthesis syn_maxfan = 5 */;
  reg [5:0]                     cal2_tap_count_cp1
                                /* synthesis syn_dspstyle = "logic" */
                                /* synthesis syn_maxfan = 5 */;
  reg [5:0]                     cal2_inc_count
                                /* synthesis syn_maxfan = 5 */;
  reg [5:0]                     cal2_dec_count
                                /* synthesis syn_maxfan = 2 */;
  reg [5:0]                     cal2_dec_count_c1;
  reg [5:0]                     cal2_dec_count_c3;
  reg                           cal2_inc_tap;
  reg                           cal2_dec_tap;
  reg                           cal2_first_edge_detect;
  reg                           cal2_dqs_count_check;
  reg [DQS_BITS_FIX-1:0]        cal2_dqs_count
                                /* synthesis syn_maxfan = 1 */;
  reg [DQS_BITS_FIX-1:0]        cal2_dqs_count_r1
                                /* synthesis syn_maxfan = 3 */;
  reg [DQS_BITS_FIX+5:0]        cal2_tap_count_index
                                /* synthesis syn_maxfan = 3 */;
  wire                          cal2_detect_edge;
  reg                           cal2_detect_edge_r;
  reg                           cal2_rd_valid;
  reg [DQS_WIDTH-1:0]           cal2_case1_reg;
  reg [DQS_WIDTH-1:0]           cal2_case2_reg;
  reg [DQS_WIDTH-1:0]           cal2_case3_reg;
  reg                           cal2_rd_data_fall_last;
  reg                           cal2_rd_data_fall_r;
  reg                           cal2_rd_data_rise_last;
  reg                           cal2_rd_data_rise_r;
  reg [3:0]                     cal2_state
                                /* synthesis syn_maxfan = 5 */;

  reg [3:0]                     calib_start;
  reg [2:0]                     calib_start_270;
  reg                           cal3_data_match;
  reg                           cal3_en;
  reg [7:0]                     cal3_data;
  reg [3:0]                     calib_done;
  reg                           calib3_done;
  reg                           ctrl_rden_270;
  reg [3:0]                     idel_set_cnt
                                /* synthesis syn_maxfan = 5 */;
  reg                           idel_set_wait;
  reg                           phy_init_rden_270;
  reg [(2*DQS_WIDTH)-1:0]       rd_data_fall_chk_r1;
  reg [DQ_WIDTH-1:0]            rd_data_fall_r;
  reg [(2*DQS_WIDTH)-1:0]       rd_data_rise_chk_r1;
  reg [DQ_WIDTH-1:0]            rd_data_rise_r;
  reg [DQS_BITS_FIX+2:0]        rden_dly_cnt;
  reg [DQS_BITS_FIX-1:0]        rden_cnt
                                /* synthesis syn_maxfan = 5 */;
  reg [DQS_BITS_FIX-1:0]        rden_cnt_r1
                                /* synthesis syn_maxfan = 5 */;
  reg [DQS_BITS_FIX-1:0]        rden_cnt_r2
                                /* synthesis syn_maxfan = 5 */;
  reg [2:0]                     rden_dly_tmp;
  reg [7:0]                     rden_edge;
  reg [8:0]                     rden_r;
  reg [23:0]                    rden_stages_r;
  reg [(3*DQS_WIDTH)-1:0]       rden_dly;
  reg [(3*DQS_WIDTH)-1:0]       rden_dly_r1;
  reg [DQS_WIDTH-1:0]           calib_rden_tmp;
  reg [DQS_WIDTH-1:0]           calib_rden_tmp_1;

  reg [DQS_BITS_FIX-1:0]        idelay_dqs_count
                                /* synthesis syn_maxfan = 5 */;
  reg                           dqs_inc;
  reg                           dqs_ce
                                /* synthesis syn_maxfan = 5 */;
  reg [DQ_PER_DQS-1:0]          dq_inc
                                /* synthesis syn_maxfan = 5 */;
  reg [DQ_PER_DQS-1:0]          dq_ce
                                /* synthesis syn_maxfan = 5 */;
  reg                           dq_rst
                                /* synthesis syn_maxfan = 5 */;
  reg                           dq_rst_cond;

  //***************************************************************************
  // Translation from CLK0 -> CLK90 and vice versa (control signals)
  //***************************************************************************

  // synchronize incrementally to improve timing
  always @(negedge clk90)
    calib_start_270 <= calib_start_0;

  always @(posedge clk90)
    calib_start <= calib_start_270;

  always @(posedge clk0)
    calib_done_0 <= calib_done;

  //***************************************************************************

  // register incoming capture data to improve timing. Adding single pipeline
  // stage does not affect functionality (as long as we make sure to wait
  // extra clock cycle after changing DQ IDELAY)
  always @(posedge clk90) begin
    rd_data_rise_r  <= rd_data_rise;
    rd_data_fall_r  <= rd_data_fall;
  end

  // furthur register a subset of the incoming captured data to use in
  // stage 3 calibration to check incoming data pattern.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -