CMOS

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
OSERDESE2为 DDR模式,修改模式为4:1 DDR模式,CLK与CLKDIV为2倍关系。

LVDS

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Xilinx原语IBUFDS、OBUFDS

IBUFDS、和OBUFDS都是差分信号缓冲器,用于不同电平接口之间的缓冲和转换。IBUFDS 用于差分输入,OBUFDS用于差分输出。

IBUFDS

在这里插入图片描述
https://docs.amd.com/r/en-US/ug953-vivado-7series-libraries/IBUFDS


//   IBUFDS    : In order to incorporate this function into the design,
//   Verilog   : the following instance declaration needs to be placed
//  instance   : in the body of the design code.  The instance name
// declaration : (IBUFDS_inst) and/or the port declarations within the
//    code     : parenthesis may be changed to properly reference and
//             : connect this function to the design.  All inputs
//             : and outputs must be connected.

//  <-----Cut code below this line---->

   // IBUFDS: Differential Input Buffer
   //         Kintex-7
   // Xilinx HDL Language Template, version 2019.1

   IBUFDS #(
      .DIFF_TERM("FALSE"),       // Differential Termination
      .IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
      .IOSTANDARD("DEFAULT")     // Specify the input I/O standard
   ) IBUFDS_inst (
      .O(O),  // Buffer output
      .I(I),  // Diff_p buffer input (connect directly to top-level port)
      .IB(IB) // Diff_n buffer input (connect directly to top-level port)
   );

   // End of IBUFDS_inst instantiation

OBUFDS

在这里插入图片描述
https://docs.amd.com/r/en-US/ug953-vivado-7series-libraries/OBUFDS

//     OBUFDS      : In order to incorporate this function into the design,
//     Verilog     : the following instance declaration needs to be placed
//    instance     : in the body of the design code.  The instance name
//   declaration   : (OBUFDS_inst) and/or the port declarations within the
//      code       : parenthesis may be changed to properly reference and
//                 : connect this function to the design.  Delete or comment
//                 : out inputs/outs that are not necessary.

//  <-----Cut code below this line---->

   // OBUFDS: Differential Output Buffer
   //         Kintex-7
   // Xilinx HDL Language Template, version 2019.1

   OBUFDS #(
      .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
      .SLEW("SLOW")           // Specify the output slew rate
   ) OBUFDS_inst (
      .O(O),     // Diff_p output (connect directly to top-level port)
      .OB(OB),   // Diff_n output (connect directly to top-level port)
      .I(I)      // Buffer input
   );

   // End of OBUFDS_inst instantiation

拓展 : IOBUFDS


//     IOBUFDS   : In order to incorporate this function into the design,
//     Verilog   : the following instance declaration needs to be placed
//    instance   : in the body of the design code.  The instance name
//   declaration : (IOBUFDS_inst) and/or the port declarations within the
//      code     : parenthesis may be changed to properly reference and
//               : connect this function to the design.  Delete or comment
//               : out inputs/outs that are not necessary.

//  <-----Cut code below this line---->

   // IOBUFDS: Differential Bi-directional Buffer
   //          Kintex-7
   // Xilinx HDL Language Template, version 2019.1

   IOBUFDS #(
      .DIFF_TERM("FALSE"),     // Differential Termination ("TRUE"/"FALSE")
      .IBUF_LOW_PWR("TRUE"),   // Low Power - "TRUE", High Performance = "FALSE" 
      .IOSTANDARD("BLVDS_25"), // Specify the I/O standard
      .SLEW("SLOW")            // Specify the output slew rate
   ) IOBUFDS_inst (
      .O(O),     // Buffer output
      .IO(IO),   // Diff_p inout (connect directly to top-level port)
      .IOB(IOB), // Diff_n inout (connect directly to top-level port)
      .I(I),     // Buffer input
      .T(T)      // 3-state enable input, high=input, low=output
   );

   // End of IOBUFDS_inst instantiation

Xilinx原语 IBUF, OBUF

IBUF

https://docs.amd.com/r/en-US/ug1344-versal-architecture-libraries/IBUF
在这里插入图片描述


// IBUF: Input Buffer
//       Versal Prime series
// Xilinx HDL Language Template, version 2024.1

IBUF IBUF_inst (
   .O(O), // 1-bit output: Buffer output
   .I(I)  // 1-bit input: Buffer input
);

// End of IBUF_inst instantiation

