FPGA纯verilog代码解码CameraLink视频,附带工程源码和技术支持
Posted 9527华安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA纯verilog代码解码CameraLink视频,附带工程源码和技术支持相关的知识,希望对你有一定的参考价值。
目录
1、CameraLink视频协议简介
CameraLink的详细不必深究,作为FPGA数据采集者而言,我们只需关心他的传输时序和传输协议。
CameraLink相机输出分三种模式:
Base模式:称之为基本模式或初级模式,通常配置为一个CameraLink芯片和一根电源线;有1个标准CameraLink接口,对应的是1对时钟差分信号和4对数据差分信号;解码后的数据位宽为281=28位;分为ABC三个Port;
Medium模式:中级模式,配置为两个CameraLink芯片和一根电源线;有2个标准CameraLink接口,对应的是2对时钟差分信号和8对数据差分信号;解码后的数据位宽为282=56位;分为ABCDEF六个Port;
Full模式:高级模式,配置为3个CameraLink芯片,两根电源线;有2个标准CameraLink接口,对应的是3对时钟差分信号和12对数据差分信号;解码后的数据位宽为28*3=84位;分为ABCDEFGH八个Port;
CameraLink差分串行输入转单端并行:以Base模式为例
以Base模式下,CameraLink输出1对时钟差分信号和4对数据差分信号,如下图:
2、FPGA实现CameraLink视频解码
解串的过程可以参考Xilinx给的参考设计,使用Xilinx的ISERDESE2和IDELAYE2实现,由于代码过于复杂,在这里实在说不清楚,只给出解串顶层的端口部分,具体代码“关注并私信我”要源码。
解串部分实现了差分穿行到单端并行的转换,输出像素时钟pixel_clk和数据data_out;
同样,解码部分也只给出解串顶层的端口部分,具体代码“关注并私信我”要源码。
这部分实现了解码CameraLink的功能,输出行、场、de、像素数据;
最后给出整个CameraLink解码代码的顶层如下:
后面还细节地给出了解码后的时序图。
`timescale 1ps/1ps
module helai_CameraLink_rx #(
// Parameters
parameter integer CAMERALINK_MODE = 3, // Set the CameraLink mode. Base-->1 Medium-->2 Full-->3
parameter integer CAMERALINK_CHAL = 4 // Set the number of data lines per channel=4
)
(
input delay_clk_200m, // Clock for input delay control: 200MHz or 300Hz clk is needed
input reset_n , // Active low reset
input [CAMERALINK_MODE-1:0] i_clk_in_p , // Input from LVDS clock receiver pin
input [CAMERALINK_MODE-1:0] i_clk_in_n , // Input from LVDS clock receiver pin
input [CAMERALINK_MODE*CAMERALINK_CHAL-1:0] i_data_in_p , // Input from LVDS data pins
input [CAMERALINK_MODE*CAMERALINK_CHAL-1:0] i_data_in_n , // Input from LVDS data pins
//decode video_clk and video_data output
output o_pixel_clk , // Pixel clock output
// Chip X signals
output o_xLVAL , // Line Valid, active high
output o_xFVAL , // Frame Valid, active high
output o_xDVAL , // Data Valid, active high. Maybe always zero.
output [7:0] o_PortA , // Camera Link interface Port A , total 8 ports
output [7:0] o_PortB , // Camera Link interface Port B , total 8 ports
output [7:0] o_PortC , // Camera Link interface Port C , total 8 ports
// Chip Y signals
output o_yLVAL , // Line Valid, active high
output o_yFVAL , // Frame Valid, active high
output o_yDVAL , // Data Valid, active high. Maybe always zero.
output [7:0] o_PortD , // Camera Link interface Port D , total 8 ports
output [7:0] o_PortE , // Camera Link interface Port E , total 8 ports
output [7:0] o_PortF , // Camera Link interface Port F , total 8 ports
// Chip Z signals
output o_zLVAL , // Line Valid, active high
output o_zFVAL , // Frame Valid, active high
output o_zDVAL , // Data Valid, active high. Maybe always zero.
output [7:0] o_PortG , // Camera Link interface Port G , total 8 ports
output [7:0] o_PortH // Camera Link interface Port H , total 8 ports
);
wire [CAMERALINK_MODE*CAMERALINK_CHAL*7-1:0] data_out; // Serial to parallel data output
//**********差分转单端,然后串并转换,由Xilinx IDELAYE2 和 ISERDESE2 原语实现**********//
lvds_n_x_1to7_sdr_rx #(
// Parameters
.N (CAMERALINK_MODE), // Set the number of channels
.X (CAMERALINK_CHAL) // Set the number of data lines per channel
)
CameraLink_sdr(
.delay_refclk_in(delay_clk_200m), // Clock for input delay control: 200MHz or 300Hz clk is needed
.reset_n (reset_n ), // Active low reset
.clk_in_p (i_clk_in_p ), // Input from LVDS clock receiver pin
.clk_in_n (i_clk_in_n ), // Input from LVDS clock receiver pin
.data_in_p (i_data_in_p ), // Input from LVDS data pins
.data_in_n (i_data_in_n ), // Input from LVDS data pins
.data_out (data_out ), // Serial to parallel data output
.pixel_clk (o_pixel_clk ) // Pixel clock output
);
//**********差分转单端,然后串并转换,由Xilinx IDELAYE2 和 ISERDESE2 原语实现**********//
//*****************根据CameraLink的数据格式,解码出行、场、de、数据*****************//
cameralink_bit_allocation_rx #(
// Parameters
.N (CAMERALINK_MODE), // Set the number of channels
.X (CAMERALINK_CHAL) // Set the number of data lines per channel
)
CameraLink_decode(
.data_in (data_out), // Parallel data input
// Chip X signals
.xLVAL (o_xLVAL), // Line Valid, active high
.xFVAL (o_xFVAL), // Frame Valid, active high
.xDVAL (o_xDVAL), // Data Valid, active high. Maybe always zero.
.PortA (o_PortA), // Camera Link interface Port A , total 8 ports
.PortB (o_PortB), // Camera Link interface Port B , total 8 ports
.PortC (o_PortC), // Camera Link interface Port C , total 8 ports
// Chip Y signals
.yLVAL (o_yLVAL), // Line Valid, active high
.yFVAL (o_yFVAL), // Frame Valid, active high
.yDVAL (o_yDVAL), // Data Valid, active high. Maybe always zero.
.PortD (o_PortD), // Camera Link interface Port D , total 8 ports
.PortE (o_PortE), // Camera Link interface Port E , total 8 ports
.PortF (o_PortF), // Camera Link interface Port F , total 8 ports
// Chip Z signals
.zLVAL (o_zLVAL), // Line Valid, active high
.zFVAL (o_zFVAL), // Frame Valid, active high
.zDVAL (o_zDVAL), // Data Valid, active high. Maybe always zero.
.PortG (o_PortG), // Camera Link interface Port G , total 8 ports
.PortH (o_PortH) // Camera Link interface Port H , total 8 ports
);
//*****************根据CameraLink的数据格式,解码出行、场、de、数据*****************//
//解码后的时许如下:
// __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
//o_pixel_clk__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\__/ \\
// ____________________________________________________________________________________
//o_xFVAL_________/
// _______________________ _______________________
//o_xLVAL_________________/ \\_________________/ \\__________
// _______________________ _______________________
//o_xDVAL_________________/ \\_________________/ \\__________
// _________________ _______________________ _________________ _______________________
//o_PortA___invalid_data__\\_______valid_data______\\___invalid_data__\\_______valid_data______\\_invalid_data_
// _________________ _______________________ _________________ _______________________
//o_PortB___invalid_data__\\_______valid_data______\\___invalid_data__\\_______valid_data______\\_invalid_data_
// _________________ _______________________ _________________ _______________________
//o_PortC___invalid_data__\\_______valid_data______\\___invalid_data__\\_______valid_data______\\_invalid_data_
endmodule
3、vivado工程介绍
下面提供一个CameraLink base模式的工程
开发板:Kintex7开发板;
开发环境:vivado2019.1;
输入:CameraLink摄像头,1280X1024@60Hz分辨率;
输出:HDMI,1920X1080@60Hz分辨率;
BD工程如下图:经典的FDMA三帧缓存架构,关于FDMA三帧缓存,请参考我之前写的文章点击查看:FDMA三帧缓存方案
工程代码架构如下:
最后给出工程的顶层代码如下:
module CameraLink_rx_hdmi_out(
input i_27m_clk , // Y2 125MHz
input i_clk_in_p ,
input i_clk_in_n ,
input [3:0] i_data_in_p ,
input [3:0] i_data_in_n ,
// HDMI
output HDMI_CLK_P ,
output HDMI_CLK_N ,
output HDMI_D2_P ,
output HDMI_D2_N ,
output HDMI_D1_P ,
output HDMI_D1_N ,
output HDMI_D0_P ,
output HDMI_D0_N ,
// DDR3
output [12:0]DDR3_0_addr ,
output [2:0] DDR3_0_ba ,
output DDR3_0_cas_n ,
output [0:0] DDR3_0_ck_n ,
output [0:0] DDR3_0_ck_p ,
output [0:0] DDR3_0_cke ,
// output [0:0] DDR3_0_cs_n ,
output [3:0] DDR3_0_dm ,
inout [31:0] DDR3_0_dq ,
inout [3:0] DDR3_0_dqs_n ,
inout [3:0] DDR3_0_dqs_p ,
output [0:0] DDR3_0_odt ,
output DDR3_0_ras_n ,
output DDR3_0_reset_n,
output DDR3_0_we_n ,
output ddr3_ok
);
helai_CameraLink_rx #(
// Parameters
.CAMERALINK_MODE (1), // Set the CameraLink mode. Base-->1 Medium-->2 Full-->3
.CAMERALINK_CHAL (4) // Set the number of data lines per channel=4
)
CameraLink_decode(
.delay_clk_200m(ui_clk_200m ), // Clock for input delay control: 200MHz or 300Hz clk is needed
.reset_n (rst_n ), // Active low reset
.i_clk_in_p (i_clk_in_p ), // Input from LVDS clock receiver pin
.i_clk_in_n (i_clk_in_n ), // Input from LVDS clock receiver pin
.i_data_in_p (i_data_in_p ), // Input from LVDS data pins
.i_data_in_n (i_data_in_n ), // Input from LVDS data pins
.o_pixel_clk (vid_clk ), // Pixel clock output
.o_xFVAL (vid_vs ), // Frame Valid, active high
.o_xDVAL (vid_de ), // Data Valid, active high. Maybe always zero.
.o_PortA (vid_data[23:16]), // Camera Link interface Port A , total 8 ports
.o_PortB (vid_data[15: 8]), // Camera Link interface Port B , total 8 ports
.o_PortC (vid_data[ 7: 0]) // Camera Link interface Port C , total 8 ports
);
wire [31:0] fdma_raddr_0 ;
wire fdma_rareq_0 ;
wire fdma_rbusy_0 ;
wire [127:0]fdma_rdata_0 ;
wire fdma_rready_0;
wire [15:0] fdma_rsize_0 ;
wire fdma_rvalid_0;
wire [31:0] fdma_waddr_0 ;
wire fdma_wareq_0 ;
wire fdma_wbusy_0 ;
wire [127:0] fdma_wdata_0 ;
wire fdma_wready_0;
wire [15:0] fdma_wsize_0 ;
wire fdma_wvalid_0;
wire ui_clk_200m ;
wire rst_n ;
design_1 u_design_1
(
.DDR3_0_addr (DDR3_0_addr ),
.DDR3_0_ba (DDR3_0_ba ),
.DDR3_0_cas_n (DDR3_0_cas_n ),
.DDR3_0_ck_n (DDR3_0_ck_n ),
.DDR3_0_ck_p (DDR3_0_ck_p ),
.DDR3_0_cke (DDR3_0_cke ),
.DDR3_0_dm (DDR3_0_dm ),
.DDR3_0_dq (DDR3_0_dq ),
.DDR3_0_dqs_n (DDR3_0_dqs_n ),
.DDR3_0_dqs_p (DDR3_0_dqs_p ),
.DDR3_0_odt (DDR3_0_odt ),
.DDR3_0_ras_n (DDR3_0_ras_n ),
.DDR3_0_reset_n(DDR3_0_reset_n),
.DDR3_0_we_n (DDR3_0_we_n ),
.clk_in1_0 (i_27m_clk ),
.ddr3_ok (ddr3_ok ),
.fdma_raddr_0 (fdma_raddr_0 ),
.fdma_rareq_0 (fdma_rareq_0 ),
.fdma_rbusy_0 (fdma_rbusy_0 ),
.fdma_rdata_0 (fdma_rdata_0 ),
.fdma_rready_0 (fdma_rready_0 ),
.fdma_rsize_0 (fdma_rsize_0 ),
.fdma_rvalid_0 (fdma_rvalid_0 ),
.fdma_waddr_0 (fdma_waddr_0 ),
.fdma_wareq_0 (fdma_wareq_0 ),
.fdma_wbusy_0 (fdma_wbusy_0 ),
.fdma_wdata_0 (fdma_wdata_0 ),
.fdma_wready_0 (fdma_wready_0 ),
.fdma_wsize_0 (fdma_wsize_0 ),
.fdma_wvalid_0 (fdma_wvalid_0 ),
.ui_clk_0 (ui_clk_200m ),
.rst_n (rst_n )
);
wire vid_clk ;
wire vid_vs ;
wire vid_de ;
wire [23:0] vid_data;
wire vga_clk;
wire vga_hs;
wire vga_vs;
wire vga_de;
wire [23:0] vga_data;
fdma_contrl #(
.VIDEO_H_SRTI_W (1920 ),
.VIDEO_H_SIZE_W (1280 ), //输入图像行分辨率
.VIDEO_V_SIZE_W (1024 ), //输入图像场分辨率
.VIDEO_H_SRTI_R (1920 ),
.VIDEO_H_SIZE_R (1920 ), //输入图像行分辨率
.VIDEO_V_SIZE_R (1080 ), //输入图像场分辨率
.VIDEO_DAAR_0 (32'h80000000), //第1帧图像缓存基地址
.VIDEO_DAAR_1 (32'h81000000), //第2帧图像缓存基地址
.VIDEO_DAAR_2 (32'h82000000), //第3帧图像缓存基地址
.FDMA_TRANS_DIV (2 ), //一行图像分2次FDMA突发写传输
.FDMA_FRAME_NUM (3 ) //缓存3帧
)
helai_fdma_contrl(
.ui_clk_200m (ui_clk_200m ),
.rst_n (rst_n ),
.cmos_pclk (vid_clk ),
.senser_vs (~vid_vs ),
.senser_de (vid_de ),
.senser_rgb (vid_data ),
.vga_clk (vga_clk ),
.vga_vs (vga_vs ),
.vga_de (vga_de ),
.o_vga_rgb (vga_data ),
.fdma_waddr_0 (fdma_waddr_0 ),
.fdma_wareq_0 (fdma_wareq_0 ),
.fdma_wbusy_0 (fdma_wbusy_0 ),
.fdma_wdata_0 (fdma_wdata_0 ),
.fdma_wready_0(fdma_wready_0),
.fdma_wsize_0 (fdma_wsize_0 ),
.fdma_wvalid_0(fdma_wvalid_0),
.fdma_raddr_0 (fdma_raddr_0 ),
.fdma_rareq_0 (fdma_rareq_0 ),
.fdma_rbusy_0 (fdma_rbusy_0 ),
.fdma_rdata_0 (fdma_rdata_0 ),
.fdma_rready_0(fdma_rready_0),
.fdma_rsize_0 (fdma_rsize_0 ),
.fdma_rvalid_0(fdma_rvalid_0)
);
dvi_transmitter_top helai_hdmi_out(
.ref_clk (ui_clk_200m),
.i_vga_hs (vga_hs ),
.i_vga_vs (vga_vs ),
.i_vga_de (vga_de ),
.i_vga_rgb (vga_data ),
.tmds_clk_p (HDMI_CLK_P ),
.tmds_clk_n (HDMI_CLK_N ),
.tmds_data0b_p(HDMI_D0_P ),
.tmds_data0b_n(HDMI_D0_N ),
.tmds_data1g_p(HDMI_D1_P ),
.tmds_data1g_n(HDMI_D1_N ),
.tmds_data2r_p(HDMI_D2_P ),
.tmds_data2r_n(HDMI_D2_N ),
.o_vga_rclk (vga_clk ),
.o_vga_hs (vga_hs ),
.o_vga_vs (vga_vs ),
.o_vga_de (vga_de ),
.o_x_pos (),
.o_y_pos ()
);
endmodule
4、福利:工程源码获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:文章末尾的V名片。
网盘资料如下:
以上是关于FPGA纯verilog代码解码CameraLink视频,附带工程源码和技术支持的主要内容,如果未能解决你的问题,请参考以下文章
FPGA纯verilog代码实现jpg解码rgb并输出显示,私我提供工程源码
FPGA/数字IC手撕代码3——通过纯verilog实现简单的ROM
FPGA纯verilog代码实现4路视频缩放拼接 提供工程源码和技术支持
FPGA纯verilog代码实现图像缩放,两种插值算法任意尺寸缩放,提供3套工程源码