OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_14/usb_fpga_2_14/trunk

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [examples/] [memfifo/] [fpga-2.04b/] [ipcore_dir/] [mem0/] [user_design/] [rtl/] [mcb_controller/] [mcb_soft_calibration.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
//*****************************************************************************
2
// (c) Copyright 2009 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: %version
53
//  \   \         Application: MIG
54
//  /   /         Filename: mcb_soft_calibration.v
55
// /___/   /\     Date Last Modified: $Date: 2011/06/02 07:17:24 $
56
// \   \  /  \    Date Created: Mon Feb 9 2009
57
//  \___\/\___\
58
//
59
//Device: Spartan6
60
//Design Name: DDR/DDR2/DDR3/LPDDR
61
//Purpose:  Xilinx reference design for MCB Soft
62
//           Calibration
63
//Reference:
64
//
65
//  Revision:      Date:  Comment
66
//       1.0:  2/06/09:   Initial version for MIG wrapper.
67
//       1.1:  2/09/09:   moved Max_Value_Previous assignments to be completely inside CASE statement for next-state logic (needed to get it working correctly)
68
//       1.2:  2/12/09:   Many other changes.
69
//       1.3:  2/26/09:   Removed section with Max_Value_pre and DQS_COUNT_PREVIOUS_pre, and instead added PREVIOUS_STATE reg and moved assignment to within STATE
70
//       1.4:  3/02/09:   Removed comments out of sensitivity list of always block to mux SDI, SDO, CS, and ADD.  Also added reg declaration for PREVIOUS_STATE
71
//       1.5:  3/16/09:   Added pll_lock port, and using it to gate reset.  Changing RST (except input port) to RST_reg and gating it with pll_lock.
72
//       1.6:  6/05/09:   Added START_DYN_CAL_PRE with pulse on SYSRST; removed MCB_UIDQCOUNT.
73
//       1.7:  6/24/09:   Gave RZQ and ZIO each their own unique ADD and SDI nets
74
//       2.0:  7/30/09:   Added dynamic Input Termination
75
//       2.1:  8/02/09:   Added sampling of DQS input delays to make sure we never decrement below h00 (or increment above hEF).
76
//       2.2:  8/04/09:   Added 2's compliment register "DQS_COUNT_VIRTUAL", and signficantly changed the increment/decrement algorythm - now will track a virtual
77
//                        negative DQS_COUNT value if needed.  Got rid of DQS_COUNT_UP/DOWN registers
78
//       2.3:  10/10/09:  Massive overhaul
79
//       2.4:  10/14/09:  Fixed: from START, if SKIP_IN_TERM_CAL go to WRITE_CALIBRATE
80
//       2.5:  10/15/09:  Changed OVERRIDE_DQS_CAL to CALMODE_EQ_CALIBRATION, and made it override SKIP_DYNAMIC_CAL (to 1) whenever C_MC_CALIBRATION_MODE="NOCALIBRATION"
81
//       2.6:  12/15/09:  Changed STATE from 7-bit to 6-bit.  Dropped (* FSM_ENCODING="BINARY" *) for STATE. Moved MCB_UICMDEN = 0 from OFF_RZQ_PTERM to RST_DELAY. 
82
//                        Changed the "reset" always block so that RST_reg is always set to 1 when the PLL loses lock, and is now held in reset for at least 16 clocks.  Added PNSKEW option.
83
//       2.7:  12/23/09:  Added new states "SKEW" and "MULTIPLY_DIVIDE" to help with timing.
84
//       2.8:  01/14/10:  Added functionality to allow for SUSPEND.  Changed MCB_SYSRST port from wire to reg.
85
//       2.9:  02/01/10:  More changes to SUSPEND and Reset logic to handle SUSPEND properly.  Also - eliminated 2's comp DQS_COUNT_VIRTUAL, and replaced with 8bit TARGET_DQS_DELAY which
86
//                        will track most recnet Max_Value.  Eliminated DQS_COUNT_PREVIOUS. Combined DQS_COUNT_INITIAL and DQS_Delay into DQS_DELAY_INITIAL.  Changed DQS_COUNT* to DQS_DELAY*.
87
//                        Changed MCB_SYSRST port back to wire (from reg).
88
//       3.0:  02/10/10:  Added count_inc and count_dec to add a few (4) UI_CLK cycles latency to the INC and DEC signals (to deal with latency on UOREFRSHFLAG)
89
//       3.1:  02/23/10:  Registered the DONE_SOFTANDHARD_CAL for timing.   
90
//       3.2:  02/28/10:  Corrected the   WAIT_SELFREFRESH_EXIT_DQS_CAL logic;
91
//       3.3:  03/02/10:  Changed PNSKEW to default on (1'b1)
92
//       3.4:  03/04/10:  Recoded the RST_Reg logic.
93
//       3.5:  03/05/10:  Changed Result register to be 16-bits.  Changed DQS_NUMERATOR/DENOMINATOR values to 3/8 (from 6/16)
94
//       3.6:  03/10/10:  Improvements to Reset logic    
95
//       3.7:  04/12/10:  Added DDR2 Initialization fix to meet 400 ns wait as outlined in step d) of JEDEC DDR2 spec .
96
//       3.8:  05/24/10:  Added 200us Wait logic to control CKE_Train. The 200us Wait counter assumes UI_CLK freq not higher than 100 MHz.
97
//       3.9   02/11/11:  Apply a different skkew for the P and N inputs for the differential LDQS and UDQS signals to provide more noise immunity.
98
//       4.0   04/11/11:  Added sync FF for RZA_IN and ZIO_IN async inputs.
99
//       4.1   03/08/12:  Fixed SELFREFRESH_MCB_REQ logic. It should not need depend on the SM STATE so that
100
//                        MCB can come out of selfresh mode. SM requires refresh cycle to update the DQS value. 
101
//       4.2   05/10/12:  All P/N terms of input and bidir memory pins are initialized with value of ZERO. TZQINIT_MAXCNT
102
//                        are set to 8 for LPDDR,DDR and DDR2 interface .
103
//                        Keep the UICMDEN in assertion state when SM is in RST_DELAY state so that MCB will not start doing
104
//                        Premable detection until the second deassertion of MCB_SYSRST. 
105
//                        
106
// End Revision
107
//**********************************************************************************
108
 
109
 
110
`timescale 1ps/1ps
111
 
112
module mcb_soft_calibration # (
113
  parameter       C_MEM_TZQINIT_MAXCNT  = 10'd512,  // DDR3 Minimum delay between resets
114
  parameter       C_MC_CALIBRATION_MODE = "CALIBRATION", // if set to CALIBRATION will reset DQS IDELAY to DQS_NUMERATOR/DQS_DENOMINATOR local_param values
115
                                                         // if set to NOCALIBRATION then defaults to hard cal blocks setting of C_MC_CALBRATION_DELAY (Quarter, etc)
116
  parameter       C_SIMULATION          = "FALSE",  // Tells us whether the design is being simulated or implemented
117
  parameter       SKIP_IN_TERM_CAL      = 1'b0,     // provides option to skip the input termination calibration
118
  parameter       SKIP_DYNAMIC_CAL      = 1'b0,     // provides option to skip the dynamic delay calibration
119
  parameter       SKIP_DYN_IN_TERM      = 1'b1,      // provides option to skip the input termination calibration
120
  parameter       C_MEM_TYPE = "DDR"            // provides the memory device used for the design
121
 
122
  )
123
  (
124
  input   wire            UI_CLK,                   // main clock input for logic and IODRP CLK pins.  At top level, this should also connect to IODRP2_MCB CLK pins
125
  input   wire            RST,                      // main system reset for both this Soft Calibration block - also will act as a passthrough to MCB's SYSRST
126
  (* IOB = "FALSE" *) output  reg            DONE_SOFTANDHARD_CAL,
127
                                                    // active high flag signals soft calibration of input delays is complete and MCB_UODONECAL is high (MCB hard calib complete)
128
  input   wire            PLL_LOCK,                 // Lock signal from PLL
129
  input   wire            SELFREFRESH_REQ,
130
  input   wire            SELFREFRESH_MCB_MODE,
131
  output  reg             SELFREFRESH_MCB_REQ ,
132
  output  reg             SELFREFRESH_MODE,
133
  output  wire            IODRP_ADD,                // IODRP ADD port
134
  output  wire            IODRP_SDI,                // IODRP SDI port
135
  input   wire            RZQ_IN,                   // RZQ pin from board - expected to have a 2*R resistor to ground
136
  input   wire            RZQ_IODRP_SDO,            // RZQ IODRP's SDO port
137
  output  reg             RZQ_IODRP_CS      = 1'b0, // RZQ IODRP's CS port
138
  input   wire            ZIO_IN,                   // Z-stated IO pin - garanteed not to be driven externally
139
  input   wire            ZIO_IODRP_SDO,            // ZIO IODRP's SDO port
140
  output  reg             ZIO_IODRP_CS      = 1'b0, // ZIO IODRP's CS port
141
  output  wire            MCB_UIADD,                // to MCB's UIADD port
142
  output  wire            MCB_UISDI,                // to MCB's UISDI port
143
  input   wire            MCB_UOSDO,                // from MCB's UOSDO port (User output SDO)
144
  input   wire            MCB_UODONECAL,            // indicates when MCB hard calibration process is complete
145
  input   wire            MCB_UOREFRSHFLAG,         //  high during refresh cycle and time when MCB is innactive
146
  output  wire            MCB_UICS,                 // to MCB's UICS port (User Input CS)
147
  output  reg             MCB_UIDRPUPDATE   = 1'b1, // MCB's UIDRPUPDATE port (gets passed to IODRP2_MCB's MEMUPDATE port: this controls shadow latch used during IODRP2_MCB writes).  Currently just trasnparent
148
  output  wire            MCB_UIBROADCAST,          // only to MCB's UIBROADCAST port (User Input BROADCAST - gets passed to IODRP2_MCB's BKST port)
149
  output  reg   [4:0]     MCB_UIADDR        = 5'b0, //  to MCB's UIADDR port (gets passed to IODRP2_MCB's AUXADDR port
150
  output  reg             MCB_UICMDEN       = 1'b1, //  set to 1 to take control of UI interface - removes control from internal calib block
151
  output  reg             MCB_UIDONECAL     = 1'b0, //  set to 0 to "tell" controller that it's still in a calibrate state
152
  output               MCB_UIDQLOWERDEC ,
153
  output               MCB_UIDQLOWERINC ,
154
  output               MCB_UIDQUPPERDEC ,
155
  output               MCB_UIDQUPPERINC ,
156
  output  reg             MCB_UILDQSDEC     = 1'b0,
157
  output  reg             MCB_UILDQSINC     = 1'b0,
158
  output  wire            MCB_UIREAD,               //  enables read w/o writing by turning on a SDO->SDI loopback inside the IODRP2_MCBs (doesn't exist in regular IODRP2).  IODRPCTRLR_R_WB becomes don't-care.
159
  output  reg             MCB_UIUDQSDEC     = 1'b0,
160
  output  reg             MCB_UIUDQSINC     = 1'b0,
161
  output                  MCB_RECAL         , //  future hook to drive MCB's RECAL pin - initiates a hard re-calibration sequence when high
162
  output  reg             MCB_UICMD,
163
  output  reg             MCB_UICMDIN,
164
  output  reg   [3:0]     MCB_UIDQCOUNT,
165
  input   wire  [7:0]     MCB_UODATA,
166
  input   wire            MCB_UODATAVALID,
167
  input   wire            MCB_UOCMDREADY,
168
  input   wire            MCB_UO_CAL_START,
169
  output  wire            MCB_SYSRST,               //  drives the MCB's SYSRST pin - the main reset for MCB
170
  output  reg   [7:0]     Max_Value,
171
  output  reg            CKE_Train
172
  );
173
 
174
 
175
localparam [4:0]
176
          IOI_DQ0       = {4'h0, 1'b1},
177
          IOI_DQ1       = {4'h0, 1'b0},
178
          IOI_DQ2       = {4'h1, 1'b1},
179
          IOI_DQ3       = {4'h1, 1'b0},
180
          IOI_DQ4       = {4'h2, 1'b1},
181
          IOI_DQ5       = {4'h2, 1'b0},
182
          IOI_DQ6       = {4'h3, 1'b1},
183
          IOI_DQ7       = {4'h3, 1'b0},
184
          IOI_DQ8       = {4'h4, 1'b1},
185
          IOI_DQ9       = {4'h4, 1'b0},
186
          IOI_DQ10      = {4'h5, 1'b1},
187
          IOI_DQ11      = {4'h5, 1'b0},
188
          IOI_DQ12      = {4'h6, 1'b1},
189
          IOI_DQ13      = {4'h6, 1'b0},
190
          IOI_DQ14      = {4'h7, 1'b1},
191
          IOI_DQ15      = {4'h7, 1'b0},
192
          IOI_UDM       = {4'h8, 1'b1},
193
          IOI_LDM       = {4'h8, 1'b0},
194
          IOI_CK_P      = {4'h9, 1'b1},
195
          IOI_CK_N      = {4'h9, 1'b0},
196
          IOI_RESET     = {4'hA, 1'b1},
197
          IOI_A11       = {4'hA, 1'b0},
198
          IOI_WE        = {4'hB, 1'b1},
199
          IOI_BA2       = {4'hB, 1'b0},
200
          IOI_BA0       = {4'hC, 1'b1},
201
          IOI_BA1       = {4'hC, 1'b0},
202
          IOI_RASN      = {4'hD, 1'b1},
203
          IOI_CASN      = {4'hD, 1'b0},
204
          IOI_UDQS_CLK  = {4'hE, 1'b1},
205
          IOI_UDQS_PIN  = {4'hE, 1'b0},
206
          IOI_LDQS_CLK  = {4'hF, 1'b1},
207
          IOI_LDQS_PIN  = {4'hF, 1'b0};
208
 
209
localparam  [5:0]   START                     = 6'h00,
210
                    LOAD_RZQ_NTERM            = 6'h01,
211
                    WAIT1                     = 6'h02,
212
                    LOAD_RZQ_PTERM            = 6'h03,
213
                    WAIT2                     = 6'h04,
214
                    INC_PTERM                 = 6'h05,
215
                    MULTIPLY_DIVIDE           = 6'h06,
216
                    LOAD_ZIO_PTERM            = 6'h07,
217
                    WAIT3                     = 6'h08,
218
                    LOAD_ZIO_NTERM            = 6'h09,
219
                    WAIT4                     = 6'h0A,
220
                    INC_NTERM                 = 6'h0B,
221
                    SKEW                      = 6'h0C,
222
                    WAIT_FOR_START_BROADCAST  = 6'h0D,
223
                    BROADCAST_PTERM           = 6'h0E,
224
                    WAIT5                     = 6'h0F,
225
                    BROADCAST_NTERM           = 6'h10,
226
                    WAIT6                     = 6'h11,
227
                    LDQS_CLK_WRITE_P_TERM     = 6'h12,
228
                    LDQS_CLK_P_TERM_WAIT      = 6'h13,
229
                    LDQS_CLK_WRITE_N_TERM     = 6'h14,
230
                    LDQS_CLK_N_TERM_WAIT      = 6'h15,
231
                    LDQS_PIN_WRITE_P_TERM     = 6'h16,
232
                    LDQS_PIN_P_TERM_WAIT      = 6'h17,
233
                    LDQS_PIN_WRITE_N_TERM     = 6'h18,
234
                    LDQS_PIN_N_TERM_WAIT      = 6'h19,
235
                    UDQS_CLK_WRITE_P_TERM     = 6'h1A,
236
                    UDQS_CLK_P_TERM_WAIT      = 6'h1B,
237
                    UDQS_CLK_WRITE_N_TERM     = 6'h1C,
238
                    UDQS_CLK_N_TERM_WAIT      = 6'h1D,
239
                    UDQS_PIN_WRITE_P_TERM     = 6'h1E,
240
                    UDQS_PIN_P_TERM_WAIT      = 6'h1F,
241
                    UDQS_PIN_WRITE_N_TERM     = 6'h20,
242
                    UDQS_PIN_N_TERM_WAIT      = 6'h21,
243
                    OFF_RZQ_PTERM             = 6'h22,
244
                    WAIT7                     = 6'h23,
245
                    OFF_ZIO_NTERM             = 6'h24,
246
                    WAIT8                     = 6'h25,
247
                    RST_DELAY                 = 6'h26,
248
                    START_DYN_CAL_PRE         = 6'h27,
249
                    WAIT_FOR_UODONE           = 6'h28,
250
                    LDQS_WRITE_POS_INDELAY    = 6'h29,
251
                    LDQS_WAIT1                = 6'h2A,
252
                    LDQS_WRITE_NEG_INDELAY    = 6'h2B,
253
                    LDQS_WAIT2                = 6'h2C,
254
                    UDQS_WRITE_POS_INDELAY    = 6'h2D,
255
                    UDQS_WAIT1                = 6'h2E,
256
                    UDQS_WRITE_NEG_INDELAY    = 6'h2F,
257
                    UDQS_WAIT2                = 6'h30,
258
                    START_DYN_CAL             = 6'h31,
259
                    WRITE_CALIBRATE           = 6'h32,
260
                    WAIT9                     = 6'h33,
261
                    READ_MAX_VALUE            = 6'h34,
262
                    WAIT10                    = 6'h35,
263
                    ANALYZE_MAX_VALUE         = 6'h36,
264
                    FIRST_DYN_CAL             = 6'h37,
265
                    INCREMENT                 = 6'h38,
266
                    DECREMENT                 = 6'h39,
267
                    DONE                      = 6'h3A;
268
 
269
localparam  [1:0]   RZQ           = 2'b00,
270
                    ZIO           = 2'b01,
271
                    MCB_PORT      = 2'b11;
272
localparam          WRITE_MODE    = 1'b0;
273
localparam          READ_MODE     = 1'b1;
274
 
275
// IOI Registers
276
localparam  [7:0]   NoOp          = 8'h00,
277
                    DelayControl  = 8'h01,
278
                    PosEdgeInDly  = 8'h02,
279
                    NegEdgeInDly  = 8'h03,
280
                    PosEdgeOutDly = 8'h04,
281
                    NegEdgeOutDly = 8'h05,
282
                    MiscCtl1      = 8'h06,
283
                    MiscCtl2      = 8'h07,
284
                    MaxValue      = 8'h08;
285
 
286
// IOB Registers
287
localparam  [7:0]   PDrive        = 8'h80,
288
                    PTerm         = 8'h81,
289
                    NDrive        = 8'h82,
290
                    NTerm         = 8'h83,
291
                    SlewRateCtl   = 8'h84,
292
                    LVDSControl   = 8'h85,
293
                    MiscControl   = 8'h86,
294
                    InputControl  = 8'h87,
295
                    TestReadback  = 8'h88;
296
 
297
// No multi/divide is required when a 55 ohm resister is used on RZQ
298
//localparam          MULT          = 1;
299
//localparam          DIV           = 1;
300
// use 7/4 scaling factor when the 100 ohm RZQ is used
301
localparam          MULT          = 7;
302
localparam          DIV           = 4;
303
 
304
localparam          PNSKEW        = 1'b1; //Default is 1'b1. Change to 1'b0 if PSKEW and NSKEW are not required
305
localparam          PNSKEWDQS     = 1'b1;
306
localparam          MULT_S    = 9;
307
localparam          DIV_S     = 8;
308
localparam          MULT_W    = 7;
309
localparam          DIV_W     = 8;
310
 
311
localparam          DQS_NUMERATOR   = 3;
312
localparam          DQS_DENOMINATOR = 8;
313
localparam          INCDEC_THRESHOLD= 8'h03; // parameter for the threshold which triggers an inc/dec to occur.  2 for half, 4 for quarter, 3 for three eighths
314
 
315
 
316
 
317
reg   [5:0]   P_Term       /* synthesis syn_preserve = 1 */;
318
reg   [6:0]   N_Term       /* synthesis syn_preserve = 1 */;
319
reg   [5:0]   P_Term_s     /* synthesis syn_preserve = 1 */;
320
reg   [6:0]   N_Term_s     /* synthesis syn_preserve = 1 */;
321
reg   [5:0]   P_Term_w     /* synthesis syn_preserve = 1 */;
322
reg   [6:0]   N_Term_w     /* synthesis syn_preserve = 1 */;
323
reg   [5:0]   P_Term_Prev  /* synthesis syn_preserve = 1 */;
324
reg   [6:0]   N_Term_Prev  /* synthesis syn_preserve = 1 */;
325
//(* FSM_ENCODING="USER" *) reg [5:0] STATE = START;   //XST does not pick up "BINARY" - use COMPACT instead if binary is desired
326
reg [5:0] STATE ;
327
reg   [7:0]   IODRPCTRLR_MEMCELL_ADDR /* synthesis syn_preserve = 1 */;
328
reg   [7:0]   IODRPCTRLR_WRITE_DATA /* synthesis syn_preserve = 1 */;
329
reg   [1:0]   Active_IODRP /* synthesis syn_maxfan = 1 */;
330
// synthesis attribute max_fanout of Active_IODRP is 1
331
reg           IODRPCTRLR_R_WB = 1'b0;
332
reg           IODRPCTRLR_CMD_VALID = 1'b0;
333
reg           IODRPCTRLR_USE_BKST = 1'b0;
334
reg           MCB_CMD_VALID = 1'b0;
335
reg           MCB_USE_BKST = 1'b0;
336
reg           Pre_SYSRST = 1'b1 /* synthesis syn_maxfan = 5 */; //internally generated reset which will OR with RST input to drive MCB's SYSRST pin (MCB_SYSRST)
337
// synthesis attribute max_fanout of Pre_SYSRST is 5
338
reg           IODRP_SDO;
339
reg   [7:0]   Max_Value_Previous  = 8'b0 /* synthesis syn_preserve = 1 */;
340
reg   [5:0]   count = 6'd0;               //counter for adding 18 extra clock cycles after setting Calibrate bit
341
reg           counter_en  = 1'b0;         //counter enable for "count"
342
reg           First_Dyn_Cal_Done = 1'b0;  //flag - high after the very first dynamic calibration is done
343
wire          START_BROADCAST ;     // Trigger to start Broadcast to IODRP2_MCBs to set Input Impedance - state machine will wait for this to be high
344
reg   [7:0]   DQS_DELAY_INITIAL   = 8'b0 /* synthesis syn_preserve = 1 */;
345
reg   [7:0]   DQS_DELAY ;        // contains the latest values written to LDQS and UDQS Input Delays
346
reg   [7:0]   TARGET_DQS_DELAY;  // used to track the target for DQS input delays - only gets updated if the Max Value changes by more than the threshold
347
reg   [7:0]   counter_inc;       // used to delay Inc signal by several ui_clk cycles (to deal with latency on UOREFRSHFLAG)
348
reg   [7:0]   counter_dec;       // used to delay Dec signal by several ui_clk cycles (to deal with latency on UOREFRSHFLAG)
349
 
350
wire  [7:0]   IODRPCTRLR_READ_DATA;
351
wire          IODRPCTRLR_RDY_BUSY_N;
352
wire          IODRP_CS;
353
wire  [7:0]   MCB_READ_DATA;
354
 
355
reg           RST_reg;
356
reg           Block_Reset;
357
 
358
reg           MCB_UODATAVALID_U;
359
 
360
wire  [2:0]   Inc_Dec_REFRSH_Flag;  // 3-bit flag to show:Inc is needed, Dec needed, refresh cycle taking place
361
wire  [7:0]   Max_Value_Delta_Up;   // tracks amount latest Max Value has gone up from previous Max Value read
362
wire  [7:0]   Half_MV_DU;           // half of Max_Value_Delta_Up
363
wire  [7:0]   Max_Value_Delta_Dn;   // tracks amount latest Max Value has gone down from previous Max Value read
364
wire  [7:0]   Half_MV_DD;           // half of Max_Value_Delta_Dn
365
 
366
reg   [9:0]   RstCounter = 10'h0;
367
wire          rst_tmp;
368
reg           LastPass_DynCal;
369
reg           First_In_Term_Done;
370
wire          Inc_Flag;               // flag to increment Dynamic Delay
371
wire          Dec_Flag;               // flag to decrement Dynamic Delay
372
 
373
wire          CALMODE_EQ_CALIBRATION; // will calculate and set the DQS input delays if C_MC_CALIBRATION_MODE parameter = "CALIBRATION"
374
wire  [7:0]   DQS_DELAY_LOWER_LIMIT;  // Lower limit for DQS input delays 
375
wire  [7:0]   DQS_DELAY_UPPER_LIMIT;  // Upper limit for DQS input delays
376
wire          SKIP_DYN_IN_TERMINATION;//wire to allow skipping dynamic input termination if either the one-time or dynamic parameters are 1
377
wire          SKIP_DYNAMIC_DQS_CAL;   //wire allowing skipping dynamic DQS delay calibration if either SKIP_DYNIMIC_CAL=1, or if C_MC_CALIBRATION_MODE=NOCALIBRATION
378
wire  [7:0]   Quarter_Max_Value;
379
wire  [7:0]   Half_Max_Value;
380
reg           PLL_LOCK_R1;
381
reg           PLL_LOCK_R2;
382
 
383
reg           SELFREFRESH_REQ_R1;
384
reg           SELFREFRESH_REQ_R2;
385
reg           SELFREFRESH_REQ_R3;
386
reg           SELFREFRESH_MCB_MODE_R1;
387
reg           SELFREFRESH_MCB_MODE_R2;
388
reg           SELFREFRESH_MCB_MODE_R3;
389
 
390
reg           WAIT_SELFREFRESH_EXIT_DQS_CAL;
391
reg           PERFORM_START_DYN_CAL_AFTER_SELFREFRESH;
392
reg           START_DYN_CAL_STATE_R1;
393
reg           PERFORM_START_DYN_CAL_AFTER_SELFREFRESH_R1;
394
reg           Rst_condition1;
395
wire          non_violating_rst;
396
reg [15:0]    WAIT_200us_COUNTER;
397
reg [7:0]     WaitTimer;
398
reg           WarmEnough;
399
 
400
wire   pre_sysrst_minpulse_width_ok;
401
reg [3:0] pre_sysrst_cnt;
402
// move the default assignment here to make FORMALITY happy.
403
assign START_BROADCAST = 1'b1;
404
assign MCB_RECAL = 1'b0;
405
assign MCB_UIDQLOWERDEC = 1'b0;
406
assign MCB_UIDQLOWERINC = 1'b0;
407
assign MCB_UIDQUPPERDEC = 1'b0;
408
assign MCB_UIDQUPPERINC = 1'b0;
409
 
410
// 'defines for which pass of the interleaved dynamic algorythm is taking place
411
`define IN_TERM_PASS  1'b0
412
`define DYN_CAL_PASS  1'b1
413
 
414
assign  Inc_Dec_REFRSH_Flag     = {Inc_Flag,Dec_Flag,MCB_UOREFRSHFLAG};
415
assign  Max_Value_Delta_Up      = Max_Value - Max_Value_Previous;
416
assign  Half_MV_DU              = {1'b0,Max_Value_Delta_Up[7:1]};
417
assign  Max_Value_Delta_Dn      = Max_Value_Previous - Max_Value;
418
assign  Half_MV_DD              = {1'b0,Max_Value_Delta_Dn[7:1]};
419
assign  CALMODE_EQ_CALIBRATION  = (C_MC_CALIBRATION_MODE == "CALIBRATION") ? 1'b1 : 1'b0; // will calculate and set the DQS input delays if = 1'b1
420
assign  Half_Max_Value          = Max_Value >> 1;
421
assign  Quarter_Max_Value       = Max_Value >> 2;
422
assign  DQS_DELAY_LOWER_LIMIT   = Quarter_Max_Value;  // limit for DQS_DELAY for decrements; could optionally be assigned to any 8-bit hex value here
423
assign  DQS_DELAY_UPPER_LIMIT   = Half_Max_Value;     // limit for DQS_DELAY for increments; could optionally be assigned to any 8-bit hex value here
424
assign  SKIP_DYN_IN_TERMINATION = SKIP_DYN_IN_TERM || SKIP_IN_TERM_CAL; //skip dynamic input termination if either the one-time or dynamic parameters are 1
425
assign  SKIP_DYNAMIC_DQS_CAL    = ~CALMODE_EQ_CALIBRATION || SKIP_DYNAMIC_CAL; //skip dynamic DQS delay calibration if either SKIP_DYNAMIC_CAL=1, or if C_MC_CALIBRATION_MODE=NOCALIBRATION
426
 
427
always @ (posedge UI_CLK)
428
     DONE_SOFTANDHARD_CAL    <= ((DQS_DELAY_INITIAL != 8'h00) || (STATE == DONE)) && MCB_UODONECAL;  //high when either DQS input delays initialized, or STATE=DONE and UODONECAL high
429
 
430
 
431
iodrp_controller iodrp_controller(
432
  .memcell_address  (IODRPCTRLR_MEMCELL_ADDR),
433
  .write_data       (IODRPCTRLR_WRITE_DATA),
434
  .read_data        (IODRPCTRLR_READ_DATA),
435
  .rd_not_write     (IODRPCTRLR_R_WB),
436
  .cmd_valid        (IODRPCTRLR_CMD_VALID),
437
  .rdy_busy_n       (IODRPCTRLR_RDY_BUSY_N),
438
  .use_broadcast    (1'b0),
439
  .sync_rst         (RST_reg),
440
  .DRP_CLK          (UI_CLK),
441
  .DRP_CS           (IODRP_CS),
442
  .DRP_SDI          (IODRP_SDI),
443
  .DRP_ADD          (IODRP_ADD),
444
  .DRP_SDO          (IODRP_SDO),
445
  .DRP_BKST         ()
446
  );
447
 
448
iodrp_mcb_controller iodrp_mcb_controller(
449
  .memcell_address  (IODRPCTRLR_MEMCELL_ADDR),
450
  .write_data       (IODRPCTRLR_WRITE_DATA),
451
  .read_data        (MCB_READ_DATA),
452
  .rd_not_write     (IODRPCTRLR_R_WB),
453
  .cmd_valid        (MCB_CMD_VALID),
454
  .rdy_busy_n       (MCB_RDY_BUSY_N),
455
  .use_broadcast    (MCB_USE_BKST),
456
  .drp_ioi_addr     (MCB_UIADDR),
457
  .sync_rst         (RST_reg),
458
  .DRP_CLK          (UI_CLK),
459
  .DRP_CS           (MCB_UICS),
460
  .DRP_SDI          (MCB_UISDI),
461
  .DRP_ADD          (MCB_UIADD),
462
  .DRP_BKST         (MCB_UIBROADCAST),
463
  .DRP_SDO          (MCB_UOSDO),
464
  .MCB_UIREAD       (MCB_UIREAD)
465
  );
466
 
467
 
468
//******************************************************************************************
469
// Mult_Divide Function - multiplies by a constant MULT and then divides by the DIV constant
470
//******************************************************************************************
471
function [7:0] Mult_Divide;
472
input   [7:0]   Input;
473
input   [7:0]   Mult;
474
input   [7:0]   Div;
475
reg     [3:0]   count;
476
reg     [15:0]   Result;
477
begin
478
  Result  = 0;
479
  for (count = 0; count < Mult; count = count+1) begin
480
    Result    = Result + Input;
481
  end
482
  Result      = Result / Div;
483
  Mult_Divide = Result[7:0];
484
end
485
endfunction
486
 
487
 always @ (posedge UI_CLK, posedge RST)
488
  begin
489
   if (RST)
490
     WAIT_200us_COUNTER <= (C_SIMULATION == "TRUE") ? 16'h7FF0 : 16'h0;
491
   else
492
      if (WAIT_200us_COUNTER[15])  // UI_CLK maximum is up to 100 MHz.
493
        WAIT_200us_COUNTER <= WAIT_200us_COUNTER                        ;
494
      else
495
        WAIT_200us_COUNTER <= WAIT_200us_COUNTER + 1'b1;
496
  end
497
 
498
 
499
generate
500
if( C_MEM_TYPE == "DDR2") begin : gen_cketrain_a
501
 
502
 
503
always @ ( posedge UI_CLK, posedge RST)
504
begin
505
if (RST)
506
   CKE_Train <= 1'b0;
507
else
508
  if (STATE == WAIT_FOR_UODONE && MCB_UODONECAL)
509
   CKE_Train <= 1'b0;
510
  else if (WAIT_200us_COUNTER[15] && ~MCB_UODONECAL)
511
   CKE_Train <= 1'b1;
512
  else
513
   CKE_Train <= 1'b0;
514
 
515
end
516
end
517
endgenerate
518
 
519
 
520
generate
521
if( C_MEM_TYPE != "DDR2") begin : gen_cketrain_b
522
always @ (RST)
523
   CKE_Train <= 1'b0;
524
end
525
endgenerate
526
 
527
//********************************************
528
//PLL_LOCK and Reset signals
529
//********************************************
530
localparam  RST_CNT         = 10'h010;          //defines pulse-width for reset
531
localparam  TZQINIT_MAXCNT  = (C_MEM_TYPE == "DDR3") ? C_MEM_TZQINIT_MAXCNT + RST_CNT : 8 + RST_CNT;
532
assign rst_tmp    = (~PLL_LOCK_R2 && ~SELFREFRESH_MODE); //rst_tmp becomes 1 if you lose PLL lock (registered twice for metastblty) and the device is not in SUSPEND
533
 
534
// Rst_contidtion1 is to make sure RESET will not happen again within TZQINIT_MAXCNT
535
assign non_violating_rst = RST & Rst_condition1;         //non_violating_rst is when the user-reset RST occurs and TZQINIT (min time between resets for DDR3) is not being violated
536
 
537
 
538
assign MCB_SYSRST = (Pre_SYSRST );
539
 
540
always @ (posedge UI_CLK or posedge RST ) begin
541
  if (RST) begin
542
    Block_Reset <= 1'b0;
543
    RstCounter  <= 10'b0;
544
end
545
  else begin
546
    Block_Reset <= 1'b0;                   //default to allow STATE to move out of RST_DELAY state
547
    if (Pre_SYSRST)
548
      RstCounter  <= RST_CNT;              //whenever STATE wants to reset the MCB, set RstCounter to h10
549
    else begin
550
      if (RstCounter < TZQINIT_MAXCNT) begin //if RstCounter is less than d512 than this will execute
551
        Block_Reset <= 1'b1;               //STATE won't exit RST_DELAY state
552
        RstCounter  <= RstCounter + 1'b1;  //and Rst_Counter increments
553
      end
554
    end
555
  end
556
end
557
 
558
 
559
 
560
always @ (posedge UI_CLK ) begin
561
if (RstCounter >= TZQINIT_MAXCNT)
562
    Rst_condition1 <= 1'b1;
563
else
564
    Rst_condition1 <= 1'b0;
565
 
566
end
567
 
568
 
569
// -- non_violating_rst asserts whenever (system-level reset) RST is asserted but must be after TZQINIT_MAXCNT is reached (min-time between resets for DDR3)
570
// -- After power stablizes, we will hold MCB in reset state for at least 200us before beginning initialization  process.   
571
// -- If the PLL loses lock during normal operation, no ui_clk will be present because mcb_drp_clk is from a BUFGCE which
572
//    is gated by pll's lock signal.   When the PLL locks again, the RST_reg stays asserted for at least 200 us which
573
//    will cause MCB to reset and reinitialize the memory afterwards.
574
// -- During SUSPEND operation, the PLL will lose lock but non_violating_rst remains low (de-asserted) and WAIT_200us_COUNTER stays at 
575
//    its terminal count.  The PLL_LOCK input does not come direct from PLL, rather it is driven by gated_pll_lock from mcb_raw_wrapper module
576
//    The gated_pll_lock in the mcb_raw_wrapper does not de-assert during SUSPEND operation, hence PLL_LOCK will not de-assert, and the soft calibration 
577
//    state machine will not reset during SUSPEND.
578
// -- RST_reg is the control signal that resets the mcb_soft_calibration's State Machine. The MCB_SYSRST is now equal to 
579
//    Pre_SYSRST. When State Machine is performing "INPUT Termination Calibration", it holds the MCB in reset by assertign MCB_SYSRST. 
580
//    It will deassert the MCB_SYSRST so that it can grab the bus to broadcast the P and N term value to all of the DQ pins. Once the calibrated INPUT 
581
//    termination is set, the State Machine will issue another short MCB_SYSRST so that MCB will use the tuned input termination during DQS preamble calibration.
582
 
583
 
584
 
585
always @ (posedge UI_CLK or posedge non_violating_rst ) begin
586
  if (non_violating_rst)
587
    RST_reg <= 1'b1;
588
  else if (~WAIT_200us_COUNTER[15])
589
    RST_reg <= 1'b1;
590
  else
591
    RST_reg     <= rst_tmp;
592
 
593
end
594
 
595
 
596
//********************************************
597
// stretching the pre_sysrst to satisfy the minimum pusle width
598
 
599
always @ (posedge UI_CLK )begin
600
  if (STATE == START_DYN_CAL_PRE)
601
     pre_sysrst_cnt <= pre_sysrst_cnt + 1;
602
  else
603
     pre_sysrst_cnt <= 4'b0;
604
end
605
 
606
assign pre_sysrst_minpulse_width_ok = pre_sysrst_cnt[3];
607
 
608
//********************************************
609
// SUSPEND Logic
610
//********************************************
611
 
612
always @ ( posedge UI_CLK, posedge RST) begin
613
  //SELFREFRESH_MCB_MODE is clocked by sysclk_2x_180
614
  if (RST)
615
    begin
616
      SELFREFRESH_MCB_MODE_R1 <= 1'b0;
617
      SELFREFRESH_MCB_MODE_R2 <= 1'b0;
618
      SELFREFRESH_MCB_MODE_R3 <= 1'b0;
619
      SELFREFRESH_REQ_R1      <= 1'b0;
620
      SELFREFRESH_REQ_R2      <= 1'b0;
621
      SELFREFRESH_REQ_R3      <= 1'b0;
622
      PLL_LOCK_R1             <= 1'b0;
623
      PLL_LOCK_R2             <= 1'b0;
624
    end
625
  else
626
    begin
627
      SELFREFRESH_MCB_MODE_R1 <= SELFREFRESH_MCB_MODE;
628
      SELFREFRESH_MCB_MODE_R2 <= SELFREFRESH_MCB_MODE_R1;
629
      SELFREFRESH_MCB_MODE_R3 <= SELFREFRESH_MCB_MODE_R2;
630
      SELFREFRESH_REQ_R1      <= SELFREFRESH_REQ;
631
      SELFREFRESH_REQ_R2      <= SELFREFRESH_REQ_R1;
632
      SELFREFRESH_REQ_R3      <= SELFREFRESH_REQ_R2;
633
      PLL_LOCK_R1             <= PLL_LOCK;
634
      PLL_LOCK_R2             <= PLL_LOCK_R1;
635
    end
636
 end
637
 
638
// SELFREFRESH should only be deasserted after PLL_LOCK is asserted.
639
// This is to make sure MCB get a locked sys_2x_clk before exiting
640
// SELFREFRESH mode.
641
 
642
always @ ( posedge UI_CLK) begin
643
  if (RST)
644
    SELFREFRESH_MCB_REQ <= 1'b0;
645
  else if (PLL_LOCK_R2 && ~SELFREFRESH_REQ_R3 )// 
646
 
647
    SELFREFRESH_MCB_REQ <=  1'b0;
648
  else if (STATE == START_DYN_CAL && SELFREFRESH_REQ_R3)
649
    SELFREFRESH_MCB_REQ <= 1'b1;
650
end
651
 
652
 
653
 
654
always @ (posedge UI_CLK) begin
655
  if (RST)
656
    WAIT_SELFREFRESH_EXIT_DQS_CAL <= 1'b0;
657
  else if (~SELFREFRESH_MCB_MODE_R3 && SELFREFRESH_MCB_MODE_R2)
658
 
659
    WAIT_SELFREFRESH_EXIT_DQS_CAL <= 1'b1;
660
  else if (WAIT_SELFREFRESH_EXIT_DQS_CAL && ~SELFREFRESH_REQ_R3 && PERFORM_START_DYN_CAL_AFTER_SELFREFRESH) // START_DYN_CAL is next state
661
    WAIT_SELFREFRESH_EXIT_DQS_CAL <= 1'b0;
662
end
663
 
664
//Need to detect when SM entering START_DYN_CAL
665
always @ (posedge UI_CLK) begin
666
  if (RST) begin
667
    PERFORM_START_DYN_CAL_AFTER_SELFREFRESH  <= 1'b0;
668
    START_DYN_CAL_STATE_R1 <= 1'b0;
669
  end
670
  else begin
671
    // register PERFORM_START_DYN_CAL_AFTER_SELFREFRESH to detect end of cycle
672
    PERFORM_START_DYN_CAL_AFTER_SELFREFRESH_R1 <= PERFORM_START_DYN_CAL_AFTER_SELFREFRESH;
673
    if (STATE == START_DYN_CAL)
674
      START_DYN_CAL_STATE_R1 <= 1'b1;
675
    else
676
      START_DYN_CAL_STATE_R1 <= 1'b0;
677
      if (WAIT_SELFREFRESH_EXIT_DQS_CAL && STATE != START_DYN_CAL && START_DYN_CAL_STATE_R1 )
678
        PERFORM_START_DYN_CAL_AFTER_SELFREFRESH <= 1'b1;
679
      else if (STATE == START_DYN_CAL && ~SELFREFRESH_MCB_MODE_R3)
680
        PERFORM_START_DYN_CAL_AFTER_SELFREFRESH <= 1'b0;
681
      end
682
  end
683
// SELFREFRESH_MCB_MODE deasserted status is hold off
684
// until Soft_Calib has at least done one loop of DQS update.
685
// New logic WarmeEnough is added to make sure PLL_Lock is lockec and all IOs stable before 
686
// deassert the status of MCB's SELFREFRESH_MODE.  This is to ensure all IOs are stable before
687
// user logic sending new commands to MCB.
688
 
689
always @ (posedge UI_CLK) begin
690
  if (RST)
691
    SELFREFRESH_MODE <= 1'b0;
692
  else if (SELFREFRESH_MCB_MODE_R2)
693
    SELFREFRESH_MODE <= 1'b1;
694
    else if (WarmEnough)
695
     SELFREFRESH_MODE <= 1'b0;
696
end
697
 
698
reg WaitCountEnable;
699
 
700
always @ (posedge UI_CLK) begin
701
  if (RST)
702
    WaitCountEnable <= 1'b0;
703
  else if (~SELFREFRESH_REQ_R2 && SELFREFRESH_REQ_R1)
704
    WaitCountEnable <= 1'b0;
705
 
706
  else if (!PERFORM_START_DYN_CAL_AFTER_SELFREFRESH && PERFORM_START_DYN_CAL_AFTER_SELFREFRESH_R1)
707
    WaitCountEnable <= 1'b1;
708
  else
709
    WaitCountEnable <=  WaitCountEnable;
710
end
711
reg State_Start_DynCal_R1 ;
712
reg State_Start_DynCal;
713
always @ (posedge UI_CLK)
714
begin
715
if (RST)
716
   State_Start_DynCal <= 1'b0;
717
else if (STATE == START_DYN_CAL)
718
   State_Start_DynCal <= 1'b1;
719
else
720
   State_Start_DynCal <= 1'b0;
721
end
722
 
723
always @ (posedge UI_CLK)
724
begin
725
if (RST)
726
   State_Start_DynCal_R1 <= 1'b0;
727
else
728
   State_Start_DynCal_R1 <= State_Start_DynCal;
729
end
730
 
731
 
732
always @ (posedge UI_CLK) begin
733
   if (RST)
734
    begin
735
       WaitTimer <= 'b0;
736
       WarmEnough <= 1'b1;
737
    end
738
  else if (~SELFREFRESH_REQ_R2 && SELFREFRESH_REQ_R1)
739
    begin
740
       WaitTimer <= 'b0;
741
       WarmEnough <= 1'b0;
742
    end
743
  else if (WaitTimer == 8'h4)
744
    begin
745
       WaitTimer <= WaitTimer ;
746
       WarmEnough <= 1'b1;
747
    end
748
  else if (WaitCountEnable)
749
       WaitTimer <= WaitTimer + 1;
750
  else
751
       WaitTimer <= WaitTimer ;
752
 
753
end
754
 
755
 
756
 
757
//********************************************
758
//Comparitors for Dynamic Calibration circuit
759
//********************************************
760
assign Dec_Flag = (TARGET_DQS_DELAY < DQS_DELAY);
761
assign Inc_Flag = (TARGET_DQS_DELAY > DQS_DELAY);
762
 
763
 
764
//*********************************************************************************************
765
//Counter for extra clock cycles injected after setting Calibrate bit in IODRP2 for Dynamic Cal
766
//*********************************************************************************************
767
 always @(posedge UI_CLK)
768
  begin
769
    if (RST_reg)
770
        count <= 6'd0;
771
    else if (counter_en)
772
        count <= count + 1'b1;
773
    else
774
        count <= 6'd0;
775
  end
776
 
777
//*********************************************************************************************
778
// Capture narrow MCB_UODATAVALID pulse - only one sysclk90 cycle wide
779
//*********************************************************************************************
780
 always @(posedge UI_CLK or posedge MCB_UODATAVALID)
781
  begin
782
    if (MCB_UODATAVALID)
783
        MCB_UODATAVALID_U <= 1'b1;
784
    else
785
        MCB_UODATAVALID_U <= MCB_UODATAVALID;
786
  end
787
 
788
  //**************************************************************************************************************
789
  //Always block to mux SDI, SDO, CS, and ADD depending on which IODRP is active: RZQ, ZIO or MCB's UI port (to IODRP2_MCBs)
790
  //**************************************************************************************************************
791
  always @(*) begin: ACTIVE_IODRP
792
    case (Active_IODRP)
793
      RZQ:      begin
794
        RZQ_IODRP_CS  = IODRP_CS;
795
        ZIO_IODRP_CS  = 1'b0;
796
        IODRP_SDO     = RZQ_IODRP_SDO;
797
      end
798
      ZIO:      begin
799
        RZQ_IODRP_CS  = 1'b0;
800
        ZIO_IODRP_CS  = IODRP_CS;
801
        IODRP_SDO     = ZIO_IODRP_SDO;
802
      end
803
      MCB_PORT: begin
804
        RZQ_IODRP_CS  = 1'b0;
805
        ZIO_IODRP_CS  = 1'b0;
806
        IODRP_SDO     = 1'b0;
807
      end
808
      default:  begin
809
        RZQ_IODRP_CS  = 1'b0;
810
        ZIO_IODRP_CS  = 1'b0;
811
        IODRP_SDO     = 1'b0;
812
      end
813
    endcase
814
  end
815
 
816
//******************************************************************
817
//State Machine's Always block / Case statement for Next State Logic
818
//
819
//The WAIT1,2,etc states were required after every state where the
820
//DRP controller was used to do a write to the IODRPs - this is because
821
//there's a clock cycle latency on IODRPCTRLR_RDY_BUSY_N whenever the DRP controller
822
//sees IODRPCTRLR_CMD_VALID go high.  OFF_RZQ_PTERM and OFF_ZIO_NTERM were added
823
//soley for the purpose of reducing power, particularly on RZQ as
824
//that pin is expected to have a permanent external resistor to gnd.
825
//******************************************************************
826
  always @(posedge UI_CLK) begin: NEXT_STATE_LOGIC
827
    if (RST_reg) begin                      // Synchronous reset
828
      MCB_CMD_VALID           <= 1'b0;
829
      MCB_UIADDR              <= 5'b0;
830
      MCB_UICMDEN             <= 1'b1;      // take control of UI/UO port
831
      MCB_UIDONECAL           <= 1'b0;      // tells MCB that it is in Soft Cal.
832
      MCB_USE_BKST            <= 1'b0;
833
      MCB_UIDRPUPDATE         <= 1'b1;
834
      Pre_SYSRST              <= 1'b1;      // keeps MCB in reset
835
      IODRPCTRLR_CMD_VALID    <= 1'b0;
836
      IODRPCTRLR_MEMCELL_ADDR <= NoOp;
837
      IODRPCTRLR_WRITE_DATA   <= 1'b0;
838
      IODRPCTRLR_R_WB         <= WRITE_MODE;
839
      IODRPCTRLR_USE_BKST     <= 1'b0;
840
      P_Term                  <= 6'b0;
841
      N_Term                  <= 7'b0;
842
      P_Term_s                <= 6'b0;
843
      N_Term_w                <= 7'b0;
844
      P_Term_w                <= 6'b0;
845
      N_Term_s                <= 7'b0;
846
      P_Term_Prev             <= 6'b0;
847
      N_Term_Prev             <= 7'b0;
848
      Active_IODRP            <= RZQ;
849
      MCB_UILDQSINC           <= 1'b0;      //no inc or dec
850
      MCB_UIUDQSINC           <= 1'b0;      //no inc or dec
851
      MCB_UILDQSDEC           <= 1'b0;      //no inc or dec
852
      MCB_UIUDQSDEC           <= 1'b0;      //no inc or dec
853
      counter_en              <= 1'b0;
854
      First_Dyn_Cal_Done      <= 1'b0;      //flag that the First Dynamic Calibration completed
855
      Max_Value               <= 8'b0;
856
      Max_Value_Previous      <= 8'b0;
857
      STATE                   <= START;
858
      DQS_DELAY               <= 8'h0; //tracks the cumulative incrementing/decrementing that has been done
859
      DQS_DELAY_INITIAL       <= 8'h0;
860
      TARGET_DQS_DELAY        <= 8'h0;
861
      LastPass_DynCal         <= `IN_TERM_PASS;
862
      First_In_Term_Done      <= 1'b0;
863
      MCB_UICMD               <= 1'b0;
864
      MCB_UICMDIN             <= 1'b0;
865
      MCB_UIDQCOUNT           <= 4'h0;
866
      counter_inc             <= 8'h0;
867
      counter_dec             <= 8'h0;
868
    end
869
    else begin
870
      counter_en              <= 1'b0;
871
      IODRPCTRLR_CMD_VALID    <= 1'b0;
872
      IODRPCTRLR_MEMCELL_ADDR <= NoOp;
873
      IODRPCTRLR_R_WB         <= READ_MODE;
874
      IODRPCTRLR_USE_BKST     <= 1'b0;
875
      MCB_CMD_VALID           <= 1'b0;
876
      MCB_UILDQSINC           <= 1'b0;            //no inc or dec
877
      MCB_UIUDQSINC           <= 1'b0;            //no inc or dec
878
      MCB_UILDQSDEC           <= 1'b0;            //no inc or dec
879
      MCB_UIUDQSDEC           <= 1'b0;            //no inc or dec
880
      MCB_USE_BKST            <= 1'b0;
881
      MCB_UICMDIN             <= 1'b0;
882
      DQS_DELAY               <= DQS_DELAY;
883
      TARGET_DQS_DELAY        <= TARGET_DQS_DELAY;
884
      case (STATE)
885
        START:  begin   //h00
886
          MCB_UICMDEN     <= 1'b1;        // take control of UI/UO port
887
          MCB_UIDONECAL   <= 1'b0;        // tells MCB that it is in Soft Cal.
888
          P_Term          <= 6'b0;
889
          N_Term          <= 7'b0;
890
          Pre_SYSRST      <= 1'b1;        // keeps MCB in reset
891
          LastPass_DynCal <= `IN_TERM_PASS;
892
          if (SKIP_IN_TERM_CAL) begin
893
               STATE <= WAIT_FOR_START_BROADCAST;
894
               P_Term <= 'b0;
895
               N_Term <= 'b0;
896
            end
897
          else if (IODRPCTRLR_RDY_BUSY_N)
898
            STATE  <= LOAD_RZQ_NTERM;
899
          else
900
            STATE  <= START;
901
        end
902
//***************************
903
// IOB INPUT TERMINATION CAL
904
//***************************
905
        LOAD_RZQ_NTERM: begin   //h01
906
          Active_IODRP            <= RZQ;
907
          IODRPCTRLR_CMD_VALID    <= 1'b1;
908
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
909
          IODRPCTRLR_WRITE_DATA   <= {1'b0,N_Term};
910
          IODRPCTRLR_R_WB         <= WRITE_MODE;
911
          if (IODRPCTRLR_RDY_BUSY_N)
912
            STATE <= LOAD_RZQ_NTERM;
913
          else
914
            STATE <= WAIT1;
915
        end
916
        WAIT1:  begin   //h02
917
          if (!IODRPCTRLR_RDY_BUSY_N)
918
            STATE <= WAIT1;
919
          else
920
            STATE <= LOAD_RZQ_PTERM;
921
        end
922
        LOAD_RZQ_PTERM: begin //h03
923
          IODRPCTRLR_CMD_VALID    <= 1'b1;
924
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
925
          IODRPCTRLR_WRITE_DATA   <= {2'b00,P_Term};
926
          IODRPCTRLR_R_WB         <= WRITE_MODE;
927
          if (IODRPCTRLR_RDY_BUSY_N)
928
            STATE <= LOAD_RZQ_PTERM;
929
          else
930
            STATE <= WAIT2;
931
        end
932
        WAIT2:  begin   //h04
933
          if (!IODRPCTRLR_RDY_BUSY_N)
934
            STATE <= WAIT2;
935
          else if ((RZQ_IN)||(P_Term == 6'b111111)) begin
936
            STATE <= MULTIPLY_DIVIDE;//LOAD_ZIO_PTERM;
937
          end
938
          else
939
            STATE <= INC_PTERM;
940
        end
941
        INC_PTERM: begin    //h05
942
          P_Term  <= P_Term + 1;
943
          STATE   <= LOAD_RZQ_PTERM;
944
        end
945
        MULTIPLY_DIVIDE: begin //06
946
           P_Term  <= Mult_Divide(P_Term-1, MULT, DIV);  //4/13/2011 compensate the added sync FF
947
           STATE <= LOAD_ZIO_PTERM;
948
        end
949
        LOAD_ZIO_PTERM: begin   //h07
950
          Active_IODRP            <= ZIO;
951
          IODRPCTRLR_CMD_VALID    <= 1'b1;
952
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
953
          IODRPCTRLR_WRITE_DATA   <= {2'b00,P_Term};
954
          IODRPCTRLR_R_WB         <= WRITE_MODE;
955
          if (IODRPCTRLR_RDY_BUSY_N)
956
            STATE <= LOAD_ZIO_PTERM;
957
          else
958
            STATE <= WAIT3;
959
        end
960
        WAIT3:  begin   //h08
961
          if (!IODRPCTRLR_RDY_BUSY_N)
962
            STATE <= WAIT3;
963
          else begin
964
            STATE   <= LOAD_ZIO_NTERM;
965
          end
966
        end
967
        LOAD_ZIO_NTERM: begin   //h09
968
          Active_IODRP            <= ZIO;
969
          IODRPCTRLR_CMD_VALID    <= 1'b1;
970
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
971
          IODRPCTRLR_WRITE_DATA   <= {1'b0,N_Term};
972
          IODRPCTRLR_R_WB         <= WRITE_MODE;
973
          if (IODRPCTRLR_RDY_BUSY_N)
974
            STATE <= LOAD_ZIO_NTERM;
975
          else
976
            STATE <= WAIT4;
977
        end
978
        WAIT4:  begin   //h0A
979
          if (!IODRPCTRLR_RDY_BUSY_N)
980
            STATE <= WAIT4;
981
          else if ((!ZIO_IN)||(N_Term == 7'b1111111)) begin
982
            if (PNSKEW) begin
983
              STATE    <= SKEW;
984
            end
985
            else
986
            STATE <= WAIT_FOR_START_BROADCAST;
987
          end
988
          else
989
            STATE <= INC_NTERM;
990
        end
991
        INC_NTERM: begin    //h0B
992
          N_Term  <= N_Term + 1;
993
          STATE   <= LOAD_ZIO_NTERM;
994
        end
995
        SKEW : begin //0C
996
            P_Term_s <= Mult_Divide(P_Term, MULT_S, DIV_S);
997
            N_Term_w <= Mult_Divide(N_Term-1, MULT_W, DIV_W);
998
            P_Term_w <= Mult_Divide(P_Term, MULT_W, DIV_W);
999
            N_Term_s <= Mult_Divide(N_Term-1, MULT_S, DIV_S);
1000
            P_Term   <= Mult_Divide(P_Term, MULT_S, DIV_S);
1001
            N_Term   <= Mult_Divide(N_Term-1, MULT_W, DIV_W);
1002
            STATE  <= WAIT_FOR_START_BROADCAST;
1003
        end
1004
        WAIT_FOR_START_BROADCAST: begin   //h0D
1005
          Pre_SYSRST    <= 1'b0;      //release SYSRST, but keep UICMDEN=1 and UIDONECAL=0. This is needed to do Broadcast through UI interface, while keeping the MCB in calibration mode
1006
          Active_IODRP  <= MCB_PORT;
1007
          if (START_BROADCAST && IODRPCTRLR_RDY_BUSY_N) begin
1008
            if (P_Term != P_Term_Prev || SKIP_IN_TERM_CAL   ) begin
1009
              STATE       <= BROADCAST_PTERM;
1010
              P_Term_Prev <= P_Term;
1011
            end
1012
            else if (N_Term != N_Term_Prev) begin
1013
              N_Term_Prev <= N_Term;
1014
              STATE       <= BROADCAST_NTERM;
1015
            end
1016
            else
1017
              STATE <= OFF_RZQ_PTERM;
1018
          end
1019
          else
1020
            STATE   <= WAIT_FOR_START_BROADCAST;
1021
        end
1022
        BROADCAST_PTERM:  begin    //h0E
1023
//SBS redundant?          MCB_UICMDEN             <= 1'b1;        // take control of UI/UO port for reentrant use of dynamic In Term tuning
1024
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
1025
          IODRPCTRLR_WRITE_DATA   <= {2'b00,P_Term};
1026
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1027
          MCB_CMD_VALID           <= 1'b1;
1028
          MCB_UIDRPUPDATE         <= ~First_In_Term_Done; // Set the update flag if this is the first time through
1029
          MCB_USE_BKST            <= 1'b1;
1030
          if (MCB_RDY_BUSY_N)
1031
            STATE <= BROADCAST_PTERM;
1032
          else
1033
            STATE <= WAIT5;
1034
        end
1035
        WAIT5:  begin   //h0F
1036
          if (!MCB_RDY_BUSY_N)
1037
            STATE <= WAIT5;
1038
          else if (First_In_Term_Done) begin  // If first time through is already set, then this must be dynamic in term
1039
            if (MCB_UOREFRSHFLAG) begin
1040
              MCB_UIDRPUPDATE <= 1'b1;
1041
              if (N_Term != N_Term_Prev) begin
1042
                N_Term_Prev <= N_Term;
1043
                STATE       <= BROADCAST_NTERM;
1044
              end
1045
              else
1046
                STATE <= OFF_RZQ_PTERM;
1047
            end
1048
            else
1049
              STATE <= WAIT5;   // wait for a Refresh cycle
1050
          end
1051
          else begin
1052
            N_Term_Prev <= N_Term;
1053
            STATE <= BROADCAST_NTERM;
1054
          end
1055
        end
1056
        BROADCAST_NTERM:  begin    //h10
1057
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
1058
          IODRPCTRLR_WRITE_DATA   <= {2'b00,N_Term};
1059
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1060
          MCB_CMD_VALID           <= 1'b1;
1061
          MCB_USE_BKST            <= 1'b1;
1062
          MCB_UIDRPUPDATE         <= ~First_In_Term_Done; // Set the update flag if this is the first time through
1063
          if (MCB_RDY_BUSY_N)
1064
            STATE <= BROADCAST_NTERM;
1065
          else
1066
            STATE <= WAIT6;
1067
        end
1068
        WAIT6:  begin             // 7'h11
1069
          if (!MCB_RDY_BUSY_N)
1070
            STATE <= WAIT6;
1071
          else if (First_In_Term_Done) begin  // If first time through is already set, then this must be dynamic in term
1072
            if (MCB_UOREFRSHFLAG) begin
1073
              MCB_UIDRPUPDATE <= 1'b1;
1074
              STATE           <= OFF_RZQ_PTERM;
1075
            end
1076
            else
1077
              STATE <= WAIT6;   // wait for a Refresh cycle
1078
          end
1079
          else
1080
               STATE <= LDQS_CLK_WRITE_P_TERM;
1081
        end
1082
          LDQS_CLK_WRITE_P_TERM:  begin   //7'h12
1083
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
1084
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1085
          IODRPCTRLR_WRITE_DATA   <= {2'b00, P_Term_w};
1086
          MCB_UIADDR              <= IOI_LDQS_CLK;
1087
          MCB_CMD_VALID           <= 1'b1;
1088
          if (MCB_RDY_BUSY_N)
1089
            STATE <= LDQS_CLK_WRITE_P_TERM;
1090
          else
1091
            STATE <= LDQS_CLK_P_TERM_WAIT;
1092
        end
1093
        LDQS_CLK_P_TERM_WAIT:  begin     //7'h13  
1094
          if (!MCB_RDY_BUSY_N)
1095
            STATE <= LDQS_CLK_P_TERM_WAIT;
1096
          else begin
1097
            STATE           <= LDQS_CLK_WRITE_N_TERM;
1098
          end
1099
        end
1100
        LDQS_CLK_WRITE_N_TERM:  begin   //7'h14
1101
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
1102
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1103
          IODRPCTRLR_WRITE_DATA   <= {1'b0, N_Term_s};
1104
          MCB_UIADDR              <= IOI_LDQS_CLK;
1105
          MCB_CMD_VALID           <= 1'b1;
1106
          if (MCB_RDY_BUSY_N)
1107
            STATE <= LDQS_CLK_WRITE_N_TERM;
1108
          else
1109
            STATE <= LDQS_CLK_N_TERM_WAIT;
1110
        end
1111
        LDQS_CLK_N_TERM_WAIT:  begin   //7'h15
1112
          if (!MCB_RDY_BUSY_N)
1113
            STATE <= LDQS_CLK_N_TERM_WAIT;
1114
          else begin
1115
            STATE           <= LDQS_PIN_WRITE_P_TERM;
1116
          end
1117
        end
1118
         LDQS_PIN_WRITE_P_TERM:  begin //7'h16
1119
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
1120
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1121
          IODRPCTRLR_WRITE_DATA   <= {2'b00, P_Term_s};
1122
          MCB_UIADDR              <= IOI_LDQS_PIN;
1123
          MCB_CMD_VALID           <= 1'b1;
1124
          if (MCB_RDY_BUSY_N)
1125
            STATE <= LDQS_PIN_WRITE_P_TERM;
1126
          else
1127
            STATE <= LDQS_PIN_P_TERM_WAIT;
1128
        end
1129
        LDQS_PIN_P_TERM_WAIT:  begin   //7'h17
1130
          if (!MCB_RDY_BUSY_N)
1131
            STATE <= LDQS_PIN_P_TERM_WAIT;
1132
          else begin
1133
            STATE           <= LDQS_PIN_WRITE_N_TERM;
1134
          end
1135
        end
1136
         LDQS_PIN_WRITE_N_TERM:  begin //7'h18
1137
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
1138
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1139
          IODRPCTRLR_WRITE_DATA   <= {1'b0, N_Term_w};
1140
          MCB_UIADDR              <= IOI_LDQS_PIN;
1141
          MCB_CMD_VALID           <= 1'b1;
1142
          if (MCB_RDY_BUSY_N)
1143
            STATE <= LDQS_PIN_WRITE_N_TERM;
1144
          else
1145
            STATE <= LDQS_PIN_N_TERM_WAIT;
1146
        end
1147
        LDQS_PIN_N_TERM_WAIT:  begin  //7'h19
1148
          if (!MCB_RDY_BUSY_N)
1149
            STATE <= LDQS_PIN_N_TERM_WAIT;
1150
          else begin
1151
            STATE           <= UDQS_CLK_WRITE_P_TERM;
1152
          end
1153
        end
1154
        UDQS_CLK_WRITE_P_TERM:  begin //7'h1A
1155
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
1156
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1157
          IODRPCTRLR_WRITE_DATA   <= {2'b00, P_Term_w};
1158
          MCB_UIADDR              <= IOI_UDQS_CLK;
1159
          MCB_CMD_VALID           <= 1'b1;
1160
          if (MCB_RDY_BUSY_N)
1161
            STATE <= UDQS_CLK_WRITE_P_TERM;
1162
          else
1163
            STATE <= UDQS_CLK_P_TERM_WAIT;
1164
        end
1165
        UDQS_CLK_P_TERM_WAIT:  begin //7'h1B
1166
          if (!MCB_RDY_BUSY_N)
1167
            STATE <= UDQS_CLK_P_TERM_WAIT;
1168
          else begin
1169
            STATE           <= UDQS_CLK_WRITE_N_TERM;
1170
          end
1171
        end
1172
        UDQS_CLK_WRITE_N_TERM:  begin //7'h1C
1173
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
1174
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1175
          IODRPCTRLR_WRITE_DATA   <= {1'b0, N_Term_s};
1176
          MCB_UIADDR              <= IOI_UDQS_CLK;
1177
          MCB_CMD_VALID           <= 1'b1;
1178
          if (MCB_RDY_BUSY_N)
1179
            STATE <= UDQS_CLK_WRITE_N_TERM;
1180
          else
1181
            STATE <= UDQS_CLK_N_TERM_WAIT;
1182
        end
1183
        UDQS_CLK_N_TERM_WAIT:  begin //7'h1D
1184
          if (!MCB_RDY_BUSY_N)
1185
            STATE <= UDQS_CLK_N_TERM_WAIT;
1186
          else begin
1187
            STATE           <= UDQS_PIN_WRITE_P_TERM;
1188
          end
1189
        end
1190
         UDQS_PIN_WRITE_P_TERM:  begin //7'h1E
1191
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
1192
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1193
          IODRPCTRLR_WRITE_DATA   <= {2'b00, P_Term_s};
1194
          MCB_UIADDR              <= IOI_UDQS_PIN;
1195
          MCB_CMD_VALID           <= 1'b1;
1196
          if (MCB_RDY_BUSY_N)
1197
            STATE <= UDQS_PIN_WRITE_P_TERM;
1198
          else
1199
            STATE <= UDQS_PIN_P_TERM_WAIT;
1200
        end
1201
        UDQS_PIN_P_TERM_WAIT:  begin  //7'h1F
1202
          if (!MCB_RDY_BUSY_N)
1203
            STATE <= UDQS_PIN_P_TERM_WAIT;
1204
          else begin
1205
            STATE           <= UDQS_PIN_WRITE_N_TERM;
1206
          end
1207
        end
1208
         UDQS_PIN_WRITE_N_TERM:  begin  //7'h20
1209
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
1210
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1211
          IODRPCTRLR_WRITE_DATA   <= {1'b0, N_Term_w};
1212
          MCB_UIADDR              <= IOI_UDQS_PIN;
1213
          MCB_CMD_VALID           <= 1'b1;
1214
          if (MCB_RDY_BUSY_N)
1215
            STATE <= UDQS_PIN_WRITE_N_TERM;
1216
          else
1217
            STATE <= UDQS_PIN_N_TERM_WAIT;
1218
        end
1219
        UDQS_PIN_N_TERM_WAIT:  begin   //7'h21
1220
          if (!MCB_RDY_BUSY_N)
1221
            STATE <= UDQS_PIN_N_TERM_WAIT;
1222
          else begin
1223
            STATE           <= OFF_RZQ_PTERM;
1224
          end
1225
        end
1226
        OFF_RZQ_PTERM:  begin        // 7'h22
1227
          Active_IODRP            <= RZQ;
1228
          IODRPCTRLR_CMD_VALID    <= 1'b1;
1229
          IODRPCTRLR_MEMCELL_ADDR <= PTerm;
1230
          IODRPCTRLR_WRITE_DATA   <= 8'b00;
1231
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1232
          P_Term                  <= 6'b0;
1233
          N_Term                  <= 5'b0;
1234
          MCB_UIDRPUPDATE         <= ~First_In_Term_Done; // Set the update flag if this is the first time through
1235
          if (IODRPCTRLR_RDY_BUSY_N)
1236
            STATE <= OFF_RZQ_PTERM;
1237
          else
1238
            STATE <= WAIT7;
1239
        end
1240
        WAIT7:  begin             // 7'h23
1241
          if (!IODRPCTRLR_RDY_BUSY_N)
1242
            STATE <= WAIT7;
1243
          else
1244
            STATE <= OFF_ZIO_NTERM;
1245
        end
1246
        OFF_ZIO_NTERM:  begin     // 7'h24
1247
          Active_IODRP            <= ZIO;
1248
          IODRPCTRLR_CMD_VALID    <= 1'b1;
1249
          IODRPCTRLR_MEMCELL_ADDR <= NTerm;
1250
          IODRPCTRLR_WRITE_DATA   <= 8'b00;
1251
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1252
          if (IODRPCTRLR_RDY_BUSY_N)
1253
            STATE <= OFF_ZIO_NTERM;
1254
          else
1255
            STATE <= WAIT8;
1256
        end
1257
        WAIT8:  begin             // 7'h25
1258
          if (!IODRPCTRLR_RDY_BUSY_N)
1259
            STATE <= WAIT8;
1260
          else begin
1261
            if (First_In_Term_Done) begin
1262
              STATE               <= START_DYN_CAL; // No need to reset the MCB if we are in InTerm tuning
1263
            end
1264
            else begin
1265
              STATE               <= WRITE_CALIBRATE; // go read the first Max_Value from RZQ
1266
            end
1267
          end
1268
        end
1269
        RST_DELAY:  begin     // 7'h26
1270
          if (Block_Reset) begin  // this ensures that more than 512 clock cycles occur since the last reset after MCB_WRITE_CALIBRATE ???
1271
            STATE       <= RST_DELAY;
1272
          end
1273
          else begin
1274
            STATE <= START_DYN_CAL_PRE;
1275
          end
1276
        end
1277
 
1278
//****************************
1279
// DYNAMIC CALIBRATION PORTION
1280
//****************************
1281
        START_DYN_CAL_PRE:  begin   // 7'h27
1282
          LastPass_DynCal <= `IN_TERM_PASS;
1283
          MCB_UICMDEN     <= 1'b0;    // release UICMDEN
1284
          MCB_UIDONECAL   <= 1'b1;    // release UIDONECAL - MCB will now initialize.
1285
          Pre_SYSRST      <= 1'b1;    // SYSRST pulse
1286
          if (~CALMODE_EQ_CALIBRATION)      // if C_MC_CALIBRATION_MODE is set to NOCALIBRATION
1287
            STATE       <= START_DYN_CAL;  // we'll skip setting the DQS delays manually
1288
          else if (pre_sysrst_minpulse_width_ok)
1289
            STATE       <= WAIT_FOR_UODONE;
1290
          end
1291
        WAIT_FOR_UODONE:  begin  //7'h28
1292
          Pre_SYSRST      <= 1'b0;    // SYSRST pulse
1293
          if (IODRPCTRLR_RDY_BUSY_N && MCB_UODONECAL) begin //IODRP Controller needs to be ready, & MCB needs to be done with hard calibration
1294
            MCB_UICMDEN <= 1'b1;    // grab UICMDEN
1295
            DQS_DELAY_INITIAL <= Mult_Divide(Max_Value, DQS_NUMERATOR, DQS_DENOMINATOR);
1296
            STATE       <= LDQS_WRITE_POS_INDELAY;
1297
          end
1298
          else
1299
            STATE       <= WAIT_FOR_UODONE;
1300
        end
1301
        LDQS_WRITE_POS_INDELAY:  begin// 7'h29
1302
          IODRPCTRLR_MEMCELL_ADDR <= PosEdgeInDly;
1303
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1304
          IODRPCTRLR_WRITE_DATA   <= DQS_DELAY_INITIAL;
1305
          MCB_UIADDR              <= IOI_LDQS_CLK;
1306
          MCB_CMD_VALID           <= 1'b1;
1307
          if (MCB_RDY_BUSY_N)
1308
            STATE <= LDQS_WRITE_POS_INDELAY;
1309
          else
1310
            STATE <= LDQS_WAIT1;
1311
        end
1312
        LDQS_WAIT1:  begin           // 7'h2A
1313
          if (!MCB_RDY_BUSY_N)
1314
            STATE <= LDQS_WAIT1;
1315
          else begin
1316
            STATE           <= LDQS_WRITE_NEG_INDELAY;
1317
          end
1318
        end
1319
        LDQS_WRITE_NEG_INDELAY:  begin// 7'h2B
1320
          IODRPCTRLR_MEMCELL_ADDR <= NegEdgeInDly;
1321
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1322
          IODRPCTRLR_WRITE_DATA   <= DQS_DELAY_INITIAL;
1323
          MCB_UIADDR              <= IOI_LDQS_CLK;
1324
          MCB_CMD_VALID           <= 1'b1;
1325
          if (MCB_RDY_BUSY_N)
1326
            STATE <= LDQS_WRITE_NEG_INDELAY;
1327
          else
1328
            STATE <= LDQS_WAIT2;
1329
        end
1330
        LDQS_WAIT2:  begin           // 7'h2C
1331
          if (!MCB_RDY_BUSY_N)
1332
            STATE <= LDQS_WAIT2;
1333
          else begin
1334
            STATE <= UDQS_WRITE_POS_INDELAY;
1335
          end
1336
        end
1337
        UDQS_WRITE_POS_INDELAY:  begin// 7'h2D
1338
          IODRPCTRLR_MEMCELL_ADDR <= PosEdgeInDly;
1339
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1340
          IODRPCTRLR_WRITE_DATA   <= DQS_DELAY_INITIAL;
1341
          MCB_UIADDR              <= IOI_UDQS_CLK;
1342
          MCB_CMD_VALID           <= 1'b1;
1343
          if (MCB_RDY_BUSY_N)
1344
            STATE <= UDQS_WRITE_POS_INDELAY;
1345
          else
1346
            STATE <= UDQS_WAIT1;
1347
        end
1348
        UDQS_WAIT1:  begin           // 7'h2E
1349
          if (!MCB_RDY_BUSY_N)
1350
            STATE <= UDQS_WAIT1;
1351
          else begin
1352
            STATE           <= UDQS_WRITE_NEG_INDELAY;
1353
          end
1354
        end
1355
        UDQS_WRITE_NEG_INDELAY:  begin// 7'h2F
1356
          IODRPCTRLR_MEMCELL_ADDR <= NegEdgeInDly;
1357
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1358
          IODRPCTRLR_WRITE_DATA   <= DQS_DELAY_INITIAL;
1359
          MCB_UIADDR              <= IOI_UDQS_CLK;
1360
          MCB_CMD_VALID           <= 1'b1;
1361
          if (MCB_RDY_BUSY_N)
1362
            STATE <= UDQS_WRITE_NEG_INDELAY;
1363
          else
1364
            STATE <= UDQS_WAIT2;
1365
        end
1366
        UDQS_WAIT2:  begin           // 7'h30
1367
          if (!MCB_RDY_BUSY_N)
1368
            STATE <= UDQS_WAIT2;
1369
          else begin
1370
            DQS_DELAY         <= DQS_DELAY_INITIAL;
1371
            TARGET_DQS_DELAY  <= DQS_DELAY_INITIAL;
1372
            STATE             <= START_DYN_CAL;
1373
          end
1374
        end
1375
//**************************************************************************************
1376
        START_DYN_CAL:  begin       // 7'h31
1377
          Pre_SYSRST        <= 1'b0;      // SYSRST not driven
1378
          counter_inc       <= 8'b0;
1379
          counter_dec       <= 8'b0;
1380
          if (SKIP_DYNAMIC_DQS_CAL & SKIP_DYN_IN_TERMINATION)
1381
            STATE <= DONE;  //if we're skipping both dynamic algorythms, go directly to DONE
1382
          else
1383
          if (IODRPCTRLR_RDY_BUSY_N && MCB_UODONECAL && ~SELFREFRESH_REQ_R1 ) begin  //IODRP Controller needs to be ready, & MCB needs to be done with hard calibration
1384
 
1385
            // Alternate between Dynamic Input Termination and Dynamic Tuning routines
1386
            if (~SKIP_DYN_IN_TERMINATION & (LastPass_DynCal == `DYN_CAL_PASS)) begin
1387
              LastPass_DynCal <= `IN_TERM_PASS;
1388
              STATE           <= LOAD_RZQ_NTERM;
1389
            end
1390
            else begin
1391
              LastPass_DynCal <= `DYN_CAL_PASS;
1392
              STATE           <= WRITE_CALIBRATE;
1393
            end
1394
          end
1395
          else
1396
            STATE     <= START_DYN_CAL;
1397
        end
1398
        WRITE_CALIBRATE:  begin   // 7'h32
1399
          Pre_SYSRST              <= 1'b0; // SYSRST not driven
1400
          IODRPCTRLR_CMD_VALID    <= 1'b1;
1401
          IODRPCTRLR_MEMCELL_ADDR <= DelayControl;
1402
          IODRPCTRLR_WRITE_DATA   <= 8'h20; // Set calibrate bit
1403
          IODRPCTRLR_R_WB         <= WRITE_MODE;
1404
          Active_IODRP            <= RZQ;
1405
          if (IODRPCTRLR_RDY_BUSY_N)
1406
            STATE <= WRITE_CALIBRATE;
1407
          else
1408
            STATE <= WAIT9;
1409
        end
1410
        WAIT9:  begin     // 7'h33
1411
          counter_en  <= 1'b1;
1412
          if (count < 6'd38)  //this adds approximately 22 extra clock cycles after WRITE_CALIBRATE
1413
            STATE     <= WAIT9;
1414
          else
1415
            STATE     <= READ_MAX_VALUE;
1416
        end
1417
        READ_MAX_VALUE: begin     // 7'h34
1418
          IODRPCTRLR_CMD_VALID    <= 1'b1;
1419
          IODRPCTRLR_MEMCELL_ADDR <= MaxValue;
1420
          IODRPCTRLR_R_WB         <= READ_MODE;
1421
          Max_Value_Previous      <= Max_Value;
1422
          if (IODRPCTRLR_RDY_BUSY_N)
1423
            STATE <= READ_MAX_VALUE;
1424
          else
1425
            STATE <= WAIT10;
1426
        end
1427
        WAIT10:  begin    // 7'h35
1428
          if (!IODRPCTRLR_RDY_BUSY_N)
1429
            STATE <= WAIT10;
1430
          else begin
1431
            Max_Value           <= IODRPCTRLR_READ_DATA;  //record the Max_Value from the IODRP controller
1432
            if (~First_In_Term_Done) begin
1433
              STATE               <= RST_DELAY;
1434
              First_In_Term_Done  <= 1'b1;
1435
            end
1436
            else
1437
              STATE               <= ANALYZE_MAX_VALUE;
1438
          end
1439
        end
1440
        ANALYZE_MAX_VALUE:  begin // 7'h36   only do a Inc or Dec during a REFRESH cycle.
1441
          if (!First_Dyn_Cal_Done)
1442
            STATE <= FIRST_DYN_CAL;
1443
          else
1444
            if ((Max_Value<Max_Value_Previous)&&(Max_Value_Delta_Dn>=INCDEC_THRESHOLD)) begin
1445
              STATE <= DECREMENT;         //May need to Decrement
1446
              TARGET_DQS_DELAY   <= Mult_Divide(Max_Value, DQS_NUMERATOR, DQS_DENOMINATOR);
1447
            end
1448
          else
1449
            if ((Max_Value>Max_Value_Previous)&&(Max_Value_Delta_Up>=INCDEC_THRESHOLD)) begin
1450
              STATE <= INCREMENT;         //May need to Increment
1451
              TARGET_DQS_DELAY   <= Mult_Divide(Max_Value, DQS_NUMERATOR, DQS_DENOMINATOR);
1452
            end
1453
          else begin
1454
            Max_Value           <= Max_Value_Previous;
1455
            STATE <= START_DYN_CAL;
1456
          end
1457
        end
1458
        FIRST_DYN_CAL:  begin // 7'h37
1459
          First_Dyn_Cal_Done  <= 1'b1;          //set flag that the First Dynamic Calibration has been completed
1460
          STATE               <= START_DYN_CAL;
1461
        end
1462
        INCREMENT: begin      // 7'h38
1463
          STATE               <= START_DYN_CAL; // Default case: Inc is not high or no longer in REFRSH
1464
          MCB_UILDQSINC       <= 1'b0;          // Default case: no inc or dec
1465
          MCB_UIUDQSINC       <= 1'b0;          // Default case: no inc or dec
1466
          MCB_UILDQSDEC       <= 1'b0;          // Default case: no inc or dec
1467
          MCB_UIUDQSDEC       <= 1'b0;          // Default case: no inc or dec
1468
          case (Inc_Dec_REFRSH_Flag)            // {Increment_Flag,Decrement_Flag,MCB_UOREFRSHFLAG},
1469
            3'b101: begin
1470
              counter_inc <= counter_inc + 1'b1;
1471
                STATE               <= INCREMENT; //Increment is still high, still in REFRSH cycle
1472
              if (DQS_DELAY < DQS_DELAY_UPPER_LIMIT && counter_inc >= 8'h04) begin //if not at the upper limit yet, and you've waited 4 clks, increment
1473
                MCB_UILDQSINC       <= 1'b1;      //increment
1474
                MCB_UIUDQSINC       <= 1'b1;      //increment
1475
                DQS_DELAY           <= DQS_DELAY + 1'b1;
1476
              end
1477
            end
1478
            3'b100: begin
1479
              if (DQS_DELAY < DQS_DELAY_UPPER_LIMIT)
1480
                STATE                <= INCREMENT; //Increment is still high, REFRESH ended - wait for next REFRESH
1481
              end
1482
            default:
1483
                STATE               <= START_DYN_CAL; // Default case
1484
          endcase
1485
        end
1486
        DECREMENT: begin      // 7'h39
1487
          STATE               <= START_DYN_CAL; // Default case: Dec is not high or no longer in REFRSH
1488
          MCB_UILDQSINC       <= 1'b0;          // Default case: no inc or dec
1489
          MCB_UIUDQSINC       <= 1'b0;          // Default case: no inc or dec
1490
          MCB_UILDQSDEC       <= 1'b0;          // Default case: no inc or dec
1491
          MCB_UIUDQSDEC       <= 1'b0;          // Default case: no inc or dec
1492
          if (DQS_DELAY != 8'h00) begin
1493
            case (Inc_Dec_REFRSH_Flag)            // {Increment_Flag,Decrement_Flag,MCB_UOREFRSHFLAG},
1494
              3'b011: begin
1495
                counter_dec <= counter_dec + 1'b1;
1496
                  STATE               <= DECREMENT; // Decrement is still high, still in REFRESH cycle
1497
                if (DQS_DELAY > DQS_DELAY_LOWER_LIMIT  && counter_dec >= 8'h04) begin //if not at the lower limit, and you've waited 4 clks, decrement
1498
                  MCB_UILDQSDEC       <= 1'b1;      // decrement
1499
                  MCB_UIUDQSDEC       <= 1'b1;      // decrement
1500
                  DQS_DELAY           <= DQS_DELAY - 1'b1; //SBS
1501
                end
1502
              end
1503
              3'b010: begin
1504
                if (DQS_DELAY > DQS_DELAY_LOWER_LIMIT) //if not at the lower limit, decrement
1505
                  STATE                 <= DECREMENT; //Decrement is still high, REFRESH ended - wait for next REFRESH
1506
                end
1507
              default: begin
1508
                  STATE               <= START_DYN_CAL; // Default case
1509
              end
1510
            endcase
1511
          end
1512
        end
1513
        DONE: begin           // 7'h3A
1514
          Pre_SYSRST              <= 1'b0;    // SYSRST cleared
1515
          MCB_UICMDEN             <= 1'b0;  // release UICMDEN
1516
          STATE <= DONE;
1517
        end
1518
        default:        begin
1519
          MCB_UICMDEN             <= 1'b0;  // release UICMDEN
1520
          MCB_UIDONECAL           <= 1'b1;  // release UIDONECAL - MCB will now initialize.
1521
          Pre_SYSRST              <= 1'b0;  // SYSRST not driven
1522
          IODRPCTRLR_CMD_VALID    <= 1'b0;
1523
          IODRPCTRLR_MEMCELL_ADDR <= 8'h00;
1524
          IODRPCTRLR_WRITE_DATA   <= 8'h00;
1525
          IODRPCTRLR_R_WB         <= 1'b0;
1526
          IODRPCTRLR_USE_BKST     <= 1'b0;
1527
          P_Term                  <= 6'b0;
1528
          N_Term                  <= 5'b0;
1529
          Active_IODRP            <= ZIO;
1530
          Max_Value_Previous      <= 8'b0;
1531
          MCB_UILDQSINC           <= 1'b0;  // no inc or dec
1532
          MCB_UIUDQSINC           <= 1'b0;  // no inc or dec
1533
          MCB_UILDQSDEC           <= 1'b0;  // no inc or dec
1534
          MCB_UIUDQSDEC           <= 1'b0;  // no inc or dec
1535
          counter_en              <= 1'b0;
1536
          First_Dyn_Cal_Done      <= 1'b0;  // flag that the First Dynamic Calibration completed
1537
          Max_Value               <= Max_Value;
1538
          STATE                   <= START;
1539
        end
1540
      endcase
1541
    end
1542
  end
1543
 
1544
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.