利用FPGA直接解码Cameralink数据:不依赖DS90CR288芯片,在Xilinx系列...
利用FPGA对cameralink的数据进行接收解码 不使用DS90CR288芯片,直接在FPGA内部进行解码。 本人在xilinx(赛灵思)A7,K7,V7,zynq7,ultrascale以及ultrascale+ 系列的FPGA上已经验证通过,相关项目已经交付。
直接手撕CameraLink协议这事,我劝你别随便试——除非你跟我一样经历过被28根差分线逼疯的夜晚。当年接手这个项目时,客户甩过来一句"别用解码芯片",差点让我把开发板摔了。但真啃下来才发现,X家的FPGA确实藏着不少宝贝。
先看CameraLink接口那堆蛇形走线,28对LVDS看着吓人其实结构清晰。重点在于理解它的时钟机制:两条差分时钟线CLK_P/N带着像素时钟,真正的玄机在上升沿和下降沿的双沿采样。这里直接上干货,LVDS接收部分的核心代码长这样:
genvar i;
generate for(i=0; i<28; i=i+1) begin : lvds_inputs
IBUFDS #(
.DIFF_TERM("TRUE"),
.IOSTANDARD("LVDS_25")
) ibufds_inst (
.I (camlink_data_p[i]),
.IB (camlink_data_n[i]),
.O (raw_data[i])
);
end endgenerate
这段代码里藏着两个关键点:DIFF_TERM开启差分终端电阻,这对信号完整性至关重要;IOSTANDARD必须严格匹配硬件设计。有次在UltraScale+板卡上翻车,就是因为忘了查Bank电压。
时钟恢复才是真正的硬仗。X家FPGA的IDDR原语这时候该出场了:
IDDR #(
.DDR_CLK_EDGE("SAME_EDGE_PIPELINED")
) iddr_inst (
.Q1(rx_data_even),
.Q2(rx_data_odd),
.C (pixel_clk),
.CE(1'b1),
.D (raw_data[0]),
.R (1'b0),
.S (1'b0)
);
注意这里的双沿采样策略,配合MMCM生成的相位偏移时钟。调试时用ILA抓波形,发现数据错位就调整CLKOUT0_PHASE参数,每次调0.5ns跟玩扭蛋机似的。
数据对齐的骚操作必须提。CameraLink的传输格式里藏着Frame Valid和Line Valid信号,但某些相机厂商根本不按协议来。这时候得祭出移位寄存器大法:
always @(posedge pixel_clk) begin
shift_reg <= {shift_reg[55:0], aligned_data};
if(shift_reg[63:56] == 8'hF0) begin //自定义同步头
valid_data <= shift_reg[55:0];
data_ready <= 1'b1;
end
end
这个滑动窗口检测器帮我搞定了三家不同厂商的相机,其中一家的同步码居然用0xAA,气得我差点给他们的FAE寄刀片。
最后说点血泪教训:Vivado的Timing Constraints必须把CLKSETUPVIOLATION压到0.2ns以下,否则高温测试准掉链子。在Zynq-7000上跑DMA传输时,AXI总线带宽算错导致数据断流,后来上了双缓冲结构才解决。
现在这套架构在A7上只用不到15%的LUT资源,最狠的一个项目用V7同时接四路CameraLink还能跑满85MHz。别问我为什么不用IP核——自己写的代码,深夜调试时连报错信息都显得眉清目秀。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)