AR# 55884

MIG 7 Series QDRII+ - "pi_edge_adv" can be stuck during calibration, which may lead to data failures

Description

Version Found: v1.9
Version Resolved: See (Xilinx Answer 45195) and (Xilinx Answer 54025)

During the EDGE_ADV stage of calibration it is possible for the "pi_edge_adv" signal to become stuck, which can lead to data failures during normal operation.

Solution

During the EDGE_ADV stage of calibration, if captured data from a byte group is aligned to the negative edge, the EDGE_ADV input to the PHASER_IN, which shifts the ICLKDIV output by one fast clock cycle, is used to adjust the data to the positive edge. When an adjustment is needed, the "pi_edge_adv" signal inside *_read_stage2_cal.v is asserted for one clock cycle. In some cases, it is possible for the "pi_edge_adv" signal in *_read_stage2_cal.v to become stuck, which can result in data byte errors.

To work around the issue, the following RTL modifications within mig_7series_v1_9_rld_phy_read_stage2_cal.v can be made:

Replace:

reg  [2:0]                           pi_edge_adv_wait_cnt;
  always @ (posedge clk) begin
         if (rst_clk) begin
             pi_edge_adv  <= #TCQ 0;
bitslip      <= #TCQ 0;
             phase_error  <= #TCQ 0;
             pi_edge_adv_wait_cnt <= #TCQ 0;
             inc_byte_cnt <= #TCQ 0;
         end else begin
    if (nCK_PER_CLK == 2) begin
               if ((clkdiv_phase_cal_done_5r) && (!edge_adv_cal_done)) begin
                 if (phase_bslip_vld_chk[byte_cnt] == 1'b1 &&
        pi_edge_adv_wait_cnt == 3'b000) begin
                    pi_edge_adv  <= #TCQ 1;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ 111;
                    inc_byte_cnt <= #TCQ 0;
                 end else if (phase_bslip_vld_chk[byte_cnt] == 1'b0 &&
                 pi_edge_adv_wait_cnt == 3'b000) begin
                    pi_edge_adv  <= #TCQ 0;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ 111;
                    inc_byte_cnt <= #TCQ 0;
                 end else if (pi_edge_adv_wait_cnt == 3'b010) begin
                    pi_edge_adv  <= #TCQ 0;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                    inc_byte_cnt <= #TCQ 1;
                 end else begin
                    pi_edge_adv  <= #TCQ 0;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                    inc_byte_cnt <= #TCQ 0;
                 end
  end //end of (clkdiv_phase_cal_done_5r) && (!edge_adv_cal_done)
end else begin //nCK_PER_CLK == 4
  //Even though we don't use the edge_adv signal we use the same
  //counter
  if (edge_adv_cal_start_r2 && (!edge_adv_cal_done)) begin
    if (phase_vld_check[byte_cnt] == 1'b1 &&
        pi_edge_adv_wait_cnt == 3'b000) begin
                   bitslip      <= #TCQ 0;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ 111;
                   inc_byte_cnt <= #TCQ 1;
    end else if (phase_vld_check[byte_cnt] == 1'b0 &&
                 pi_edge_adv_wait_cnt == 3'b000) begin
                   bitslip      <= #TCQ 1;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ 111;
                   inc_byte_cnt <= #TCQ 0;
    end else if (pi_edge_adv_wait_cnt == 3'b010) begin
                   bitslip      <= #TCQ 0;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                   inc_byte_cnt <= #TCQ 0;
                 end else begin
                   bitslip      <= #TCQ 0;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                   inc_byte_cnt <= #TCQ 0;
                 end
  end
end //end of //nCK_PER_CLK == 4
         end //end of else
      end //end of always


With:

reg  [3:0]                           pi_edge_adv_wait_cnt;
 always @ (posedge clk) begin
         if (rst_clk) begin
             pi_edge_adv  <= #TCQ 0;
bitslip      <= #TCQ 0;
             phase_error  <= #TCQ 0;
             pi_edge_adv_wait_cnt <= #TCQ 0;
             inc_byte_cnt <= #TCQ 0;
         end else begin
    if (nCK_PER_CLK == 2) begin
               if ((clkdiv_phase_cal_done_5r) && (!edge_adv_cal_done)) begin
                 if (phase_bslip_vld_chk[byte_cnt] == 1'b1 &&
        pi_edge_adv_wait_cnt == 4'b0000) begin
                    pi_edge_adv  <= #TCQ 1;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ 4'b1111;
                    inc_byte_cnt <= #TCQ 0;
                 end else if (phase_bslip_vld_chk[byte_cnt] == 1'b0 &&
                 pi_edge_adv_wait_cnt == 4'b0000) begin
                    pi_edge_adv  <= #TCQ 0;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ 4'b1111;
                    inc_byte_cnt <= #TCQ 0;
                 end else if (pi_edge_adv_wait_cnt == 4'b0010) begin
                    pi_edge_adv  <= #TCQ 0;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                    inc_byte_cnt <= #TCQ 1;
                 end else begin
                    pi_edge_adv  <= #TCQ 0;
                    phase_error  <= #TCQ 0;
                    pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                    inc_byte_cnt <= #TCQ 0;
                 end
  end //end of (clkdiv_phase_cal_done_5r) && (!edge_adv_cal_done)
end else begin //nCK_PER_CLK == 4
  //Even though we don't use the edge_adv signal we use the same
  //counter
  if (edge_adv_cal_start_r2 && (!edge_adv_cal_done)) begin
    if (phase_vld_check[byte_cnt] == 1'b1 &&
        pi_edge_adv_wait_cnt == 4'b0000) begin
                   bitslip      <= #TCQ 0;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ 4'b1111;
                   inc_byte_cnt <= #TCQ 1;
    end else if (phase_vld_check[byte_cnt] == 1'b0 &&
                 pi_edge_adv_wait_cnt == 4'b0000) begin
                   bitslip      <= #TCQ 1;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ 4'b1111;
                   inc_byte_cnt <= #TCQ 0;
    end else if (pi_edge_adv_wait_cnt == 4'b0010) begin
                   bitslip      <= #TCQ 0;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                   inc_byte_cnt <= #TCQ 0;
                 end else begin
                   bitslip      <= #TCQ 0;
                   phase_error  <= #TCQ 0;
                   pi_edge_adv_wait_cnt <= #TCQ pi_edge_adv_wait_cnt -1 ;
                   inc_byte_cnt <= #TCQ 0;
                 end
  end
end //end of //nCK_PER_CLK == 4
         end //end of else
      end //end of always

Revision History
05/06/2013 - Initial release

Linked Answer Records

Master Answer Records

AR# 55884
Date 10/03/2013
Status Active
Type Known Issues
Devices
IP