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

📄 phy_calib.v

📁 DDR2源代码 DDR2源代码 DDR2源代码
💻 V
📖 第 1 页 / 共 5 页
字号:
  reg                            cal4_dlyce_gate;  reg                            cal4_dlyinc_gate;  reg                            cal4_dlyrst_gate;  reg [4:0]                      cal4_gate_srl_a;  reg [5:0]                      cal4_idel_adj_cnt;  reg                            cal4_idel_adj_inc;  reg                            cal4_idel_bit_tap;  reg [5:0]                      cal4_idel_tap_cnt;  reg                            cal4_idel_max_tap;  reg [4:0]                      cal4_rden_srl_a;  reg                            cal4_ref_req;  reg                            cal4_seek_left;  reg                            cal4_stable_window;  reg [2:0]                      cal4_state;  reg [3:0]                      cal4_window_cnt;  reg [3:0]                      calib_done_tmp;         // only for stg1/2/4  reg                            calib_ctrl_gate_pulse_r;  reg                            calib_ctrl_rden;  reg                            calib_ctrl_rden_r;  wire                           calib_ctrl_rden_negedge;  reg                            calib_ctrl_rden_negedge_r;  reg [3:0]                      calib_done_r;  reg [3:0]                      calib_err;  reg [1:0]                      calib_err_2;  wire                           calib_init_gate_pulse;  reg                            calib_init_gate_pulse_r;  reg                            calib_init_gate_pulse_r1;  reg                            calib_init_rden;  reg                            calib_init_rden_r;  reg [4:0]                      calib_rden_srl_a;  wire [4:0]                     calib_rden_srl_a_r;  reg [(5*DQS_WIDTH)-1:0]        calib_rden_dly;  reg                            calib_rden_edge_r;  reg [4:0]                      calib_rden_pipe_cnt;  wire                           calib_rden_srl_out;  wire                           calib_rden_srl_out_r;  reg                            calib_rden_srl_out_r1;  reg                            calib_rden_valid;  reg                            calib_rden_valid_stgd;  reg [DQ_BITS-1:0]              count_dq;  reg [DQS_BITS_FIX-1:0]         count_dqs;  reg [DQS_BITS_FIX-1:0]         count_gate;  reg [DQS_BITS_FIX-1:0]         count_rden;  reg                            ctrl_rden_r;  wire                           dlyce_or;  reg [(5*DQS_WIDTH)-1:0]        gate_dly;  wire [(5*DQS_WIDTH)-1:0]       gate_dly_r;  wire                           gate_srl_in;  wire [DQS_WIDTH-1:0]           gate_srl_out;  wire [DQS_WIDTH-1:0]           gate_srl_out_r;  reg [2:0]                      idel_set_cnt;  wire                           idel_set_wait;  reg [DQ_BITS-1:0]              next_count_dq;  reg [DQS_BITS_FIX-1:0]         next_count_dqs;  reg [DQS_BITS_FIX-1:0]         next_count_gate;  reg                            phy_init_rden_r;  reg                            phy_init_rden_r1;  reg [DQ_WIDTH-1:0]             rd_data_fall_1x_r;  reg [DQS_WIDTH-1:0]            rd_data_fall_1x_r1;  reg [DQS_WIDTH-1:0]            rd_data_fall_2x_r;  wire [DQS_WIDTH-1:0]           rd_data_fall_chk_q1;  wire [DQS_WIDTH-1:0]           rd_data_fall_chk_q2;  reg [DQ_WIDTH-1:0]             rd_data_rise_1x_r;  reg [DQS_WIDTH-1:0]            rd_data_rise_1x_r1;  reg [DQS_WIDTH-1:0]            rd_data_rise_2x_r;  wire [DQS_WIDTH-1:0]           rd_data_rise_chk_q1;  wire [DQS_WIDTH-1:0]           rd_data_rise_chk_q2;  reg                            rdd_fall_q1;  reg                            rdd_fall_q1_r;  reg                            rdd_fall_q1_r1;  reg                            rdd_fall_q2;  reg                            rdd_fall_q2_r;  reg                            rdd_rise_q1;  reg                            rdd_rise_q1_r;  reg                            rdd_rise_q1_r1;  reg                            rdd_rise_q2;  reg                            rdd_rise_q2_r;  reg [DQS_BITS_FIX-1:0]         rdd_mux_sel;  reg                            rden_dec;  reg [(5*DQS_WIDTH)-1:0]        rden_dly;  wire [(5*DQS_WIDTH)-1:0]       rden_dly_r;  reg [4:0]                      rden_dly_0;  reg                            rden_inc;  reg [DQS_WIDTH-1:0]            rden_mux;  wire [DQS_WIDTH-1:0]           rden_srl_out;  // Debug  integer                        x;  reg [5:0]                      dbg_dq_tap_cnt [DQ_WIDTH-1:0];  reg [5:0]                      dbg_dqs_tap_cnt [DQS_WIDTH-1:0];  reg [5:0]                      dbg_gate_tap_cnt [DQS_WIDTH-1:0];  //***************************************************************************  // Debug output ("dbg_phy_calib_*")  // NOTES:  //  1. All debug outputs coming out of PHY_CALIB are clocked off CLKDIV0,  //     although they are also static after calibration is complete. This  //     means the user can either connect them to a Chipscope ILA, or to  //     either a sync/async VIO input block. Using an async VIO has the  //     advantage of not requiring these paths to meet cycle-to-cycle timing.  //  2. The widths of most of these debug buses are dependent on the # of  //     DQS/DQ bits (e.g. dq_tap_cnt width = 6 * (# of DQ bits)  // SIGNAL DESCRIPTION:  //  1. calib_done:   4 bits - each one asserted as each phase of calibration  //                   is completed.  //  2. calib_err:    4 bits - each one asserted when a calibration error  //                   encountered for that stage. Some of these bits may not  //                   be used (not all cal stages report an error).  //  3. dq_tap_cnt:   final IDELAY tap counts for all DQ IDELAYs  //  4. dqs_tap_cnt:  final IDELAY tap counts for all DQS IDELAYs  //  5. gate_tap_cnt: final IDELAY tap counts for all DQS gate  //                   synchronization IDELAYs  //  6. rd_data_sel:  final read capture MUX (either "positive" or "negative"  //                   edge capture) settings for all DQS groups  //  7. rden_dly:     related to # of cycles after issuing a read until when  //                   read data is valid - for all DQS groups  //  8. gate_dly:     related to # of cycles after issuing a read until when  //                   clock enable for all DQ's is deasserted to prevent  //                   effect of DQS postamble glitch - for all DQS groups  //***************************************************************************  //*****************************************************************  // Record IDELAY tap values by "snooping" IDELAY control signals  //*****************************************************************  // record DQ IDELAY tap values  genvar dbg_dq_tc_i;  generate    for (dbg_dq_tc_i = 0; dbg_dq_tc_i < DQ_WIDTH;         dbg_dq_tc_i = dbg_dq_tc_i + 1) begin: gen_dbg_dq_tap_cnt      assign dbg_calib_dq_tap_cnt[(6*dbg_dq_tc_i)+5:(6*dbg_dq_tc_i)]               = dbg_dq_tap_cnt[dbg_dq_tc_i];      always @(posedge clkdiv)        if (rstdiv | dlyrst_dq)          dbg_dq_tap_cnt[dbg_dq_tc_i] <= 6'b000000;        else          if (dlyce_dq[dbg_dq_tc_i])            if (dlyinc_dq[dbg_dq_tc_i])              dbg_dq_tap_cnt[dbg_dq_tc_i]                <= dbg_dq_tap_cnt[dbg_dq_tc_i] + 1;            else              dbg_dq_tap_cnt[dbg_dq_tc_i]                <= dbg_dq_tap_cnt[dbg_dq_tc_i] - 1;    end  endgenerate  // record DQS IDELAY tap values  genvar dbg_dqs_tc_i;  generate    for (dbg_dqs_tc_i = 0; dbg_dqs_tc_i < DQS_WIDTH;         dbg_dqs_tc_i = dbg_dqs_tc_i + 1) begin: gen_dbg_dqs_tap_cnt      assign dbg_calib_dqs_tap_cnt[(6*dbg_dqs_tc_i)+5:(6*dbg_dqs_tc_i)]               = dbg_dqs_tap_cnt[dbg_dqs_tc_i];      always @(posedge clkdiv)        if (rstdiv | dlyrst_dqs)          dbg_dqs_tap_cnt[dbg_dqs_tc_i] <= 6'b000000;        else          if (dlyce_dqs[dbg_dqs_tc_i])            if (dlyinc_dqs[dbg_dqs_tc_i])              dbg_dqs_tap_cnt[dbg_dqs_tc_i]                <= dbg_dqs_tap_cnt[dbg_dqs_tc_i] + 1;            else              dbg_dqs_tap_cnt[dbg_dqs_tc_i]                <= dbg_dqs_tap_cnt[dbg_dqs_tc_i] - 1;    end  endgenerate  // record DQS gate IDELAY tap values  genvar dbg_gate_tc_i;  generate    for (dbg_gate_tc_i = 0; dbg_gate_tc_i < DQS_WIDTH;         dbg_gate_tc_i = dbg_gate_tc_i + 1) begin: gen_dbg_gate_tap_cnt      assign dbg_calib_gate_tap_cnt[(6*dbg_gate_tc_i)+5:(6*dbg_gate_tc_i)]               = dbg_gate_tap_cnt[dbg_gate_tc_i];      always @(posedge clkdiv)        if (rstdiv | dlyrst_gate[dbg_gate_tc_i])          dbg_gate_tap_cnt[dbg_gate_tc_i] <= 6'b000000;        else          if (dlyce_gate[dbg_gate_tc_i])            if (dlyinc_gate[dbg_gate_tc_i])              dbg_gate_tap_cnt[dbg_gate_tc_i]                <= dbg_gate_tap_cnt[dbg_gate_tc_i] + 1;            else              dbg_gate_tap_cnt[dbg_gate_tc_i]                <= dbg_gate_tap_cnt[dbg_gate_tc_i] - 1;    end  endgenerate  assign dbg_calib_done        = calib_done;  assign dbg_calib_err         = calib_err;  assign dbg_calib_rd_data_sel = cal2_rd_data_sel;  assign dbg_calib_rden_dly    = rden_dly;  assign dbg_calib_gate_dly    = gate_dly;  //***************************************************************************  // Read data pipelining, and read data "ISERDES" data width expansion  //***************************************************************************  // For all data bits, register incoming capture data to slow clock 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)  // Also note in this case that we're "missing" every other clock cycle's  // worth of data capture since we're sync'ing to the slow clock. This is  // fine for stage 1 and stage 2 cal, but not for stage 3 and 4 (see below  // for different circuit to handle those stages)  always @(posedge clkdiv) begin    rd_data_rise_1x_r <= rd_data_rise;    rd_data_fall_1x_r <= rd_data_fall;  end  // For every DQ_PER_DQS bit, generate what is essentially a ISERDES-type  // data width expander. Will need this for stage 3 and 4 cal, where we need  // to compare data over consecutive clock cycles. We can also use this for  // stage 2 as well (stage 2 doesn't require every bit to be looked at, only  // one bit per DQS group)  genvar rdd_i;  generate    for (rdd_i = 0; rdd_i < DQS_WIDTH; rdd_i = rdd_i + 1) begin: gen_rdd      // first stage: keep data in fast clk domain. Store data over two      // consecutive clock cycles for rise/fall data for proper transfer      // to slow clock domain      always @(posedge clk) begin        rd_data_rise_2x_r[rdd_i] <= rd_data_rise[(rdd_i*DQ_PER_DQS)];        rd_data_fall_2x_r[rdd_i] <= rd_data_fall[(rdd_i*DQ_PER_DQS)];      end      // second stage, register first stage to slow clock domain, 2nd stage      // consists of both these flops, and the rd_data_rise_1x_r flops      always @(posedge clkdiv) begin        rd_data_rise_1x_r1[rdd_i] <= rd_data_rise_2x_r[rdd_i];        rd_data_fall_1x_r1[rdd_i] <= rd_data_fall_2x_r[rdd_i];      end      // now we have four outputs - representing rise/fall outputs over last      // 2 fast clock cycles. However, the ordering these represent can either      // be: (1) Q2 = data @ time = n, Q1 = data @ time = n+1, or (2)      // Q2 = data @ time = n - 1, Q1 = data @ time = n (and data at [Q1,Q2]      // is "staggered") - leave it up to the stage of calibration using this      // to figure out which is which, if they care at all (e.g. stage 2 cal      // doesn't care about the ordering)      assign rd_data_rise_chk_q1[rdd_i]               = rd_data_rise_1x_r[(rdd_i*DQ_PER_DQS)];      assign rd_data_rise_chk_q2[rdd_i]               = rd_data_rise_1x_r1[rdd_i];      assign rd_data_fall_chk_q1[rdd_i]               = rd_data_fall_1x_r[(rdd_i*DQ_PER_DQS)];      assign rd_data_fall_chk_q2[rdd_i]               = rd_data_fall_1x_r1[rdd_i];    end  endgenerate  //*****************************************************************  // Outputs of these simplified ISERDES circuits then feed MUXes based on  // which DQ the current calibration algorithm needs to look at  //*****************************************************************  // generate MUX control; assume that adding an extra pipeline stage isn't  // an issue - whatever stage cal logic is using output of MUX will wait  // enough time after changing it  always @(posedge clkdiv) begin    (* full_case, parallel_case *) case (calib_done[2:0])      3'b001: rdd_mux_sel <= next_count_dqs;      3'b011: rdd_mux_sel <= count_rden;      3'b111: rdd_mux_sel <= next_count_gate;    endcase  end  always @(posedge clkdiv) begin    rdd_rise_q1 <= rd_data_rise_chk_q1[rdd_mux_sel];    rdd_rise_q2 <= rd_data_rise_chk_q2[rdd_mux_sel];    rdd_fall_q1 <= rd_data_fall_chk_q1[rdd_mux_sel];    rdd_fall_q2 <= rd_data_fall_chk_q2[rdd_mux_sel];  end  //***************************************************************************  // Demultiplexor to control (reset, increment, decrement) IDELAY tap values  //   For DQ:  //     STG1: for per-bit-deskew, only inc/dec the current DQ. For non-per  //       deskew, increment all bits in the current DQS set  //     STG2: inc/dec all DQ's in the current DQS set.  // NOTE: Nice to add some error checking logic here (or elsewhere in the  //       code) to check if logic attempts to overflow tap value  //***************************************************************************

⌨️ 快捷键说明

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