1、介绍

随着电子行业技术的发展,特别是在传输接口的发展上,IEEE1284被 USB 接口取代,PATA被 SATA 取代,PCI被 PCI-Express 所取代,无一不证明了传统并行接口的速度已经达到一个瓶颈了,取而代之的是速度更快的串行接口,于是原本用于光纤通信的SerDes 技术成为了为高速串行接口的主流。串行接口主要应用了差分信号传输技术,具有功耗低、抗干扰强,速度快的特点,理论上串行接口的最高传输速率可达到10Gbps 以上。

2、理论

Xlinx的原语OSERDESE2是一种专用的并-串转换器,每个OSERDESE2模块都包括一个专用串行化程序用于数据和3状态控制。数据和3状态序列化程序都可以工作在SDR和DDR模式。数据串行化的位宽可以达到8:1(如果使用原语模块级联,则可以到10:1和14:1)。3状态序列化最高可达14:1,有一个专用的DDR3模式可用于支持高速内存应用程序。

OSERDESE2的框图如下:

OSERDESE2的端口说明如下:

端口 类型  位宽 描述
CLK 输入 1 串行时钟
CLKDIV 输入 1 并行时钟,是CLK的一个分频时钟
D1 -- D8 输入 1 并行数据输入端口
OCE 输入 1 高电平有效的时钟使能信号
OFB 输出 1 输出反馈端口,结合使用原语ISERDESE2或者ODELAYE2的时候会用到
OQ 输出 1 串行数据输出
RST 输入 1 复位信号
SHIFTIN1/SHIFTIN2 输入 1 级联输入信号,级联时与SHIFTOUT1/SHIFTOUT2相连
SHIFTOUT1/SHIFTOUT2 输出 1 级联输出信号,级联时与SHIFTIN1/SHIFTIN2相连
TBYTEIN 输入 1 Byte group 3-state input
TBYTEOUT 输出 1 Byte group 3-state output
TCE 输入 1 高电平有效的3态控制模块时钟使能信号
TFB 输出 1 输出反馈端口,结合使用原语ISERDESE2或者ODELAYE2的时候会用到
TQ 输出 1 3态控制模块的输出端口
T1 -- T4 输入 1 3态控制模块的输入端口

需要例化的一些可用属性如下:

属性 类型 可选值         默认值 描述
DATA_RATE_OQ 字符型 DDR,SDR DDR 数据是以DDR还是以SDR的形式输出
DATA_RATE_TQ 字符型 DDR,SDR,BUF DDR 3态控制是以DDR还是以SDR的形式输出
DATA_WIDTH 十进制 4,2,3,5,6,7,8,10,14 4 数据位宽
INIT_OQ 二进制 1'b0 to 1'b1 1'b0 输出数据的初始化值
INIT_TQ 二进制 1'b0 to 1'b1 1'b0 3态控制输出的初始化值
SERDES_MODE 字符型 MASTER,SLAVE MASTER 主、从模式,位宽小于等于8位时,不需要扩展到两个原语模块,选择MASTER,两个原语模块级联扩展位宽时,一个选择MASTER,另一个选择SLAVE
SRVAL_OQ 二进制 1'b0 to 1'b1 1'b0 OQ output value when SR is used
SRVAL_TQ 二进制 1'b0 to 1'b1 1'b0 TQ output value when SR is used
TBYTE_CTL 字符型 FALSE,TRUE FALSE 用于DDR3模式,使能三态模式的字符操作
TBYTE_SRC 字符型 FALSE,TRUE FALSE 用于DDR3模式,使能三态模式字符源
TRISTATE_WIDTH 十进制 4,1 4 3态转换位宽

TRISTATE_WIDTH的选取见下表:

SDR、DDR输出模式下位宽的选取有如下限制:

输出数据会有一些时钟周期的延迟,具体见下表:

3、8位数据的并串转换

接下里例化一个原语来熟悉下用法,8位数据的并串转换,采用DDR输出。

官方手册的8位DDR转化时序图如下:

例化原语OSERDESE2(打开VIvado--Tools--Language Templates,搜索“OSERDESE2”,可以找到Xilinx提供的模板),与DDR、3态控制相关的端口,输入全设置为0,输出不关心,编写Verilog如下:

