Xilinx中oserdes的原语及IP的使用

应用场景

在高速应用中,我们经常性的听说serdes的应用,确实serdes是一项重要的应用。serdes又可以分为iserdes与oserdes两个操作分别是串行转并行以及并行转串行,因为FPGA内部跑的频率较低,不能处理那么高的串行频率需要转成并行处理。举两个serdes的例子以供大家明白它的作用:
1、HDMI中的发射端用到了Oserdes接收端用到了Iserdes,因为HDMI是数字串行通信
2、在GTP的应用中,如PCIE、SFP都用到了serdes操作
我们下篇文章会讲解HDMI应用。知道了serdes的作用,那么学习起来这个操作才有意义。

serdes原语的应用

首先从vivado中调出oserdes原语如下
在这里插入图片描述
接下来对其接口信号进行描述:

 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
                    

1、DATA_RATE_OQ:数据模式,DDR代表上升沿和下降沿都发送数据,SDR代表只在上升沿发送数据
2、DATA_RATE_TQ:三态门模式,同上,这里我们不关注三态状态,所有与三态设置相关的信号输入设置成0,输出不关心。
3、INIT_OQ:初始化数据输出端初始值
4、SERDES_MODE:串行的模式,在10,14串行通信的时候用到,如下图:
在这里插入图片描述
用到两个serdes,上面的选择Master下面的选择Slave
5、SRVAL_OQ:复位时输出电平的状态
6、OFB:反馈输出,这里不关心即可
7、OQ:输出信号
8、SHIFTOUT1:serdes串联时送给上一个serdes用到的信号
9、SHIFTOUT2:serdes串联时送给上一个serdes用到的信号
10、CLK:串行块时钟,在HDMI中是CLKDIV的5倍
11、CLKDIV:并行数据的随路时钟
12、DX:并行输入数据
13、OCE:模块使能信号,默认为1使能
14、RST:模块复位信号,默认为1复位
15、SHIFTIN1:serdes串联时送接收下一个serdes用到的信号
16、SHIFTIN2:serdes串联时送接收下一个serdes用到的信号
我们这里使用典型的10bit数据转串行数据发送。

serdes原语的使用示例

这里将以10bit转成串行输出为例给出相应的代码,注意原语中TRISTATE_WIDTH设置为1,因为手册中的说明如下:
在这里插入图片描述
所以代码如下:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : 
// Module Name  : par2ser.v
// Create Time  : 2020-02-23 14:20:43
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************


