作者: 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 电平。 1. 速率的考虑 为什么说要考虑速率呢?这里一个是和 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 了。 2. 使用电阻网络 这种方法尤其简单,说白了,对接收端来说尤其简单,说白了,就是说你 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 监控芯片。 3. 使用专门的电平 Level shift 芯片 因为基本上MIPI还是用于手机和监控类居多,一般的SoC都支持MIPI直接输入。 这方面的电平转换不多, 一个是使用专用芯片,比如说国外的 MC20901 之类的芯片,另外国内的龙迅也有类似的。 另外一种就是采用高速的信号 buffer/repeater 芯片转成 LVDS 信号, TI 有很多种这样的芯片,比如说性能顶尖的 DS25BR100 (足以满足 2.5Gbps MIPI ,带均衡和加重的),当然这个性能好意味着高价格,对于速度没有那么高的应用,选稍次一档的也很香,电路结构和图 1 类似,就是把 150 Ω电阻的位置换成这个 buffer/repeater 芯片,输出就直接是 LVDS 到 FPGA 了,标标准准的。 这种方案适合 800Mbps~1600Mbps 应用场景,除了一些极大靶面或者极高帧率的 Sensor 外,大多数的一般 sensor 都包含在内了。 4. 超过 1.6Gbps 怎么办 还有一种情况,就是必须要用到 lane 速率超过 1.6Gbps ,这种情况怎么办呢?那就得用到高速 serdes 了 GTP 、 GTH 、 GTY 了,针对这种情况, Xilinx 专门出了一个应用指南,这个比较特殊,熊猫君记得编号是 XAPP1339 ,名字叫做“ Implementing 2.5G MIPI D-PHY Controllers ”,前提是 FPGA 需要带高速 Serdes ,成本要高一些, Xilinx 官网有参考设计,在安富利可以买到评估板,如下图 2 所示,本文按下不表。 图 2 安富利使用高速 Serdes 的参考板 二、 软件设计 这里的软件设计只考虑介绍手撸的,对 Xilinx 官方 IP 和参考设计不做表述。这里面主要的关键点是考虑使用什么样的时钟网络拓扑。 1. 两种时钟拓扑的考量 这里面有种时钟架构可供选择,各有优缺点,根据实际情况选择之。 第一种是使用锁相环( PLL ): 这种方案的有点是时钟稳定、抖动小,外部偶尔有个小毛刺可能影响不大,缺点一个是需要考虑失锁的问题,这个对连续时钟输出的没啥影响,但是对 Gated 时钟就比价致命,如果低功耗间隔太长,重新转到高速模式时间又太短,很有可能锁相环就失锁了,导致丢掉了 HS 帧前面的一部分数据找不到同步头接收失败;另一个是只能支持一种固定速率。因此,在选用这种方案的时候要特别注意。 第二种方案是直接使用时钟 BUFER : 这种方案无需知道进来的时钟速率是多少,所以可以很方便的通过配置 sensor 的寄存器来切换 MIPI 通道 lane 速率(这种对大靶面的传感器应用尤为常见 , 拍照和视频流采用不同的输出速率)。缺点是容易受外界干扰,对信号完整性和干扰屏蔽处理要求较高。 这个两种时钟方案的结构如下图 3 所示。 图 3 两种时钟拓扑结构 对 MIPI 而言,数据并串转换的最小单位是字节, DDR 采样方式,因此 byte_clk 频率是 bit_clk 的 1/4 。 2. 物理层的接收 咱们一般而言不考虑双向通信和 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 帧都要搜索同步字节。一次这里需要手撸一小段代码自己来截取为最好。 3. CSI 层的实现 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 讨论群或微信公众号讨论交流或获取相关资源。