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.13/] [memfifo.srcs/] [sources_1/] [ip/] [mig_7series_0/] [mig_7series_0/] [user_design/] [rtl/] [phy/] [mig_7series_v2_3_ddr_phy_ocd_samp.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
//*****************************************************************************
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: %version
53
//  \   \         Application: MIG
54
//  /   /         Filename: ddr_phy_v2_3_phy_ocd_samp.v
55
// /___/   /\     Date Last Modified: $Date: 2011/02/25 02:07:40 $
56
// \   \  /  \    Date Created: Aug 03 2009 
57
//  \___\/\___\
58
//
59
//Device: 7 Series
60
//Design Name: DDR3 SDRAM
61
//Purpose: Controls the number of samples and generates an aggregate
62
//sampling result.
63
//
64
// The following shows the nesting of the sampling loop.  Nominally built
65
// to accomodate the "complex" sampling protocol.  Adapted for use with
66
// "simple" samplng.
67
//
68
//                    simple                    complex
69
//                                 
70
// samples            OCAL_SIMPLE_SCAN_SAMPS    1 or 50 Depends on SIM_CAL_OPTION
71
//   rd_victim_sel    0                         0 to 7
72
//     data_cnt       1                         157
73
//
74
// First it collects comparison results provided on the
75
// two bit "match" bus.  A particular phaser tap setting may be recorded one
76
// or many times depending on various parameter settings.  
77
// The two bit match bus corresponds to comparisons for the
78
// zero or rising phase, and the oneeighty or falling phase.  The "aggregate"
79
// starts out as NULL and then begins collecting comparison results
80
// when phy_rddata_en_1 is high.  The first result is always set into
81
// the aggregate result.  Subsequent results that match aggregate, don't
82
// make any change.  Subsequent compare results that don't match cause the aggregate
83
// to turn to FUZZ.
84
//
85
// A "sample" is defined as a single DRAM burst for the simple step, and
86
// an entire 157 DRAM data bursts across the 8 victim bits for complex.
87
//
88
// Once all samples have been taken, the samp_result is computed by
89
// comparing the number of successful compares against the threshold.
90
//
91
// The second function is to track and control the number of samples.  For 
92
// "simple" data, the number of samples is set by OCAL_SIMPLE_SCAN_SAMPS.  
93
// For "complex" data, nominally
94
// the complex data pattern consists of a sequence of 157 DRAM chunks.  This
95
// sequence is run with each bit in the byte designated as the "victim".  This sequence
96
// is repeated 50 times, although when SIM_CAL_OPTION is set to none "NONE", it is only
97
// repeated once.
98
//
99
// This block generates oclk_calib_resume.  For the simple pattern, a single DRAM
100
// burst is returned  For complex its 157  which indicates the start of the 157*50
101
// sequence for a bit.  samp_done is pulsed.
102
//
103
//Reference:
104
//Revision History:
105
//*****************************************************************************
106
 
107
`timescale 1ps/1ps
108
 
109
module mig_7series_v2_3_ddr_phy_ocd_samp #
110
  (parameter nCK_PER_CLK             = 4,
111
   parameter OCAL_SIMPLE_SCAN_SAMPS  = 2,
112
   parameter SCAN_PCT_SAMPS_SOLID    = 95,
113
   parameter TCQ                     = 100,
114
   parameter SIM_CAL_OPTION          = "NONE")
115
  (/*AUTOARG*/
116
  // Outputs
117
  samp_done, oclk_calib_resume, rd_victim_sel, samp_result,
118
  // Inputs
119
  complex_oclkdelay_calib_start, clk, rst, reset_scan,
120
  ocal_num_samples_inc, match, phy_rddata_en_1, taps_set
121
  );
122
 
123
  function integer clogb2 (input integer size); // ceiling logb2
124
    begin
125
      size = size - 1;
126
      for (clogb2=1; size>1; clogb2=clogb2+1)
127
            size = size >> 1;
128
    end
129
  endfunction // clogb2
130
 
131
  localparam ONE = 1;
132
 
133
  localparam CMPLX_DATA_CNT = nCK_PER_CLK == 2 ? 157 * 2 : 157;
134
  localparam SIMP_DATA_CNT = nCK_PER_CLK == 2 ? 2 : 1;
135
 
136
  localparam DATA_CNT_WIDTH = nCK_PER_CLK == 2 ? 9 : 8;
137
 
138
  localparam CMPLX_SAMPS = SIM_CAL_OPTION == "NONE" ? 50 : 1;
139
 
140
  // Plus one because were counting in natural numbers. 
141
  localparam SAMP_CNT_WIDTH = clogb2(OCAL_SIMPLE_SCAN_SAMPS > CMPLX_SAMPS
142
                                       ? OCAL_SIMPLE_SCAN_SAMPS : CMPLX_SAMPS) + 1;
143
 
144
  // Remember SAMPLES is natural number counting.  One corresponds to one sample.
145
  localparam integer SIMP_SAMPS_SOLID_THRESH = OCAL_SIMPLE_SCAN_SAMPS * SCAN_PCT_SAMPS_SOLID * 0.01;
146
  localparam integer CMPLX_SAMPS_SOLID_THRESH = CMPLX_SAMPS * SCAN_PCT_SAMPS_SOLID * 0.01;
147
 
148
  input complex_oclkdelay_calib_start;
149
 
150
  wire [SAMP_CNT_WIDTH-1:0] samples =  complex_oclkdelay_calib_start
151
                                         ? CMPLX_SAMPS[SAMP_CNT_WIDTH-1:0]
152
                                         : OCAL_SIMPLE_SCAN_SAMPS[SAMP_CNT_WIDTH-1:0];
153
 
154
  localparam [1:0] NULL       = 2'b11,
155
                   FUZZ       = 2'b00,
156
                   ONEEIGHTY  = 2'b10,
157
                   ZERO       = 2'b01;
158
 
159
  input clk;
160
  input rst;
161
 
162
  input reset_scan;
163
 
164
  // Given the need to count phy_data_en, this is not useful.
165
  input ocal_num_samples_inc;
166
 
167
  input [1:0] match;
168
 
169
  input phy_rddata_en_1;
170
 
171
  input taps_set;
172
 
173
  reg samp_done_ns, samp_done_r;
174
  always @(posedge clk) samp_done_r <= #TCQ samp_done_ns;
175
  output samp_done;
176
  assign samp_done = samp_done_r;
177
 
178
  reg [1:0] agg_samp_ns, agg_samp_r;
179
  always @(posedge clk) agg_samp_r <= #TCQ agg_samp_ns;
180
 
181
  reg oclk_calib_resume_ns, oclk_calib_resume_r;
182
  always @(posedge clk) oclk_calib_resume_r <= #TCQ oclk_calib_resume_ns;
183
  output oclk_calib_resume;
184
  assign oclk_calib_resume = oclk_calib_resume_r;
185
 
186
  // Complex data counting.
187
  // Inner most loop.  157 phy_data_en.
188
  reg [DATA_CNT_WIDTH-1:0] data_cnt_ns, data_cnt_r;
189
  always @(posedge clk) data_cnt_r <= #TCQ data_cnt_ns;
190
 
191
  // Nominally, 50 samples of the above 157 phy_data_en.
192
  reg [SAMP_CNT_WIDTH-1:0] samps_ns, samps_r;
193
  always @(posedge clk) samps_r <= #TCQ samps_ns;
194
 
195
  // Step through the 8 bits in the byte.
196
  reg [2:0] rd_victim_sel_ns, rd_victim_sel_r;
197
  always @(posedge clk) rd_victim_sel_r <= #TCQ rd_victim_sel_ns;
198
  output [2:0] rd_victim_sel;
199
  assign rd_victim_sel = rd_victim_sel_r;
200
 
201
  reg [SAMP_CNT_WIDTH-1:0] zero_ns, zero_r, oneeighty_ns, oneeighty_r;
202
  always @(posedge clk) zero_r <= #TCQ zero_ns;
203
  always @(posedge clk) oneeighty_r <= #TCQ oneeighty_ns;
204
 
205
  output [1:0] samp_result;
206
  assign samp_result[0] = zero_r >=  (complex_oclkdelay_calib_start
207
                                      ? CMPLX_SAMPS_SOLID_THRESH[SAMP_CNT_WIDTH-1:0]
208
                                    : SIMP_SAMPS_SOLID_THRESH[SAMP_CNT_WIDTH-1:0]);
209
  assign samp_result[1] = oneeighty_r >= (complex_oclkdelay_calib_start
210
                                         ? CMPLX_SAMPS_SOLID_THRESH[SAMP_CNT_WIDTH-1:0]
211
                                         : SIMP_SAMPS_SOLID_THRESH[SAMP_CNT_WIDTH-1:0]);
212
 
213
  reg [0:0] sm_ns, sm_r;
214
  always @(posedge clk) sm_r <= #TCQ sm_ns;
215
 
216
  wire [DATA_CNT_WIDTH-1:0] data_cnt = complex_oclkdelay_calib_start
217
                                         ? CMPLX_DATA_CNT[DATA_CNT_WIDTH-1:0]
218
                                         : SIMP_DATA_CNT[DATA_CNT_WIDTH-1:0];
219
  wire [2:0] rd_victim_end = complex_oclkdelay_calib_start ? 3'h7 : 3'h0;
220
  wire data_end = data_cnt_r == ONE[DATA_CNT_WIDTH-1:0];
221
  wire samp_end = samps_r == ONE[SAMP_CNT_WIDTH-1:0];
222
 
223
  // Primary state machine.
224
 
225
  always @(*) begin
226
 
227
  // Default next state assignments.
228
 
229
    agg_samp_ns = agg_samp_r;
230
    data_cnt_ns = data_cnt_r;
231
    oclk_calib_resume_ns = 1'b0;
232
    oneeighty_ns = oneeighty_r;
233
    rd_victim_sel_ns = rd_victim_sel_r;
234
    samp_done_ns = samp_done_r;
235
    samps_ns = samps_r;
236
    sm_ns = sm_r;
237
    zero_ns = zero_r;
238
 
239
    if (rst == 1'b1) begin
240
  // RESET next states
241
      sm_ns = /*AK("READY")*/1'd0;
242
 
243
    end else
244
 
245
  // State based actions and next states. 
246
      case (sm_r)
247
 
248
        /*AL("READY")*/1'd0:begin
249
          agg_samp_ns = NULL;
250
          data_cnt_ns = data_cnt;
251
          oneeighty_ns = {SAMP_CNT_WIDTH{1'b0}};
252
          rd_victim_sel_ns = 3'b0;
253
          samps_ns = complex_oclkdelay_calib_start ? CMPLX_SAMPS[SAMP_CNT_WIDTH-1:0]
254
                                                   : OCAL_SIMPLE_SCAN_SAMPS[SAMP_CNT_WIDTH-1:0];
255
          zero_ns = {SAMP_CNT_WIDTH{1'b0}};
256
 
257
          if (taps_set) begin
258
            samp_done_ns = 1'b0;
259
            sm_ns = /*AK("AWAITING_DATA")*/1'd1;
260
            oclk_calib_resume_ns = 1'b1;
261
          end
262
        end
263
 
264
        /*AL("AWAITING_DATA")*/1'd1:begin
265
          if (phy_rddata_en_1) begin
266
 
267
            case (agg_samp_r)
268
              NULL : if (~&match) agg_samp_ns = match;
269
              ZERO, ONEEIGHTY : if (~(agg_samp_r == match || &match)) agg_samp_ns = FUZZ;
270
              FUZZ : ;
271
            endcase // case (agg_samp_r)
272
 
273
            if (~data_end) data_cnt_ns = data_cnt_r - ONE[DATA_CNT_WIDTH-1:0];
274
            else begin
275
              data_cnt_ns = data_cnt;
276
              if (rd_victim_end != rd_victim_sel_r) rd_victim_sel_ns = rd_victim_sel_r + 3'h1;
277
              else begin
278
                rd_victim_sel_ns = 3'h0;
279
                if (agg_samp_ns == ZERO) zero_ns = zero_r + ONE[SAMP_CNT_WIDTH-1:0];
280
                if (agg_samp_ns == ONEEIGHTY) oneeighty_ns = oneeighty_r + ONE[SAMP_CNT_WIDTH-1:0];
281
                agg_samp_ns = NULL;
282
                if (~samp_end) samps_ns = samps_r - ONE[SAMP_CNT_WIDTH-1:0];
283
                else samp_done_ns = 1'b1;
284
              end
285
            end
286
 
287
            if (samp_done_ns) sm_ns = /*AK("READY")*/1'd0;
288
            else oclk_calib_resume_ns = ~complex_oclkdelay_calib_start && data_end;
289
          end
290
        end
291
 
292
      endcase // case (sm_r)
293
  end // always @ begin
294
 
295
 
296
endmodule // mig_7series_v2_3_ddr_phy_ocd_samp
297
 
298
// Local Variables:
299
// verilog-autolabel-prefix: "1'd"
300
// End:

powered by: WebSVN 2.1.0

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