FPGA实现不同分辨率视频切换输出,串口协议帧控制,提供工程源码和技术支持
创始人
2024-05-25 16:07:07
0

目录

  • 1、不同分辨率视频切换输出原理
  • 2、设计思想和架构详解
  • 3、vivado工程详解
  • 4、上板调试验证并演示
  • 5、福利:工程代码的获取

1、不同分辨率视频切换输出原理

不同分辨率的视频输出对应不同的时序和时钟,一般情况下是不存在同时或分时输出的,但现实项目中如果遇到这样的情况怎么办呢?
很好办,找我就行了。。。
不同分辨率的视频肯定有大有小,但输出分辨率却只有一个,很显然,要选择大的分辨率时序作为输出时序,大视频原样输出,小视频在大分辨率下降采样输出;
以本设计为例,输入分辨率有720P和1080P,那么输出时序当然就是1080P,720P视频在1080P时序下降采样输出;

2、设计思想和架构详解

设计架构如下:
在这里插入图片描述

输入1:ov5640摄像头1280x720@60Hz;
输入2:hdmi输入1920x1080@60Hz;
输出:hdmi输出1920x1080@60Hz;
具体哪一路作为输出视频,由串口协议帧控制;
具体协议如下:
串口协议帧有效数据0x00 0x00 0xaa 0xbb 输入2作为输出;
串口协议帧有效数据0x00 0x00 0xcc 0xdd 输入1作为输出;

ov5640摄像头输入:
ov5640摄像头输出rgb565格式视频,需要iic配置和数据采集,详细配置和采集源码请将文章看到最后;

HDMI输入和输出:
HDMI输入采用silicon9011解码,HDMI输出采用silicon9134编码,关于这一块的配置和使用,请参考我之前写的文章点击查看:silicon9011和silicon9134编解码

串口协议帧解析:
主要控制不同分辨率参数写入FDMA控制器,进而控制DDR读写,这个串口协议帧解析方案高度贴近真实项目,也是我常用的套路,关于串口协议帧解析这一块,请参考我之前写的文章点击查看:串口协议帧解析方案

FDMA数据缓存方案:
经典的图像缓存DDR3的方案,关于FDMA数据缓存方案点击查看:FDMA数据缓存方案这一块,请参考我之前写的文章

3、vivado工程详解

vivado版本:2019.1;
如果是高版本打开,升级IP即可;
如果是低版本打开,打开工程后需另存为,然后即可使用;
工程BD如下:
在这里插入图片描述
工程代码架构如下:
在这里插入图片描述
顶层源码如下:

