⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oversample_8x.v

📁 使用IDELAY实现8倍过采样异步串行信号恢复信号
💻 V
字号:
//------------------------------------------------------------------------------ 
// Copyright (c) 2006 Xilinx, Inc. 
// All Rights Reserved 
//------------------------------------------------------------------------------ 
//   ____  ____ 
//  /   /\/   / 
// /___/  \  /   Vendor: Xilinx 
// \   \   \/    Author: John F. Snow, Advanced Product Division, Xilinx, Inc.
//  \   \        Filename: $RCSfile: oversample_8x.v,rcs $
//  /   /        Date Last Modified:  $Date: 2006-09-22 14:00:22-06 $
// /___/   /\    Date Created: Jan 13, 2006 
// \   \  /  \ 
//  \___\/\___\ 
// 
//
// Revision History: 
// $Log: oversample_8x.v,rcs $
// Revision 1.0  2006-09-22 14:00:22-06  jsnow
// Initial release.
//
//------------------------------------------------------------------------------ 
//
//     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
//     SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
//     XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
//     AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
//     OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
//     IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
//     AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
//     FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
//     WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
//     IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
//     REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
//     INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//     FOR A PARTICULAR PURPOSE.
//
//------------------------------------------------------------------------------ 
//
// This is a single channel 8X oversampling data recovery unit using bit-rate
// clocks. It requires two phases of a clock running at the bit rate and uses 
// two IDELAY primitives to provide the 45 degree phase shifting of the serial 
// data.
//
//------------------------------------------------------------------------------
module oversample_8x (
    input   wire        clk0,           // bit rate clock
    input   wire        clk90,          // clk0 shifted 90 degrees
    input   wire        PAD_din_p,      // serial input data
    input   wire        PAD_din_n,      // inverted serial input data
    output  reg         dout_rdy,       // output data ready
    output  reg  [19:0] dout);          // output data

parameter IDELAY_45_DEGREES     = 6;    // Specifies the delay for a
                                        // 1/8 bit delay with IDELAY.
                                        // 6 is correct value for 270 Mb/s.

//-----------------------------------------------------------------------------
// Signal definitions
//
wire            sdata_in;           // true output of IBUFDS_DIFF_OUT
wire            sdata_inb;          // complementary output of IBUFDS_DIFF_OUT
wire            sdat_0_dly;         // 0 degree data from IDELAY
wire            sdatb_45_dly;       // 45 degree data from IDELAY
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            a1, a2, a3;         // 0 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            b1, b2, b3;         // 45 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            c1, c2, c3;         // 90 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            d1, d2, d3;         // 135 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            e1, e2, e3;         // 180 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            f1, f2, f3;         // 225 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            g1, g2, g3;         // 270 degree capture pipeline
(* EQUIVALENT_REGISTER_REMOVAL = "NO" *)
(* SHREG_EXTRACT = "NO" *)
wire            h1, h2, h3;         // 315 degree capture pipeline
wire [7:0]      instage_dout;       // 8X oversampled data from input stage
reg  [7:0]      samples_0 = 8'b0;   // used to make 20-bit dout vector
reg  [7:0]      samples_1 = 8'b0;   // used to make 20-bit dout vector
reg  [7:0]      samples_2 = 8'b0;   // used to make 20-bit dout vector
(* KEEP = "TRUE" *)
reg  [4:0]      period = 5'b00001;  // sequencer for 20-bit vector creation 

//
// The IBUFDS_DIFF_OUT primitive provides both true and complementary outputs
// of an LVDS input pair.
//
(* DIFF_TERM = "TRUE" *)
IBUFDS_DIFF_OUT # (
    .IOSTANDARD ("LVDS_25"))
IBUFSDI (                    
    .I          (PAD_din_p),
    .IB         (PAD_din_n),
    .O          (sdata_in),
    .OB         (sdata_inb));

//
// IDELAY primitives
//
// Two IDELAY primitives are used to create two phases of the data, one delayed
// 45 degrees relative to the other. Note that IDELAY block with 0 delay
// actually provides the data delayed by 45 degrees relative to the output
// of the other IDELAY block because the IDELAY primitive with the higher
// delay is providing older data. Also note that the 45 degree delayed data
// is inverted. This inversion is correct at the output of this module.
//
IDELAY #(
    .IOBDELAY_TYPE  ("FIXED"),
    .IOBDELAY_VALUE (IDELAY_45_DEGREES))
