xilinx c语言u16,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)

48f1538a013061d14c935802ef9d7703.png

通信框图:

1ff6b48c416e204c28a3a9a01eb4e56f.png

因为串行转成并行的时候,输出的数据无法判断哪个 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的接收时钟。

2-基于6U VPX的双TMS320C6678&plus;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的逻辑容量越 ...

随机推荐

ACM&sol;ICPC 之 靠墙走-DFS&plus;BFS&lpar;POJ3083&rpar;

//POJ3083 //DFS求靠左墙(右墙)走的路径长+BFS求最短路 //Time:0Ms Memory:716K #include #include

记录bigdesk中ElasticSearch的性能参数

定时采集bigdesk中的Elasticsearch性能参数,并保存到数据库或ELK,以便于进行长期监控. 基于python脚本实现,脚本如下: #coding=gbk import httplibi ...

HBase概念学习(七)HBase与Mapreduce集成

这篇文章是看了HBase权威指南之后,依据上面的解说搬下来的样例,可是略微有些不一样. HBase与mapreduce的集成无非就是mapreduce作业以HBase表作为输入,或者作为输出,也或者作 ...

第3章 Java语言基础----成员变量与局部变量

在对局部变量进行赋值时,不能对非静态字段age进行静态引用,图1错误,加上static后图二正确,图3与图4类似,如下图所示: 图1图2 图3图4 2.成员变量times在类中定义,局部变量times ...

Java中Json解析

首先准备一个JSON格式的字符串 * String JsonStr = "{object:{persons:" + "[{name:'呵呵',image:'http:// ...

用Node&period;JS&plus;MongoDB搭建个人博客(万众期待的router&period;js)(四)

万众期待的router.js,是我现在最想写的一个博客.因为他包含了整个个人博客的精髓.在这里,所有的请求配置,返回的参数等等所做的业务逻辑都在这个文件里实现. 我会详细说明这些代码的作用,所以这篇博 ...

UWP 使用UCT的Markdown控件

之前在网上偶然碰到过 一个在线的Markdown Text编辑器 http://mahua.jser.me/,功能很齐全. 然后就突然有了一个大胆的想法 这个玩意要是在uwp中实现,用来做更新日志说明 ...

新手学python(3):yield与序列化

1 Yield生成器 Yield是我在其他语言中没有见过的一个属性,算是python的一大特色,用好之后可以使代码更简洁.考虑一个简单的例子,文件的遍历.要遍历一个目录下的所有文件需要递归的操作.如果 ...

android startActivityForResult 使用实例

ActivityForResult.java public class ActivityForResult extends Activity { Button bn; EditText city; @ ...

《Linux内核分析》第六周学习小结

进程的描述和进程的创建 一.进程的描述 进程描述符task_struct数据结构: (1)操作系统的三大功能: 进程管理.内存管理.文件系统 (2)进程的作用: 将信号.进程间通信.内存管理和文件系统 ...

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值