OBUF

https://docs.amd.com/r/en-US/ug1344-versal-architecture-libraries/OBUF
在这里插入图片描述


// OBUF: Output Buffer
//       Versal Prime series
// Xilinx HDL Language Template, version 2024.1

OBUF OBUF_inst (
   .O(O), // 1-bit output: Buffer output (connect directly to top-level port)
   .I(I)  // 1-bit input: Buffer input
);

// End of OBUF_inst instantiation

Xilinx原语 IBUFG

IBUFG 通过外部引脚驱动全局时钟网络。
BUFG 通过内部信号驱动全局时钟网络。

Xilinx原语 BUFG,BUFIO,BUFR

BUFG

https://docs.amd.com/r/en-US/ug953-vivado-7series-libraries/BUFG

全局缓冲, BUFG 的输出到达 FPGA 内部的 IOB、 CLB、块 RAM 的时钟延迟和抖动最小.

在这里插入图片描述


// BUFG: Global Clock Simple Buffer
//       7 Series
// Xilinx HDL Language Template, version 2024.1

BUFG BUFG_inst (
   .O(O), // 1-bit output: Clock output
   .I(I)  // 1-bit input: Clock input
);

// End of BUFG_inst instantiation

BUFIO

https://docs.amd.com/r/en-US/ug953-vivado-7series-libraries/BUFIO

BUFIO 是 IO 时钟网络,其独立于全局时钟资源,适合采集源同步数据。它只能驱动 IO Block里面的逻辑,不能驱动 CLB 里面的 LUT, REG 等逻辑。

BUFIO 在采集源同步 IO 数据时,提供非常小的延时。但是不能驱动FPGA的内部逻辑,需要BUFIO和BUFG搭配起来使用以实现最佳的性能。
在这里插入图片描述


// BUFIO: Local Clock Buffer for I/O
//        7 Series
// Xilinx HDL Language Template, version 2024.1

BUFIO BUFIO_inst (
   .O(O), // 1-bit output: Clock output (connect to I/O clock loads).
   .I(I)  // 1-bit input: Clock input (connect to an IBUF or BUFMR).
);

// End of BUFIO_inst instantiation

BUFR

BUFR 是 regional 时钟网络,它的驱动范围只能局限在一个 clock region 的逻辑。 BUFR 相比 BUFG 的最大优势是偏斜和功耗都比较小。
https://docs.amd.com/r/en-US/ug953-vivado-7series-libraries/BUFR


// BUFR: Regional Clock Buffer for I/O and Logic Resources within a Clock Region
//       7 Series
// Xilinx HDL Language Template, version 2024.1

BUFR #(
   .BUFR_DIVIDE("BYPASS"),   // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
   .SIM_DEVICE("7SERIES")  // Must be set to "7SERIES"
)
BUFR_inst (
   .O(O),     // 1-bit output: Clock output port
   .CE(CE),   // 1-bit input: Active high, clock enable (Divided modes only)
   .CLR(CLR), // 1-bit input: Active high, asynchronous clear (Divided modes only)
   .I(I)      // 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);

// End of BUFR_inst instantiation

Xilinx原语 ISERDESE2,OSERDESE2

ISERDESE2

Primitive: Input SERial/DESerializer with Bitslip
在这里插入图片描述


// ISERDESE2: Input SERial/DESerializer with Bitslip
//            7 Series
// Xilinx HDL Language Template, version 2024.1

ISERDESE2 #(
   .DATA_RATE("DDR"),           // DDR, SDR
   .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)
   .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)
   .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)
   // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
   .INIT_Q1(1'b0),
   .INIT_Q2(1'b0),
   .INIT_Q3(1'b0),
   .INIT_Q4(1'b0),
   .INTERFACE_TYPE("MEMORY"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE
   .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD
   .NUM_CE(2),                  // Number of clock enables (1,2)
   .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)
   .SERDES_MODE("MASTER"),      // MASTER, SLAVE
   // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)
   .SRVAL_Q1(1'b0),
   .SRVAL_Q2(1'b0),
   .SRVAL_Q3(1'b0),
   .SRVAL_Q4(1'b0)
)
ISERDESE2_inst (
   .O(O),                       // 1-bit output: Combinatorial output
   // Q1 - Q8: 1-bit (each) output: Registered data outputs
   .Q1(Q1),
   .Q2(Q2),
   .Q3(Q3),
   .Q4(Q4),
   .Q5(Q5),
   .Q6(Q6),
   .Q7(Q7),
   .Q8(Q8),
   // SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
   .SHIFTOUT1(SHIFTOUT1),
   .SHIFTOUT2(SHIFTOUT2),
   .BITSLIP(BITSLIP),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to
                                // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1
                                // to Q8 output ports will shift, as in a barrel-shifter operation, one
                                // position every time Bitslip is invoked (DDR operation is different from
                                // SDR).

   // CE1, CE2: 1-bit (each) input: Data register clock enable inputs
   .CE1(CE1),
   .CE2(CE2),
   .CLKDIVP(CLKDIVP),           // 1-bit input: TBD
   // Clocks: 1-bit (each) input: ISERDESE2 clock input ports
   .CLK(CLK),                   // 1-bit input: High-speed clock
   .CLKB(CLKB),                 // 1-bit input: High-speed secondary clock
   .CLKDIV(CLKDIV),             // 1-bit input: Divided clock
   .OCLK(OCLK),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY"
   // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity
   .DYNCLKDIVSEL(DYNCLKDIVSEL), // 1-bit input: Dynamic CLKDIV inversion
   .DYNCLKSEL(DYNCLKSEL),       // 1-bit input: Dynamic CLK/CLKB inversion
   // Input Data: 1-bit (each) input: ISERDESE2 data input ports
   .D(D),                       // 1-bit input: Data input
   .DDLY(DDLY),                 // 1-bit input: Serial data from IDELAYE2
   .OFB(OFB),                   // 1-bit input: Data feedback from OSERDESE2
   .OCLKB(OCLKB),               // 1-bit input: High speed negative edge output clock
   .RST(RST),                   // 1-bit input: Active high asynchronous reset
   // SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
   .SHIFTIN1(SHIFTIN1),
   .SHIFTIN2(SHIFTIN2)
);

// End of ISERDESE2_inst instantiation

OSERDESE2

7系列FPGA器件中的专用并串转换器。

Primitive: Output SERial/DESerializer with bitslip

在这里插入图片描述


// OSERDESE2: Output SERial/DESerializer with bitslip
//            7 Series
// Xilinx HDL Language Template, version 2024.1

OSERDESE2 #(
   .DATA_RATE_OQ("DDR"),   // DDR, SDR
   .DATA_RATE_TQ("DDR"),   // DDR, BUF, SDR
   .DATA_WIDTH(4),         // Parallel data width (2-8,10,14)
   .INIT_OQ(1'b0),         // Initial value of OQ output (1'b0,1'b1)
   .INIT_TQ(1'b0),         // Initial value of TQ output (1'b0,1'b1)
   .SERDES_MODE("MASTER"), // MASTER, SLAVE
   .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
   .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
   .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
   .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
   .TRISTATE_WIDTH(4)      // 3-state converter width (1,4)
)
OSERDESE2_inst (
   .OFB(OFB),             // 1-bit output: Feedback path for data
   .OQ(OQ),               // 1-bit output: Data path output
   // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
   .SHIFTOUT1(SHIFTOUT1),
   .SHIFTOUT2(SHIFTOUT2),
   .TBYTEOUT(TBYTEOUT),   // 1-bit output: Byte group tristate
   .TFB(TFB),             // 1-bit output: 3-state control
   .TQ(TQ),               // 1-bit output: 3-state control
   .CLK(CLK),             // 1-bit input: High speed clock
   .CLKDIV(CLKDIV),       // 1-bit input: Divided clock
   // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
   .D1(D1),
   .D2(D2),
   .D3(D3),
   .D4(D4),
   .D5(D5),
   .D6(D6),
   .D7(D7),
   .D8(D8),
   .OCE(OCE),             // 1-bit input: Output data clock enable
   .RST(RST),             // 1-bit input: Reset
   // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
   .SHIFTIN1(SHIFTIN1),
   .SHIFTIN2(SHIFTIN2),
   // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
   .T1(T1),
   .T2(T2),
   .T3(T3),
   .T4(T4),
   .TBYTEIN(TBYTEIN),     // 1-bit input: Byte group tristate
   .TCE(TCE)              // 1-bit input: 3-state clock enable
);

// End of OSERDESE2_inst instantiation

ad_data_clk

// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsibilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
//   1. The GNU General Public License version 2 as published by the
//      Free Software Foundation, which can be found in the top level directory
//      of this repository (LICENSE_GPL2), and also online at:
//      <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
//   2. An ADI specific BSD license, which can be found in the top level directory
//      of this repository (LICENSE_ADIBSD), and also on-line at:
//      https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
//      This will allow to generate bit files and not release the source code,
//      as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************

`timescale 1ns/100ps

module ad_data_clk #(

  parameter   SINGLE_ENDED = 0) (

  input               rst,
  output              locked,

  input               clk_in_p,
  input               clk_in_n,
  output              clk);

  // internal signals

  wire                clk_ibuf_s;

  // defaults

  assign locked = 1'b1;

  // instantiations

  generate
  if (SINGLE_ENDED == 1) begin
  IBUFG i_rx_clk_ibuf (
    .I (clk_in_p),
    .O (clk_ibuf_s));
  end else begin
  IBUFGDS i_rx_clk_ibuf (
    .I (clk_in_p),
    .IB (clk_in_n),
    .O (clk_ibuf_s));
  end
  endgenerate

  BUFG i_clk_gbuf (
    .I (clk_ibuf_s),
    .O (clk));

endmodule

// ***************************************************************************
// ***************************************************************************

ad_data_in

// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsibilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
//   1. The GNU General Public License version 2 as published by the
//      Free Software Foundation, which can be found in the top level directory
//      of this repository (LICENSE_GPL2), and also online at:
//      <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
//   2. An ADI specific BSD license, which can be found in the top level directory
//      of this repository (LICENSE_ADIBSD), and also on-line at:
//      https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
//      This will allow to generate bit files and not release the source code,
//      as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************

`timescale 1ns/100ps

module ad_data_in #(

  // parameters

  parameter   SINGLE_ENDED = 0,
  parameter   FPGA_TECHNOLOGY = 0,
  parameter   IODELAY_ENABLE = 1,
  parameter   IODELAY_CTRL = 0,
  parameter   IODELAY_GROUP = "dev_if_delay_group",
  parameter   REFCLK_FREQUENCY = 200) (

  // data interface

  input               rx_clk,
  input               rx_data_in_p,
  input               rx_data_in_n,
  output              rx_data_p,
  output              rx_data_n,

  // delay-data interface

  input               up_clk,
  input               up_dld,
  input       [ 4:0]  up_dwdata,
  output      [ 4:0]  up_drdata,

  // delay-cntrl interface

  input               delay_clk,
  input               delay_rst,
  output              delay_locked);

  // internal parameters

  localparam  NONE = -1;
  localparam  SEVEN_SERIES = 1;
  localparam  ULTRASCALE = 2;
  localparam  ULTRASCALE_PLUS = 3;

  localparam  IODELAY_CTRL_ENABLED = (IODELAY_ENABLE == 1) ? IODELAY_CTRL : 0;
  localparam  IODELAY_CTRL_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE" :
    (FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";

  localparam  IODELAY_FPGA_TECHNOLOGY = (IODELAY_ENABLE == 1) ? FPGA_TECHNOLOGY : NONE;
  localparam  IODELAY_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE_PLUS" :
    (FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";

  // internal signals

  wire                rx_data_ibuf_s;
  wire                rx_data_idelay_s;
  wire        [ 8:0]  up_drdata_s;

  // delay controller

  generate
  if (IODELAY_CTRL_ENABLED == 0) begin
  assign delay_locked = 1'b1;
  end else begin
  (* IODELAY_GROUP = IODELAY_GROUP *)
  IDELAYCTRL #(.SIM_DEVICE (IODELAY_CTRL_SIM_DEVICE)) i_delay_ctrl (
    .RST (delay_rst),
    .REFCLK (delay_clk),
    .RDY (delay_locked));
  end
  endgenerate

  // receive data interface, ibuf -> idelay -> iddr

  generate
  if (SINGLE_ENDED == 1) begin
  IBUF i_rx_data_ibuf (
    .I (rx_data_in_p),
    .O (rx_data_ibuf_s));
  end else begin
  IBUFDS i_rx_data_ibuf (
    .I (rx_data_in_p),
    .IB (rx_data_in_n),
    .O (rx_data_ibuf_s));
  end
  endgenerate

  // idelay

  generate
  if (IODELAY_FPGA_TECHNOLOGY == SEVEN_SERIES) begin
  (* IODELAY_GROUP = IODELAY_GROUP *)
  IDELAYE2 #(
    .CINVCTRL_SEL ("FALSE"),
    .DELAY_SRC ("IDATAIN"),
    .HIGH_PERFORMANCE_MODE ("FALSE"),
    .IDELAY_TYPE ("VAR_LOAD"),
    .IDELAY_VALUE (0),
    .REFCLK_FREQUENCY (REFCLK_FREQUENCY),
    .PIPE_SEL ("FALSE"),
    .SIGNAL_PATTERN ("DATA"))
  i_rx_data_idelay (
    .CE (1'b0),
    .INC (1'b0),
    .DATAIN (1'b0),
    .LDPIPEEN (1'b0),
    .CINVCTRL (1'b0),
    .REGRST (1'b0),
    .C (up_clk),
    .IDATAIN (rx_data_ibuf_s),
    .DATAOUT (rx_data_idelay_s),
    .LD (up_dld),
    .CNTVALUEIN (up_dwdata),
    .CNTVALUEOUT (up_drdata));
  end
  endgenerate

  generate
  if ((IODELAY_FPGA_TECHNOLOGY == ULTRASCALE) || (IODELAY_FPGA_TECHNOLOGY == ULTRASCALE_PLUS)) begin
  assign up_drdata = up_drdata_s[8:4];
  (* IODELAY_GROUP = IODELAY_GROUP *)
  IDELAYE3 #(
    .SIM_DEVICE (IODELAY_SIM_DEVICE),
    .DELAY_SRC ("IDATAIN"),
    .DELAY_TYPE ("VAR_LOAD"),
    .REFCLK_FREQUENCY (REFCLK_FREQUENCY),
    .DELAY_FORMAT ("COUNT"))
  i_rx_data_idelay (
    .CASC_RETURN (1'b0),
    .CASC_IN (1'b0),
    .CASC_OUT (),
    .CE (1'b0),
    .CLK (up_clk),
    .INC (1'b0),
    .LOAD (up_dld),
    .CNTVALUEIN ({up_dwdata, 4'd0}),
    .CNTVALUEOUT (up_drdata_s),
    .DATAIN (1'b0),
    .IDATAIN (rx_data_ibuf_s),
    .DATAOUT (rx_data_idelay_s),
    .RST (1'b0),
    .EN_VTC (~up_dld));
  end
  endgenerate

  generate
  if (IODELAY_FPGA_TECHNOLOGY == NONE) begin
  assign rx_data_idelay_s = rx_data_ibuf_s;
	assign up_drdata = 5'd0;
  end
  endgenerate

  // iddr

  generate
  if ((FPGA_TECHNOLOGY == ULTRASCALE) || (FPGA_TECHNOLOGY == ULTRASCALE_PLUS)) begin
  IDDRE1 #(.DDR_CLK_EDGE ("SAME_EDGE")) i_rx_data_iddr (
    .R (1'b0),
    .C (rx_clk),
    .CB (~rx_clk),
    .D (rx_data_idelay_s),
    .Q1 (rx_data_p),
    .Q2 (rx_data_n));
  end
  endgenerate

  generate
  if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
  IDDR #(.DDR_CLK_EDGE ("SAME_EDGE")) i_rx_data_iddr (
    .CE (1'b1),
    .R (1'b0),
    .S (1'b0),
    .C (rx_clk),
    .D (rx_data_idelay_s),
    .Q1 (rx_data_p),
    .Q2 (rx_data_n));
  end
  endgenerate

endmodule

// ***************************************************************************
// ***************************************************************************

ad_data_out

// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsibilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
//   1. The GNU General Public License version 2 as published by the
//      Free Software Foundation, which can be found in the top level directory
//      of this repository (LICENSE_GPL2), and also online at:
//      <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
//   2. An ADI specific BSD license, which can be found in the top level directory
//      of this repository (LICENSE_ADIBSD), and also on-line at:
//      https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
//      This will allow to generate bit files and not release the source code,
//      as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************

`timescale 1ns/100ps

module ad_data_out #(

  parameter   FPGA_TECHNOLOGY = 0,
  parameter   SINGLE_ENDED = 0,
  parameter   IODELAY_ENABLE = 0,
  parameter   IODELAY_CTRL = 0,
  parameter   IODELAY_GROUP = "dev_if_delay_group",
  parameter   REFCLK_FREQUENCY = 200) (

  // data interface

  input               tx_clk,
  input               tx_data_p,
  input               tx_data_n,
  output              tx_data_out_p,
  output              tx_data_out_n,

  // delay-data interface

  input               up_clk,
  input               up_dld,
  input       [ 4:0]  up_dwdata,
  output      [ 4:0]  up_drdata,

  // delay-cntrl interface

  input               delay_clk,
  input               delay_rst,
  output              delay_locked);

  localparam  NONE = -1;
  localparam  SEVEN_SERIES = 1;
  localparam  ULTRASCALE = 2;
  localparam  ULTRASCALE_PLUS = 3;

  localparam  IODELAY_CTRL_ENABLED = (IODELAY_ENABLE == 1) ? IODELAY_CTRL : 0;
  localparam  IODELAY_CTRL_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE" :
    (FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";

  localparam  IODELAY_FPGA_TECHNOLOGY = (IODELAY_ENABLE == 1) ? FPGA_TECHNOLOGY : NONE;
  localparam  IODELAY_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE_PLUS_ES1" :
    (FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";

  // internal signals

  wire                tx_data_oddr_s;
  wire                tx_data_odelay_s;

  // delay controller

  generate
  if (IODELAY_CTRL_ENABLED == 0) begin
  assign delay_locked = 1'b1;
  end else begin
  (* IODELAY_GROUP = IODELAY_GROUP *)
  IDELAYCTRL #(.SIM_DEVICE (IODELAY_CTRL_SIM_DEVICE)) i_delay_ctrl (
    .RST (delay_rst),
    .REFCLK (delay_clk),
    .RDY (delay_locked));
  end
  endgenerate

  // transmit data interface, oddr -> odelay -> obuf

  generate
  if ((FPGA_TECHNOLOGY == ULTRASCALE) || (FPGA_TECHNOLOGY == ULTRASCALE_PLUS)) begin
  ODDRE1 i_tx_data_oddr (
    .SR (1'b0),
    .C (tx_clk),
    .D1 (tx_data_n),
    .D2 (tx_data_p),
    .Q (tx_data_oddr_s));
  end
  endgenerate

  generate
  if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
  ODDR #(.DDR_CLK_EDGE ("SAME_EDGE")) i_tx_data_oddr (
    .CE (1'b1),
    .R (1'b0),
    .S (1'b0),
    .C (tx_clk),
    .D1 (tx_data_n),
    .D2 (tx_data_p),
    .Q (tx_data_oddr_s));
  end
  endgenerate

  // odelay

  generate
  if (IODELAY_FPGA_TECHNOLOGY == SEVEN_SERIES) begin
  (* IODELAY_GROUP = IODELAY_GROUP *)
  ODELAYE2 #(
    .CINVCTRL_SEL ("FALSE"),
    .DELAY_SRC ("ODATAIN"),
    .HIGH_PERFORMANCE_MODE ("FALSE"),
    .ODELAY_TYPE ("VAR_LOAD"),
    .ODELAY_VALUE (0),
    .REFCLK_FREQUENCY (REFCLK_FREQUENCY),
    .PIPE_SEL ("FALSE"),
    .SIGNAL_PATTERN ("DATA"))
  i_tx_data_odelay (
    .CE (1'b0),
    .CLKIN (1'b0),
    .INC (1'b0),
    .LDPIPEEN (1'b0),
    .CINVCTRL (1'b0),
    .REGRST (1'b0),
    .C (up_clk),
    .ODATAIN (tx_data_oddr_s),
    .DATAOUT (tx_data_odelay_s),
    .LD (up_dld),
    .CNTVALUEIN (up_dwdata),
    .CNTVALUEOUT (up_drdata));
  end
  endgenerate

  generate
  if (IODELAY_FPGA_TECHNOLOGY == NONE) begin
  assign up_drdata = 5'd0;
  assign tx_data_odelay_s = tx_data_oddr_s;
  end
  endgenerate

  // obuf

  generate
  if (SINGLE_ENDED == 1) begin
  assign tx_data_out_n = 1'b0;
  OBUF i_tx_data_obuf (
    .I (tx_data_odelay_s),
    .O (tx_data_out_p));
  end else begin
  OBUFDS i_tx_data_obuf (
    .I (tx_data_odelay_s),
    .O (tx_data_out_p),
    .OB (tx_data_out_n));
  end
  endgenerate

endmodule

// ***************************************************************************
// ***************************************************************************

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