//------------------------------------------------------------------------
//--OSERDESE2测试模块
//------------------------------------------------------------------------//------------<模块及端口声明>--------------------------------------------
module serializer(input         clk_ser     ,           //串行输出时钟,50M*4=200Minput            clk_per     ,           //并行输入时钟,50Minput            rst_n       ,           //复位信号,低电平有效input    [7:0]   par_data    ,           //并行输入数据output          ser_data                //串行输出数据
);//------------<例化原语>---------------------------------------------------
OSERDESE2 #(.DATA_RATE_OQ       ("DDR")       ,           // DDR, SDR.DATA_RATE_TQ        ("SDR")       ,           // DDR, BUF, SDR.DATA_WIDTH     (8)         ,           // 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 (.OFB                ()                  ,   // 1-bit output: Feedback path for data.OQ              (ser_data)          ,   // 1-bit output: Data path output.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_ser)           ,   // 1-bit input: High speed clock.CLKDIV         (clk_per)           ,   // 1-bit input: Divided clock.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          ()                  ,.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

每隔20ns随机生成1个8位2进制数据作为并行输入,观察串行输出,Testbench如下:

//------------------------------------------------
//--OSERDESE2原语仿真
//------------------------------------------------`timescale 1ns / 1ps         //时间单位/精度//------------<模块及端口声明>----------------------------------------
module tb_serializer();reg          clk_per     ;
reg         clk_ser     ;
reg         rst_n       ;
reg [7:0]   par_data    ;
wire        ser_data    ;//------------<设置初始测试条件>----------------------------------------
initial beginclk_per <= 1'b0;clk_ser <=  1'b1;rst_n <= 1'b0;par_data <= 8'd0;#180rst_n <= 1'b1;
end
//------------<设置时钟>----------------------------------------------
always #10  clk_per = ~clk_per;
always #2.5 clk_ser = ~clk_ser;always #20  par_data <= $random % 256;      //每20ns随机生成一个8位数据用于并行输入//------------<例化被测试模块>----------------------------------------
serializer  serializer_inst(.clk_per    (clk_per)   ,.clk_ser   (clk_ser)   ,.rst_n     (rst_n)     ,.par_data  (par_data)  ,.ser_data  (ser_data)
);endmodule

仿真结果如下:

可以看出:

  • 在第1条蓝线处,是复位后并行时钟的第1个上升沿,此时采集到的数据为0000_0001
  • 在第2条蓝线处,也就是4个串行时钟的延迟后,串行输出开始有数据,分别为1-0-0-0-0-0-0-0,可以看出是第1个上升沿采集到的数据输出(0000_0001从低位往高位输出)
  • 在第2条蓝线处,是复位后并行时钟的第2个上升沿,此时采集到的数据为0000_1101
  • 在第3条蓝线处,也就是4个串行时钟的延迟后,串行输出开始有数据,分别为1-0-1-1-0-0-0-0,可以看出是第2个上升沿采集到的数据输出(0000_1101从低位往高位输出)

其他与上述相同,符合官方给出的时序图

4、10位数据的并串转换(级联)

OSERDESE2原语还支持例化两次原语级联,以便实现10位、14位位宽的串行化转换。下图是10位位宽的级联框图,其中一个设置位MASTER,另一个设置为SLAVE,通过SHIFTIN与SHIFTOUT连接。

需要注意:数据的输出从MASTER输出,数据的高位输入到SLAVE模块时,需要从D3开始(只能使用D3~D8)

接下里例化一个原语来实现10位数据的并串转换,采用DDR输出。

例化2个原语OSERDESE2级联(打开VIvado--Tools--Language Templates,搜索“OSERDESE2”,可以找到Xilinx提供的模板),与DDR、3态控制相关的端口,输入全设置为0,输出不关心,编写Verilog如下:

//------------------------------------------------------------------------
//--OSERDESE2测试模块
//------------------------------------------------------------------------//------------<模块及端口声明>--------------------------------------------
module serializer(input         clk_ser     ,           //串行输出时钟,50M*5=250Minput            clk_per     ,           //并行输入时钟,50Minput            rst_n       ,           //复位信号,低电平有效input    [9:0]   par_data    ,           //并行输入数据,位宽10output          ser_data                //串行输出数据
);
//------------<wire定义>------------------------------------------------------
wire    shift1;     //级联线1
wire    shift2;     //级联线2//------------<例化原语>------------------------------------------------------//例化主模块MASTER
OSERDESE2 #(.DATA_RATE_OQ       ("DDR")       ,           // DDR, SDR.DATA_RATE_TQ        ("SDR")       ,           // 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_inst1 (.OFB               ()                  ,   // 1-bit output: Feedback path for data.OQ              (ser_data)          ,   // 1-bit output: Data path output.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_ser)           ,   // 1-bit input: High speed clock.CLKDIV         (clk_per)           ,   // 1-bit input: Divided clock.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          (shift1)            ,.SHIFTIN2          (shift2)            ,.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
);//例化从模块SLAVE
OSERDESE2 #(.DATA_RATE_OQ       ("DDR")       ,           // DDR, SDR.DATA_RATE_TQ        ("SDR")       ,           // 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_inst2 (.OFB               ()                  ,   // 1-bit output: Feedback path for data.OQ              ()                  ,   // 1-bit output: Data path output.SHIFTOUT1     (shift1)                    ,.SHIFTOUT2     (shift2)                    ,.TBYTEOUT          ()                  ,   // 1-bit output: Byte group tristate.TFB                ()                  ,   // 1-bit output: 3-state control.TQ             ()                  ,   // 1-bit output: 3-state control.CLK                (clk_ser)           ,   // 1-bit input: High speed clock.CLKDIV         (clk_per)           ,   // 1-bit input: Divided clock.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          ()                  ,.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

每隔20ns随机生成1个10位2进制数据作为并行输入,观察串行输出,Testbench如下:

//------------------------------------------------
//--OSERDESE2原语仿真
//------------------------------------------------`timescale 1ns / 1ps         //时间单位/精度//------------<模块及端口声明>----------------------------------------
module tb_serializer();reg          clk_per     ;
reg         clk_ser     ;
reg         rst_n       ;
reg [9:0]   par_data    ;
wire        ser_data    ;//------------<设置初始测试条件>----------------------------------------
initial beginclk_per <= 1'b0;clk_ser <=  1'b0;rst_n <= 1'b0;par_data <= 10'd0;#180rst_n <= 1'b1;
end
//------------<设置时钟>----------------------------------------------
always #10  clk_per = ~clk_per;
always #2   clk_ser = ~clk_ser;always #20  par_data <= $random % 1024;     //每20ns随机生成一个10位数据用于并行输入//------------<例化被测试模块>----------------------------------------
serializer  serializer_inst(.clk_per    (clk_per)   ,.clk_ser   (clk_ser)   ,.rst_n     (rst_n)     ,.par_data  (par_data)  ,.ser_data  (ser_data)
);endmodule

仿真结果如下:

可以看出:

  • 在第1条蓝线处,是复位后并行时钟的第1个上升沿,此时采集到的数据为11000_00001
  • 在第2条蓝线处,也就是4个串行时钟的延迟后,串行输出开始有数据,分别为1-0-0-0-0-0-0-0-1-1,可以看出是第1个上升沿采集到的数据输出(11000_00001从低位往高位输出)
  • 在第2条蓝线处,是复位后并行时钟的第2个上升沿,此时采集到的数据为01000_01101
  • 在第3条蓝线处,也就是4个串行时钟的延迟后,串行输出开始有数据,分别为1-0-1-1-0-0-0-0-1-0,可以看出是第2个上升沿采集到的数据输出(01000_01101从低位往高位输出)

其他与上述相同。

这里官方手册没有给出10bitDDR输出的时序图,输出延迟给出的表如下图:

可以看到这里10:1的输出延迟应该是5个时钟周期,但是我上面仿真的却是4个时钟周期,一开始我还以为是哪里错了,搞得我重复仿真了好几遍,后面又看了一下手册,终于在延迟表的下面发现了这句话(上图标红):CLK、CLKDIV的时钟沿通常不是相位一致的。当这两个时钟的时钟沿相位一致时,延迟会存在一个周期的差异。

这样的话,仿真结果应该是没有问题。

5、参考

7 Series FPGAs SelectIO Resources User Guide(UG471)--Xlinx

Xilinx中oserdes的原语及IP的使用

Xinlix原语OSERDESE2的使用和仿真相关推荐

  1. 【XINLIX 原语】XILINX 原语的使用之 IBUFDS 差分转单端、OBUFDS 单端转差分

    目录 IBUFGDS IBUFDS 介绍 IBUFDS 示意图 例化方式 OBUFDS OBUFDS 介绍 OBUFDS 示意图 例化方式 在 XILINX 中有许多原语,常见的差分转单端 IBUFD ...

  2. FPGA极速入门(持续更新)

    第一章:VERILOG速览 关于参数与符号: 1.1 数值表示:以8'b10_110_110为例,8指的是位宽,b指的是数据类型为2进制,可以用下划线或者空格作数值分隔,不影响数值大小.此外,字符串类 ...

  3. VIVADO仿真功能系列

    版权声明:本文为CSDN博主「FPGADesigner」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/F ...

  4. Vivado使用技巧(18):仿真功能概述

    仿真功能概述 仿真FPGA开发中常用的功能,通过给设计注入激励和观察输出结果,验证设计的功能性.Vivado设计套件支持如下仿真工具:Vivado Simulator.Questa.ModelSim. ...

  5. HDMI接口介绍及其代码

    一.初衷 HDMI是之前项目的一部分,本来不打算上传博客的,最近我们专业课设开始,恰好可以选择完成HDMI显示,也重新整理一下之前的项目,对于课设,这只是实现了基本功能,附加条件等过几天再更:希望这篇 ...

  6. Vivado simulation使用简介

    作为FPGA入门小白,使用vivado simulation进行仿真分析是必不可少的,但是对simulation界面的使用一直不是很熟悉,现在此做详细的总结. 基本操作 Vivado Simulato ...

  7. Verilog语言快速入门(一)

    组合逻辑的一般模板 时序电路的一般模板 模块总体结构 模块说明 功能描述 1.assign语句   1)算数型 2)逻辑型 3)关系运算符 4) 等价运算符 5)按位运算符 6)缩减运算符 7) 移位 ...

  8. FPGA学习日记(七)HDMI图像数据传输

    一.实现目标 将像素数据通过HDMI传输,在显示器上显示. 二.数据流传输 HDMI常采用TMDS传输(上升沿复位)方式: (1)通过三个通道分别可传入8位的rgb视频信号,2位的控制信号,4位的音频 ...

  9. VIVADO的差分转单端IBUFDS的使用

    VIVADO的差分转单端IBUFDS的使用 pp_0604 2020-07-06 11:43:47 1883 收藏 8 分类专栏: 笔记 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版 ...

最新文章

  1. mysql系列十、mysql索引结构的实现B+树/B-树原理
  2. Windows Phone 实用开发技巧(9):自定义Windows Phone 页面切换动画
  3. linux nfs时间不对,NFS挂载主机或不稳定的原因与解决方法
  4. pytorch安装换源ubuntu_ubuntu 安装pytorch问题
  5. python网络爬虫系列(0)——爬虫概述 http协议复习
  6. 04_SpringCloud 整合Ribbon细粒度配置自定义
  7. 2、运行WordCount程序
  8. 2021年微信视频号生态趋势调查报告
  9. 【SICP练习】115 练习3.41
  10. linux 查看网络流量
  11. MATLAB程序设计的绘图函数
  12. 基于PLC和组态软件的多方式运行小车控制系统设计
  13. 深入理解MessageQueue
  14. 舱机器人尾巴毛茸茸_第一千五百二十四章 毛茸茸【二合一】
  15. 阿里、华为都是外包公司?
  16. 【SpringBoot】自定义starter实现详解
  17. 计算机起源于发展论文,关于计算机起源及发展的论文
  18. Efficient Image Dehazing with Boundary Constraint and Contextual Regularization
  19. 又一年没有中国队的世界杯,你还会熬夜打call吗?网友的回答亮了
  20. python django + uwsgi+Nginx宝塔centos7的部署方案

热门文章

  1. 利用log4j写日志
  2. 安卓Socket与pc端c#服务器的通信 附完整代码
  3. w7计算机防火墙无法更改,Win7系统电脑防火墙设置无法更改该怎么解决?
  4. xcode5 Localized 多语言 本地化
  5. 72 ----直纹面、二次直纹面、单叶双曲面、双曲抛物面
  6. PLY文件读取与显示
  7. 第3.1章:StarRocks数据导入--Insert into
  8. 信息收集之基础端口扫描《诸神之眼——Nmap网络安全审计技术揭秘》总结一
  9. Tomcat执行startup.bat出现闪退的可能原因
  10. 角度转度分秒lisp函数_自改小程序,提示错误,运行另一个lisp后就不会出错,求帮忙!...