LVDS接口程序设计框架及仿真

1、程序框架

主要module有:

1)ad9253_lvds_top.v,顶层模块;

2)ad9253_lvds_iobuffer.v,IO缓冲模块;

3)ad9253_lvds_clock.v,采样clock生成模块;

4)ad9253_lvds_frame.v,帧同步模块;

5)ad9253_lvds_data.v,数据采集模块。

2、ISERDES2原语介绍

接之前博文所述,LVDS串行接口在FPGA中实际上要进行的就是并串转换,核心模块即为ISERDES2,下面该原语接口功能和配置进行简单介绍。

上图为ISERDES2使用时的原语框图,使用时可以在Vivado中获取原语模板如下图所示:

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)
   );

根据原语模板可以看到其应用需要分别配置端口和属性,下面进行简单介绍。

2.1、ISERDES2原语端口说明·

1、寄存器输出端Q1-Q8

输出端将串行输入数据并行输出,如图所示:

2、组合输出端口O

组合输出端输出可以直接输出输入端数据D或者来自IDELAY模块数据DDLY。

3、位宽扩展端口SHIFTOUT1和SHIFTOUT2,SHIFTIN1和SHIFTIN2

当输入串行数据位宽超过8Bit时,为了进行串并转换,可以通过将两个ISERDES2模块设置成主从方式并联起来,实现1:10位或1:14位(只适用于DDR模式),如下图所示:

两个模块通过位宽扩展端口进行连接。

4、串行数据输入端口D和DDLY

端口D输入的数据来自IOB,即为ADC数据引脚,端口DDLY输入的数据来自IDELAY模块进行延时后数据。

5、时钟输入端CLK和CLKB

随路时钟输入,一般为DCO经过IDELAY模块产生的IntBitclk,CLKB为其反相输入。

6、时钟使能端CE1和CE2

使能输入的CLK和CLKB。

7、复位引脚RST

复位ISERDES2模块,高电平使能。

8、分频时钟输入端CLKDIV和CLKDIVP

此时钟作为Frame信号,确定数据转换的起始位置,一般为IntBitclk分频而来的CLK。

9、高速时钟输入端OCLK和OCLKB

这个时钟来自Memory。

10、Bitslip引脚

对采样数据进行移位,从而实现数据对齐,经过IDELAY模块生成的BitClk_MonClkin和BitClk_RefClkin与DATA之间存在延时,为此通过采集FCO并进行移位消除延时影响。Bitslip操作在DDR和SDR模式下有区别,如下图所示:

在SDR模式中,每次Bitslip操作都会导致输出数据向左偏移一位,例如0x1001_0111_1011经过Bitslip变成0x0010_1111_0111;

在DDR模式中,每次Bitslip操作都会导致输出数据交替进行右移一位和左移三位,如下图所示:

11、反馈输入端OFB

来自OLOGIC2、OLOGIC3和OSERDES2的输出反馈脚

12、动态设置时钟反相端DYNCLKDIVSEL和DYNCLK

此端口可以对输入时钟进行反相操作。

2.2、ISERDES2原语属性说明·

1、数据速率属性DATA_RATE

可选择DDR模式或SDR模式

2、数据位宽属性DATA_WIDTH

数据位宽可设置如下表所示,当位宽超过8位时,需要进行ISERDESE2扩展

3、动态时钟反转使能属性DYN_CLK_INV_EN和DYN_CLKDIV_INV_EN

对时钟进行反转,可选择TRUE or FALSE

4、接口类型属性INTERFACE_TYPE

可选择存储器类型或NETWORKING,对于ADC信号应用的是NETWORKING

5、使能时钟数量NUM_EN

当选择1时,只需要输入CLK,当选择2时,输入CLK和CLKB

6、使能反馈路径OFB_USED

TRUE or FALSE

7、ISERDESE2模式属性SERDES_MODE

当使用扩展时,SERDES模块的属性可选择为主模式或从模式

8、采样初始值设置INIT_Q1,INIT_Q2,INIT_Q3,INIT_Q4;SRVAL_Q1,SRVAL_Q2,SRVAL_Q3,SRVAL_Q4

一般初始化为0

9、选择D或DDLY作为输入IOBDELAY

