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.18/] [memfifo.srcs/] [sources_1/] [ip/] [mig_7series_0/] [mig_7series_0/] [user_design/] [rtl/] [phy/] [mig_7series_v2_3_poc_tap_base.v] - Rev 2
Compare with Previous | Blame | View Log
//***************************************************************************** // (c) Copyright 2009 - 2012 Xilinx, Inc. All rights reserved. // // This file contains confidential and proprietary information // of Xilinx, Inc. and is protected under U.S. and // international copyright and other intellectual property // laws. // // DISCLAIMER // This disclaimer is not a license and does not grant any // rights to the materials distributed herewith. Except as // otherwise provided in a valid license issued to you by // Xilinx, and to the maximum extent permitted by applicable // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and // (2) Xilinx shall not be liable (whether in contract or tort, // including negligence, or under any other theory of // liability) for any loss or damage of any kind or nature // related to, arising under or in connection with these // materials, including for any direct, or any indirect, // special, incidental, or consequential loss or damage // (including loss of data, profits, goodwill, or any type of // loss or damage suffered as a result of any action brought // by a third party) even if such damage or loss was // reasonably foreseeable or Xilinx had been advised of the // possibility of the same. // // CRITICAL APPLICATIONS // Xilinx products are not designed or intended to be fail- // safe, or for use in any application requiring fail-safe // performance, such as life-support or safety devices or // systems, Class III medical devices, nuclear facilities, // applications related to the deployment of airbags, or any // other applications that could lead to death, personal // injury, or severe property or environmental damage // (individually and collectively, "Critical // Applications"). Customer assumes the sole risk and // liability of any use of Xilinx products in Critical // Applications, subject only to applicable laws and // regulations governing limitations on product liability. // // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS // PART OF THIS FILE AT ALL TIMES. // //***************************************************************************** // ____ ____ // / /\/ / // /___/ \ / Vendor: Xilinx // \ \ \/ Version:%version // \ \ Application: MIG // / / Filename: mig_7series_v2_3_poc_tap_base.v // /___/ /\ Date Last Modified: $$ // \ \ / \ Date Created:Tue 15 Jan 2014 // \___\/\___\ // //Device: Virtex-7 //Design Name: DDR3 SDRAM //Purpose: All your taps are belong to us. // //In general, this block should be able to start up with a random initialization of //the various counters. But its probably easier, more normative and quicker time to solution //to just initialize to zero with rst. // // Following deassertion of reset, endlessly increments the MMCM delay with PSEN. For // each MMCM tap it samples the phase detector output a programmable number of times. // When the sampling count is achieved, PSEN is pulsed and sampling of the next MMCM // tap begins. // // Following a PSEN, sampling pauses for MMCM_SAMP_WAIT clocks. This is workaround // for a bug in the MMCM where its output may have noise for a period following // the PSEN. // // Samples are taken every other fabric clock. This is because the MMCM phase shift // clock operates at half the fabric clock. The reason for this is unknown. // // At the end of the sampling period, a filtering step is implemented. samps_solid_thresh // is the minumum number of samples that must be seen to declare a solid zero or one. If // neithr the one and zero samples cross this threshold, then the sampple is declared fuzz. // // A "run_polarity" bit is maintained. It is set appropriately whenever a solid sample // is observed. // // A "run" counter is maintained. If the current sample is fuzz, or opposite polarity // from a previous sample, then the run counter is reset. If the current sample is the // same polarity run_polarity, then the run counter is incremented. // // If a run_polarity reversal or fuzz is observed and the run counter is not zero // then the run_end strobe is pulsed. // //Reference: //Revision History: //***************************************************************************** `timescale 1 ps / 1 ps module mig_7series_v2_3_poc_tap_base # (parameter MMCM_SAMP_WAIT = 10, parameter POC_USE_METASTABLE_SAMP = "FALSE", parameter TCQ = 100, parameter SAMPCNTRWIDTH = 8, parameter TAPCNTRWIDTH = 7, parameter TAPSPERKCLK = 112) (/*AUTOARG*/ // Outputs psincdec, psen, run, run_end, run_polarity, samps_hi_held, tap, // Inputs pd_out, clk, samples, samps_solid_thresh, psdone, rst, poc_sample_pd ); function integer clogb2 (input integer size); // ceiling logb2 begin size = size - 1; for (clogb2=1; size>1; clogb2=clogb2+1) size = size >> 1; end endfunction // clogb2 input pd_out; input clk; input [SAMPCNTRWIDTH:0] samples, samps_solid_thresh; input psdone; input rst; localparam ONE = 1; localparam SAMP_WAIT_WIDTH = clogb2(MMCM_SAMP_WAIT); reg [SAMP_WAIT_WIDTH-1:0] samp_wait_ns, samp_wait_r; always @(posedge clk) samp_wait_r <= #TCQ samp_wait_ns; reg pd_out_r; always @(posedge clk) pd_out_r <= #TCQ pd_out; wire pd_out_sel = POC_USE_METASTABLE_SAMP == "TRUE" ? pd_out_r : pd_out; output psincdec; assign psincdec = 1'b1; output psen; reg psen_int; assign psen = psen_int; reg [TAPCNTRWIDTH-1:0] run_r; reg [TAPCNTRWIDTH-1:0] run_ns; always @(posedge clk) run_r <= #TCQ run_ns; output [TAPCNTRWIDTH-1:0] run; assign run = run_r; output run_end; reg run_end_int; assign run_end = run_end_int; reg run_polarity_r; reg run_polarity_ns; always @(posedge clk) run_polarity_r <= #TCQ run_polarity_ns; output run_polarity; assign run_polarity = run_polarity_r; reg [SAMPCNTRWIDTH-1:0] samp_cntr_r; reg [SAMPCNTRWIDTH-1:0] samp_cntr_ns; always @(posedge clk) samp_cntr_r <= #TCQ samp_cntr_ns; reg [SAMPCNTRWIDTH:0] samps_hi_r; reg [SAMPCNTRWIDTH:0] samps_hi_ns; always @(posedge clk) samps_hi_r <= #TCQ samps_hi_ns; reg [SAMPCNTRWIDTH:0] samps_hi_held_r; reg [SAMPCNTRWIDTH:0] samps_hi_held_ns; always @(posedge clk) samps_hi_held_r <= #TCQ samps_hi_held_ns; output [SAMPCNTRWIDTH:0] samps_hi_held; assign samps_hi_held = samps_hi_held_r; reg [TAPCNTRWIDTH-1:0] tap_ns, tap_r; always @(posedge clk) tap_r <= #TCQ tap_ns; output [TAPCNTRWIDTH-1:0] tap; assign tap = tap_r; localparam SMWIDTH = 2; reg [SMWIDTH-1:0] sm_ns; reg [SMWIDTH-1:0] sm_r; always @(posedge clk) sm_r <= #TCQ sm_ns; reg samps_zero_ns, samps_zero_r, samps_one_ns, samps_one_r; always @(posedge clk) samps_zero_r <= #TCQ samps_zero_ns; always @(posedge clk)samps_one_r <= #TCQ samps_one_ns; // Interesting corner case... what if both samps_zero and samps_one are // hi? Could happen for small sample counts and reasonable values of // PCT_SAMPS_SOLID. Doesn't affect samps_solid. run_polarity assignment // consistently breaks tie with samps_one_r. wire [SAMPCNTRWIDTH:0] samps_lo = samples + ONE[SAMPCNTRWIDTH:0] - samps_hi_r; always @(*) begin samps_zero_ns = samps_zero_r; samps_one_ns = samps_one_r; samps_zero_ns = samps_lo >= samps_solid_thresh; samps_one_ns = samps_hi_r >= samps_solid_thresh; end // always @ begin wire new_polarity = run_polarity_ns ^ run_polarity_r; input poc_sample_pd; always @(*) begin if (rst == 1'b1) begin // RESET next states psen_int = 1'b0; sm_ns = /*AUTOLINK("SAMPLE")*/2'd0; run_polarity_ns = 1'b0; run_ns = {TAPCNTRWIDTH{1'b0}}; run_end_int = 1'b0; samp_cntr_ns = {SAMPCNTRWIDTH{1'b0}}; samps_hi_ns = {SAMPCNTRWIDTH+1{1'b0}}; tap_ns = {TAPCNTRWIDTH{1'b0}}; samp_wait_ns = MMCM_SAMP_WAIT[SAMP_WAIT_WIDTH-1:0]; samps_hi_held_ns = {SAMPCNTRWIDTH+1{1'b0}}; end else begin // Default next states; psen_int = 1'b0; sm_ns = sm_r; run_polarity_ns = run_polarity_r; run_ns = run_r; run_end_int = 1'b0; samp_cntr_ns = samp_cntr_r; samps_hi_ns = samps_hi_r; tap_ns = tap_r; samp_wait_ns = samp_wait_r; if (|samp_wait_r) samp_wait_ns = samp_wait_r - ONE[SAMP_WAIT_WIDTH-1:0]; samps_hi_held_ns = samps_hi_held_r; // State based actions and next states. case (sm_r) /*AL("SAMPLE")*/2'd0: begin if (~|samp_wait_r && poc_sample_pd | POC_USE_METASTABLE_SAMP == "TRUE") begin if (POC_USE_METASTABLE_SAMP == "TRUE") samp_wait_ns = ONE[SAMP_WAIT_WIDTH-1:0]; if ({1'b0, samp_cntr_r} == samples) sm_ns = /*AK("COMPUTE")*/2'd1; samps_hi_ns = samps_hi_r + {{SAMPCNTRWIDTH{1'b0}}, pd_out_sel}; samp_cntr_ns = samp_cntr_r + ONE[SAMPCNTRWIDTH-1:0]; end end /*AL("COMPUTE")*/2'd1:begin sm_ns = /*AK("PSEN")*/2'd2; end /*AL("PSEN")*/2'd2:begin sm_ns = /*AK("PSDONE_WAIT")*/2'd3; psen_int = 1'b1; samp_cntr_ns = {SAMPCNTRWIDTH{1'b0}}; samps_hi_ns = {SAMPCNTRWIDTH+1{1'b0}}; samps_hi_held_ns = samps_hi_r; tap_ns = (tap_r < TAPSPERKCLK[TAPCNTRWIDTH-1:0] - ONE[TAPCNTRWIDTH-1:0]) ? tap_r + ONE[TAPCNTRWIDTH-1:0] : {TAPCNTRWIDTH{1'b0}}; if (run_polarity_r) begin if (samps_zero_r) run_polarity_ns = 1'b0; end else begin if (samps_one_r) run_polarity_ns = 1'b1; end if (new_polarity) begin run_ns ={TAPCNTRWIDTH{1'b0}}; run_end_int = 1'b1; end else run_ns = run_r + ONE[TAPCNTRWIDTH-1:0]; end /*AL("PSDONE_WAIT")*/2'd3:begin samp_wait_ns = MMCM_SAMP_WAIT[SAMP_WAIT_WIDTH-1:0] - ONE[SAMP_WAIT_WIDTH-1:0]; if (psdone) sm_ns = /*AK("SAMPLE")*/2'd0; end endcase // case (sm_r) end // else: !if(rst == 1'b1) end // always @ (*) endmodule // mig_7series_v2_3_poc_tap_base // Local Variables: // verilog-library-directories:(".") // verilog-library-extensions:(".v") // verilog-autolabel-prefix: "2'd" // End: