Xinlix原语OSERDESE2的使用和仿真
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的使用和仿真相关推荐
- 【XINLIX 原语】XILINX 原语的使用之 IBUFDS 差分转单端、OBUFDS 单端转差分
目录 IBUFGDS IBUFDS 介绍 IBUFDS 示意图 例化方式 OBUFDS OBUFDS 介绍 OBUFDS 示意图 例化方式 在 XILINX 中有许多原语,常见的差分转单端 IBUFD ...
- FPGA极速入门(持续更新)
第一章:VERILOG速览 关于参数与符号: 1.1 数值表示:以8'b10_110_110为例,8指的是位宽,b指的是数据类型为2进制,可以用下划线或者空格作数值分隔,不影响数值大小.此外,字符串类 ...
- VIVADO仿真功能系列
版权声明:本文为CSDN博主「FPGADesigner」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/F ...
- Vivado使用技巧(18):仿真功能概述
仿真功能概述 仿真FPGA开发中常用的功能,通过给设计注入激励和观察输出结果,验证设计的功能性.Vivado设计套件支持如下仿真工具:Vivado Simulator.Questa.ModelSim. ...
- HDMI接口介绍及其代码
一.初衷 HDMI是之前项目的一部分,本来不打算上传博客的,最近我们专业课设开始,恰好可以选择完成HDMI显示,也重新整理一下之前的项目,对于课设,这只是实现了基本功能,附加条件等过几天再更:希望这篇 ...
- Vivado simulation使用简介
作为FPGA入门小白,使用vivado simulation进行仿真分析是必不可少的,但是对simulation界面的使用一直不是很熟悉,现在此做详细的总结. 基本操作 Vivado Simulato ...
- Verilog语言快速入门(一)
组合逻辑的一般模板 时序电路的一般模板 模块总体结构 模块说明 功能描述 1.assign语句 1)算数型 2)逻辑型 3)关系运算符 4) 等价运算符 5)按位运算符 6)缩减运算符 7) 移位 ...
- FPGA学习日记(七)HDMI图像数据传输
一.实现目标 将像素数据通过HDMI传输,在显示器上显示. 二.数据流传输 HDMI常采用TMDS传输(上升沿复位)方式: (1)通过三个通道分别可传入8位的rgb视频信号,2位的控制信号,4位的音频 ...
- VIVADO的差分转单端IBUFDS的使用
VIVADO的差分转单端IBUFDS的使用 pp_0604 2020-07-06 11:43:47 1883 收藏 8 分类专栏: 笔记 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版 ...
最新文章
- mysql系列十、mysql索引结构的实现B+树/B-树原理
- Windows Phone 实用开发技巧(9):自定义Windows Phone 页面切换动画
- linux nfs时间不对,NFS挂载主机或不稳定的原因与解决方法
- pytorch安装换源ubuntu_ubuntu 安装pytorch问题
- python网络爬虫系列(0)——爬虫概述 http协议复习
- 04_SpringCloud 整合Ribbon细粒度配置自定义
- 2、运行WordCount程序
- 2021年微信视频号生态趋势调查报告
- 【SICP练习】115 练习3.41
- linux 查看网络流量
- MATLAB程序设计的绘图函数
- 基于PLC和组态软件的多方式运行小车控制系统设计
- 深入理解MessageQueue
- 舱机器人尾巴毛茸茸_第一千五百二十四章 毛茸茸【二合一】
- 阿里、华为都是外包公司?
- 【SpringBoot】自定义starter实现详解
- 计算机起源于发展论文,关于计算机起源及发展的论文
- Efficient Image Dehazing with Boundary Constraint and Contextual Regularization
- 又一年没有中国队的世界杯,你还会熬夜打call吗?网友的回答亮了
- python django + uwsgi+Nginx宝塔centos7的部署方案
热门文章
- 利用log4j写日志
- 安卓Socket与pc端c#服务器的通信 附完整代码
- w7计算机防火墙无法更改,Win7系统电脑防火墙设置无法更改该怎么解决?
- xcode5 Localized 多语言 本地化
- 72 ----直纹面、二次直纹面、单叶双曲面、双曲抛物面
- PLY文件读取与显示
- 第3.1章:StarRocks数据导入--Insert into
- 信息收集之基础端口扫描《诸神之眼——Nmap网络安全审计技术揭秘》总结一
- Tomcat执行startup.bat出现闪退的可能原因
- 角度转度分秒lisp函数_自改小程序,提示错误,运行另一个lisp后就不会出错,求帮忙!...