利用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跟玩扭蛋机似的。

利用FPGA对cameralink的数据进行接收解码 不使用DS90CR288芯片,直接在FPGA内部进行解码。 本人在xilinx(赛灵思)A7,K7,V7,zynq7,ultrascale以及ultrascale+ 系列的FPGA上已经验证通过,相关项目已经交付。

数据对齐的骚操作必须提。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核——自己写的代码,深夜调试时连报错信息都显得眉清目秀。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