Xilinx FPGA LVDS应用
最近项目需要用到差分信号传输,于是看了一下FPGA上差分信号的使用。Xilinx FPGA中,主要通过原语实现差分信号的收发:OBUFDS(差分输出BUF),IBUFDS(差分输入BUF)。
注意在分配引脚时,只需要分配SIGNAL_P的引脚,SIGNAL_N会自动连接到相应差分对引脚上;若没有使用差分信号原语,则在引脚电平上没有LVDS的选项(IO Planning PlanAhead)。
测试代码:
//////////////////////////////////////////////////////////////////////////////////
module lvds_test( sys_clk,
sys_rst, signal_in_p,
signal_in_n,
signal_out_p,
signal_out_n, led_signal
); input sys_clk,sys_rst;
input signal_in_p,signal_in_n;
output signal_out_p,signal_out_n;
output led_signal; wire signal_out_temp;
reg[:] clk_cnt; always @ (posedge sys_clk) begin
if(!sys_rst) clk_cnt <= 'd0;
else begin
if(clk_cnt == 'd10_000_000) clk_cnt <= 32'd0;
else clk_cnt <= clk_cnt+'b1;
end
end assign signal_out=(clk_cnt >= 'd5_000_000) ? 1 : 0; OBUFDS signal_out_diff( .O(signal_out_p),
.OB(signal_out_n),
.I(signal_out)
); IBUFDS signal_in_diff( .O(led_signal),
.I(signal_in_p),
.IB(signal_in_n)
); endmodule
约束文件:
NET "signal_out_p" IOSTANDARD = LVDS_33; NET "signal_out_p" LOC = U16; NET "sys_clk" IOSTANDARD = LVCMOS33;
NET "sys_rst" IOSTANDARD = LVCMOS33; NET "led_signal" LOC = D18; NET "led_signal" IOSTANDARD = LVCMOS33;
#Created by Constraints Editor (xc6slx45t-csg324-) - //
NET "sys_clk" TNM_NET = "sys_clk";
TIMESPEC TS_sys_clk = PERIOD "sys_clk" MHz HIGH %; NET "signal_in_p" LOC = T12;
NET "signal_in_n" LOC = V12;
NET "sys_clk" LOC = G8;
NET "sys_rst" LOC = U3; # PlanAhead Generated IO constraints NET "signal_in_p" IOSTANDARD = LVDS_33;
约束文件IO Planning PlanAhead产生,原语的使用可参考:E:\Xilinx\ISE\14.7\ISE_DS\ISE\doc\usenglish\isehelp\spartan6里面提供了所用器件的原语。同时,Xilinx器件内部信号内部还提供了100欧姆电阻匹配,可参考Spartan-6 FPGA SelectIO Resources(UG381)
补充:
若要实现高速通信的场合,可以利用FPGA内部自带的SelectIO资源,利用ISERDESE2、 OSERDESE2,实现串-并,并-串的转换,理论速度可达到750Mbs,参考资料:Spartan-6 FPGA Data Sheet: DC and Switching Characteristics(UG162)
通信框图:
因为串行转成并行的时候,输出的数据无法判断哪个 Bit 是高位,哪个 bit 是低位,因此,对于 ISERDESE2 可以利用bitslip 信号来重新对齐串行数据以获得正确的字节数据;代码实现时,也需要先进行数据对齐,才能进行数据的正常接收。
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
module lvds_test(
input clk_50m,//全局时钟
input rstn, //复位 input clk_in_from_pin_p, //lvds时钟输出P
input clk_in_from_pin_n, //lvds时钟输入N
input data_in_from_pin_p, //lvds输入数据P
input data_in_from_pin_n, //lvds输入数据N output clk_out_to_pin_p, //lvds时钟输出P
output clk_out_to_pin_n, //lvds时钟输出N
output data_out_to_pin_p, //lvds输出数据P
output data_out_to_pin_n //lvds输出数据N
); wire clk_div_out_1; //低速时钟1,串行发送时钟的8分频
wire clk_div_out_2; //低速时钟2,串行接收时钟的8分频 wire [:] datain; //LVDS输入的8位并行数据 //产生LVDS发送的测试数据,0~FF
reg [:] dataout;
always @(posedge clk_div_out_1) begin
if (~rstn)
dataout <= ;
else if (dataout == 'hff)
dataout <= ;
else
dataout <= dataout + 'b1;
end //产生BITSLIP信号,用于修改串转并的Bit的起始位置
wire [:] data_delay;
reg BITSLIP='b0;
reg slip_check;
reg equal='b0;
assign data_delay=datain; always @(posedge clk_div_out_2)
begin
if (~rstn)
slip_check <= 'b0;
else if(data_delay=='h80) //当串转并的输入的数据为0x80的时候,检测开始
slip_check <= 'b1;
else
slip_check <= 'b0;
end always @(posedge clk_div_out_2)
begin
if (~rstn) begin
BITSLIP <= 'b0;
equal<='b0;
end
else if((slip_check=='b1) && (equal==1'b0))
if (data_delay =='h81) begin //如果检测到数据0x80后面的下一个时钟的数据为0x81时
BITSLIP <= 'b0; //BITSLIP不为高
equal<='b1; //数据正确信号为高
end
else begin
BITSLIP <= 'b1; //BITSLIP产生一个高脉冲,改变串转并的数据排列
equal<='b0; //数据正确信号为低
end
else begin
BITSLIP <= 'b0;
equal<=equal;
end
end //并转串,8位数据dataout转换成串行数据,并通过lvds差分信号输出
p_to_s p_to_s_inst
(
// From the device out to the system
.DATA_OUT_FROM_DEVICE(dataout), //Input pins
.DATA_OUT_TO_PINS_P(data_out_to_pin_p), //Output pins
.DATA_OUT_TO_PINS_N(data_out_to_pin_n), //Output pins
.CLK_TO_PINS_P(clk_out_to_pin_p), //Output pins
.CLK_TO_PINS_N(clk_out_to_pin_n), //Output pins .CLK_IN(clk_50m), // Single ended clock from IOB
.CLK_DIV_OUT(clk_div_out_1), // Slow clock output
.IO_RESET(~rstn) //system reset
); //串转并,LVDS差分信号转换成单端信号再通过串转并,转换为8位数据datain
s_to_p s_to_p_inst
(
// From the system into the device
.DATA_IN_FROM_PINS_P(data_in_from_pin_p), //Input pins
.DATA_IN_FROM_PINS_N(data_in_from_pin_n), //Input pins
.DATA_IN_TO_DEVICE(datain), //Output pins .BITSLIP(BITSLIP), //Input pin
.CLK_IN_P(clk_in_from_pin_p), // Differential clock from IOB
.CLK_IN_N(clk_in_from_pin_n), // Differential clock from IOB
.CLK_DIV_OUT(clk_div_out_2), // Slow clock output
.IO_RESET(~rstn) //system reset
); endmodule
其中,clk_div_out_1和clk_div_out_2是8分频得到的(ISERDESE2、 OSERDESE2核实现),OSERDESE2输出的LVDS 差分时钟可作为ISERDESE2的接收时钟。
Xilinx FPGA LVDS应用的更多相关文章
- 2-基于6U VPX的双TMS320C6678+Xilinx FPGA K7 XC7K420T的图像信号处理板
基于6U VPX的双TMS320C6678+Xilinx FPGA K7 XC7K420T的图像信号处理板 综合图像处理硬件平台包括图像信号处理板2块,视频处理板1块,主控板1块,电源板1块,VPX背 ...
- 基于Xilinx FPGA的视频图像采集系统
本篇要分享的是基于Xilinx FPGA的视频图像采集系统,使用摄像头采集图像数据,并没有用到SDRAM/DDR.这个工程使用的是OV7670 30w像素摄像头,用双口RAM做存储,显示窗口为320x ...
- Xilinx FPGA引脚txt文件导入excel中
需求 为了把xilinx FPGA的官方引脚文件txt转成excel文件(实际官网中有对应的csv文件就是excel文件了...) xilinx FPGA引脚地址:https://china.xili ...
- Xilinx FPGA复位逻辑处理小结(转)
Xilinx FPGA复位逻辑处理小结 1. 为什么要复位呢? (1)FPGA上电的时候对设计进行初始化: (2)使用一个外部管脚来实现全局复位,复位作为一个同步信号将所有存储单元设置为一个已知的状态 ...
- Xilinx FPGA开发环境vivado使用流程
Xilinx FPGA开发环境vivado使用流程 1.启动vivado 2016.1 2.选择Create New Project 3.指定工程名字和工程存放目录 4.选择RTL Project 5 ...
- 你真的会Xilinx FPGA的复位吗?
Get Smart About Reset: Think Local, Not Global. 对于复位信号的处理,为了方便我们习惯上采用全局复位,博主在很长一段时间内都是将复位信号作为一个I/O口, ...
- Xilinx FPGA高速串行收发器简介
1 Overview 与传统的并行实现方法相比,基于串行I/O的设计具有很多优势,包括:器件引脚数较少.降低了板空间要求.印刷电路板(PCB)层数较少.可以轻松实现PCB设计.连接器较小.电磁干扰降低 ...
- 关于Xilinx FPGA JTAG下载时菊花链路中的芯片数量
关于Xilinx FPGA JTAG下载时菊花链路中的芯片数量 emesjx | 2014-08-13 13:13:30 阅读:1793 发布文章 当一个系统中含有多片(2片以上)Xil ...
- Xilinx FPGA结构
FPGA是什么?FPGA是现场可编程逻辑阵列,由可编程逻辑资源(LUT和 REG),可编程连线,可编程I/O构成.Xilinx的FPGA的基本结构是一样的,但随着半导体工艺的发展,FPGA的逻辑容量越 ...
随机推荐
- MySQL笔记 存储过程 游标 触发器
第二十三章 使用存储过程 MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成 存储过程简单来说,就 ...
- WPF DataGrid 样式设置
隔行换色,鼠标单击,悬浮样式都有,其具体效果如图 1 所示. 图 1 WPF DataGrid 样式设置效果图 其中: 界面设计代码下所示 ? + 查看代码 1 2 3 4 5 6 7 8 9 10 ...
- kazoo python zookeeper 选主
本文讲述基于zookeeper选主与故障切换的方法.我们的例子使用的是python. 使用的库是kazoo,安装方式 pip install kazoo 应用场景: 多个实例部署,但不是" ...
- 从字符串获得MAC地址的方法
今日有感于编程水平下降,特意练习一下,根据MAC地址字符串,获取MAC地址的2种方法. #include <stdio.h> void func1(char *str){ unsigned ...
- 吾八哥学Python(二):Python代码编辑器的选用
Python开发环境配置好了,但发现自带的代码编辑器貌似用着有点不大习惯啊,所以咱们就找一个"好用的"代码编辑器吧,网上搜了一下资料,Python常用的编辑器有如下一些: 1. S ...
- 从零开始搭建框架SSM+Redis+Mysql(一)之摘要
从零开始搭建框架SSM+Redis+Mysql(一)之摘要 本文章为本人实际的操作后的回忆笔记,如果有步骤错漏,希望来信307793969@qq.com或者评论指出. 本文章只体现过程,仅体现操作流程 ...
- Table样式设置
<table class="listTable"> <tr><th width="40px">序号</th>&l ...
- 双端链表--Java实现
/*双端链表--比普通链表多了一个指向最后一个节点的引用 * 特点: 链表可以进行尾巴插入--输出顺序和输入顺序一致 * 但是不可以进行尾巴删除因为没有倒数第二节点的引用 * */ public cl ...
- yii2之GridView小部件
GridView小部件用于展示多条数据的列表.GridView小部件的使用需要数据提供器即yii\data\ActiveDataProvider的实例作为参数,所以 第一步就是要在控制器方法中创建这个 ...
- Linux系统挂载操作mount详解
在Linux系统中,文件系统不挂载是无法使用的.挂载,即是让文件系统在操作系统中可用.在Linux中使用mount命令来挂载文件系统,有永久性挂载和临时性挂载两种挂载方式. 1. 永久性挂载: 修改配 ...