在工业视觉和高速图像采集领域,CameraLink接口凭借其高带宽、低延迟的特性成为专业设备的首选方案。最近我在一个机器视觉检测项目中,需要实现FPGA到CameraLink相机的数据发送功能,过程中积累了一些实战经验。不同于常规的并行数据传输,CameraLink协议对时钟同步、数据编码和电气特性有着严格的要求,这也是很多工程师首次接触时容易踩坑的地方。
这个项目的核心需求是通过Xilinx Artix-7 FPGA开发板,将预处理后的图像数据通过CameraLink Base模式传输到工业相机。关键难点在于:需要严格遵循CameraLink协议的电气规范,同时处理好FPGA内部时钟域与串行器时钟的相位关系。下面我会从硬件设计、数据编码、时钟管理三个维度,拆解整个实现过程。
CameraLink的物理层采用LVDS差分信号,在Artix-7上需要配置SelectIO资源为LVDS_25标准。具体引脚约束示例:
verilog复制set_property PACKAGE_PIN F12 [get_ports {camlink_data_p[0]}]
set_property IOSTANDARD LVDS_25 [get_ports {camlink_data_p[0]}]
每个差分对应需要添加100Ω端接电阻,PCB布局时应注意:
CameraLink接收端通常需要+12V供电,发送端要注意:
CameraLink Base模式使用4对数据通道(X0-X3),每通道传输7位有效数据。在FPGA内部需要将原始数据重组为28位总线:
verilog复制wire [27:0] camlink_data;
assign camlink_data = {
3'b000, // 保留位
line_valid,
frame_valid,
pixel_data[23:16], // X3通道
pixel_data[15:8], // X2通道
pixel_data[7:0] // X1通道
};
推荐使用Xilinx的SelectIO Wizard生成串行器原语:
verilog复制OSERDESE2 #(
.DATA_RATE_OQ("DDR"),
.DATA_WIDTH(7),
.SERDES_MODE("MASTER")
) serdes_inst (
.OQ(camlink_data_p),
.OCE(1'b1),
.CLK(serial_clk),
.CLKDIV(parallel_clk),
.D(camlink_data[6:0])
);
CameraLink要求串行时钟频率为数据率的1/7,对于85MHz像素时钟:
tcl复制create_clock -name clk_85m -period 11.759 [get_ports clk_in]
create_generated_clock -name serial_clk \
-source [get_pins mmcm_inst/CLKOUT0] \
-divide_by 1 [get_pins serdes_inst/CLK]
图像数据从系统时钟域到并行时钟域的转换:
verilog复制async_fifo #(
.WIDTH(28),
.DEPTH(16)
) fifo_inst (
.wr_clk(sys_clk),
.rd_clk(parallel_clk),
.din(raw_data),
.dout(camlink_data)
);
使用示波器验证信号质量时:
数据错位:
时钟失锁:
EMI超标:
通过实测发现,在连续传输2048x2048图像时:
具体时序约束示例:
tcl复制set_output_delay -clock [get_clocks serial_clk] \
-max 1.5 [get_ports {camlink_data_p*}]
set_multicycle_path -setup 2 \
-from [get_clocks parallel_clk] \
-to [get_clocks serial_clk]
这个项目最终实现了稳定的85fps@2048x2048传输,关键是在时钟树设计和信号完整性方面投入了大量调试时间。建议在初期就使用IBERT工具进行链路质量预检,可以节省后期50%以上的调试工作量。