IO SERDER
IO SERDES可以分成两种,在不同的场合有不同的含义,第一种是指的高速收发器GTx bank对应的SERDES,第二种就是SelectedIO提供的SERDES功能,GTX的功能在\ref{ssec_gtx}介绍过,这里主要写的是SelectedIO的SERDES功能。
从李诚师兄开始研发了一套基于普通IO的光纤通信方案(当然再之前的师兄有没有做过我就不是很了解了),光纤通信一个比较关键的问题就是串并转换的问题,也就是我们所说的Serializer/Deserializer,Xilinx的FPGA内置了Selected IO,就提供了相应的硬件结构。
具体的使用还是要看UG471 SelectIO, 这里主要对SelectIO的一些功能进行介绍。 主要提供了:差分匹配、IDELAY、ODELAY、IDELAYCTRL、ISERDES、OSERDES和ZHOLD_DELAY的功能
I/O DELAY
顾名思义,这两个功能在在相应的管脚上叠加上一定的延迟值,用来使FPGA内部的逻辑时序满足,比较常用的是IDELAY功能,ODELAY目前还没有用到过(HR bank不支持ODELAY功能)。图\ref{fig_idelaye2}所示为IDELAY的接口结构图,其中的IDATAIN就是数据输入管脚,注意这个信号只能从IBUF来,当然数据也可以从FPGA逻辑来,就要送到DATAIN管脚上,DATAOUT就是延迟之后的数据,可以送到内部逻辑去,也可以送到ISERDES上去;
C管脚是控制信号的时钟管脚,REFRST、LD、CE、INC都要和这个时钟同步才行,这个时钟必须从时钟buffer过来(全局或者本地的都可以),其他的管脚自行参考手册,根据不同的工作模式来选取需要的DELAY值。
下面的代码提供了一种IDELAY使用的范例,在这个代码中只使用了LD的功能,也就是说,每次load生效的时候就把IDELAY的值载入进去,经过一个延迟之后IDELAY的值会生效。 这个代码的开头的那个编译指令一定不能漏掉,否则布局布线的时候会不通过,IDELAYCTRL的时候会用到这条编译指令。
(* IODELAY_GROUP = IODELAY_GROUP_NAME *)
IDELAYE2
#(
.CINVCTRL_SEL ("FALSE"), // TRUE, FALSE
.DELAY_SRC ("IDATAIN"), // IDATAIN, DATAIN
.HIGH_PERFORMANCE_MODE("FALSE"), // TRUE, FALSE
.IDELAY_TYPE ("VAR_LOAD"), // FIXED, VARIABLE, or VAR_LOADABLE
.IDELAY_VALUE (0), // 0 to 31
.REFCLK_FREQUENCY (200.0),
.PIPE_SEL ("FALSE"),
.SIGNAL_PATTERN ("DATA")) // CLOCK, DATA
idelaye2_bus
(
.DATAOUT (data_dly_to_device_o),
.DATAIN (1'b0), // Data from FPGA logic
.C (clk_div),
.CE (), // (in_delay_data_ce),
.INC (), // in_delay_data_inc),
.IDATAIN (data_in_from_buf_w), // Driven by IOB
.LD (idly_tap_load_w),
.REGRST (io_reset),
.LDPIPEEN (1'b0),
.CNTVALUEIN (idelay_tap_to_io_i[0 +: 5]), // in_delay_tap_in),
.CNTVALUEOUT (idelay_tap_from_io_o[0 +: 5]), // in_delay_tap_out),
.CINVCTRL (1'b0)
);
ODELAY就不介绍了,因为我也没用过。
IDELAYCTRL
只要用了I/O DELAY中的一个,IDELAYCTRL是必须要加的,在老版本的Vivado中这个可能是不会报错的,但是在新版本里布局布线的时候会报Error,当然如果直接调SelectIO的IP Core是没有这个问题的。
IDELAYCTRL的作用只有一个,为IO DELAY提供稳定的时钟参考,经过上面介绍,还遗留有一个问题:IDELAY的一个tap是多少,这个tap就是由IDELAYCTRL来控制的,IDELAYCTRL就只有三个管脚:输入时钟、复位和Lock输出,参考DS182,输入时钟的频率可以选择:$200MHz, 300MHz, 400MHz$(其中-1的FPGA只有$200MHz$可选),这个时钟的精度可以不用这么高,可以有$\pm 10MHz$的晃动,当这个时钟稳定之后IDELAYCTRL的lock信号会拉高,之后就可以开始进行IDELAY的操作了。 IDELAYCTRL还肩负有时钟稳定和温度补偿的功能,当稳定发生变化的时候,能够相应的对IDELAY的延迟进行补偿,因为IDELAY的本质目的是让建立保持时间满足。
那么现在开始来讨论tap的问题,对于一个参考时钟,IDELAY将其分成64份,比如说200M的时候分成64份,每份就是78ps,也就是说每个调节的步长是78ps,而UIDELAY最多可以调节32个步长,所以说调节的范围就是$0\to 2.5ns$,可能这里会有疑问,很多时候很难覆盖一个数据的时钟周期,其实我们不需要覆盖一个数据的时钟周期,只要让IDELAY调节的时候避开亚稳态区域就可以了,而FPGA的建立时间一半需求只有几百个ps,这个调节的范围肯定是满足的,当信号的数据率太快时才考虑用更高的参考时钟。
>
一定要注意的是,每个clock region的IDELAYCTRL只有一个!!!一般来说也就是一个bank只有一个IDELAYCTRL资源,要注意的是IDELAYCTRL和IDELAY都是实实在在的硬件资源,不是用可编程的部分实现的,硬件资源有多少就只能用多少。
千万不要每个IDELAY配一个IDELAYCTRL,编译会报错的
ISERDES
下面就开始介绍ISERDES了,其实ISERDES自己用逻辑写也是完全没有问题的,本质上来说就是一个移位的操作,基于以下两个理由用ISERDES会比自己写更好:一是因为这是硬件资源,不会占用可编程逻辑部分的资源;二是因为这部分硬件是经过专门优化的,支持的时钟频率很高,而且不会出现时序问题,从DS182上可以查到ISERDES的setup时间只有0.02ns,后来的时间要0.11ns,其实仔细算算这个频率是很高的,自己写逻辑的话200M以上其实就有点危险了。因此能用ISERDES的时候最好就直接用。从下图中可以看到,其实就是一些D触发器搭成的,所以在别的地方其实可以参考这样的结构来写相应的串并转换模块。

ISERDES其实也没啥好说的,提供两个时钟:频率分别是串并转换倍数关系就行,然后就可以开始工作了,值得注意的有以下两点
- 输入数据只能够有两个来源:直接从IOB过来,也就是直接从输入管脚来接到D上,或者是从IDELAYE2过来接到DDLY上,这里再一次看到专用硬件资源的好处,这部分可以实现0延迟。
- 最先到的数据会出现在最高位上,这点尤其要注意和OSERDES是相反的。
对于SDR来说数据的位宽可以选择$2\to 8$,对于DDR来说能选择的范围是2,4,6,8,10,14,当数据的一个word太宽了时候最好自己进行一些拆分。
OSERDES
OSERDES相对于ISERDES来说简单太多,数据直接往端口上送就行了,注意LSB先被串行出去,因此在写收发模块的时候记得自己将数据的LSB和MSB调整好

