ZYNQ7020 LVDS信号传输实战:OBUFDS与IBUFDS原语应用解析

1. 从单端到差分:为什么LVDS是高速传输的首选?

如果你玩过ZYNQ7020,或者任何一款FPGA,想把一个高速时钟或者数据信号从芯片里送出去,你可能会直接把它连到某个输出引脚上。但当你跑到几百兆赫兹甚至更高频率时,问题就来了:单端信号对外部噪声太敏感了,信号质量下降得厉害,传输距离也上不去。这时候,就该LVDS登场了。

LVDS,全称低压差分信号,它不是什么新玩意儿,但在高速、抗干扰、低功耗的场合,几乎是“标配”。它的工作原理特别巧妙:不是用一个引脚对地输出一个电压,而是用一对引脚,输出两个极性相反、幅度相等的信号。接收端不关心这对信号具体是几伏,只关心它们之间的电压差。外界的共模噪声会同时作用在这两根线上,但差值几乎不变,这就天然具备了强大的抗干扰能力。实测下来,用LVDS传数据,比单端信号稳太多了。

在ZYNQ7020这类7系列FPGA里,硬件上已经为LVDS这类差分信号做好了准备。芯片的I/O Bank里,相邻的物理引脚可以被配置成一个差分对(比如PN)。但是,你写Verilog代码时,如果直接把一个内部信号assign给两个输出端口,工具可不会自动帮你生成差分驱动电路。这就需要我们手动调用Xilinx提供的“原语”——你可以把它理解为FPGA底层最基础的硬件模块。对于输出LVDS,这个原语就是OBUFDS;对于接收LVDS,则是IBUFDS。我刚开始搞这块的时候,以为只要约束文件里指定了LVDS标准就行,结果综合出来根本不对,信号出不去,踩了个大坑。后来才明白,必须得在代码里显式地例化这些原语,工具才会调用对应的硬件资源。

2. 实战第一步:用OBUFDS原语输出LVDS信号

好了,理论说完,我们直接上代码。假设你FPGA内部有一个50MHz的时钟信号clk_i,你想把它以LVDS的形式发送出去,正负端分别接到顶层端口dout_pdout_n上。

你会怎么写?我猜你可能第一反应是:

assign dout_p = clk_i;
assign dout_n = ~clk_i;

千万别这么干! 我试过,这么写综合工具要么报错,要么综合出来的根本不是真正的差分输出,性能极差,而且你后面想加IO约束都困难。

正确的做法是调用OBUFDS原语。下面是一个最基础的例化模板:

OBUFDS #(
    .IOSTANDARD("LVDS_25"), // 指定输出IO标准为LVDS_25
    .SLEW("SLOW")           // 指定输出压摆率为慢速
) dout_OBUFDS_inst (
    .O  (dout_p), // 差分正端输出,连接至顶层端口
    .OB (dout_n), // 差分负端输出,连接至顶层端口
    .I  (clk_i)   // 内部单端信号输入
);

这段代码是什么意思呢?我来拆解一下:

  • OBUFDS:这就是我们要用的输出差分缓冲器原语。
  • #( ... ):这是Verilog的参数例化语法,用来配置原语的属性。
    • .IOSTANDARD("LVDS_25"):这是最关键的参数之一。它告诉FPGA,这对引脚要用LVDS_25电平标准。这里的“25”代表典型的输出共模电压是2.5V。这个参数必须和你的硬件设计(Bank电压)以及约束文件保持一致。
    • .SLEW("SLOW"):压摆率控制。设为“SLOW”可以减小信号边沿的陡峭程度,从而降低电磁干扰(EMI),但会限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值