1 |
2 |
ZTEX |
//*****************************************************************************
|
2 |
|
|
// (c) Copyright 2009 - 2012 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: mig_7series_v2_3_poc_tap_base.v
|
55 |
|
|
// /___/ /\ Date Last Modified: $$
|
56 |
|
|
// \ \ / \ Date Created:Tue 15 Jan 2014
|
57 |
|
|
// \___\/\___\
|
58 |
|
|
//
|
59 |
|
|
//Device: Virtex-7
|
60 |
|
|
//Design Name: DDR3 SDRAM
|
61 |
|
|
//Purpose: All your taps are belong to us.
|
62 |
|
|
//
|
63 |
|
|
//In general, this block should be able to start up with a random initialization of
|
64 |
|
|
//the various counters. But its probably easier, more normative and quicker time to solution
|
65 |
|
|
//to just initialize to zero with rst.
|
66 |
|
|
//
|
67 |
|
|
// Following deassertion of reset, endlessly increments the MMCM delay with PSEN. For
|
68 |
|
|
// each MMCM tap it samples the phase detector output a programmable number of times.
|
69 |
|
|
// When the sampling count is achieved, PSEN is pulsed and sampling of the next MMCM
|
70 |
|
|
// tap begins.
|
71 |
|
|
//
|
72 |
|
|
// Following a PSEN, sampling pauses for MMCM_SAMP_WAIT clocks. This is workaround
|
73 |
|
|
// for a bug in the MMCM where its output may have noise for a period following
|
74 |
|
|
// the PSEN.
|
75 |
|
|
//
|
76 |
|
|
// Samples are taken every other fabric clock. This is because the MMCM phase shift
|
77 |
|
|
// clock operates at half the fabric clock. The reason for this is unknown.
|
78 |
|
|
//
|
79 |
|
|
// At the end of the sampling period, a filtering step is implemented. samps_solid_thresh
|
80 |
|
|
// is the minumum number of samples that must be seen to declare a solid zero or one. If
|
81 |
|
|
// neithr the one and zero samples cross this threshold, then the sampple is declared fuzz.
|
82 |
|
|
//
|
83 |
|
|
// A "run_polarity" bit is maintained. It is set appropriately whenever a solid sample
|
84 |
|
|
// is observed.
|
85 |
|
|
//
|
86 |
|
|
// A "run" counter is maintained. If the current sample is fuzz, or opposite polarity
|
87 |
|
|
// from a previous sample, then the run counter is reset. If the current sample is the
|
88 |
|
|
// same polarity run_polarity, then the run counter is incremented.
|
89 |
|
|
//
|
90 |
|
|
// If a run_polarity reversal or fuzz is observed and the run counter is not zero
|
91 |
|
|
// then the run_end strobe is pulsed.
|
92 |
|
|
//
|
93 |
|
|
//Reference:
|
94 |
|
|
//Revision History:
|
95 |
|
|
//*****************************************************************************
|
96 |
|
|
|
97 |
|
|
`timescale 1 ps / 1 ps
|
98 |
|
|
|
99 |
|
|
module mig_7series_v2_3_poc_tap_base #
|
100 |
|
|
(parameter MMCM_SAMP_WAIT = 10,
|
101 |
|
|
parameter POC_USE_METASTABLE_SAMP = "FALSE",
|
102 |
|
|
parameter TCQ = 100,
|
103 |
|
|
parameter SAMPCNTRWIDTH = 8,
|
104 |
|
|
parameter TAPCNTRWIDTH = 7,
|
105 |
|
|
parameter TAPSPERKCLK = 112)
|
106 |
|
|
(/*AUTOARG*/
|
107 |
|
|
// Outputs
|
108 |
|
|
psincdec, psen, run, run_end, run_polarity, samps_hi_held, tap,
|
109 |
|
|
// Inputs
|
110 |
|
|
pd_out, clk, samples, samps_solid_thresh, psdone, rst,
|
111 |
|
|
poc_sample_pd
|
112 |
|
|
);
|
113 |
|
|
|
114 |
|
|
|
115 |
|
|
function integer clogb2 (input integer size); // ceiling logb2
|
116 |
|
|
begin
|
117 |
|
|
size = size - 1;
|
118 |
|
|
for (clogb2=1; size>1; clogb2=clogb2+1)
|
119 |
|
|
size = size >> 1;
|
120 |
|
|
end
|
121 |
|
|
endfunction // clogb2
|
122 |
|
|
|
123 |
|
|
input pd_out;
|
124 |
|
|
input clk;
|
125 |
|
|
input [SAMPCNTRWIDTH:0] samples, samps_solid_thresh;
|
126 |
|
|
input psdone;
|
127 |
|
|
input rst;
|
128 |
|
|
|
129 |
|
|
localparam ONE = 1;
|
130 |
|
|
|
131 |
|
|
localparam SAMP_WAIT_WIDTH = clogb2(MMCM_SAMP_WAIT);
|
132 |
|
|
reg [SAMP_WAIT_WIDTH-1:0] samp_wait_ns, samp_wait_r;
|
133 |
|
|
always @(posedge clk) samp_wait_r <= #TCQ samp_wait_ns;
|
134 |
|
|
|
135 |
|
|
reg pd_out_r;
|
136 |
|
|
always @(posedge clk) pd_out_r <= #TCQ pd_out;
|
137 |
|
|
wire pd_out_sel = POC_USE_METASTABLE_SAMP == "TRUE" ? pd_out_r : pd_out;
|
138 |
|
|
|
139 |
|
|
output psincdec;
|
140 |
|
|
assign psincdec = 1'b1;
|
141 |
|
|
output psen;
|
142 |
|
|
reg psen_int;
|
143 |
|
|
assign psen = psen_int;
|
144 |
|
|
|
145 |
|
|
reg [TAPCNTRWIDTH-1:0] run_r;
|
146 |
|
|
reg [TAPCNTRWIDTH-1:0] run_ns;
|
147 |
|
|
always @(posedge clk) run_r <= #TCQ run_ns;
|
148 |
|
|
output [TAPCNTRWIDTH-1:0] run;
|
149 |
|
|
assign run = run_r;
|
150 |
|
|
|
151 |
|
|
output run_end;
|
152 |
|
|
reg run_end_int;
|
153 |
|
|
assign run_end = run_end_int;
|
154 |
|
|
|
155 |
|
|
reg run_polarity_r;
|
156 |
|
|
reg run_polarity_ns;
|
157 |
|
|
always @(posedge clk) run_polarity_r <= #TCQ run_polarity_ns;
|
158 |
|
|
output run_polarity;
|
159 |
|
|
assign run_polarity = run_polarity_r;
|
160 |
|
|
|
161 |
|
|
reg [SAMPCNTRWIDTH-1:0] samp_cntr_r;
|
162 |
|
|
reg [SAMPCNTRWIDTH-1:0] samp_cntr_ns;
|
163 |
|
|
always @(posedge clk) samp_cntr_r <= #TCQ samp_cntr_ns;
|
164 |
|
|
|
165 |
|
|
reg [SAMPCNTRWIDTH:0] samps_hi_r;
|
166 |
|
|
reg [SAMPCNTRWIDTH:0] samps_hi_ns;
|
167 |
|
|
always @(posedge clk) samps_hi_r <= #TCQ samps_hi_ns;
|
168 |
|
|
|
169 |
|
|
reg [SAMPCNTRWIDTH:0] samps_hi_held_r;
|
170 |
|
|
reg [SAMPCNTRWIDTH:0] samps_hi_held_ns;
|
171 |
|
|
always @(posedge clk) samps_hi_held_r <= #TCQ samps_hi_held_ns;
|
172 |
|
|
output [SAMPCNTRWIDTH:0] samps_hi_held;
|
173 |
|
|
assign samps_hi_held = samps_hi_held_r;
|
174 |
|
|
|
175 |
|
|
reg [TAPCNTRWIDTH-1:0] tap_ns, tap_r;
|
176 |
|
|
always @(posedge clk) tap_r <= #TCQ tap_ns;
|
177 |
|
|
output [TAPCNTRWIDTH-1:0] tap;
|
178 |
|
|
assign tap = tap_r;
|
179 |
|
|
|
180 |
|
|
localparam SMWIDTH = 2;
|
181 |
|
|
reg [SMWIDTH-1:0] sm_ns;
|
182 |
|
|
reg [SMWIDTH-1:0] sm_r;
|
183 |
|
|
always @(posedge clk) sm_r <= #TCQ sm_ns;
|
184 |
|
|
|
185 |
|
|
reg samps_zero_ns, samps_zero_r, samps_one_ns, samps_one_r;
|
186 |
|
|
always @(posedge clk) samps_zero_r <= #TCQ samps_zero_ns;
|
187 |
|
|
always @(posedge clk)samps_one_r <= #TCQ samps_one_ns;
|
188 |
|
|
|
189 |
|
|
// Interesting corner case... what if both samps_zero and samps_one are
|
190 |
|
|
// hi? Could happen for small sample counts and reasonable values of
|
191 |
|
|
// PCT_SAMPS_SOLID. Doesn't affect samps_solid. run_polarity assignment
|
192 |
|
|
// consistently breaks tie with samps_one_r.
|
193 |
|
|
wire [SAMPCNTRWIDTH:0] samps_lo = samples + ONE[SAMPCNTRWIDTH:0] - samps_hi_r;
|
194 |
|
|
always @(*) begin
|
195 |
|
|
samps_zero_ns = samps_zero_r;
|
196 |
|
|
samps_one_ns = samps_one_r;
|
197 |
|
|
samps_zero_ns = samps_lo >= samps_solid_thresh;
|
198 |
|
|
samps_one_ns = samps_hi_r >= samps_solid_thresh;
|
199 |
|
|
end // always @ begin
|
200 |
|
|
wire new_polarity = run_polarity_ns ^ run_polarity_r;
|
201 |
|
|
|
202 |
|
|
input poc_sample_pd;
|
203 |
|
|
|
204 |
|
|
always @(*) begin
|
205 |
|
|
|
206 |
|
|
if (rst == 1'b1) begin
|
207 |
|
|
|
208 |
|
|
// RESET next states
|
209 |
|
|
psen_int = 1'b0;
|
210 |
|
|
sm_ns = /*AUTOLINK("SAMPLE")*/2'd0;
|
211 |
|
|
run_polarity_ns = 1'b0;
|
212 |
|
|
run_ns = {TAPCNTRWIDTH{1'b0}};
|
213 |
|
|
run_end_int = 1'b0;
|
214 |
|
|
samp_cntr_ns = {SAMPCNTRWIDTH{1'b0}};
|
215 |
|
|
samps_hi_ns = {SAMPCNTRWIDTH+1{1'b0}};
|
216 |
|
|
tap_ns = {TAPCNTRWIDTH{1'b0}};
|
217 |
|
|
samp_wait_ns = MMCM_SAMP_WAIT[SAMP_WAIT_WIDTH-1:0];
|
218 |
|
|
samps_hi_held_ns = {SAMPCNTRWIDTH+1{1'b0}};
|
219 |
|
|
end else begin
|
220 |
|
|
|
221 |
|
|
// Default next states;
|
222 |
|
|
psen_int = 1'b0;
|
223 |
|
|
sm_ns = sm_r;
|
224 |
|
|
run_polarity_ns = run_polarity_r;
|
225 |
|
|
run_ns = run_r;
|
226 |
|
|
run_end_int = 1'b0;
|
227 |
|
|
samp_cntr_ns = samp_cntr_r;
|
228 |
|
|
samps_hi_ns = samps_hi_r;
|
229 |
|
|
tap_ns = tap_r;
|
230 |
|
|
samp_wait_ns = samp_wait_r;
|
231 |
|
|
if (|samp_wait_r) samp_wait_ns = samp_wait_r - ONE[SAMP_WAIT_WIDTH-1:0];
|
232 |
|
|
samps_hi_held_ns = samps_hi_held_r;
|
233 |
|
|
|
234 |
|
|
// State based actions and next states.
|
235 |
|
|
case (sm_r)
|
236 |
|
|
/*AL("SAMPLE")*/2'd0: begin
|
237 |
|
|
if (~|samp_wait_r && poc_sample_pd | POC_USE_METASTABLE_SAMP == "TRUE") begin
|
238 |
|
|
if (POC_USE_METASTABLE_SAMP == "TRUE") samp_wait_ns = ONE[SAMP_WAIT_WIDTH-1:0];
|
239 |
|
|
if ({1'b0, samp_cntr_r} == samples) sm_ns = /*AK("COMPUTE")*/2'd1;
|
240 |
|
|
samps_hi_ns = samps_hi_r + {{SAMPCNTRWIDTH{1'b0}}, pd_out_sel};
|
241 |
|
|
samp_cntr_ns = samp_cntr_r + ONE[SAMPCNTRWIDTH-1:0];
|
242 |
|
|
end
|
243 |
|
|
end
|
244 |
|
|
|
245 |
|
|
/*AL("COMPUTE")*/2'd1:begin
|
246 |
|
|
sm_ns = /*AK("PSEN")*/2'd2;
|
247 |
|
|
end
|
248 |
|
|
|
249 |
|
|
/*AL("PSEN")*/2'd2:begin
|
250 |
|
|
sm_ns = /*AK("PSDONE_WAIT")*/2'd3;
|
251 |
|
|
psen_int = 1'b1;
|
252 |
|
|
samp_cntr_ns = {SAMPCNTRWIDTH{1'b0}};
|
253 |
|
|
samps_hi_ns = {SAMPCNTRWIDTH+1{1'b0}};
|
254 |
|
|
samps_hi_held_ns = samps_hi_r;
|
255 |
|
|
tap_ns = (tap_r < TAPSPERKCLK[TAPCNTRWIDTH-1:0] - ONE[TAPCNTRWIDTH-1:0])
|
256 |
|
|
? tap_r + ONE[TAPCNTRWIDTH-1:0]
|
257 |
|
|
: {TAPCNTRWIDTH{1'b0}};
|
258 |
|
|
|
259 |
|
|
if (run_polarity_r) begin
|
260 |
|
|
if (samps_zero_r) run_polarity_ns = 1'b0;
|
261 |
|
|
end else begin
|
262 |
|
|
if (samps_one_r) run_polarity_ns = 1'b1;
|
263 |
|
|
end
|
264 |
|
|
if (new_polarity) begin
|
265 |
|
|
run_ns ={TAPCNTRWIDTH{1'b0}};
|
266 |
|
|
run_end_int = 1'b1;
|
267 |
|
|
end else run_ns = run_r + ONE[TAPCNTRWIDTH-1:0];
|
268 |
|
|
end
|
269 |
|
|
|
270 |
|
|
/*AL("PSDONE_WAIT")*/2'd3:begin
|
271 |
|
|
samp_wait_ns = MMCM_SAMP_WAIT[SAMP_WAIT_WIDTH-1:0] - ONE[SAMP_WAIT_WIDTH-1:0];
|
272 |
|
|
if (psdone) sm_ns = /*AK("SAMPLE")*/2'd0;
|
273 |
|
|
end
|
274 |
|
|
|
275 |
|
|
endcase // case (sm_r)
|
276 |
|
|
end // else: !if(rst == 1'b1)
|
277 |
|
|
end // always @ (*)
|
278 |
|
|
|
279 |
|
|
endmodule // mig_7series_v2_3_poc_tap_base
|
280 |
|
|
|
281 |
|
|
// Local Variables:
|
282 |
|
|
// verilog-library-directories:(".")
|
283 |
|
|
// verilog-library-extensions:(".v")
|
284 |
|
|
// verilog-autolabel-prefix: "2'd"
|
285 |
|
|
// End:
|