精华内容
下载资源
问答
  • Serdes系列总结——Xilinx serdes IP使用(一)——3G serdesIP核的详细设置IP example的使用附件 器件:Xilinx zynq 7035 版本:vivado2019.2 实现:一个线速率为3.072G的,输入为20bit,输出为20bit的无协议无编码...

    Serdes系列总结——Xilinx serdes IP使用(一)——3G serdes

    器件:Xilinx zynq 7035
    版本:vivado2019.2
    实现:一个线速率为3.072G的,输入为20bit,输出为20bit的无协议无编码的4对serdes例程,参考时钟为153.6MHz
    目的:记录从仿真到上板调试的过程,方便回忆

    IP核的详细设置

    第一个选项卡 GT Selection
    在这里插入图片描述在这里插入图片描述
    第二个选项卡 GT Line Rate,RefClk Selection
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    设置时钟管脚位置和serdes管脚位置。(如何根据硬件工程师给出的管脚来设置GTX的位置?结尾补充)
    第三个选项卡 Encoding and Clocking
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    第四个选项卡 Comma Alignment and Equalization
    Comma Alignment 不用设置
    在这里插入图片描述
    第五个选项卡 PCIe,SATA,PRBS
    大部分不选
    在这里插入图片描述
    第六、七个选项卡没有要选的。
    最后Summary
    在这里插入图片描述
    最后,生成IP核后,鼠标放到IP核右键,点击open IP example design,生成了一个example的工程

    IP example的使用

    因为这个IPexample里面自带了数据发送和数据校验的模块,实际应用中,我们需要把需要发送的数据接口和需要接收的接口引出来,需要对这个example进行修改。
    这里主要对关键改动点进行说明:

    gtwizard_0_exdes.v中

    (1)输入输出接口
    DRP_CLK 一般为单端输入就可以了,这里要改
    TRACK_DATA_OUT 这个不需要
    增加serdes收发复位的接口
    增加接收和发送数据的接口,每一路收发都包括收发数据、随路时钟、复位

    (2)gtwizard_0_support模块,修改如下内容,把输入输出数据接口引出到顶层端口

    .gt0_data_valid_in              (1'b1),
    .gt1_data_valid_in              (1'b1),
    .gt2_data_valid_in              (1'b1),
    .gt3_data_valid_in              (1'b1),
    
    .gt0_rxdata_out                 (o_rx_data_0),//(gt0_rxdata_i),
    .gt0_txdata_in                  (i_tx_data_0),//(gt0_txdata_i),
    .gt1_rxdata_out                 (o_rx_data_1),//(gt1_rxdata_i),
    .gt1_txdata_in                  (i_tx_data_1),//(gt1_txdata_i),
    .gt2_rxdata_out                 (o_rx_data_2),//(gt2_rxdata_i),
    .gt2_txdata_in                  (i_tx_data_2),//(gt2_txdata_i),
    .gt3_rxdata_out                 (o_rx_data_3),//(gt3_rxdata_i),
    .gt3_txdata_in                  (i_tx_data_3),//(gt3_txdata_i),
    
    

    (3)把输入输出的随路时钟和复位引出到顶层端口

    assign o_tx_serdes_clk_0 = gt0_txusrclk_i;
    assign o_tx_serdes_clk_1 = gt1_txusrclk_i;
    assign o_tx_serdes_clk_2 = gt2_txusrclk_i;
    assign o_tx_serdes_clk_3 = gt3_txusrclk_i;
    
    assign o_rx_serdes_clk_0 = gt0_rxusrclk_i;
    assign o_rx_serdes_clk_1 = gt1_rxusrclk_i;
    assign o_rx_serdes_clk_2 = gt2_rxusrclk_i;
    assign o_rx_serdes_clk_3 = gt3_rxusrclk_i;
    
    assign o_tx_resetdone_0 = gt0_txfsmresetdone_i;
    assign o_tx_resetdone_1 = gt1_txfsmresetdone_i;
    assign o_tx_resetdone_2 = gt2_txfsmresetdone_i;    
    assign o_tx_resetdone_3 = gt3_txfsmresetdone_i;
    
    assign o_rx_resetdone_0 = gt0_rxfsmresetdone_i;
    assign o_rx_resetdone_1 = gt1_rxfsmresetdone_i;
    assign o_rx_resetdone_2 = gt2_rxfsmresetdone_i;    
    assign o_rx_resetdone_3 = gt3_rxfsmresetdone_i;
    
    

    除了上面,该例程还有一个大坑需要规避。(干货)
    gtwizard_0_GT_USRCLK_SOURCE.v文件中
    添加

        wire            gt1_rxusrclk_i;
        wire            gt2_rxusrclk_i;
        wire            gt3_rxusrclk_i;   
        BUFG rxoutclk_bufg1_i1
        (
            .I                              (gt1_rxoutclk_i),
            .O                              (gt1_rxusrclk_i)
        );
    
        BUFG rxoutclk_bufg1_i2
        (
            .I                              (gt2_rxoutclk_i),
            .O                              (gt2_rxusrclk_i)
        );
    
        BUFG rxoutclk_bufg1_i3
        (
            .I                              (gt3_rxoutclk_i),
            .O                              (gt3_rxusrclk_i)
        );
    
    assign GT1_RXUSRCLK_OUT = gt1_rxusrclk_i; //gt0_rxusrclk_i
    assign GT1_RXUSRCLK2_OUT = gt1_rxusrclk_i;// gt0_rxusrclk_i
    assign GT2_RXUSRCLK_OUT = gt2_rxusrclk_i;// gt0_rxusrclk_i
    assign GT2_RXUSRCLK2_OUT = gt2_rxusrclk_i;// gt0_rxusrclk_i
    assign GT3_RXUSRCLK_OUT = gt3_rxusrclk_i;// gt0_rxusrclk_i
    assign GT3_RXUSRCLK2_OUT = gt3_rxusrclk_i;// gt0_rxusrclk_i
    
    

    这里的修改尤其重要,感觉是xilinx的一个BUG,如果这里不改,仿真会没有问题,但上板调试的时候,只要serdes0接口不接的话,其他接口就会不稳定。其中的缘由可通过代码去理解

    最后,顶层的例化为:

       gtwizard_0_exdes 
        gtwizard_0_exdes_i
        (
             .Q3_CLK0_GTREFCLK_PAD_N_IN           (tx_refclk_n_r), 
             .Q3_CLK0_GTREFCLK_PAD_P_IN           (tx_refclk_p_r),
            .DRP_CLK_IN                        (drp_clk_r),
        .o_tx_serdes_clk_0        (w_tx_serdes_clk_0         ),
        .o_tx_resetdone_0         (w_tx_resetdone_0          ),
        .i_tx_data_0              (w_tx_fifo_out_0           ),
        .o_tx_serdes_clk_1        (w_tx_serdes_clk_1         ),
        .o_tx_resetdone_1         (w_tx_resetdone_1          ),
        .i_tx_data_1              (w_tx_fifo_out_1           ),
        .o_tx_serdes_clk_2        (w_tx_serdes_clk_2         ),
        .o_tx_resetdone_2         (w_tx_resetdone_2          ),
        .i_tx_data_2              (w_tx_fifo_out_2           ),
        .o_tx_serdes_clk_3        (w_tx_serdes_clk_3         ),
        .o_tx_resetdone_3         (w_tx_resetdone_3          ),
        .i_tx_data_3              (w_tx_fifo_out_3           ),
        .o_rx_serdes_clk_0        (w_rx_serdes_clk_0         ),
        .o_rx_resetdone_0         (w_rx_resetdone_0          ),
        .o_rx_data_0              (w_rx_fifo_in_0            ), 
        .o_rx_serdes_clk_1        (w_rx_serdes_clk_1         ),
        .o_rx_resetdone_1         (w_rx_resetdone_1          ),
        .o_rx_data_1              (w_rx_fifo_in_1            ), 
        .o_rx_serdes_clk_2        (w_rx_serdes_clk_2         ),
        .o_rx_resetdone_2         (w_rx_resetdone_2          ),
        .o_rx_data_2              (w_rx_fifo_in_2            ), 
        .o_rx_serdes_clk_3        (w_rx_serdes_clk_3         ),
        .o_rx_resetdone_3         (w_rx_resetdone_3          ),
        .o_rx_data_3              (w_rx_fifo_in_3            ),     
        .i_soft_reset             (4'h0                ),
        .i_rx_reset               (4'h0                ),   
            .RXN_IN                              (rxn_in_i),
            .RXP_IN                              (rxp_in_i),
            .TXN_OUT                             (txn_out_i),
            .TXP_OUT                             (txp_out_i)
        );
    
    

    时钟输入都是153.6M的,输入数据按最简单的办法,输入一个固定数
    reg [19:0] w_tx_fifo_out_0 = 20’haaaaa ;
    reg [19:0] w_tx_fifo_out_1 = 20’haaaaa ;
    reg [19:0] w_tx_fifo_out_2 = 20’haaaaa ;
    reg [19:0] w_tx_fifo_out_3 = 20’haaaaa ;
    发射20’haaaaa,将sedes输出管脚直接连入输入管脚(仿真的时候),看接收的数据是什么?
    注意,为什么发射20’haaaaa 。因为目前没有任何编码,CDR 恢复时钟,是需要有比特翻转才能对接收时钟进行恢复的。尽管在仿真阶段,可以没有bit翻转。但上板调试之后显然就会出问题。

    该工程添加管脚约束后可以直接用于上板调试,直接用光口1和光口2进行光纤对接,通过ILA抓取接收的数据,如果是稳定的20’haaaaa和稳定的20’h55555,则是正常。

    实际应用中,还需自己进行66b/64b编解码的添加,而且还需自己用代码来实现帧对齐等等,较为复杂。后面我们在讲一个example中就自带66/64编码的例子

    附件

    下载地址:
    SERDES_3G
    SERDES_3G.rar中
    gtwizard_0_ex_yuanshi为 IP example直接生成的工程,
    gtwizard_0_ex_xiugai 为在上面基础上修改的工程。
    在gtwizard_0_ex_xiugai文件夹中 找到啊 tb.tcl,修改tcl中的文件路径后,直接可以modelsim运行(modelsim要提前配置好库文件)
    运行结果如下图所示,即成功
    在这里插入图片描述


    写于2021年10月16日
    如需交流,QQ:172146579

    展开全文
  • Xilinx 7系列SERDES应用

    千次阅读 2017-10-06 19:14:06
    SERDES是英文SERializer(串行器)/DESerializer(解串器)的简称。它是一种主流的时分多路复用(TDM)、点对点(P2P)的串行通信技术。即在发送端多路低速并行信号被转换成高速串行信号,经过传输媒体(光缆或铜线),最后在...

    SERDES是英文SERializer(串行器)/DESerializer(解串器)的简称。它是一种主流的时分多路复用(TDM)、点对点(P2P)的串行通信技术。即在发送端多路低速并行信号被转换成高速串行信号,经过传输媒体(光缆或铜线),最后在接收端高速串行信号重新转换成低速并行信号。这种点对点的串行通信技术充分利用传输媒体的信道容量,减少所需的传输信道和器件引脚数目,提升信号的传输速度,从而大大降低通信成本。xilinx 7系列通过原语调用serdes接口,就可以实现串并(并串)转化的应用。
    平台:AT7 Xilinx USB3.0+LVDS+FPGA开发板
    语言:SystemVerilog
    功能:20M时钟产生8位的数据经serdes串化,由一对LVDS输出,再由另一对LVDS接收,经serdes解串恢复8bit的数据。
    这里,在特权的LVDS测试例程上简化,只用调用原语serdes验证数据的传输(说实话,特权同学的例程代码,确实有点凌乱,前后看了两天。可能是对这些其中用到的原语不熟吧)

    `timescale 1ns / 1ps
    
    module srdes_test(
            //外部输入时钟和复位接口
            input logic             sys_clk_i,
            input logic             ext_rst_n,    //复位信号,低电平有效
            //LED指示灯接口
            output logic [7:0]      led,    //用于测试的LED指示灯
            //LVDS发送接口
            output logic [1:0]      lvds_txdb_p,
            output logic [1:0]      lvds_txdb_n, //数据
    //        output logic            lvds_txclk_p,   
    //        output logic            lvds_txclk_n,    //时钟            
            //LVDS接收接口
            input logic [1:0]       lvds_rxdb_p,
            input logic [1:0]       lvds_rxdb_n    //数据
    //        input logic             lvds_rxclk_p,
    //        input logic             lvds_rxclk_n    //时钟    
        );
        //led 输出
        assign led = 8'hFF;
        wire tx_1 = '0;
        OBUFDS io_lvds_out(
                        .O( lvds_txdb_p[1] ),
                        .OB( lvds_txdb_n[1] ),
                        .I( tx_1 )  );
        localparam DATA_CHECK = 8'hD0; //8'b1101_0000
        /***************************************************************
        * 1,时钟
        ***************************************************************/
        wire sys_rst;
        wire  clk_20M_OUT,clk_160M_OUT,clk_200M_OUT;
         clk_pll20M instance_name
         (
          // Clock out ports
          .clk_20M_OUT(clk_20M_OUT),     // output clk_20M_OUT
          .clk_160M_OUT(clk_160M_OUT),     // output clk_160M_OUT
          .clk_200M_OUT(clk_200M_OUT),     // output clk_200M_OUT
          // Status and control signals
          .reset( !ext_rst_n ), // input reset
          .locked( !sys_rst ),       // output locked
         // Clock in ports
          .clk_50M_IN( sys_clk_i ));      // input clk_50M_IN
    
        /***************************************************************
        * 2,发送
        ***************************************************************/  
        //数据产生
        logic [7:0] data_out;
        data_gen_module #(
            .DATA_WIDTH(8)    
        )Udata_gen (
            .clk( clk_20M_OUT ),
            .en( !sys_rst ),
            .dout( data_out )
        );   
        logic check;   
        wire [7:0] data_tx = check ? DATA_CHECK:data_out;
        wire        tx_data_out;
    
        OSERDESE2 #(
            .DATA_WIDTH         (8),             // SERDES word width
            .TRISTATE_WIDTH     (1), 
            .DATA_RATE_OQ       ("SDR"),         // <SDR>, DDR
            .DATA_RATE_TQ       ("SDR"),         // <SDR>, DDR
            .SERDES_MODE        ("MASTER"))      // <DEFAULT>, MASTER, SLAVE
        oserdes_m (
            .OQ               (tx_data_out),
            .OCE             ( 1'b1 ),
            .CLK             ( clk_160M_OUT ),
            .RST             ( sys_rst ),
            .CLKDIV          ( clk_20M_OUT ),
            .D8              (data_tx[7]),
            .D7              (data_tx[6]),
            .D6              (data_tx[5]),
            .D5              (data_tx[4]),
            .D4              (data_tx[3]),
            .D3              (data_tx[2]),
            .D2              (data_tx[1]),
            .D1              (data_tx[0]),
            .TQ              (),
            .T1              (1'b0),
            .T2              (1'b0),
            .T3              (1'b0),
            .T4              (1'b0),
            .TCE             (1'b1),
            .TBYTEIN         (1'b0),
            .TBYTEOUT        (),
            .OFB             (),
            .TFB             (),
            .SHIFTOUT1       (),            
            .SHIFTOUT2       (),            
            .SHIFTIN1        (1'b0),    
            .SHIFTIN2        (1'b0)) ;
    
        OBUFDS io_data_out(
                        .O( lvds_txdb_p[0] ),
                        .OB( lvds_txdb_n[0] ),
                        .I( tx_data_out )  );  
    
        /***************************************************************
        * 3,接收
        ***************************************************************/
        wire delay_ready;
        IDELAYCTRL  icontrol (                          
        // Instantiate input delay control block
                     .REFCLK ( clk_200M_OUT ),
                     .RST    ( sys_rst ),
                     .RDY    (delay_ready) );
    
        wire bslip;  
        wire [7:0] bslip_din;           
        lvds_bitslip#(
               .PATTERN_A(8'hD0)
           )Ubitslip(
               .clk_d( clk_20M_OUT ),  // lvds 数据时钟20M
               .rst_n( 1'b1 ), 
               .din( bslip_din),   
               .bitslip( bslip )
           );  
        wire data_in;
        IBUFDS #(
             .DIFF_TERM("TRUE"),       // Differential Termination
             .IBUF_LOW_PWR("FALSE"),     // Low power="TRUE", Highest performance="FALSE" 
             .IOSTANDARD("DEFAULT")     // Specify the input I/O standard
          ) IBUFDS_inst (
             .O( data_in ),  // Buffer output
             .I( lvds_rxdb_p[0] ),    // Diff_p buffer input (connect directly to top-level port)
             .IB( lvds_rxdb_n[0] )    // Diff_n buffer input (connect directly to top-level port)
          );
        wire data_ind; 
        logic [4:0] delay2_val;  
        IDELAYE2 #(
             .CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)
             .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
             .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
             .IDELAY_TYPE("VAR_LOAD"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
             .IDELAY_VALUE(0),                // 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("DATA")          // DATA, CLOCK input signal
          )
           idelay_d(
             .CNTVALUEOUT( ), // 5-bit output: Counter value output
             .DATAOUT( data_ind ),         // 1-bit output: Delayed data output
             .C( clk_20M_OUT ),                     // 1-bit input: Clock input
             .CE( 1'b0 ),                   // 1-bit input: Active high enable increment/decrement input
             .CINVCTRL(  ),       // 1-bit input: Dynamic clock inversion input
             .CNTVALUEIN( delay2_val ),   // 5-bit input: Counter value input
             .DATAIN( 1'b0 ),           // 1-bit input: Internal delay data input
             .IDATAIN( data_in),         // 1-bit input: Data input from the I/O
             .INC( 1'b0 ),                 // 1-bit input: Increment / Decrement tap delay input
             .LD( 1'b1 ),                   // 1-bit input: Load IDELAY_VALUE input
             .LDPIPEEN( 1'b0 ),       // 1-bit input: Enable PIPELINE register to load data input
             .REGRST  ( 1'b0 )            // 1-bit input: Active-high reset tap-delay input
          );
    
        logic [7:0] data_rx;
            ISERDESE2 #(
               .DATA_WIDTH          (8),                 
               .DATA_RATE           ("SDR"),             
           //    .SERDES_MODE        ("MASTER"),             
               .IOBDELAY            ("IFD"),             
               .INTERFACE_TYPE      ("NETWORKING"))
            iserdes_rx (
               .O ( ),                       // 1-bit output: Combinatorial output
               // Q1 - Q8: 1-bit (each) output: Registered data outputs
               .Q1(data_rx[7]),
               .Q2(data_rx[6]),
               .Q3(data_rx[5]),
               .Q4(data_rx[4]),
               .Q5(data_rx[3]),
               .Q6(data_rx[2]),
               .Q7(data_rx[1]),
               .Q8(data_rx[0]),
               // SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
               .SHIFTOUT1( ),
               .SHIFTOUT2( ),
               .BITSLIP(bslip),           
    
               // CE1, CE2: 1-bit (each) input: Data register clock enable inputs
               .CE1( 1'b1 ),
               .CE2( 1'b1 ),
               .CLKDIVP( 1'b0 ),           // 1-bit input: TBD
               // Clocks: 1-bit (each) input: ISERDESE2 clock input ports
               .CLK( clk_160M_OUT ),                   // 1-bit input: High-speed clock
               .CLKB(~clk_160M_OUT),                 // 1-bit input: High-speed secondary clock
               .CLKDIV( clk_20M_OUT ),             // 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( 1'b0 ),                       // 1-bit input: Data input
               .DDLY( data_ind ),                 // 1-bit input: Serial data from IDELAYE2
    
               .OCLKB( 1'b0 ),               // 1-bit input: High speed negative edge output clock
               .RST( 1'b0 ),                   // 1-bit input: Active high asynchronous reset
               // SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
               .SHIFTIN1( 1'b0 ),
               .SHIFTIN2( 1'b0 )
            );  
          assign bslip_din =  data_rx;                       
        /***************************************************************
        * 4,监测
        ***************************************************************/      
    
         vio_1 Uvio_1 (
             .clk( clk_20M_OUT ),                // input wire clk
             .probe_out0( {delay2_val} )         // output wire [9 : 0] probe_out0
           );
        ila_0 Uila_0 (
             .clk(clk_160M_OUT), // input wire clk
    
             .probe0( data_tx ), // input wire [15:0]  probe0  
             .probe1( data_rx ), // input wire [15:0]  probe1 
             .probe2(bslip) // input wire [1:0]  probe2
            ); 
        vio_0 Uvio_0 (
              .clk( clk_20M_OUT ),                // input wire clk
              .probe_in0( check ),      // input wire [0 : 0] probe_in0
              .probe_out0( check )       // output wire [0 : 0] probe_out0
            ); 
    
    endmodule
    
    展开全文
  • -02-XilinxSerDes接口介绍【Xilinx-LVDS读写功能实现】

    万次阅读 多人点赞 2017-01-13 18:28:41
    因为摄像头输出的LVDS信号速率会达到600Mbps,我们将不能够通过FPGA的I/O接口直接去读取这么高速率的信号。因此,需要使用Xilinx FPGA内的SerDes去实现高速数据的串并转换。

    因为摄像头输出的LVDS信号速率会达到600Mbps,我们将不能够通过FPGA的I/O接口直接去读取这么高速率的信号。因此,需要使用Xilinx FPGA内的SerDes去实现高速数据的串并转换。

    熊猫君的文章“Zynq高速串行CMOS接口的设计与实现”,都已经说清楚了,大神~~

    参考文档ug953,ug471,我们为了捕获OV7251摄像头LVDS的数据信号,将会使用的以下资源:
    - IDELAYCTRL
    - IDELAYE2
    - ISERDESE2
    - ODELAYE2 (用于模拟LVDS输出信号)
    - OSERDESE2 (用于模拟LVDS输出信号)
    - MMCME2_ADV
    - BUFG, BUFR, BUFIO, IBUFG, IBUFDS, OBUFDS

    1. IDELAYCTRL
    这里写图片描述
    因FPGA的电压偏置、制造过程、电压、温度的不同,可能会对整个芯片的时序造成一些小的影响。IDELAYCTRL可以通过一个较高频率的参考时钟REFCLK为IDELAY或ODELAY提供延时抽头,可选0~31。参考时钟的频率可选200MHz或者300MHz,它们的每个抽头的分辨率分别约是78ps和52ps。我们的LVDS输入为600Mbps,则选用200MHz需要21taps,300MHz需要32taps,所以最终选择200MHz为参考时钟。
    使用时还需要注意需要对IDELAYCTRL进行LOC约束,实现工具将IDELAYCTRL实例自动复制到整个器件,甚至复制到未使用延迟单元的时钟区域中。这样做资源占用率较高,在每个时钟区域内都要使用一个全局 时钟资源,并且使用布线资源较多,因此功耗较大。参考文档:输入输出延迟单元IODELAY简介

    2. IDELAYE2
    这里写图片描述
    IDELAYE2逻辑是一个31抽头的循环延时补偿模块,对输入的信号进行指定分辨率的延时,从而保证从外部采集到的时钟和数据信号对应的建立保持时间在可接受的范围内。简单的说就是通过配置不同的Tap值,将600MHz的输入信号实现在1.667ns周期范围内进行相位调整。
    为了调整时不出现数据的信号的断裂或者过分的变化,我们需要对Tap值每次只进行加一或者减一操作,不能一次调整的过大。参考xapp585进行动态相位补偿设计,章节:SDR Data Reception with Per-Bit Deskew。

    3. ISERDESE2
    这里写图片描述
    ISERDESE2就是我们的核心模块了,负责将串行数据转换为并行数据。
    单个ISERDESE2的位宽只有8bit,而我们的数据是10bit,好在我们可以把两个ISERDESE2进行级联实现10bit串并转换。结构如下图,将bit8和bit9分别连为Slave的Q3和Q4。
    这里写图片描述

    虽然前面通过IDELAYE2对数据的相位进行了调整,数据的建立保持时间都OK,可以正常捕获串行数据了。但是,OV7251只有一对差分时钟线和一对差分数据线,而没有额外的串行数据同步信号线,我们必须对串行数据进行字对齐(对于我们来说,像素数据是10bit,所以是进行10bit对齐)。这就需要使用ISERDESE2中的Bitslip功能模块了。
    Bitslip功能是通过BITSLIP输入信号来调整数据对齐的,BITSLIP信号的参考时钟是CLKDIV。每发送一次BITSLIP信号,对齐边沿就会按照下图的方式变化,SDR和DDR模式的变化方式不同。
    这里写图片描述
    OV7251发出的数据是DDR方式,所以是按照上图右边的方式进行变化:右移1位,左移3位,右移1位,左移3位……。而前面说到,既然没有同步信号线,我们就只能够使用数据线中的同步码Sync Code去实现字对齐。OV7251的帧格式如下图,我可以使用编码3FF 000 000 2AC来实现BITSLIP调整。
    这里写图片描述
    我的处理方式和熊猫君的方式相同:图像开始传输后,在每一帧中都去搜索固定的同步码“3FF 000 000 2AC”。如果在这一帧找到了同步码则表示同步完成,若没有找到同步码,则在下一帧开始前触发一次BITSLIP信号,然后继续查找。直到找到了同步码为止,或者超过了20次BITSLIP仍然没有找到,则代表同步失败。

    ODELAYE2和OSERDESE2相对来说没有那么复杂,就不介绍了。

    4. MMCME2_ADV
    时钟

    5. BUF
    buf

    展开全文
  • FPGASERDES的应用需要考虑到板级硬件,SERDES参数和使用,应用协议等方面。由于这种复杂性,SERDES的调试工作对很多工程师来说是一个挑战。本文将描述SERDES的一般
  • Xilinx SerDes调试方案

    2021-01-20 04:47:51
     [导读] FPGA SERDES的应用需要考虑到板级硬件,SERDES参数和使用,应用协议等方面。由于这种复杂性,SERDES的调试工作对很多工程师来说是一个挑战。  关键词:SerDesXilinx  FPGA SERDES的应用需要考虑到板级...
  • xilinx 高速收发器Serdes深入研究

    万次阅读 多人点赞 2017-08-29 20:50:51
    xilinx 高速收发器Serdes深入研究原理 8b10b 环回设置

    一、为什么要用Serdes

    传统的源同步传输,时钟和数据分离。在速率比较低时(<1000M),没有问题。
    这里写图片描述
    在速率越来越高时,这样会有问题
    这里写图片描述
    由于传输线的时延不一致和抖动存在,接收端不能正确的采样数据,对不准眼图中点。
    然后就想到了从数据里面恢复出时钟去采样数据,即CDR
    这里写图片描述
    这样就不存在延迟不一致的情况,有轻微的抖动也不会影响采样(恢复的时钟会随着数据一起抖动)。

    二 、为什么要用8b10b,64b66b?

    1 提供足够的跳变来恢复时钟

    这里写图片描述
    这样还有问题,收发两端必须共地,但往往很难实现。
    这里写图片描述
    于是采样差分信号传输,为了防止共模电压在接收端导致电流过大,使用电流驱动模式。看到接收端有电容进行交流耦合,隔直流。这样又带来一个问题,需要DC平衡。所以有了下面另一个原因。

    2 DC平衡,即0和1的数量要相等。

    这里写图片描述

    3 run length,0和1连续出现的最大长度

    AGC自动增益控制需要交流分量才能实现放大
    这里写图片描述

    4 comma码,K码

    在serdes上面的高速串行流在接收端需要重新串并转化成多字并行,怎么找到字的边界进行对齐呢?
    这就需要一个特殊的序列,这就是comma码。
    传输过程中需要的一些控制,最好不要和数据冲突了,这就是K码。

    基于以上四个原因,就有了8b10b,64b66b的出现。

    三 、8b10b编码

    8b10b编码一句话概括起来就是把8bit的数据变成10bit的数据,其中所有1或0的个数不会超过6个,并且连续的1或0的个数不会超过4个。这样原本1024的汉明空间编码后就大大减小了。其中有256个data码和12K码控制码。这样数据和控制码不会重合。
    这里写图片描述
    其中K28.1,K28.5,K28.7可以作为分隔码,也叫comma码,用于接收端在串行的数据流中找到字节边界。常用的K28.5即0xBC。因为正常传输的数据也可能有0xBC,怎么区分呢?是有一根单独的控制线,tx_is_K在传输K码时拉高,在传数据时拉低,去控制8b10b的编码模块到底是编码成数据还是控制K码。

    四、Xilinx Serdes的几个细节

    1.COMMA码使用

    K28.5,0xBC,+0101_111100,-1010_000011; 为检测字节分割。
    使用其它K码,作为帧开始,帧结束,时钟修正和数据对齐。

    2.多字节处理

    在数据率比较高的时候,外部位宽可能是2字(16位)或者4字(32位)。这是如果收发双方不约定好在高低哪个字发送comma码,这时是可以检测字边界,但接收端就会出现高低字节翻转的情况。在任意对于单COMMA的数据对齐,选择偶数字节对齐。发送的时候 0x5ABC->2’b01。
    这里写图片描述
    也可以选择发送组合的comma码,就是把NP的comma拼接起来发送,这样接收端就检测16bit的双字边界。也可以避免上面的情况出现。发送的时候0xBCBC->2’b11
    这里写图片描述
    注意:decode valid comma only不要选,因为还可能发送其他的K码用于控制。反正8b10b是用的收发器硬核的资源,不用白不用。

    3、环回设置:

    1.“000”:正常模式
    2.“001”:近端PCS环回
    3.“010”:近端PMA环回
    4.“100”:远端PMA环回
    5.“110”:远端PCS环回
    注意Xilinx例化的example的文件中配置的环回是预留环回接口的意思,仍然需要另外手动配置。

    4、fsm_down状态机

    这里写图片描述
    在Monitor Data_Valid模块,是用的frame_check的正确的信号,校验失败会导致复位GTrxreset。可以不用这个反馈,直接置1。需要手动改一下。

    5.通道绑定

    限于篇幅,单独列出

    6.时钟纠正

    限于篇幅,单独列出

    展开全文
  •  [导读] FPGA SERDES的应用需要考虑到板级硬件,SERDES参数和使用,应用协议等方面。由于这种复杂性,SERDES的调试工作对很多工程师来说是一个挑战。  关键词:SerDesXilinx  FPGA SERDES的应用需要考虑到板级...
  • xilinx-serdes调试问题

    2021-12-21 10:43:50
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录一、vivado-serdes调试问题二...xilinx的-1速率的FPGA-gt-是没办法跑到10G的。注意在选择ibert工程时需要注意一个QUAD会有两个外部的参考
  • Serdes系列总结——Xilinx serdes IP使用(三)——12G serdesIP核的详细设置IPexample的使用附件 器件:Xilinx zynq zu6cg 版本:vivado2019.2 实现:12.16512G的serdes,一个输入为64bit,输出为64bit的6664B编码的...
  • Serdes系列总结——Xilinx serdes IP使用(二)——10G serdesIP核的详细设置IP example的使用附件 器件:Xilinx zynq 7035 版本:vivado2019.2 实现:10.1376G的serdes,一个输入为64bit,输出为64bit的6664B编码的4...
  • xilinx 7系列 serdes GTP的仿真文件,本人仿真与实际验证通过,对做高速串行的朋友可以借鉴
  • Xilinx官方指南,本指南详细介绍了Xilinx的Spartan6系列的serdes模块,用于连接高速ADC/DAC,包含了具体的实例,非常详细,使用serdes前必读
  • 高速FPGA串并收发器SERDES实现ADS6445的AD转换 在使用TI公司四通道、14Bit、最大速率125M的ADS6445。利用Xilinx V5系列器件的串行收发控制器ISERDES的原语来实现数据的接收。 (1)ADS6445基础知识和配置 ADS6445是...
  • Xilinx 7 系列FPGA中的 Serdes小结

    千次阅读 2019-01-22 15:19:32
    FPGA series LS-GTR GTP GTX GTH GTY GTZ Artix-7 x 6.6Gb/s x x x x Kintex-7 x x 12.5Gb/s x x x ZYNQ 7000 x 6.25Gb/s 12.5Gb/s x x x Zynq UltraScale+ MPSoCs 6Gb/s x x 16.3Gb/s ......
  • Serdes系列总结——Xilinx ibert IP使用IP设置测试界面眼图质量的评判 IP设置 IBERT ip的设置非常简单,只要设置好serdes管脚对应的信息即可,生成的example直接是可以生成bit,上板调试的。下面以zynq 7035的GTX为...
  • xilinx IP核配置,一步一步验证Xilinx Serdes GTX最高8.0Gbps

    万次阅读 多人点赞 2017-08-28 22:34:07
    一步一步验证Xilinx Serdes高速收发器 GTX 最高线速 8.0Gbps 手把手IP核配置,理解每个配置选项的原理
  • 1. 概述:本文从系统方面入手,利用vivado丰富的IP资源,设计一个链路可配置的PCIe EP(当然RC也...2. 参考文件:Xilinx vivado的各类参考文件 PCIe 2.0 Spec Xilinx PCIe IP 3. 环境:如下图:采用V7485t,FPG...
  • Serdes 知识详解.pdf

    2020-06-25 13:33:13
    本篇主要介绍了 SerDes 的基本结构和用好 SerDes 需要掌握一些的知识,希望对你的工作有所帮助
  • 1、通道绑定原理 通道绑定只支持8b10b编码协议,通道绑定利用内部的FIFO来抵消通道间的延时差,原理如下图 master channel 和slave channel都有特定的字节,可以是K码。当master 检测到K码时,进行一个计数,slave...
  • SERDES_3G.rar

    2021-10-16 21:24:42
    https://blog.csdn.net/gzy0506/article/details/120803797 Serdes系列总结——Xilinx serdes IP使用(一)——3G serdes的附件
  • 1、时钟纠正原理 时钟纠正比较简单,下面一个图就能说清楚。 首先为什么要使用时钟纠正,是因为CDR恢复的用户时钟user_clk和硬核时钟XCLK虽然频率一样,但是会有略微的不同,正是这样导致内部的FIFO有可能...
  • Xilinx_SERDES动态延迟加解串的使用

    千次阅读 2017-10-23 16:38:18
    Xilinx SELECTIO IP核调用配作可变延迟加输入解串工作模式时信号接口如下表所示: 接口名 方向 注释 DATA_IN_FROM_PINS Input 来自外部IO数据输入引脚 DATA_IN_TO_DEVICE Output CLK_OUT同步后的输出数据 ...
  • xilinx serdes时钟纠正clock correction

    千次阅读 2017-08-29 21:27:16
    xilinx serdes时钟纠正clock correction
  • xilinx serdes通道绑定channel bonding

    千次阅读 2017-08-29 21:04:46
    xilinx serdes通道绑定channel bonding,通道对齐,消除延时 把多根serdes通道绑定成一根逻辑上的通道
  • XILINXserdes GT IP真的是够复杂的,生成的例子也是复杂,而且为了适配各种情况,代码里很多冗余的东西,发送部分比较简单 ,接收部分有点繁琐,我做了点注释,这里的只做的GTP的,GTX的自己看吧。 ///////////...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 735
精华内容 294
关键字:

serdesxilinx