IDLY (
    .O      (sdat_0_dly),
    .C      (1'b0),
    .CE     (1'b0),
    .I      (sdata_in),
    .INC    (1'b0),
    .RST    (1'b0));

IDELAY #(
    .IOBDELAY_TYPE  ("FIXED"),
    .IOBDELAY_VALUE (0))
IDLYB (
    .O      (sdatb_45_dly),
    .C      (1'b0),
    .CE     (1'b0),
    .I      (sdata_inb),
    .INC    (1'b0),
    .RST    (1'b0));

//
// Data capture flip flops
//
// These FFs sample the data and transfer all samples into a common clock 
// domain -- the rising edge of the clk0 phase.
//
// All FFs are instantiated as FF primitives so that they can be easily RLOCed
// relative to each other to keep routing delay and skew to a minimum.
//

//
// These 3 FFs provide the 0 degree sample point.
//
(* RLOC = "X1Y1" *)
(* IOB = "FALSE" *)
FDCPE a1FF (    
    .Q          (a1),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdat_0_dly),
    .PRE        (1'b0));
    
FDCPE a2FF (    
    .Q          (a2),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (a1),
    .PRE        (1'b0));

FDCPE a3FF (    
    .Q          (a3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (a2),
    .PRE        (1'b0));

// 
// These 3 FFs provide the 45 degree sample point.
//
(* RLOC = "X1Y1" *)
(* IOB = "FALSE" *)
FDCPE b1FF (    
    .Q          (b1),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdatb_45_dly),
    .PRE        (1'b0));
    
FDCPE b2FF (    
    .Q          (b2),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (b1),
    .PRE        (1'b0));

FDCPE b3FF (    
    .Q          (b3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (b2),
    .PRE        (1'b0));

//
// These 3 FFs provide the 90 degree sample point.
//
(* RLOC = "X1Y0" *)
(* IOB = "FALSE" *)
FDCPE c1FF (    
    .Q          (c1),
    .C          (clk90),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdat_0_dly),
    .PRE        (1'b0));
    
FDCPE c2FF (    
    .Q          (c2),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (c1),
    .PRE        (1'b0));

FDCPE c3FF (    
    .Q          (c3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (c2),
    .PRE        (1'b0));

//
// These 3 FFs provide the 135 degree sample point.
//
(* RLOC = "X1Y0" *)
(* IOB = "FALSE" *)
FDCPE d1FF (    
    .Q          (d1),
    .C          (clk90),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdatb_45_dly),
    .PRE        (1'b0));
    
FDCPE d2FF (    
    .Q          (d2),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (d1),
    .PRE        (1'b0));

FDCPE d3FF (    
    .Q          (d3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (d2),
    .PRE        (1'b0));

//
// These 3 FFs provide the 180 degree sample point.
//
(* RLOC = "X0Y1" *)
(* IOB = "FALSE" *)
FDCPE e1FF (    
    .Q          (e1),
    .C          (~clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdat_0_dly),
    .PRE        (1'b0));
    
FDCPE e2FF (    
    .Q          (e2),
    .C          (~clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (e1),
    .PRE        (1'b0));

FDCPE e3FF (    
    .Q          (e3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (e2),
    .PRE        (1'b0));

//
// These 3 FFs provide the 225 degree sample point.
//
(* RLOC = "X0Y1" *)
(* IOB = "FALSE" *)
FDCPE f1FF (    
    .Q          (f1),
    .C          (~clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdatb_45_dly),
    .PRE        (1'b0));
    
FDCPE f2FF (    
    .Q          (f2),
    .C          (~clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (f1),
    .PRE        (1'b0));

FDCPE f3FF (    
    .Q          (f3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (f2),
    .PRE        (1'b0));

//
// These 3 FFs provide the 270 degree sample point.
//
(* RLOC = "X0Y0" *)
(* IOB = "FALSE" *)
FDCPE g1FF (    
    .Q          (g1),
    .C          (~clk90),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdat_0_dly),
    .PRE        (1'b0));
    
FDCPE g2FF (    
    .Q          (g2),
    .C          (~clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (g1),
    .PRE        (1'b0));

FDCPE g3FF (    
    .Q          (g3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (g2),
    .PRE        (1'b0));

// 
// These 3 FFs provide the 315 degree sample point.
//
(* RLOC = "X0Y0" *)
(* IOB = "FALSE" *)
FDCPE h1FF (    
    .Q          (h1),
    .C          (~clk90),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (sdatb_45_dly),
    .PRE        (1'b0));
    
FDCPE h2FF (    
    .Q          (h2),
    .C          (~clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (h1),
    .PRE        (1'b0));

FDCPE h3FF (    
    .Q          (h3),
    .C          (clk0),
    .CE         (1'b1),
    .CLR        (1'b0),
    .D          (h2),
    .PRE        (1'b0));

// 
// Input stage vector assignment. All samples created from the 45 degree data 
// must be inverted to compensate for the fact that the 45 degree data is 
// inverted.
//
assign instage_dout = {~h3, g3, ~f3, e3, ~d3, c3, ~b3, a3};
                                                                                                                                        
//
// 8-bit to 20-bit conversion
//
// This logic takes the 8 samples produced by the input stage every rising edge
// of clk0 and saves up 5 consecutive sets of these samples to create two
// 20-bit sample output vectors.
//

always @ (posedge clk0)
    period <= {period[3:0], period[4]};
    
always @ (posedge clk0)
    if (period[0] | period[3])
        samples_0 <= instage_dout;
        
always @ (posedge clk0)
    if (period[1] | period[4])
        samples_1 <= instage_dout;

always @ (posedge clk0)
    if (period[2])
        samples_2 <= instage_dout;

always @ (posedge clk0)
    if (period[3])
        dout <= {samples_2[3:0], samples_1, samples_0};
    else if (period[0])
        dout <= {samples_1, samples_0, samples_2[7:4]};
                   
//
// To provide the maximum amount of setup time into the DRU, the dout_rdy signal
// is asserted during the clock cycle just before dout is updated. Thus, the
// DRU takes the last data on the same clock edge on which dout is updated with
// new data.
//
always @ (posedge clk0)
    dout_rdy <= period[2] | period[4];
                                                
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -