做数字电路设计的朋友对差分信号的定义应该都不会太陌生,在当前比较流行的高速串行总线上,基本都是使用的差分信号。比如USB,PCIE,SATA等等。大多数的FPGA也都支持差分信号,甚至某些新型号的CPLD也开始支持差分信号了。
那么在FPGA中如何正确定义和使用差分信号呢?在这篇文章里,我们基于ALTERA公司的CYCLONE III系列的FPGA芯片,做一些讨论。
一,差分信号输出
我们先在设计中定义一个名字为DIF_OUT的输出信号。并将UART_CLK时钟赋给它(UART_CLK为串口时钟,大概为115.2kHz)。(该实验是在一个FPGA的项目上添加部分差分信号的设计来做的,会引用到原设计里的一些信号,但在介绍中,只会给出与差分信号实验相关的部分)如下面所示:
module FPGA_TOP(
……
DIF_OUT,
……
);
……
output DIF_OUT;
……
assign DIF_OUT = UART_CLK;
endmodule
在设计里,DIF_OUT和其他变量的定义和赋值方式是一样的,没有任何的区别。如果需要将DIF_OUT当做差分信号输出的话,就必须在Pin Planner中对其I/O Standard进行定义。如下图所示,我们可以把I/O Standard定义为1.2V的单端输出信号。
我们也可以把I/O Standard定义为BUS_LVDS类型的信号,这个时候会出现什么情况呢?从下面的图可以看到,系统会在将DIF_OUT定义为Bus LVDS类型的同时,多添加一个DIF_OUT(n)的信号,并且根据DIF_OUT的location自动选定DIF_OUT(n)的location。在Differential Pair里,会显示这两个信号互为差分信号对,也就是说,这是一组差分信号。
那我们看一下这一组差分信号的输出电平。下面是在示波器上抓取的信号波形,可以看到二者的电平是相反的。
再看一下两者的电平值,可以看到,电平是0V,高电平是330mV左右。这是正常的差分信号的电平。
我们再通过实例讨论一下CYCLONE III中定义差分信号时的注意事项。
1. 差分信号对必须按照芯片的定义来配置。
FPGA芯片的管脚定义中,会给出哪两个IO可以当做一对差分信号来使用,如下图中,我们刚才使用了EP3C5E144 BANK3中的IO,DIFFIO_B11p(52)和IO,DIFFIO_B11n(53)来定义DIF_OUT这一对差分信号。
如果我们不这样定义呢,比如说定义DIF_OUT到Pin46上,看会出现什么情况。先定义DIF_OUT到Pin46上,I/O Standard暂且选为2.5V,如下图所示:
然后我们去看I/O Standard的下拉列表,根本就没有Bus LVDS的选项,也就是说,没有办法把这个信号定义为差分信号。如果我们先定义I/O Standard为Bus LVDS,然后去选择location到PIN_46,这个时候会出现下面的对话框,也就是说,没有办法定义这个pin为差分信号。
2. 差分信号所在BANK的IO参考电压(VCCIO)必须设定为2.5V
我们在BANK3添加DP_DATA[7]的信号,location选为PIN_38,I/O Standard选为3.3-V LVTTL(这就意味着BANK3的IO参考电压为3.3V),然后编译设计。软件会报告如下的错误(截图的原因,只给出Error的前半部分):
可以看出,差分信号需要的VCCIO是2.5V。
实际上软件并不知道在实际的系统上该BANK的VCCIO接的电源是多少,只要不定义该BANK的任一IO的I/O Standard为非2.5V的值,编译的时候都会认为该BANK的VCCIO是2.5V。至于说如果VCCIO接了非2.5V的电源,编译后的程序在FPGA上能不能正常工作就不太好讲了。唯一可以确认的是,我实验的结果是VCCIO接3.3V的话差分信号可以正常工作。
3. Location上紧邻着某一对差分信号的信号不能作为单端信号使用
我们把DP_SEL[0]信号的location设定到PIN_51,I/O Standard设定为2.5V,重新编译系统,会看到下面的Error:
也就是说,DP_SEL[0]这个单端信号离DIF_OUT这对差分信号太近了,不能这样分配。我们把DP_SEL[0]定义到BANK3中的location PIN_49上,重新综合,可以发现,软件没有报错,在Pin Planner中,也正确定义了这三个信号,如下图所示:
如果我们选择DP_SEL[0]的location为PIN_50的话,软件仍然会报上面的错误,也就是说,同BANK中,location离差分信号距离小于等于2的信号不能用作单端信号