📄 mem_interface_top_phy_calib_0.v
字号:
//*****************************************************************************
// 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 + -