AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Files Variables
mig_7series_v1_9_ddr_phy_prbs_rdlvl.v
1  //*****************************************************************************
2 // (c) Copyright 2009 - 2013 Xilinx, Inc. All rights reserved.
3 //
4 // This file contains confidential and proprietary information
5 // of Xilinx, Inc. and is protected under U.S. and
6 // international copyright and other intellectual property
7 // laws.
8 //
9 // DISCLAIMER
10 // This disclaimer is not a license and does not grant any
11 // rights to the materials distributed herewith. Except as
12 // otherwise provided in a valid license issued to you by
13 // Xilinx, and to the maximum extent permitted by applicable
14 // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
15 // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
16 // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
17 // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
18 // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
19 // (2) Xilinx shall not be liable (whether in contract or tort,
20 // including negligence, or under any other theory of
21 // liability) for any loss or damage of any kind or nature
22 // related to, arising under or in connection with these
23 // materials, including for any direct, or any indirect,
24 // special, incidental, or consequential loss or damage
25 // (including loss of data, profits, goodwill, or any type of
26 // loss or damage suffered as a result of any action brought
27 // by a third party) even if such damage or loss was
28 // reasonably foreseeable or Xilinx had been advised of the
29 // possibility of the same.
30 //
31 // CRITICAL APPLICATIONS
32 // Xilinx products are not designed or intended to be fail-
33 // safe, or for use in any application requiring fail-safe
34 // performance, such as life-support or safety devices or
35 // systems, Class III medical devices, nuclear facilities,
36 // applications related to the deployment of airbags, or any
37 // other applications that could lead to death, personal
38 // injury, or severe property or environmental damage
39 // (individually and collectively, "Critical
40 // Applications"). Customer assumes the sole risk and
41 // liability of any use of Xilinx products in Critical
42 // Applications, subject only to applicable laws and
43 // regulations governing limitations on product liability.
44 //
45 // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
46 // PART OF THIS FILE AT ALL TIMES.
47 //
48 //*****************************************************************************
49 // ____ ____
50 // / /\/ /
51 // /___/ \ / Vendor: Xilinx
52 // \ \ \/ Version:
53 // \ \ Application: MIG
54 // / / Filename: ddr_phy_prbs_rdlvl.v
55 // /___/ /\ Date Last Modified: $Date: 2011/06/24 14:49:00 $
56 // \ \ / \ Date Created:
57 // \___\/\___\
58 //
59 //Device: 7 Series
60 //Design Name: DDR3 SDRAM
61 //Purpose:
62 // PRBS Read leveling calibration logic
63 // NOTES:
64 // 1. Window detection with PRBS pattern.
65 //Reference:
66 //Revision History:
67 //*****************************************************************************
68 
69 /******************************************************************************
70 **$Id: ddr_phy_prbs_rdlvl.v,v 1.2 2011/06/24 14:49:00 mgeorge Exp $
71 **$Date: 2011/06/24 14:49:00 $
72 **$Author: mgeorge $
73 **$Revision: 1.2 $
74 **$Source: /devl/xcs/repo/env/Databases/ip/src2/O/mig_7series_v1_3/data/dlib/7series/ddr3_sdram/verilog/rtl/phy/ddr_phy_prbs_rdlvl.v,v $
75 *******************************************************************************/
76 
77 `timescale 1ps/1ps
78 
80  (
81  parameter TCQ = 100, // clk->out delay (sim only)
82  parameter nCK_PER_CLK = 2, // # of memory clocks per CLK
83  parameter DQ_WIDTH = 64, // # of DQ (data)
84  parameter DQS_CNT_WIDTH = 3, // = ceil(log2(DQS_WIDTH))
85  parameter DQS_WIDTH = 8, // # of DQS (strobe)
86  parameter DRAM_WIDTH = 8, // # of DQ per DQS
87  parameter RANKS = 1, // # of DRAM ranks
88  parameter SIM_CAL_OPTION = "NONE", // Skip various calibration steps
89  parameter PRBS_WIDTH = 8 // PRBS generator output width
90  )
91  (
92  input clk,
93  input rst,
94  // Calibration status, control signals
95  input prbs_rdlvl_start,
96  output reg prbs_rdlvl_done,
97  output reg prbs_last_byte_done,
98  output reg prbs_rdlvl_prech_req,
99  input prech_done,
100  input phy_if_empty,
101  // Captured data in fabric clock domain
102  input [2*nCK_PER_CLK*DQ_WIDTH-1:0] rd_data,
103  //Expected data from PRBS generator
104  input [2*nCK_PER_CLK*PRBS_WIDTH-1:0] compare_data,
105  // Decrement initial Phaser_IN Fine tap delay
106  input [5:0] pi_counter_read_val,
107  // Stage 1 calibration outputs
108  output reg pi_en_stg2_f,
109  output reg pi_stg2_f_incdec,
110  output [255:0] dbg_prbs_rdlvl,
111  output [DQS_CNT_WIDTH:0] pi_stg2_prbs_rdlvl_cnt
112  );
113 
114 
115 
116 
117  localparam [5:0] PRBS_IDLE = 6'h00;
118  localparam [5:0] PRBS_NEW_DQS_WAIT = 6'h01;
119  localparam [5:0] PRBS_PAT_COMPARE = 6'h02;
120  localparam [5:0] PRBS_DEC_DQS = 6'h03;
121  localparam [5:0] PRBS_DEC_DQS_WAIT = 6'h04;
122  localparam [5:0] PRBS_INC_DQS = 6'h05;
123  localparam [5:0] PRBS_INC_DQS_WAIT = 6'h06;
124  localparam [5:0] PRBS_CALC_TAPS = 6'h07;
125  localparam [5:0] PRBS_TAP_CHECK = 6'h08;
126  localparam [5:0] PRBS_NEXT_DQS = 6'h09;
127  localparam [5:0] PRBS_NEW_DQS_PREWAIT = 6'h0A;
128  localparam [5:0] PRBS_DONE = 6'h0B;
129 
130 
131  localparam [11:0] NUM_SAMPLES_CNT = (SIM_CAL_OPTION == "NONE") ? 12'hFFF : 12'h001;
132  localparam [11:0] NUM_SAMPLES_CNT1 = (SIM_CAL_OPTION == "NONE") ? 12'hFFF : 12'h001;
133  localparam [11:0] NUM_SAMPLES_CNT2 = (SIM_CAL_OPTION == "NONE") ? 12'hFFF : 12'h001;
134 
135 
136  wire [DQS_CNT_WIDTH+2:0]prbs_dqs_cnt_timing;
137  reg [DQS_CNT_WIDTH+2:0] prbs_dqs_cnt_timing_r;
138  reg [DQS_CNT_WIDTH:0] prbs_dqs_cnt_r;
139  reg prbs_prech_req_r;
140  reg [5:0] prbs_state_r;
141  reg [5:0] prbs_state_r1;
142  reg wait_state_cnt_en_r;
143  reg [3:0] wait_state_cnt_r;
144  reg cnt_wait_state;
145  reg found_edge_r;
146  reg prbs_found_1st_edge_r;
147  reg prbs_found_2nd_edge_r;
148  reg [5:0] prbs_1st_edge_taps_r;
149  reg found_stable_eye_r;
150  reg [5:0] prbs_dqs_tap_cnt_r;
151  reg [5:0] prbs_dec_tap_calc_plus_3;
152  reg [5:0] prbs_dec_tap_calc_minus_3;
153  reg prbs_dqs_tap_limit_r;
154  reg [5:0] prbs_inc_tap_cnt;
155  reg [5:0] prbs_dec_tap_cnt;
156  reg [DRAM_WIDTH-1:0] mux_rd_fall0_r1;
157  reg [DRAM_WIDTH-1:0] mux_rd_fall1_r1;
158  reg [DRAM_WIDTH-1:0] mux_rd_rise0_r1;
159  reg [DRAM_WIDTH-1:0] mux_rd_rise1_r1;
160  reg [DRAM_WIDTH-1:0] mux_rd_fall2_r1;
161  reg [DRAM_WIDTH-1:0] mux_rd_fall3_r1;
162  reg [DRAM_WIDTH-1:0] mux_rd_rise2_r1;
163  reg [DRAM_WIDTH-1:0] mux_rd_rise3_r1;
164  reg [DRAM_WIDTH-1:0] mux_rd_fall0_r2;
165  reg [DRAM_WIDTH-1:0] mux_rd_fall1_r2;
166  reg [DRAM_WIDTH-1:0] mux_rd_rise0_r2;
167  reg [DRAM_WIDTH-1:0] mux_rd_rise1_r2;
168  reg [DRAM_WIDTH-1:0] mux_rd_fall2_r2;
169  reg [DRAM_WIDTH-1:0] mux_rd_fall3_r2;
170  reg [DRAM_WIDTH-1:0] mux_rd_rise2_r2;
171  reg [DRAM_WIDTH-1:0] mux_rd_rise3_r2;
172  reg mux_rd_valid_r;
173  reg rd_valid_r1;
174  reg rd_valid_r2;
175  reg rd_valid_r3;
176  reg new_cnt_dqs_r;
177  reg prbs_tap_en_r;
178  reg prbs_tap_inc_r;
179  reg pi_en_stg2_f_timing;
180  reg pi_stg2_f_incdec_timing;
181  wire [DQ_WIDTH-1:0] rd_data_rise0;
182  wire [DQ_WIDTH-1:0] rd_data_fall0;
183  wire [DQ_WIDTH-1:0] rd_data_rise1;
184  wire [DQ_WIDTH-1:0] rd_data_fall1;
185  wire [DQ_WIDTH-1:0] rd_data_rise2;
186  wire [DQ_WIDTH-1:0] rd_data_fall2;
187  wire [DQ_WIDTH-1:0] rd_data_rise3;
188  wire [DQ_WIDTH-1:0] rd_data_fall3;
189  wire [PRBS_WIDTH-1:0] compare_data_r0;
190  wire [PRBS_WIDTH-1:0] compare_data_f0;
191  wire [PRBS_WIDTH-1:0] compare_data_r1;
192  wire [PRBS_WIDTH-1:0] compare_data_f1;
193  wire [PRBS_WIDTH-1:0] compare_data_r2;
194  wire [PRBS_WIDTH-1:0] compare_data_f2;
195  wire [PRBS_WIDTH-1:0] compare_data_r3;
196  wire [PRBS_WIDTH-1:0] compare_data_f3;
197  reg [DQS_CNT_WIDTH:0] rd_mux_sel_r;
198  reg [5:0] prbs_2nd_edge_taps_r;
199 
200  reg [6*DQS_WIDTH*RANKS-1:0] prbs_final_dqs_tap_cnt_r;
201  reg [1:0] rnk_cnt_r;
202  reg [5:0] rdlvl_cpt_tap_cnt;
203  reg prbs_rdlvl_start_r;
204 
205  reg compare_err;
206  reg compare_err_r0;
207  reg compare_err_f0;
208  reg compare_err_r1;
209  reg compare_err_f1;
210  reg compare_err_r2;
211  reg compare_err_f2;
212  reg compare_err_r3;
213  reg compare_err_f3;
214 
215  reg samples_cnt1_en_r;
216  reg samples_cnt2_en_r;
217  reg [11:0] samples_cnt_r;
218  reg num_samples_done_r;
219  reg [DQS_WIDTH-1:0] prbs_tap_mod;
220 
221 
222 
223 
224  //**************************************************************************
225  // DQS count to hard PHY during write calibration using Phaser_OUT Stage2
226  // coarse delay
227  //**************************************************************************
228 // assign pi_stg2_prbs_rdlvl_cnt = prbs_dqs_cnt_r;
229 // assign dbg_prbs_rdlvl = {prbs_tap_mod, prbs_2nd_edge_taps_r, prbs_1st_edge_taps_r, rdlvl_cpt_tap_cnt, prbs_dqs_cnt_r,
230 // prbs_rdlvl_done, prbs_rdlvl_start, phy_if_empty, compare_err, prbs_found_2nd_edge_r, prbs_found_1st_edge_r, prbs_dqs_tap_cnt_r, pi_counter_read_val,
231 // mux_rd_fall3_r2, mux_rd_rise3_r2, mux_rd_fall2_r2, mux_rd_rise2_r2, mux_rd_fall1_r2, mux_rd_rise1_r2, mux_rd_fall0_r2, mux_rd_rise0_r2,
232 // compare_data_f3, compare_data_r3, compare_data_f2, compare_data_r2, compare_data_f1, compare_data_r1, compare_data_f0, compare_data_r0};
233 
234  assign dbg_prbs_rdlvl[0+:8] = compare_data_r0;
235  assign dbg_prbs_rdlvl[8+:8] = compare_data_f0;
236  assign dbg_prbs_rdlvl[16+:8] = compare_data_r1;
237  assign dbg_prbs_rdlvl[24+:8] = compare_data_f1;
238  assign dbg_prbs_rdlvl[32+:8] = compare_data_r2;
239  assign dbg_prbs_rdlvl[40+:8] = compare_data_f2;
240  assign dbg_prbs_rdlvl[48+:8] = compare_data_r3;
241  assign dbg_prbs_rdlvl[56+:8] = compare_data_f3;
242 
243  assign dbg_prbs_rdlvl[64+:8] = mux_rd_rise0_r2;
244  assign dbg_prbs_rdlvl[72+:8] = mux_rd_fall0_r2;
245  assign dbg_prbs_rdlvl[80+:8] = mux_rd_rise1_r2;
246  assign dbg_prbs_rdlvl[88+:8] = mux_rd_fall1_r2;
247  assign dbg_prbs_rdlvl[96+:8] = mux_rd_rise2_r2;
248  assign dbg_prbs_rdlvl[104+:8] = mux_rd_fall2_r2;
249  assign dbg_prbs_rdlvl[112+:8] = mux_rd_rise3_r2;
250  assign dbg_prbs_rdlvl[120+:8] = mux_rd_fall3_r2;
251 
252  assign dbg_prbs_rdlvl[128+:6] = pi_counter_read_val;
253  assign dbg_prbs_rdlvl[134+:6] = prbs_dqs_tap_cnt_r;
254 
255  assign dbg_prbs_rdlvl[140] = prbs_found_1st_edge_r;
256  assign dbg_prbs_rdlvl[141] = prbs_found_2nd_edge_r;
257  assign dbg_prbs_rdlvl[142] = compare_err;
258  assign dbg_prbs_rdlvl[143] = phy_if_empty;
259  assign dbg_prbs_rdlvl[144] = prbs_rdlvl_start;
260  assign dbg_prbs_rdlvl[145] = prbs_rdlvl_done;
261 
262  assign dbg_prbs_rdlvl[146+:5] = prbs_dqs_cnt_r;
263  assign dbg_prbs_rdlvl[151+:6] = rdlvl_cpt_tap_cnt;
264  assign dbg_prbs_rdlvl[157+:6] = prbs_1st_edge_taps_r;
265  assign dbg_prbs_rdlvl[163+:6] = prbs_2nd_edge_taps_r;
266  assign dbg_prbs_rdlvl[169+:9] = prbs_tap_mod;
267 
268  assign dbg_prbs_rdlvl[255:178]= 'b0;//reserved
269 
270  //***************************************************************************
271  //***************************************************************************
272  // Data mux to route appropriate bit to calibration logic - i.e. calibration
273  // is done sequentially, one bit (or DQS group) at a time
274  //***************************************************************************
275 
276  generate
277  if (nCK_PER_CLK == 4) begin: rd_data_div4_logic_clk
278  assign rd_data_rise0 = rd_data[DQ_WIDTH-1:0];
279  assign rd_data_fall0 = rd_data[2*DQ_WIDTH-1:DQ_WIDTH];
280  assign rd_data_rise1 = rd_data[3*DQ_WIDTH-1:2*DQ_WIDTH];
281  assign rd_data_fall1 = rd_data[4*DQ_WIDTH-1:3*DQ_WIDTH];
282  assign rd_data_rise2 = rd_data[5*DQ_WIDTH-1:4*DQ_WIDTH];
283  assign rd_data_fall2 = rd_data[6*DQ_WIDTH-1:5*DQ_WIDTH];
284  assign rd_data_rise3 = rd_data[7*DQ_WIDTH-1:6*DQ_WIDTH];
285  assign rd_data_fall3 = rd_data[8*DQ_WIDTH-1:7*DQ_WIDTH];
286  assign compare_data_r0 = compare_data[PRBS_WIDTH-1:0];
287  assign compare_data_f0 = compare_data[2*PRBS_WIDTH-1:PRBS_WIDTH];
288  assign compare_data_r1 = compare_data[3*PRBS_WIDTH-1:2*PRBS_WIDTH];
289  assign compare_data_f1 = compare_data[4*PRBS_WIDTH-1:3*PRBS_WIDTH];
290  assign compare_data_r2 = compare_data[5*PRBS_WIDTH-1:4*PRBS_WIDTH];
291  assign compare_data_f2 = compare_data[6*PRBS_WIDTH-1:5*PRBS_WIDTH];
292  assign compare_data_r3 = compare_data[7*PRBS_WIDTH-1:6*PRBS_WIDTH];
293  assign compare_data_f3 = compare_data[8*PRBS_WIDTH-1:7*PRBS_WIDTH];
294  end else begin: rd_data_div2_logic_clk
295  assign rd_data_rise0 = rd_data[DQ_WIDTH-1:0];
296  assign rd_data_fall0 = rd_data[2*DQ_WIDTH-1:DQ_WIDTH];
297  assign rd_data_rise1 = rd_data[3*DQ_WIDTH-1:2*DQ_WIDTH];
298  assign rd_data_fall1 = rd_data[4*DQ_WIDTH-1:3*DQ_WIDTH];
299  assign compare_data_r0 = compare_data[PRBS_WIDTH-1:0];
300  assign compare_data_f0 = compare_data[2*PRBS_WIDTH-1:PRBS_WIDTH];
301  assign compare_data_r1 = compare_data[3*PRBS_WIDTH-1:2*PRBS_WIDTH];
302  assign compare_data_f1 = compare_data[4*PRBS_WIDTH-1:3*PRBS_WIDTH];
303  end
304  endgenerate
305 
306  always @(posedge clk) begin
307  rd_mux_sel_r <= #TCQ prbs_dqs_cnt_r;
308  end
309 
310  // Register outputs for improved timing.
311  // NOTE: Will need to change when per-bit DQ deskew is supported.
312  // Currenly all bits in DQS group are checked in aggregate
313  generate
314  genvar mux_i;
315  for (mux_i = 0; mux_i < DRAM_WIDTH; mux_i = mux_i + 1) begin: gen_mux_rd
316  always @(posedge clk) begin
317  mux_rd_rise0_r1[mux_i] <= #TCQ rd_data_rise0[DRAM_WIDTH*rd_mux_sel_r + mux_i];
318  mux_rd_fall0_r1[mux_i] <= #TCQ rd_data_fall0[DRAM_WIDTH*rd_mux_sel_r + mux_i];
319  mux_rd_rise1_r1[mux_i] <= #TCQ rd_data_rise1[DRAM_WIDTH*rd_mux_sel_r + mux_i];
320  mux_rd_fall1_r1[mux_i] <= #TCQ rd_data_fall1[DRAM_WIDTH*rd_mux_sel_r + mux_i];
321  mux_rd_rise2_r1[mux_i] <= #TCQ rd_data_rise2[DRAM_WIDTH*rd_mux_sel_r + mux_i];
322  mux_rd_fall2_r1[mux_i] <= #TCQ rd_data_fall2[DRAM_WIDTH*rd_mux_sel_r + mux_i];
323  mux_rd_rise3_r1[mux_i] <= #TCQ rd_data_rise3[DRAM_WIDTH*rd_mux_sel_r + mux_i];
324  mux_rd_fall3_r1[mux_i] <= #TCQ rd_data_fall3[DRAM_WIDTH*rd_mux_sel_r + mux_i];
325  end
326  end
327  endgenerate
328 
329  generate
330  genvar muxr2_i;
331  if (nCK_PER_CLK == 4) begin: gen_mux_div4
332  for (muxr2_i = 0; muxr2_i < DRAM_WIDTH; muxr2_i = muxr2_i + 1) begin: gen_rd_4
333  always @(posedge clk) begin
334  if (mux_rd_valid_r) begin
335  mux_rd_rise0_r2[muxr2_i] <= #TCQ mux_rd_rise0_r1[muxr2_i];
336  mux_rd_fall0_r2[muxr2_i] <= #TCQ mux_rd_fall0_r1[muxr2_i];
337  mux_rd_rise1_r2[muxr2_i] <= #TCQ mux_rd_rise1_r1[muxr2_i];
338  mux_rd_fall1_r2[muxr2_i] <= #TCQ mux_rd_fall1_r1[muxr2_i];
339  mux_rd_rise2_r2[muxr2_i] <= #TCQ mux_rd_rise2_r1[muxr2_i];
340  mux_rd_fall2_r2[muxr2_i] <= #TCQ mux_rd_fall2_r1[muxr2_i];
341  mux_rd_rise3_r2[muxr2_i] <= #TCQ mux_rd_rise3_r1[muxr2_i];
342  mux_rd_fall3_r2[muxr2_i] <= #TCQ mux_rd_fall3_r1[muxr2_i];
343  end
344  end
345  end
346  end else if (nCK_PER_CLK == 2) begin: gen_mux_div2
347  for (muxr2_i = 0; muxr2_i < DRAM_WIDTH; muxr2_i = muxr2_i + 1) begin: gen_rd_2
348  always @(posedge clk) begin
349  if (mux_rd_valid_r) begin
350  mux_rd_rise0_r2[muxr2_i] <= #TCQ mux_rd_rise0_r1[muxr2_i];
351  mux_rd_fall0_r2[muxr2_i] <= #TCQ mux_rd_fall0_r1[muxr2_i];
352  mux_rd_rise1_r2[muxr2_i] <= #TCQ mux_rd_rise1_r1[muxr2_i];
353  mux_rd_fall1_r2[muxr2_i] <= #TCQ mux_rd_fall1_r1[muxr2_i];
354  end
355  end
356  end
357  end
358  endgenerate
359 
360 
361  // Registered signal indicates when mux_rd_rise/fall_r is valid
362  always @(posedge clk) begin
363  mux_rd_valid_r <= #TCQ ~phy_if_empty && prbs_rdlvl_start;
364  rd_valid_r1 <= #TCQ mux_rd_valid_r;
365  rd_valid_r2 <= #TCQ rd_valid_r1;
366  end
367 
368 // Counter counts # of samples compared
369 // Reset sample counter when not "sampling"
370 // Otherwise, count # of samples compared
371 // Same counter is shared for three samples checked
372  always @(posedge clk)
373  if (rst)
374  samples_cnt_r <= #TCQ 'b0;
375  else begin
376  if (!rd_valid_r1 ||
377  (prbs_state_r == PRBS_DEC_DQS_WAIT) ||
378  (prbs_state_r == PRBS_INC_DQS_WAIT) ||
379  (prbs_state_r == PRBS_DEC_DQS) ||
380  (prbs_state_r == PRBS_INC_DQS) ||
381  (samples_cnt_r == NUM_SAMPLES_CNT) ||
382  (samples_cnt_r == NUM_SAMPLES_CNT1))
383  samples_cnt_r <= #TCQ 'b0;
384  else if (rd_valid_r1 &&
385  (((samples_cnt_r < NUM_SAMPLES_CNT) && ~samples_cnt1_en_r) ||
386  ((samples_cnt_r < NUM_SAMPLES_CNT1) && ~samples_cnt2_en_r) ||
387  ((samples_cnt_r < NUM_SAMPLES_CNT2) && samples_cnt2_en_r)))
388  samples_cnt_r <= #TCQ samples_cnt_r + 1;
389  end
390 
391 // Count #2 enable generation
392 // Assert when correct number of samples compared
393  always @(posedge clk)
394  if (rst)
395  samples_cnt1_en_r <= #TCQ 1'b0;
396  else begin
397  if ((prbs_state_r == PRBS_IDLE) ||
398  (prbs_state_r == PRBS_DEC_DQS) ||
399  (prbs_state_r == PRBS_INC_DQS) ||
400  (prbs_state_r == PRBS_NEW_DQS_PREWAIT))
401  samples_cnt1_en_r <= #TCQ 1'b0;
402  else if ((samples_cnt_r == NUM_SAMPLES_CNT) && rd_valid_r1)
403  samples_cnt1_en_r <= #TCQ 1'b1;
404  end
405 
406 // Counter #3 enable generation
407 // Assert when correct number of samples compared
408  always @(posedge clk)
409  if (rst)
410  samples_cnt2_en_r <= #TCQ 1'b0;
411  else begin
412  if ((prbs_state_r == PRBS_IDLE) ||
413  (prbs_state_r == PRBS_DEC_DQS) ||
414  (prbs_state_r == PRBS_INC_DQS) ||
415  (prbs_state_r == PRBS_NEW_DQS_PREWAIT))
416  samples_cnt2_en_r <= #TCQ 1'b0;
417  else if ((samples_cnt_r == NUM_SAMPLES_CNT1) && rd_valid_r1 && samples_cnt1_en_r)
418  samples_cnt2_en_r <= #TCQ 1'b1;
419  end
420 
421 // Assert when all the three sample counts are done
422  always @(posedge clk)
423  if (rst)
424  num_samples_done_r <= #TCQ 1'b0;
425  else begin
426  if (!rd_valid_r1 ||
427  (prbs_state_r == PRBS_DEC_DQS) ||
428  (prbs_state_r == PRBS_INC_DQS))
429  num_samples_done_r <= #TCQ 'b0;
430  else begin
431  if ((samples_cnt_r == NUM_SAMPLES_CNT2-1) && samples_cnt2_en_r)
432  num_samples_done_r <= #TCQ 1'b1;
433  end
434  end
435 
436 
437  //***************************************************************************
438  // Compare Read Data for the byte being Leveled with Expected data from PRBS
439  // generator. Resulting compare_err signal used to determine read data valid
440  // edge.
441  //***************************************************************************
442  generate
443  if (nCK_PER_CLK == 4) begin: cmp_err_4to1
444  always @ (posedge clk) begin
445  if (rst || new_cnt_dqs_r) begin
446  compare_err <= #TCQ 1'b0;
447  compare_err_r0 <= #TCQ 1'b0;
448  compare_err_f0 <= #TCQ 1'b0;
449  compare_err_r1 <= #TCQ 1'b0;
450  compare_err_f1 <= #TCQ 1'b0;
451  compare_err_r2 <= #TCQ 1'b0;
452  compare_err_f2 <= #TCQ 1'b0;
453  compare_err_r3 <= #TCQ 1'b0;
454  compare_err_f3 <= #TCQ 1'b0;
455  end else if (rd_valid_r1) begin
456  compare_err_r0 <= #TCQ (mux_rd_rise0_r2 != compare_data_r0);
457  compare_err_f0 <= #TCQ (mux_rd_fall0_r2 != compare_data_f0);
458  compare_err_r1 <= #TCQ (mux_rd_rise1_r2 != compare_data_r1);
459  compare_err_f1 <= #TCQ (mux_rd_fall1_r2 != compare_data_f1);
460  compare_err_r2 <= #TCQ (mux_rd_rise2_r2 != compare_data_r2);
461  compare_err_f2 <= #TCQ (mux_rd_fall2_r2 != compare_data_f2);
462  compare_err_r3 <= #TCQ (mux_rd_rise3_r2 != compare_data_r3);
463  compare_err_f3 <= #TCQ (mux_rd_fall3_r2 != compare_data_f3);
464  compare_err <= #TCQ (compare_err_r0 | compare_err_f0 |
465  compare_err_r1 | compare_err_f1 |
466  compare_err_r2 | compare_err_f2 |
467  compare_err_r3 | compare_err_f3);
468  end
469  end
470  end else begin: cmp_err_2to1
471  always @ (posedge clk) begin
472  if (rst || new_cnt_dqs_r) begin
473  compare_err <= #TCQ 1'b0;
474  compare_err_r0 <= #TCQ 1'b0;
475  compare_err_f0 <= #TCQ 1'b0;
476  compare_err_r1 <= #TCQ 1'b0;
477  compare_err_f1 <= #TCQ 1'b0;
478  end else if (rd_valid_r1) begin
479  compare_err_r0 <= #TCQ (mux_rd_rise0_r2 != compare_data_r0);
480  compare_err_f0 <= #TCQ (mux_rd_fall0_r2 != compare_data_f0);
481  compare_err_r1 <= #TCQ (mux_rd_rise1_r2 != compare_data_r1);
482  compare_err_f1 <= #TCQ (mux_rd_fall1_r2 != compare_data_f1);
483  compare_err <= #TCQ (compare_err_r0 | compare_err_f0 |
484  compare_err_r1 | compare_err_f1);
485  end
486  end
487  end
488  endgenerate
489 
490 //***************************************************************************
491 // Decrement initial Phaser_IN fine delay value before proceeding with
492 // read calibration
493 //***************************************************************************
494 
495 
496 //***************************************************************************
497 // Demultiplexor to control Phaser_IN delay values
498 //***************************************************************************
499 
500 // Read DQS
501  always @(posedge clk) begin
502  if (rst) begin
503  pi_en_stg2_f_timing <= #TCQ 'b0;
504  pi_stg2_f_incdec_timing <= #TCQ 'b0;
505  end else if (prbs_tap_en_r) begin
506 // Change only specified DQS
507  pi_en_stg2_f_timing <= #TCQ 1'b1;
508  pi_stg2_f_incdec_timing <= #TCQ prbs_tap_inc_r;
509  end else begin
510  pi_en_stg2_f_timing <= #TCQ 'b0;
511  pi_stg2_f_incdec_timing <= #TCQ 'b0;
512  end
513  end
514 
515 // registered for timing
516  always @(posedge clk) begin
517  pi_en_stg2_f <= #TCQ pi_en_stg2_f_timing;
518  pi_stg2_f_incdec <= #TCQ pi_stg2_f_incdec_timing;
519  end
520 
521 //***************************************************************************
522 // generate request to PHY_INIT logic to issue precharged. Required when
523 // calibration can take a long time (during which there are only constant
524 // reads present on this bus). In this case need to issue perioidic
525 // precharges to avoid tRAS violation. This signal must meet the following
526 // requirements: (1) only transition from 0->1 when prech is first needed,
527 // (2) stay at 1 and only transition 1->0 when RDLVL_PRECH_DONE asserted
528 //***************************************************************************
529 
530  always @(posedge clk)
531  if (rst)
532  prbs_rdlvl_prech_req <= #TCQ 1'b0;
533  else
534  prbs_rdlvl_prech_req <= #TCQ prbs_prech_req_r;
535 
536 //*****************************************************************
537 // keep track of edge tap counts found, and current capture clock
538 // tap count
539 //*****************************************************************
540 
541  always @(posedge clk)
542  if (rst) begin
543  prbs_dqs_tap_cnt_r <= #TCQ 'b0;
544  rdlvl_cpt_tap_cnt <= #TCQ 'b0;
545  end else if (new_cnt_dqs_r) begin
546  prbs_dqs_tap_cnt_r <= #TCQ pi_counter_read_val;
547  rdlvl_cpt_tap_cnt <= #TCQ pi_counter_read_val;
548  end else if (prbs_tap_en_r) begin
549  if (prbs_tap_inc_r)
550  prbs_dqs_tap_cnt_r <= #TCQ prbs_dqs_tap_cnt_r + 1;
551  else if (prbs_dqs_tap_cnt_r != 'd0)
552  prbs_dqs_tap_cnt_r <= #TCQ prbs_dqs_tap_cnt_r - 1;
553  end
554 
555  always @(posedge clk)
556  if (rst) begin
557  prbs_dec_tap_calc_plus_3 <= #TCQ 'b0;
558  prbs_dec_tap_calc_minus_3 <= #TCQ 'b0;
559  end else if (new_cnt_dqs_r) begin
560  prbs_dec_tap_calc_plus_3 <= #TCQ 'b000011;
561  prbs_dec_tap_calc_minus_3 <= #TCQ 'b111100;
562  end else begin
563  prbs_dec_tap_calc_plus_3 <= #TCQ (prbs_dqs_tap_cnt_r - rdlvl_cpt_tap_cnt + 3);
564  prbs_dec_tap_calc_minus_3 <= #TCQ (prbs_dqs_tap_cnt_r - rdlvl_cpt_tap_cnt - 3);
565  end
566 
567  always @(posedge clk)
568  if (rst || new_cnt_dqs_r)
569  prbs_dqs_tap_limit_r <= #TCQ 1'b0;
570  else if (prbs_dqs_tap_cnt_r == 6'd63)
571  prbs_dqs_tap_limit_r <= #TCQ 1'b1;
572 
573  // Temp wire for timing.
574  // The following in the always block below causes timing issues
575  // due to DSP block inference
576  // 6*prbs_dqs_cnt_r.
577  // replacing this with two left shifts + one left shift to avoid
578  // DSP multiplier.
579 
580  assign prbs_dqs_cnt_timing = {2'd0, prbs_dqs_cnt_r};
581 
582 
583  always @(posedge clk)
584  prbs_dqs_cnt_timing_r <= #TCQ prbs_dqs_cnt_timing;
585 
586 
587  // Storing DQS tap values at the end of each DQS read leveling
588  always @(posedge clk) begin
589  if (rst) begin
590  prbs_final_dqs_tap_cnt_r <= #TCQ 'b0;
591  end else if ((prbs_state_r == PRBS_NEXT_DQS) && (prbs_state_r1 != PRBS_NEXT_DQS)) begin
592  prbs_final_dqs_tap_cnt_r[(((prbs_dqs_cnt_timing_r <<2) + (prbs_dqs_cnt_timing_r <<1))
593  +(rnk_cnt_r*DQS_WIDTH*6))+:6]
594  <= #TCQ prbs_dqs_tap_cnt_r;
595  end
596  end
597 
598 
599 
600 
601  //*****************************************************************
602 
603  always @(posedge clk) begin
604  prbs_state_r1 <= #TCQ prbs_state_r;
605  prbs_rdlvl_start_r <= #TCQ prbs_rdlvl_start;
606  end
607 
608 // Wait counter for wait states
609  always @(posedge clk)
610  if ((prbs_state_r == PRBS_NEW_DQS_WAIT) ||
611  (prbs_state_r == PRBS_INC_DQS_WAIT) ||
612  (prbs_state_r == PRBS_DEC_DQS_WAIT) ||
613  (prbs_state_r == PRBS_NEW_DQS_PREWAIT))
614  wait_state_cnt_en_r <= #TCQ 1'b1;
615  else
616  wait_state_cnt_en_r <= #TCQ 1'b0;
617 
618  always @(posedge clk)
619  if (!wait_state_cnt_en_r) begin
620  wait_state_cnt_r <= #TCQ 'b0;
621  cnt_wait_state <= #TCQ 1'b0;
622  end else begin
623  if (wait_state_cnt_r < 'd15) begin
624  wait_state_cnt_r <= #TCQ wait_state_cnt_r + 1;
625  cnt_wait_state <= #TCQ 1'b0;
626  end else begin
627  // Need to reset to 0 to handle the case when there are two
628  // different WAIT states back-to-back
629  wait_state_cnt_r <= #TCQ 'b0;
630  cnt_wait_state <= #TCQ 1'b1;
631  end
632  end
633 
634 //*****************************************************************
635 // PRBS Read Level State Machine
636 //*****************************************************************
637 
638  always @(posedge clk)
639  if (rst) begin
640  prbs_dqs_cnt_r <= #TCQ 'b0;
641  prbs_tap_en_r <= #TCQ 1'b0;
642  prbs_tap_inc_r <= #TCQ 1'b0;
643  prbs_prech_req_r <= #TCQ 1'b0;
644  prbs_state_r <= #TCQ PRBS_IDLE;
645  prbs_found_1st_edge_r <= #TCQ 1'b0;
646  prbs_found_2nd_edge_r <= #TCQ 1'b0;
647  prbs_1st_edge_taps_r <= #TCQ 6'bxxxxxx;
648  prbs_inc_tap_cnt <= #TCQ 'b0;
649  prbs_dec_tap_cnt <= #TCQ 'b0;
650  new_cnt_dqs_r <= #TCQ 1'b0;
651  if (SIM_CAL_OPTION == "FAST_CAL")
652  prbs_rdlvl_done <= #TCQ 1'b1;
653  else
654  prbs_rdlvl_done <= #TCQ 1'b0;
655  prbs_2nd_edge_taps_r <= #TCQ 6'bxxxxxx;
656  prbs_last_byte_done <= #TCQ 1'b0;
657  rnk_cnt_r <= #TCQ 2'b00;
658  prbs_tap_mod <= #TCQ 'd0;
659  end else begin
660 
661  case (prbs_state_r)
662 
663  PRBS_IDLE: begin
664  prbs_last_byte_done <= #TCQ 1'b0;
665  prbs_prech_req_r <= #TCQ 1'b0;
666  if (prbs_rdlvl_start && ~prbs_rdlvl_start_r) begin
667  if (SIM_CAL_OPTION == "SKIP_CAL")
668  prbs_state_r <= #TCQ PRBS_DONE;
669  else begin
670  new_cnt_dqs_r <= #TCQ 1'b1;
671  prbs_state_r <= #TCQ PRBS_NEW_DQS_WAIT;
672  end
673  end
674  end
675 
676  // Wait for the new DQS group to change
677  // also gives time for the read data IN_FIFO to
678  // output the updated data for the new DQS group
679  PRBS_NEW_DQS_WAIT: begin
680  prbs_last_byte_done <= #TCQ 1'b0;
681  prbs_prech_req_r <= #TCQ 1'b0;
682  if (cnt_wait_state) begin
683  new_cnt_dqs_r <= #TCQ 1'b0;
684  prbs_state_r <= #TCQ PRBS_PAT_COMPARE;
685  end
686  end
687 
688  // Check for presence of data eye edge. During this state, we
689  // sample the read data multiple times, and look for changes
690  // in the read data, specifically:
691  // 1. A change in the read data compared with the value of
692  // read data from the previous delay tap. This indicates
693  // that the most recent tap delay increment has moved us
694  // into either a new window, or moved/kept us in the
695  // transition/jitter region between windows. Note that this
696  // condition only needs to be checked for once, and for
697  // logistical purposes, we check this soon after entering
698  // this state (see comment in PRBS_PAT_COMPARE below for
699  // why this is done)
700  // 2. A change in the read data while we are in this state
701  // (i.e. in the absence of a tap delay increment). This
702  // indicates that we're close enough to a window edge that
703  // jitter will cause the read data to change even in the
704  // absence of a tap delay change
705  PRBS_PAT_COMPARE: begin
706 
707  // Continue to sample read data and look for edges until the
708  // appropriate time interval (shorter for simulation-only,
709  // much, much longer for actual h/w) has elapsed
710  if (num_samples_done_r || compare_err) begin
711  if (prbs_dqs_tap_limit_r)
712  // Only one edge detected and ran out of taps since only one
713  // bit time worth of taps available for window detection. This
714  // can happen if at tap 0 DQS is in previous window which results
715  // in only left edge being detected. Or at tap 0 DQS is in the
716  // current window resulting in only right edge being detected.
717  // Depending on the frequency this case can also happen if at
718  // tap 0 DQS is in the left noise region resulting in only left
719  // edge being detected.
720  prbs_state_r <= #TCQ PRBS_CALC_TAPS;
721  else if (compare_err || (prbs_dqs_tap_cnt_r == 'd0)) begin
722  // Sticky bit - asserted after we encounter an edge, although
723  // the current edge may not be considered the "first edge" this
724  // just means we found at least one edge
725  prbs_found_1st_edge_r <= #TCQ 1'b1;
726 
727  // Both edges of data valid window found:
728  // If we've found a second edge after a region of stability
729  // then we must have just passed the second ("right" edge of
730  // the window. Record this second_edge_taps = current tap-1,
731  // because we're one past the actual second edge tap, where
732  // the edge taps represent the extremes of the data valid
733  // window (i.e. smallest & largest taps where data still valid
734  if (prbs_found_1st_edge_r) begin
735  prbs_found_2nd_edge_r <= #TCQ 1'b1;
736  prbs_2nd_edge_taps_r <= #TCQ prbs_dqs_tap_cnt_r - 1;
737  prbs_state_r <= #TCQ PRBS_CALC_TAPS;
738  end else begin
739  // Otherwise, an edge was found (just not the "second" edge)
740  // Assuming DQS is in the correct window at tap 0 of Phaser IN
741  // fine tap. The first edge found is the right edge of the valid
742  // window and is the beginning of the jitter region hence done!
743  if (compare_err)
744  prbs_1st_edge_taps_r <= #TCQ prbs_dqs_tap_cnt_r + 1;
745  else
746  prbs_1st_edge_taps_r <= #TCQ 'd0;
747 
748  prbs_inc_tap_cnt <= #TCQ rdlvl_cpt_tap_cnt - prbs_dqs_tap_cnt_r;
749  prbs_state_r <= #TCQ PRBS_INC_DQS;
750  end
751  end else begin
752  // Otherwise, if we haven't found an edge....
753  // If we still have taps left to use, then keep incrementing
754  if (prbs_found_1st_edge_r)
755  prbs_state_r <= #TCQ PRBS_INC_DQS;
756  else
757  prbs_state_r <= #TCQ PRBS_DEC_DQS;
758  end
759  end
760  end
761 
762  // Increment Phaser_IN delay for DQS
763  PRBS_INC_DQS: begin
764  prbs_state_r <= #TCQ PRBS_INC_DQS_WAIT;
765  if (prbs_inc_tap_cnt > 'd0)
766  prbs_inc_tap_cnt <= #TCQ prbs_inc_tap_cnt - 1;
767  if (~prbs_dqs_tap_limit_r) begin
768  prbs_tap_en_r <= #TCQ 1'b1;
769  prbs_tap_inc_r <= #TCQ 1'b1;
770  end else begin
771  prbs_tap_en_r <= #TCQ 1'b0;
772  prbs_tap_inc_r <= #TCQ 1'b0;
773  end
774  end
775 
776  // Wait for Phaser_In to settle, before checking again for an edge
777  PRBS_INC_DQS_WAIT: begin
778  prbs_tap_en_r <= #TCQ 1'b0;
779  prbs_tap_inc_r <= #TCQ 1'b0;
780  if (cnt_wait_state) begin
781  if (prbs_inc_tap_cnt > 'd0)
782  prbs_state_r <= #TCQ PRBS_INC_DQS;
783  else
784  prbs_state_r <= #TCQ PRBS_PAT_COMPARE;
785  end
786  end
787 
788  // Calculate final value of Phaser_IN taps. At this point, one or both
789  // edges of data eye have been found, and/or all taps have been
790  // exhausted looking for the edges
791  // NOTE: The amount to be decrement by is calculated, not the
792  // absolute setting for DQS.
793  PRBS_CALC_TAPS: begin
794  if (prbs_found_2nd_edge_r && prbs_found_1st_edge_r)
795  // Both edges detected
796  prbs_dec_tap_cnt
797  <= #TCQ ((prbs_2nd_edge_taps_r -
798  prbs_1st_edge_taps_r)>>1) + 1;
799  else if (~prbs_found_2nd_edge_r && prbs_found_1st_edge_r)
800  // Only left edge detected
801  prbs_dec_tap_cnt
802  <= #TCQ ((prbs_dqs_tap_cnt_r - prbs_1st_edge_taps_r)>>1);
803  else
804  // No edges detected
805  prbs_dec_tap_cnt
806  <= #TCQ (prbs_dqs_tap_cnt_r>>1);
807  // Now use the value we just calculated to decrement CPT taps
808  // to the desired calibration point
809  prbs_state_r <= #TCQ PRBS_TAP_CHECK; //PRBS_DEC_DQS;
810  end
811 
812  PRBS_TAP_CHECK: begin
813  // Fix for CR690798 - limit PRBS tap to +/- 3 taps of rdlvl_cpt_tap_cnt
814  if (prbs_dec_tap_calc_minus_3 > prbs_dec_tap_cnt) begin // proposing a re-order of the condition
815  prbs_tap_mod[prbs_dqs_cnt_timing_r] <= #TCQ 1'b1;
816  prbs_dec_tap_cnt <= #TCQ prbs_dec_tap_calc_minus_3;
817  end else if (prbs_dec_tap_calc_plus_3 < prbs_dec_tap_cnt) begin // proposing a re-order of the condition
818  prbs_tap_mod[prbs_dqs_cnt_timing_r] <= #TCQ 1'b1;
819  prbs_dec_tap_cnt <= #TCQ prbs_dec_tap_calc_plus_3;
820  end
821  prbs_state_r <= #TCQ PRBS_DEC_DQS;
822  end
823 
824  // decrement capture clock for final adjustment - center
825  // capture clock in middle of data eye. This adjustment will occur
826  // only when both the edges are found usign CPT taps. Must do this
827  // incrementally to avoid clock glitching (since CPT drives clock
828  // divider within each ISERDES)
829  PRBS_DEC_DQS: begin
830  prbs_tap_en_r <= #TCQ 1'b1;
831  prbs_tap_inc_r <= #TCQ 1'b0;
832  // once adjustment is complete, we're done with calibration for
833  // this DQS, repeat for next DQS
834  if (prbs_dec_tap_cnt > 'd0)
835  prbs_dec_tap_cnt <= #TCQ prbs_dec_tap_cnt - 1;
836  if (prbs_dec_tap_cnt == 6'b000001)
837  prbs_state_r <= #TCQ PRBS_NEXT_DQS;
838  else
839  prbs_state_r <= #TCQ PRBS_DEC_DQS_WAIT;
840  end
841 
842  PRBS_DEC_DQS_WAIT: begin
843  prbs_tap_en_r <= #TCQ 1'b0;
844  prbs_tap_inc_r <= #TCQ 1'b0;
845  if (cnt_wait_state) begin
846  if (prbs_dec_tap_cnt > 'd0)
847  prbs_state_r <= #TCQ PRBS_DEC_DQS;
848  else
849  prbs_state_r <= #TCQ PRBS_PAT_COMPARE;
850  end
851  end
852 
853  // Determine whether we're done, or have more DQS's to calibrate
854  // Also request precharge after every byte, as appropriate
855  PRBS_NEXT_DQS: begin
856  prbs_prech_req_r <= #TCQ 1'b1;
857  prbs_tap_en_r <= #TCQ 1'b0;
858  prbs_tap_inc_r <= #TCQ 1'b0;
859  // Prepare for another iteration with next DQS group
860  prbs_found_1st_edge_r <= #TCQ 1'b0;
861  prbs_found_2nd_edge_r <= #TCQ 1'b0;
862  prbs_1st_edge_taps_r <= #TCQ 'd0;
863  prbs_2nd_edge_taps_r <= #TCQ 'd0;
864  if (prbs_dqs_cnt_r >= DQS_WIDTH-1) begin
865  prbs_last_byte_done <= #TCQ 1'b1;
866  end
867 
868  // Wait until precharge that occurs in between calibration of
869  // DQS groups is finished
870  if (prech_done) begin
871  prbs_prech_req_r <= #TCQ 1'b0;
872  if (prbs_dqs_cnt_r >= DQS_WIDTH-1) begin
873  if (rnk_cnt_r == RANKS-1) begin
874  // All DQS groups in all ranks done
875  prbs_state_r <= #TCQ PRBS_DONE;
876  end else begin
877  // Process DQS groups in next rank
878  rnk_cnt_r <= #TCQ rnk_cnt_r + 1;
879  new_cnt_dqs_r <= #TCQ 1'b1;
880  prbs_dqs_cnt_r <= #TCQ 'b0;
881  prbs_state_r <= #TCQ PRBS_IDLE;
882  end
883  end else begin
884  // Process next DQS group
885  new_cnt_dqs_r <= #TCQ 1'b1;
886  prbs_dqs_cnt_r <= #TCQ prbs_dqs_cnt_r + 1;
887  prbs_state_r <= #TCQ PRBS_NEW_DQS_PREWAIT;
888  end
889  end
890  end
891 
892  PRBS_NEW_DQS_PREWAIT: begin
893  if (cnt_wait_state) begin
894  prbs_state_r <= #TCQ PRBS_NEW_DQS_WAIT;
895  end
896  end
897 
898  // Done with this stage of calibration
899  PRBS_DONE: begin
900  prbs_prech_req_r <= #TCQ 1'b0;
901  prbs_last_byte_done <= #TCQ 1'b0;
902  prbs_rdlvl_done <= #TCQ 1'b1;
903  end
904 
905  endcase
906  end
907 
908 endmodule