D和DDLY引脚是ISERDESE2的专用输入。D输入是直接连接到IOB,DDLY引脚直接连接到IDELAYE2。ADC数据输入由D进行输入。

3、采样clock程序设计

BitClk由DCO经IDELAY2模块而来,经IBUFIO缓冲作为采样clock,经BUFR进行分频得到同步clock

时序如下:

代码模块如下:

module ad9253_lvds_clock #(
    parameter C_StatTaps = 5'd15
)
(
    input SysRefClk,
    input BitClk,
    input BitClkRst,
    input BitClk_MonClkIn,
    input BitClk_RefClkIn,
    
    output BitClkDone,
    output BitClk_MonClkOut,
    output BitClk_RefClkOut 

);
wire IntBitClk;
wire [7:0] allign_word;

//IDELAY
(* IODELAY_GROUP = "DELAY1" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
IDELAYE2 #(
  .CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)
  .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
  .HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
  .IDELAY_TYPE("FIXED"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
  .IDELAY_VALUE(C_StatTaps),                // Input delay tap setting (0-31)
  .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
  .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
  .SIGNAL_PATTERN("CLOCK")          // DATA, CLOCK input signal
)
IDELAYE2_inst (
  .CNTVALUEOUT(), // 5-bit output: Counter value output
  .DATAOUT(IntBitClk),         // 1-bit output: Delayed data output
  .C(BitClk_RefClkOut),                     // 1-bit input: Clock input
  .CE(1'b0),                   // 1-bit input: Active high enable increment/decrement input
  .CINVCTRL(1'b0),       // 1-bit input: Dynamic clock inversion input
  .CNTVALUEIN(5'd0),   // 5-bit input: Counter value input
  .DATAIN(1'b0),           // 1-bit input: Internal delay data input
  .IDATAIN(BitClk),         // 1-bit input: Data input from the I/O
  .INC(1'b0),                 // 1-bit input: Increment / Decrement tap delay input
  .LD(BitClkRst),                   // 1-bit input: Load IDELAY_VALUE input
  .LDPIPEEN(1'b0),       // 1-bit input: Enable PIPELINE register to load data input
  .REGRST(BitClkRst)            // 1-bit input: Active-high reset tap-delay input
); 

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

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

4、帧同步程序设计

帧同步目的在于对齐同步clock和FCO之间的延时,故通过采样clock对FCO进行采集,通过Bitslip操作,将延时进行对齐。ADC输出时序如下图所示:

通过BitClk对FCLK采样后,进行Bitslip操作,当结果等于pattern值时,表示BitClk_RefClkOut与FCO已对齐。下图为代码框架:

代码模块如下:

module ad9253_lvds_frame#(
    parameter FrmPattern = 8'b11110000
)
(
    input FrmClk,
    input FrmClkDiv,
    
    input FrmClk_p,
    
    input FrmClkRst,
    input FrmClkDone,
    
    output FrmClkBitSlip_p,
    output FrmAlignDone 

);
wire    [7:0]   IntFrmSrdsOutp;
reg             FrmClkBitSlip_pout;

//ISERDESE2
ISERDESE2 #(
    .DATA_RATE         ("DDR"), // DDR, SDR
    .DATA_WIDTH        (8), // 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    ("NETWORKING"), // 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_inst1(
    .O            (), // 1-bit output: Combinatorial output
    // Q1 - Q8: 1-bit (each) output: Registered data outputs
    .Q1           (IntFrmSrdsOutp[0]),
    .Q2           (IntFrmSrdsOutp[1]),
    .Q3           (IntFrmSrdsOutp[2]),
    .Q4           (IntFrmSrdsOutp[3]),
    .Q5           (IntFrmSrdsOutp[4]),
    .Q6           (IntFrmSrdsOutp[5]),
    .Q7           (IntFrmSrdsOutp[6]),
    .Q8           (IntFrmSrdsOutp[7]),
    // SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
    .SHIFTOUT1    (),
    .SHIFTOUT2    (),
    .BITSLIP      (FrmClkBitSlip_pout), // 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          (FrmClkDone),
    .CE2          (1'b1),
    .CLKDIVP      (1'b0), // 1-bit input: TBD
    // Clocks: 1-bit (each) input: ISERDESE2 clock input ports
    .CLK          (FrmClk), // 1-bit input: High-speed clock
    .CLKB         (~FrmClk), // 1-bit input: High-speed secondary clock
    .CLKDIV       (FrmClkDiv), // 1-bit input: Divided clock
    .OCLK         (1'b0), // 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 (1'b0), // 1-bit input: Dynamic CLKDIV inversion
    .DYNCLKSEL    (1'b0), // 1-bit input: Dynamic CLK/CLKB inversion
    // Input Data: 1-bit (each) input: ISERDESE2 data input ports
    .D            (FrmClk_p), // 1-bit input: Data input
    .DDLY         (1'b0), // 1-bit input: Serial data from IDELAYE2
    .OFB          (1'b0), // 1-bit input: Data feedback from OSERDESE2
    .OCLKB        (1'b0), // 1-bit input: High speed negative edge output clock
    .RST          (~FrmClkRst), // 1-bit input: Active high asynchronous reset
    // SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
    .SHIFTIN1     (1'b0),
    .SHIFTIN2     (1'b0)
);

//Frame Alignment State Machine

always @(posedge FrmClkDiv or negedge FrmClkRst)
begin
    if((!FrmClkRst) || (!FrmClkDone))
    begin
        FrmClkBitSlip_pout <= 1'b0;
        rBitslipCnt <= 8'd0;
        rFrmAlignDone <= 1'b0;
    end
    else
    begin
        if(IntFrmSrdsOutp == FrmPattern)
        begin
            rFrmAlignDone <= 1'b1;
        end
        else if((rBitslipCnt == 8'd255) && (IntFrmSrdsOutp != FrmPattern))
        begin
            FrmClkBitSlip_pout <= 1'b1;
            rBitslipCnt <= 8'd1;
        end
        else if((IntFrmSrdsOutp != FrmPattern) && (rBitslipCnt < 8'd255))
        begin
            FrmClkBitSlip_pout <= 1'b0;
            rBitslipCnt <= rBitslipCnt + 1'd1;
        end
    end
end

assign FrmClkBitSlip_p = FrmClkBitSlip_pout;
assign FrmAlignDone = rFrmAlignDone;

endmodule

5、数据采集程序设计

数据采集比较简单,通过已经对齐后的clock和ISERDESE2模块对两根data线进行串并转换即可,代码框架为:

代码模块如下:

module ad9253_lvds_data#(
    parameter  BITWISEorBYTEWISE = 1
)
(
    input DatClk,
    input DatClkDiv,
    input DatRst,

    input DatBitSlip_p,
    input BitClkDone,
    input FrmAlignDone,

    input DatD0_p,
    input DatD0_n,
    input DatD1_p,
    input DatD1_n,

    output [13:0] DatOut
);
wire  [7:0] DatSrdsout1;    //Frame hign data1   
wire  [7:0] DatSrdsout2;    //Frame low data2 

//D0_P ISERDESE
    ISERDESE2 #(
        .DATA_RATE         ("DDR"), // DDR, SDR
        .DATA_WIDTH        (8), // 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    ("NETWORKING"), // 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),
        .IS_CLK_INVERTED   (1'b0)
    )
    ISERDESE2_inst0(
        .O            (), // 1-bit output: Combinatorial output
        // Q1 - Q8: 1-bit (each) output: Registered data outputs
        .Q1           (DatSrdsout1[0]),
        .Q2           (DatSrdsout1[1]),
        .Q3           (DatSrdsout1[2]),
        .Q4           (DatSrdsout1[3]),
        .Q5           (DatSrdsout1[4]),
        .Q6           (DatSrdsout1[5]),
        .Q7           (DatSrdsout1[6]),
        .Q8           (DatSrdsout1[7]),
        // SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
        .SHIFTOUT1    (),
        .SHIFTOUT2    (),
        .BITSLIP      (DatBitSlip_p), // 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          (BitClkDone&FrmAlignDone),
        .CE2          (1'b1),
        .CLKDIVP      (1'b0), // 1-bit input: TBD
        // Clocks: 1-bit (each) input: ISERDESE2 clock input ports
        .CLK          (DatClk), // 1-bit input: High-speed clock
        .CLKB         (~DatClk), // 1-bit input: High-speed secondary clock
        .CLKDIV       (DatClkDiv), // 1-bit input: Divided clock
        .OCLK         (1'b0), // 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 (1'b0), // 1-bit input: Dynamic CLKDIV inversion
        .DYNCLKSEL    (1'b0), // 1-bit input: Dynamic CLK/CLKB inversion
        // Input Data: 1-bit (each) input: ISERDESE2 data input ports
        .D            (DatD0_p), // 1-bit input: Data input
        .DDLY         (1'b0), // 1-bit input: Serial data from IDELAYE2
        .OFB          (1'b0), // 1-bit input: Data feedback from OSERDESE2
        .OCLKB        (1'b0), // 1-bit input: High speed negative edge output clock
        .RST          (~DatRst), // 1-bit input: Active high asynchronous reset
        // SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
        .SHIFTIN1     (1'b0),
        .SHIFTIN2     (1'b0)
    );
   
    //D1_P ISERDESE
    ISERDESE2 #(
        .DATA_RATE         ("DDR"), // DDR, SDR
        .DATA_WIDTH        (8), // 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    ("NETWORKING"), // 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_inst2(
        .O            (), // 1-bit output: Combinatorial output
        // Q1 - Q8: 1-bit (each) output: Registered data outputs
        .Q1           (DatSrdsout2[0]),
        .Q2           (DatSrdsout2[1]),
        .Q3           (DatSrdsout2[2]),
        .Q4           (DatSrdsout2[3]),
        .Q5           (DatSrdsout2[4]),
        .Q6           (DatSrdsout2[5]),
        .Q7           (DatSrdsout2[6]),
        .Q8           (DatSrdsout2[7]),
        // SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
        .SHIFTOUT1    (),
        .SHIFTOUT2    (),
        .BITSLIP      (DatBitSlip_p), // 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          (BitClkDone&FrmAlignDone),
        .CE2          (1'b1),
        .CLKDIVP      (1'b0), // 1-bit input: TBD
        // Clocks: 1-bit (each) input: ISERDESE2 clock input ports
        .CLK          (~DatClk), // 1-bit input: High-speed clock
        .CLKB         (DatClk), // 1-bit input: High-speed secondary clock
        .CLKDIV       (DatClkDiv), // 1-bit input: Divided clock
        .OCLK         (1'b0), // 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 (1'b0), // 1-bit input: Dynamic CLKDIV inversion
        .DYNCLKSEL    (1'b0), // 1-bit input: Dynamic CLK/CLKB inversion
        // Input Data: 1-bit (each) input: ISERDESE2 data input ports
        .D            (DatD1_p), // 1-bit input: Data input
        .DDLY         (1'b0), // 1-bit input: Serial data from IDELAYE2
        .OFB          (1'b0), // 1-bit input: Data feedback from OSERDESE2
        .OCLKB        (1'b0), // 1-bit input: High speed negative edge output clock
        .RST          (~DatRst), // 1-bit input: Active high asynchronous reset
        // SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
        .SHIFTIN1     (1'b0),
        .SHIFTIN2     (1'b0)
);

//Data Output
wire [13:0] DatOut_TEMP1, DatOut_TEMP2;
assign DatOut_TEMP1 = {DatSrdsout2, DatSrdsout1[7:2]};
assign DatOut_TEMP2 = {DatSrdsout2[7], DatSrdsout1[7], DatSrdsout2[6], DatSrdsout1[6],DatSrdsout2[5], DatSrdsout1[5],DatSrdsout2[4], DatSrdsout1[4],
                                                        DatSrdsout2[3], DatSrdsout1[3],DatSrdsout2[2], DatSrdsout1[2],DatSrdsout2[1], DatSrdsout1[1]};
assign DatOut = BITWISEorBYTEWISE?DatOut_TEMP1:DatOut_TEMP2;

endmodule

代码中,将两个LANE采集的数据进行了整合,对BYTEWISE和BITWISE模式进行了区分。至此通过ISERDESE对AD9253进行基本采集功能的驱动代码完成。

6、TestBench写LVDS时序及仿真结果

下一节给出一些TestBench编写技巧,对部分module进行仿真,通过仿真验证程序的正确性。

  • 44
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值