module par2ser(
    input                   clk_1x          ,
    input                   clk_5x          ,
    input                   rst_n           ,
    input           [ 9:0]  par_data        ,

    output  wire            ser_data_p      ,
    output  wire            ser_data_n  
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
wire                        shiftout1       ;
wire                        shiftout2       ;
wire                        ser_data        ;
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/

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

 OSERDESE2 #(
    .DATA_RATE_OQ               ("DDR"                  ),   // DDR, SDR
    .DATA_RATE_TQ               ("DDR"                  ),   // DDR, BUF, SDR
    .DATA_WIDTH                 (10                     ),         // 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             (1                      )      // 3-state converter width (1,4)
   ) OSERDESE2_inst_master (
      .OFB                      (                       ),             // 1-bit output: Feedback path for data
      .OQ                       (ser_data               ),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1                (                       ),
      .SHIFTOUT2                (                       ),
      .TBYTEOUT                 (                       ),   // 1-bit output: Byte group tristate
      .TFB                      (                       ),             // 1-bit output: 3-state control
      .TQ                       (                       ),               // 1-bit output: 3-state control
      .CLK                      (clk_5x                 ),             // 1-bit input: High speed clock
      .CLKDIV                   (clk_1x                 ),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1                       (par_data[0]            ),
      .D2                       (par_data[1]            ),
      .D3                       (par_data[2]            ),
      .D4                       (par_data[3]            ),
      .D5                       (par_data[4]            ),
      .D6                       (par_data[5]            ),
      .D7                       (par_data[6]            ),
      .D8                       (par_data[7]            ),
      .OCE                      (1'b1                   ),             // 1-bit input: Output data clock enable
      .RST                      (~rst_n                 ),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1                 (shiftout1              ),
      .SHIFTIN2                 (shiftout2              ),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1                       (1'b0                   ),
      .T2                       (1'b0                   ),
      .T3                       (1'b0                   ),
      .T4                       (1'b0                   ),
      .TBYTEIN                  (1'b0                   ),     // 1-bit input: Byte group tristate
      .TCE                      (1'b0                   )              // 1-bit input: 3-state clock enable
   );

   // End of OSERDESE2_inst instantiation
 OSERDESE2 #(
    .DATA_RATE_OQ               ("DDR"                  ),   // DDR, SDR
    .DATA_RATE_TQ               ("DDR"                  ),   // DDR, BUF, SDR
    .DATA_WIDTH                 (10                     ),         // 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                ("SLAVE"               ), // 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             (1                      )      // 3-state converter width (1,4)
   ) OSERDESE2_inst_slave (
      .OFB                      (                       ),             // 1-bit output: Feedback path for data
      .OQ                       (                       ),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1                (shiftout1              ),
      .SHIFTOUT2                (shiftout2              ),
      .TBYTEOUT                 (                       ),   // 1-bit output: Byte group tristate
      .TFB                      (                       ),             // 1-bit output: 3-state control
      .TQ                       (                       ),               // 1-bit output: 3-state control
      .CLK                      (clk_5x                 ),             // 1-bit input: High speed clock
      .CLKDIV                   (clk_1x                 ),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1                       (                       ),
      .D2                       (                       ),
      .D3                       (par_data[8]            ),
      .D4                       (par_data[9]            ),
      .D5                       (                       ),
      .D6                       (                       ),
      .D7                       (                       ),
      .D8                       (                       ),
      .OCE                      (1'b1                   ),             // 1-bit input: Output data clock enable
      .RST                      (~rst_n                 ),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1                 (                       ),
      .SHIFTIN2                 (                       ),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1                       (1'b0                   ),
      .T2                       (1'b0                   ),
      .T3                       (1'b0                   ),
      .T4                       (1'b0                   ),
      .TBYTEIN                  (1'b0                   ),     // 1-bit input: Byte group tristate
      .TCE                      (1'b0                   )              // 1-bit input: 3-state clock enable
   );                    




endmodule

serdes原语的测试代码

`timescale 1ns / 1ps
`define     CLOCK        20
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/02/23 14:23:39
// Design Name: 
// Module Name: tb_par2ser
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_par2ser;
reg                        clk_1x          ;
reg                        clk_5x          ;
reg                        rst_n           ;
reg                [ 9:0]  par_data        ;
wire                       ser_data_p      ;
wire                       ser_data_n      ;

initial begin
    clk_1x          =       1'b0;
    clk_5x          =       1'b0;
    rst_n           <=      1'b0;
    #(100*`CLOCK)
    rst_n           <=      1'b1;
end
always #(`CLOCK/2)      clk_1x          =           ~clk_1x;
always #(`CLOCK/8)      clk_5x          =           ~clk_5x;

always @(posedge clk_1x or negedge rst_n)
    if(rst_n == 1'b0)
        par_data            <=          10'b11_1111_1111;
    else 
        par_data            <=          par_data - 1'b1; 



par2ser par2ser_inst(
    .clk_1x                 (clk_1x                 ),
    .clk_5x                 (clk_5x                 ),
    .rst_n                  (rst_n                  ),
    .par_data               (par_data               ),

    .ser_data_p             (ser_data_p             ),
    .ser_data_n             (ser_data_n             )
);
endmodule

仿真代码没有任何难度,看一下便明白原理。

serdes原语的仿真结果

在这里插入图片描述
从上面图形中我们可以验证我们oserdes程序的正确性。

select_io的使用

上面的原语或许不是那么容易理解,那么我们同样完成上面的功能,通过使用IP来完成,该IP的名字叫做select_io,在vivado中调用对应的IP,如下
在这里插入图片描述
首先的界面设置如下:
在这里插入图片描述
第二个界面设置如下:
在这里插入图片描述
第三个默认即可
在这里插入图片描述
从上面的设置中我们可以发现是与原语的参数设置一致的。

select_io的测试代码

测试代码如下:

`timescale 1ns / 1ps
`define     CLOCK        20
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/02/23 15:39:03
// Design Name: 
// Module Name: tb_select_io
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_select_io;
reg                        clk_1x          ;
reg                        clk_5x          ;
reg                        rst_n           ;
reg                [ 9:0]  par_data        ;
wire                       ser_data_p      ;
wire                       ser_data_n      ;
initial begin
    clk_1x          =       1'b0;
    clk_5x          =       1'b0;
    rst_n           <=      1'b0;
    #(100*`CLOCK)
    rst_n           <=      1'b1;
end
always #(`CLOCK/2)      clk_1x          =           ~clk_1x;
always #(`CLOCK/8)      clk_5x          =           ~clk_5x;
always @(posedge clk_1x or negedge rst_n)
    if(rst_n == 1'b0)
        par_data            <=          10'b11_1111_1111;
    else 
        par_data            <=          par_data - 1'b1; 

selectio_wiz_0 selectio_wiz_0_inst
 (
   .data_out_from_device            (par_data                       ), // input [9:0] data_out_from_device
   .data_out_to_pins_p              (ser_data_p                     ), // output [0:0] data_out_to_pins_p
   .data_out_to_pins_n              (ser_data_n                     ), // output [0:0] data_out_to_pins_n
   .clk_in                          (clk_5x                         ), // input clk_in                            
   .clk_div_in                      (clk_1x                         ), // input clk_div_in                        
   .io_reset                        (~rst_n                         ) // input io_reset
); 

endmodule

测试结果

在这里插入图片描述
从测试结果上看,IP与原语的作用相同。

总结

创作不易,认为文章有帮助的同学们可以关注点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

  • 29
    点赞
  • 146
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值