`timescale 1ns / 1psmodule top(  
//ddr3  output [14: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      , input        CLK_IN1_D_0_clk_n,input        CLK_IN1_D_0_clk_p,output       ddr3_ok          ,  inout        cmos_scl,          //cmos i2c clockinout        cmos_sda,          //cmos i2c datainput        cmos_vsync,        //cmos vsyncinput        cmos_href,         //cmos hsync refrence,data validinput        cmos_pclk,         //cmos pxiel clockoutput       cmos_xclk,         //cmos externl clockinput   [7:0]cmos_db,           //cmos dataoutput       cmos_rst_n,        //cmos resetoutput       cmos_pwdn,         //cmos power downoutput       hdmi_in_nreset   ,     //9011/9013 resetinput        vin_clk          ,            //clock for 9111/9013input        vin_hs           ,             //horizontal synchronization for 9011/9013input        vin_vs           ,             //vertical synchronization for 9011/9013input        vin_de           ,             //data valid for 9011/9013input[23:0]  vin_data         ,           //data for 9011/9013   inout        hdmi_scl         ,           //HDMI I2C clockinout        hdmi_sda         ,           //HDMI I2C data//hdmi_out  output       vout_hs          ,            //horizontal synchronization for 9134output       vout_vs          ,            //vertical synchronization for 9134output       vout_de          ,            //data valid for 9134output       vout_clk         ,           //clock for 9134output[23:0] vout_data        ,            //data for 9134output       hdmi_nreset      ,input  		  i_uart_rx ,output 		  o_uart_tx );wire        clk_25m   ;
wire	    clk_200m  ;
wire        clk_hdmi  ;
wire        pll_resetn;
wire [0:0]  resetn;
wire        ud_r_0_ud_rclk;
wire [31:0] ud_r_0_ud_rdata;
wire        ud_r_0_ud_rde;
wire        ud_r_0_ud_rvs;reg        ud_w_0_ud_wclk ;
reg [23:0] ud_w_0_ud_wdata;
reg        ud_w_0_ud_wde  ;
reg        ud_w_0_ud_wvs  ;
reg [10:0] dis_h;
reg [10:0] dis_v;wire        ui_clk_100m;wire [9:0]   lut_index;
wire [31:0]  lut_data; 
wire [9:0]   lut_index_hdmi;
wire [31:0]  lut_data_hdmi ; wire [23:0] ov5640_rgb;
wire 	    ov5640_de ;
wire 	    ov5640_vs ;
wire        o_data_req;wire [23:0] i_rgb;  
wire 	    o_hs ;  
wire 	    o_vs ;  
wire 	    o_de ;  
wire [23:0] o_rgb;  
wire hdmi_clk_rstn;wire       o_rx_done;
wire [31:0]o_rx_data;
reg  [31:0] _rx_data;assign hdmi_nreset   =pll_resetn;  
assign hdmi_in_nreset=pll_resetn;assign ud_r_0_ud_rclk=clk_hdmi;
assign ud_r_0_ud_rvs=o_vs;
assign ud_r_0_ud_rde=o_data_req;
assign i_rgb=ud_r_0_ud_rdata[23:0];
assign vout_clk=clk_hdmi;
assign vout_hs=o_hs;
assign vout_vs=o_vs;
assign vout_de=o_de;
assign vout_data=o_rgb;
assign cmos_rst_n = 1'b1;
assign cmos_pwdn  = 1'b0;i2c_config i2c_config_ov5640(
.rst            (~pll_resetn    ),
.clk            (clk_200m       ),
.clk_div_cnt    (16'd500        ),
.i2c_addr_2byte (1'b1           ),
.lut_index      (lut_index      ),
.lut_dev_addr   (lut_data[31:24]),
.lut_reg_addr   (lut_data[23:8] ),
.lut_reg_data   (lut_data[7:0]  ),
.error          (               ),
.done           (               ),
.i2c_scl        (cmos_scl       ),
.i2c_sda        (cmos_sda       )
);ov5640_reg_cfg #(.DISPAY_H(1280),.DISPAY_V(720 )
)
u_ov5640_reg_cfg(.lut_index(lut_index),   //Look-up table address.lut_data (lut_data )    //Device address (8bit I2C address), register address, register data
);i2c_config i2c_config_hdmi(.rst            (~pll_resetn    ),.clk            (clk_200m       ),.clk_div_cnt    (16'd500        ),.i2c_addr_2byte (1'b0           ),.lut_index      (lut_index_hdmi      ),.lut_dev_addr   (lut_data_hdmi[31:24]),.lut_reg_addr   (lut_data_hdmi[23:8] ),.lut_reg_data   (lut_data_hdmi[7:0]  ),.error          (               ),.done           (               ),.i2c_scl        (hdmi_scl       ),.i2c_sda        (hdmi_sda       )
);lut_hdmi u_lut_hdmi(.lut_index(lut_index_hdmi),   //Look-up table address.lut_data (lut_data_hdmi)    //Device address (8bit I2C address), register address, register data
);uiSensorRGB565 u_uiSensorRGB565(.cmos_clk_i  (clk_25m),//cmos senseor clock..rst_n_i     (resetn ),//system reset.active low..cmos_pclk_i (cmos_pclk),//input pixel clock..cmos_href_i (cmos_href),//input pixel hs signal..cmos_vsync_i(cmos_vsync),//input pixel vs signal..cmos_data_i (cmos_db),//data..cmos_xclk_o (cmos_xclk),//output clock to cmos sensor..rgb_o       (ov5640_rgb),.de_o        (ov5640_de ),.vs_o        (ov5640_vs ),.hs_o        ());uart_rx_analysis_top #(.CLK_FREQ(200_000_000),  //系统时钟频率.UART_BPS(115200     )   //串口波特率
)
uart_rx_analysis(.clk       (clk_200m),.rst_n     (resetn  ),.i_uart_rx (i_uart_rx),.o_uart_tx (o_uart_tx),.o_rx_done (o_rx_done),.o_rx_data (o_rx_data)
);ila_0 u_ila_0 (.clk(clk_200m), // input wire clk.probe0(o_rx_done), // input wire [0:0]  probe0  .probe1(o_rx_data) // input wire [31:0]  probe1
);always @(posedge clk_200m) beginif(~resetn) _rx_data<=32'h00000000;else if(o_rx_done) _rx_data<=o_rx_data;
endalways @(*) beginif(_rx_data==32'h0000aabb) beginud_w_0_ud_wclk =vin_clk ;ud_w_0_ud_wdata=vin_data;ud_w_0_ud_wde  =vin_de  ;ud_w_0_ud_wvs  =vin_vs  ;dis_h          =11'd1920;dis_v          =11'd1080;		endelse if(_rx_data==32'h0000ccdd) beginud_w_0_ud_wclk =cmos_pclk ;ud_w_0_ud_wdata={ov5640_rgb[7:0],ov5640_rgb[15:8],ov5640_rgb[23:16]};ud_w_0_ud_wde  =ov5640_de  ;ud_w_0_ud_wvs  =ov5640_vs  ;	dis_h          =11'd1280;dis_v          =11'd720 ;			endelse beginud_w_0_ud_wclk =vin_clk ;ud_w_0_ud_wdata=vin_data;ud_w_0_ud_wde  =vin_de  ;ud_w_0_ud_wvs  =vin_vs  ;	dis_h          =11'd1920;dis_v          =11'd1080;		end
enddesign_1_wrapper u_design_1_wrapper (.CLK_IN1_D_0_clk_n(CLK_IN1_D_0_clk_n),.CLK_IN1_D_0_clk_p(CLK_IN1_D_0_clk_p),.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_cs_n      (DDR3_0_cs_n      ),.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_200m         (clk_200m         ),.clk_hdmi         (clk_hdmi         ),.ddr3_ok          (ddr3_ok          ),.pll_resetn       (pll_resetn       ),.resetn           (resetn           ),.ud_r_0_ud_rclk   (ud_r_0_ud_rclk   ),.ud_r_0_ud_rdata  (ud_r_0_ud_rdata  ),.ud_r_0_ud_rde    (ud_r_0_ud_rde    ),.ud_r_0_ud_rempty (ud_r_0_ud_rempty ),.ud_r_0_ud_rvs    (ud_r_0_ud_rvs    ),.ud_w_0_ud_wclk   (ud_w_0_ud_wclk   ),.ud_w_0_ud_wdata  (ud_w_0_ud_wdata  ),.ud_w_0_ud_wde    (ud_w_0_ud_wde    ),.ud_w_0_ud_wfull  (ud_w_0_ud_wfull  ),.ud_w_0_ud_wvs    (ud_w_0_ud_wvs    ),.ui_clk_100m      (ui_clk_100m      ),.clk_25m          (clk_25m          ),.R_XSIZE_0        (dis_h            ),	.R_YSIZE_0        (dis_v            ),	.W_XSIZE_0        (dis_h            ),	.W_YSIZE_0        (dis_v            )	);	video_timing_control vga(.i_clk     (clk_hdmi   ),	.i_rst_n   (pll_resetn ), .i_start_x (0),.i_start_y (0),.i_disp_h  (dis_h),.i_disp_v  (dis_v),	.i_rgb     (i_rgb      ),.o_hs      (o_hs       ),.o_vs      (o_vs       ),.o_de      (o_de       ),.o_rgb     (o_rgb      ),.o_data_req(o_data_req )
);
endmodule

资源消耗和功耗如下:使用的是Xilinx Artix7-35T;
在这里插入图片描述

4、上板调试验证并演示

开发板:Xilinx Artix7-35T开发板; 开发环境:vivado2019.1;
输入1:ov5640摄像头1280x720@60Hz;
输入2:hdmi输入1920x1080@60Hz;
输出:hdmi输出1920x1080@60Hz;

输出演示视频如下:

FPGA实现不同分辨率视频切换输出,串口协议帧控制,提供工程

5、福利:工程代码的获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下:
在这里插入图片描述

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:哪种网络模式具有... 使用AWS ECS中的awsvpc网络模式来获得最佳性能。awsvpc网络模式允许ECS任务直接在V...