当前位置:   article > 正文

Xilinx 7系列SERDES应用_xilinx serdes

xilinx serdes

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/872990
推荐阅读
相关标签
  

闽ICP备14008679号