作者:Hello,Panda
这次分享一个在Xilinx FPGA实现MIPI DPHY接口的案例(包括CIS协议层)。截止目前为止,Xilinx仅在Ultrascale+及其以上版本的FPGA IO可直接支持MIPI 电平输入,其他的,都需要转换成LVDS来接收。在软件支持上,Xilinx在高版本的Vivado(Vitis)上开放了MIPI DPHY IP,但是这个IP可能用起来有诸多的限制,比如说,不可以动态切换Lane速率、比如说必须是Gated的时钟、比如说所有时钟通道和数据Lane的LP信号都必须接进来占用很多IO等等。所以,熊猫君在这里分享手动撸代码的途径,根据自己的需求想做成啥样就啥样,哪管它格式千奇百怪,另外给大家分享的是,撸这个代码不用怕,真的很简单,熟练一些的三天就成,不太熟练的也就一个星期,毕竟咱们不需要把协议栈的每个边边角角都整出来,够咱用就可以了。好了,不说废话了,咱们以MIPI DPHY CSI为例预备开始,搭建一个MIPI RX摄像头数据的案例!
之前咱不是介绍过,Xilinx低版本的FPGA上并不能直接支持MIPI DPHY电平标准,因此不能直接就把摄像头接到FPGA的Select IO上,咱得想办法把它变成可以认识的LVDS电平。
为什么说要考虑速率呢?这里一个是和FPGA内部的资源相关,另外一个是和信号完整性相关。
FPGA内部的资源是怎么个说法呢?因为是要用到Select IO的Iserdes,因此受IO时钟速率的影响,可以布线到IO的最高时钟在7系列器件里面是BUIO,可以达到800MH(Spartan-6的BUFPLL可能低一些,记得好像是600MHz来着的,有需要的可以自行查证),那么就意味着在7系列FPGA上接MIPI进来最大的Lane速率只能到1600Mbps。
另外,信号完整性是怎么一个说法呢?咱们这个毕竟是高速信号,对眼图采样窗口什么很看重的,这方面Xilinx很有经验,它给画了一条线:800Mbps,lane速率低于800Mbps的,可以通过电阻网络用很低的成本就把事儿给办了;但是速度高了可不行,采样可能就不正确了,那怎么办呢?就得用专门的level shift芯片将MIPI信号转成LVDS了。
这种方法尤其简单,说白了,对接收端来说尤其简单,说白了,就是说你MIPI电平的摆幅很低,那好啊,我把终端电阻加大(150Ω,需要注意的是内部的DIFF_TERM要False掉)一点儿,可以确保差分终端电阻两端的电压够LVDS的裁决门限就行了,这个Xilinx还专门有一个xapp的参考设计,具体编号没有记,有需要可以自行去找DoCNav要。至于低速LP信号,分出来以后要是BANK富裕可以专门搞一个1.2V的bank,如果不富裕,也可以加一个输入阻抗很大的电平转换芯片(比如74LVC1T45)把它转成任意你想要的电平标准,比如1.8V、2.5V或3.3V。那么,整个输入的网络结构就变成了图1这个样子的了。
图1 电阻网络结构图
至于哪些信号要接进来,如果引脚足够多,那么所有LP信号和HS信号都可以接进来,如果不富裕且不需要用到嵌入的低速数据的话,因为咱们的Lane已知,除了HS信号外,将lane0的LP信号接进来用于状态判断就行了。
低速的适用于大多数分辨率/帧率在1080P60及以下的,比如几乎所有的内窥镜用Sensor,如最常用OV9734;大部分的Sony和安森美的2M监控芯片。
因为基本上MIPI还是用于手机和监控类居多,一般的SoC都支持MIPI直接输入。这方面的电平转换不多,基本上停留在连个方案层次上一个是使用专用芯片,比如说国外的MC20901之类的芯片,另外国内的龙迅也有类似的。
另外一种就是采用高速的信号buffer/repeater芯片转成LVDS信号,TI有很多种这样的芯片,比如说性能顶尖的DS25BR100(足以满足2.5Gbps MIPI,带均衡和加重的),当然这个性能好意味着高价格,对于速度没有那么高的应用,选稍次一档的也很香,电路结构和图1类似,就是把150Ω电阻的位置换成这个buffer/repeater芯片,输出就直接是LVDS到FPGA了,标标准准的。
这种方案适合800Mbps~1600Mbps应用场景,除了一些极大靶面或者极高帧率的Sensor外,大多数的一般sensor都包含在内了。
还有一种情况,就是必须要用到lane速率超过1.6Gbps,这种情况怎么办呢?那就得用到高速serdes了GTP、GTH、GTY了,针对这种情况,Xilinx专门出了一个应用指南,这个比较特殊,熊猫君记得编号是XAPP1339,名字叫做“Implementing 2.5G MIPI D-PHY Controllers”,前提是FPGA需要带高速Serdes,成本要高一些,Xilinx官网有参考设计,在安富利可以买到评估板,如下图2所示,本文按下不表。
图2 安富利使用高速Serdes的参考板
这里的软件设计只考虑介绍手撸的,对Xilinx官方IP和参考设计不做表述。这里面主要的关键点是考虑使用什么样的时钟网络拓扑。
这里面有种时钟架构可供选择,各有优缺点,根据实际情况选择之。
第一种是使用锁相环(PLL):这种方案的有点是时钟稳定、抖动小,外部偶尔有个小毛刺可能影响不大,缺点一个是需要考虑失锁的问题,这个对连续时钟输出的没啥影响,但是对Gated时钟就比价致命,如果低功耗间隔太长,重新转到高速模式时间又太短,很有可能锁相环就失锁了,导致丢掉了HS帧前面的一部分数据找不到同步头接收失败;另一个是只能支持一种固定速率。因此,在选用这种方案的时候要特别注意。
第二种方案是直接使用时钟BUFER:这种方案无需知道进来的时钟速率是多少,所以可以很方便的通过配置sensor的寄存器来切换MIPI通道lane速率(这种对大靶面的传感器应用尤为常见,拍照和视频流采用不同的输出速率)。缺点是容易受外界干扰,对信号完整性和干扰屏蔽处理要求较高。
这个两种时钟方案的结构如下图3所示。
图3 两种时钟拓扑结构
对MIPI而言,数据并串转换的最小单位是字节,DDR采样方式,因此byte_clk频率是bit_clk的1/4。
咱们一般而言不考虑双向通信和ESCAPE信号处理,那么MIPI D-PHY物理层的主要工作就是采样LP状态信号和将高速串行数据恢复成按字节排序的并行数据,不管多少个Lane,方法都一个样。这个工作被称作解串,只需要用到IDELAY和ISERDES原语就行。MIPI标准默认是时钟相对数据的相位是90°,DDR采样方式,也就是说,时钟的上升沿和下降沿刚好在数据的中间,因此在PCB Layout的时钟,时钟和数据最好是需要等长的,这样保证到达时间是一样的。IDELAY的作用是将PCB布线和内部路径的延时找回来使之满足最佳采样要求,这在直接使用时钟BUFER的时钟拓扑设计中尤为重要,另外,因每次布局布线后都会存在一些路径差异,最好是约束Fixed布线路径。ISERDES的作用是串转并,将数据转为并行的,这里的串并比设为1:8就好,至于这俩源语怎么用,可以参照Xilinx的Select IO手册或者参照我上一篇分享文章《Zynq高速串行CMOS接口设计与实现》。
恢复成字节数据的第二步就是找同步头B8’H,这里千万不要用Iserdes自带的bitslip功能,因为同步字每一个HS帧就一个字节,而且每一个HS帧都要搜索同步字节。一次这里需要手撸一小段代码自己来截取为最好。
CSI层主要就是将1lane,或多lane的数据按照协议规定解析出来并将图像数据拼接输出,有的可能会存在多个虚拟通道,需要注意一下。MIPI 一般会分为长短帧,长帧为数据帧,一帧一般就是一行数据;短帧为标志帧,用于指示帧行的开始结束,这个我们可以根据自己的Sensor实现一种就行了,没有必要像标准那样把所有的数据类型都囊括进来。
这里需要注意一下的是,MIPI DPHY和CPHY的长帧的帧头排列方式不一样,CPHY是固定的每个通道都有6个word的的帧头信息。但是DPHY的帧头信息排布和数据一样,都是根据实际的通道数分散到各通道。
CSI层的工作时钟可以使用FPGA内部的一个合适时钟,不和MIPI的像素时钟挂钩,从CSI层出来的数据就是直接的一个一个的像素数据了。
针对特定的Sensor实现CSI层,整个MIPI的接收逻辑框图如下图4所示,整个接收逻辑所占用的Slice资源一般不会大于1K。
图4 MIPI DPHY接收逻辑设计框图
本次的分享到这里就结束了,欢迎加入QQ讨论群或微信公众号讨论交流或获取相关资源。另,博主可提供基于Xilinx、Altera、lattice的相关软硬件方案和产品定制服务,也欢迎大家多多支持!