一品威客官方网站/网络公关公司联系方式
目录
- 1、前言
- 2、模拟视频概述
- 3、模拟视频颜色空间
- 4、逐行与隔行
- 5、BT656数据与解码
- BT656数据格式
- BT656数据解码
- 6、TW2867芯片解读与配置
- TW2867芯片解读
- TW2867芯片配置
- TW2867时序分析
- 7、设计思路与框架
- 8、vivado工程详解
- 9、上板调试验证
- 10、福利:工程代码的获取
1、前言
大自然的信号都是模拟的,视频信号也不例外。视频信号是指电视信号、静止图象信号和可视电视图像信号。视频信号分为三种制式:PAL、NTSC 和 SECAM。既然 PAL、NTSC、SECAM 都是模拟信号,FPGA 处理的是数字信号(有些 FPGA内部自带 AD,可以处理模拟信号,例如 Altera 的 MAX10),因此中间需要一个芯片做转换,也就是一个 ADC,学名叫做视频解码芯片。
本设计使用TW2867作为视频解码芯片,TW2867可输出PAL或者NTSC,代码中设置了配置参数,可任意选择其一,TW2867解码出4路BT656视频,BT656解码、图像缩放、视频去隔行、图像缓存后HDMI输出。
本文详细描述了FPGA实现模拟视频解码输出的设计方案,工程代码编译通过后上板调试验证,文章末尾有演示视频,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
2、模拟视频概述
大自然的信号都是模拟的,视频信号也不例外。视频信号是指电视信号、静止图象信号和可视电视图像信号。视频信号分为三种制式:PAL、NTSC 和 SECAM,接下来简单介绍一下这对于后期调试电路很有帮助。
PAL 制又称为帕尔制。PAL 是英文 Phase Alteration Line 的缩写,意思是逐行倒相,也属于同时制。“PAL”有时亦被用来指 625 线,每秒 25 格,隔行扫描,PAL 色彩编码的电视制式。NTSC 是 National Television Standards Committee 的缩写,意思是“(美国)国家电视标准委员会”。NTSC 负责开发一套美国标准电视广播传输和接收协议。SECAM 制式,又称塞康制,SECAM 是法文 Sequentiel Couleur A Memoire 缩写,意为“按顺序传送彩色与存储”,是一个首先用在法国模拟彩色电视系统。这只是简单的概述,关于 PAL、NTSC 和 SECAM 更详细的资料请参考视频技术手册。
既然 PAL、NTSC、SECAM 都是模拟信号,FPGA 处理的是数字信号(有些 FPGA内部自带 AD,可以处理模拟信号,例如 Altera 的 MAX10),因此中间需要一个芯片做转换,也就是一个 ADC,学名叫做视频解码芯片,本设计使用TW2867作为视频解码芯片。
3、模拟视频颜色空间
颜色空间也就是颜色的集合。有 3 个最常用的模型:RGB(计算机图形学)、YUV/YCbCr(视频系统)和 CMYK(打印系统)。在此只介绍 RGB 和 YUV/YCbCr。RGB 就是 red、green、blue 的缩写,也就是三原色,常用于计算机图像学中。常用的 RGB 格式有 RGB555、RGB565、RGB888 等。RGB565 含义是 red 占 5bit,green 占6bit,blue 占 5biit,一个占 16bit,颜色深度为 65536 色,常见的存储器有 8bit、16bit等,RGB565 的显示系统非常适合使用这种存储器。
在 YUV/YCbCr 空间中,Y 表示明亮度(Luminance、Luma)信号,U 表示色度(Chrominance)信号,V 表示浓度(Chroma)信号,只是对颜色空间另一种表示方法。常见的 YUV 格式有 YUV422、YUV444 等。YUV444 格式如下图所示,每一个像素分别用24bit 量化,分别量化成 Y、Cb、Cr,各占 8bit,从另一个方面说 YUV444 相当于RGB888,数据量是一样的,YUV444 格式如下图所示:
YUV422 格式如下图所示,它相当于在 YUV444 基础之上丢掉 Cb 和 Cr 数据,2 个像素量化成 32bit 数据,包括 2 个 Y,1 个 Cb,1 个 Cr,相当于 1 个像素需要 16bit 表示,相当于 RGB565 数据量。
TW2867输出的是YUV422 格式。
4、逐行与隔行
先简单区分一个概念,隔行扫描(Interlace scan)和逐行扫描(Progressive scan)。如下图所示,这是隔行扫描示意图,也就是先显示奇数行,然后再显示偶数行,这只是其中一种隔行扫描的方式,用途比较广泛,除此之外还有隔 2 行、隔 3 行扫描。
如下图所示,这是逐行扫描示意图,也就从第一行扫描,一直扫描到最后一行。目前显示器是逐行扫描的。
隔行转逐行是通过 DDR3 内存实现的,详细内容请参考工程代码。
5、BT656数据与解码
BT656数据格式
BT656 是一种视频输出格式,TW2867 视频输出是 BT656 格式,只有一小部分不一样,BT656 格式时钟是 27MHz,输出视频格式是 YUV422,隔行输出。
如上图所示是一行 BT656 数据结构,分成 4 段:EAV(4-byte)、BLANKING(280-byte)、SAV(4-byte)和有效数据(1440-byte),接下来分别介绍。BLANKING:280-byte,0x80 和 0x10 交替出现。有效数据:1440-byte,一共 720 个像素,Y 占 720 个数据,Cb 和 Cr 分别占 360 个数据。EAV 和 SAV:分别占 4-byte,前三个字节相同,是 0XFF,0X00,0X00,最后一个不同,根据这个字节进行解码。
EAV 和 SAV 的结构如上图所示,其中 F、V、H 含义:
F 是场信号,0 表示场 1,1 表示场 2,也就是奇偶场。V 表示场有效,0 表示场数据有效,1 表示是垂直消隐。H 区分 EAV 和 SAV 信号。P3-P0 只是校验保护位,由 F、V、H 进行异或运算得到。如下图所示,这是一帧 BT656 数据格式,一共包括 625 行,每行 1728 个字节,有效数据大小是 720x576,分成 2 场,每场 720x288,其余行是消隐信号。
BT656 规定一行有 1728 个字节,一帧有 625 行,每秒传输 25 帧数据,8bit 总线并行传输。1728x625x25=27000000=27M,经过计算就知道 27MHz 的来历了。在这 625行中有用的数据是 576 行,在 BT656 视频格式中有效视频大小是 720x576,其余的当做消隐处理。
BT656数据解码
压力来了,怎样才能做好 BT656 解码来适应不同的模块呢?根据BT656数据格式,解析并丢弃EAV(4-byte)、BLANKING(280-byte)、SAV(4-byte),保留有效数据(1440-byte),同时恢复行同步、场同步、奇偶场号、数据有效以及像素数据,详细内容请参考工程代码。
6、TW2867芯片解读与配置
TW2867芯片解读
本次设计使用的是专用模拟视频解码芯片 TW2867,支持 4 路模拟视频输入,4 路模拟音频输入,1 路音频输出,视频输出是标准 BT656 格式。由于 FPGA 引脚限制,MIS603 音频部分没有做;TW2867输入 4 路模拟视频信号,输出YUV422数字视频流,每路视频流是 BT656 格式,BT656 视频时钟 27MHz,4 路复合 =27MHzx4=108MHz,视频接口连接到 FPGA。
TW2867视频输出引脚说明如下:
对于 4 路复合视频时钟 108MHz,对硬件要求很高,数据线和时钟线等长布线。
TW2867芯片配置
TW2867 内部有很多寄存器,在此给出几个常用的寄存器及其含义,更多的内容请参考 TW2867 数据手册。
输出使能控制和时钟输出控制:
在这个寄存器中主要关心bit6配置为1,输出使能;bit3-2配置为0,CLKNO1输出27MHz时钟,bit1-0 配置为 2,CLKPO1 输出108MHz 时钟,通过这 2 个时钟可以把 4 路视频信号分开。这个寄存器配置为 0x42。
Bit6:配置为 1,标准 ITU-R656 格式。
Bit5-4:选择视频复合后输出引脚,配置为 1,从 CHID1 输出。
Bit3:配置为 0,正常 ITU-R656 格式。
Bit2:配置为 0,输出视频中有 EAV-SAV 信号。
Bit1:配置为 1,bit7-4 是 EAV/SAV 编码。
Bit0:配置为 0,奇数场和偶数场行数相等。
综上,这个寄存器配置为 0x52。
视频通道输出控制:
这个寄存器配置为 0x02,4 路视频通过时分复用到 VD1[7:0]输出,硬件设计连接到 VD1。
视频功能控制:
Bit7:配置为 0,视频视频数据输出限制到 0-254。
Bit6:配置为 1,ACKG 的输入参考是 ASYNP。
Bit5:配置为 0,输出格式是 YUV422 格式。
Bit4:配置为 1。
Bit3:配置为 0,仅用于测试。
Bit2:配置为 0,消隐时数据输出 0x80 和 0x10。
Bit1:配置为 0,ITU-R BT656 同步信号在消隐部分。
Bit0:配置为 1,HACTIVE 在垂直消隐期间使能。
这个寄存器配置为 0x51。
TW2867时序分析
之前介绍了 BT656 格式时钟 27MHz 的来源,TW2867 支持 4 路实时 BT656 视频,采样时分复用,最大时钟频率是 108MHz,因此需要一个 108MHz 的时钟输入引脚,考虑到方便解调出每路视频信号增加了一个 27MHz 的时钟输入信号,再加上 8 根数据,这样 10 根线就可以输入 4 路视频信号,在硬件设计上大大简化,降低了布线的复杂度。
如下图所示,TW2867 在 4 路视频复合时的时序图,那就是 4 个通道视频轮流输出,即通道 1 视频数据、通道 2 视频数据、通道 3 视频数据、通道 4 视频数据,然后重复。
通过了解视频数据复合方式,那解复合程序就可以设计了,那面说说思路。采用时分复用,每个通道数据轮流输出,那就需要一个计数器实现把每个通道的数据分离,即将 108MHz 时钟数据分成 4 个 27MHz 时钟数据。由于是 4 路视频,需要产生一个模长为 4 的计数器,根据计数器的数据把数据分配到 4 个视频通道上。详细内容请参考工程代码。
7、设计思路与框架
设计思路与框架如下:
图像输入:
4路PAL摄像头;
4路视频通道分离:
将4路复合视频分离出4路独立的视频通路;
BT656解码:
解码BT656,恢复出行、场、de、数据,BT656输出的是YUV422,这里直接提取数据输出YUV444;
颜色空间转换:
YUV444转RGB888,很简单,不多说;
图像缓存去隔行:
BT656分辨率是 720x576,写入DDR前,现将一行像素缩小至320;
在前面的教程中分析过隔行与逐行的区别,由于一行数据需要 2 次写入 DDR 才能写完,因此需要一个计数器,这样写入了 1 行数据,留出的空间是 2 行的空间,为另一场数据写入流出了空间,在留出的空间中写入数据,从而组成一帧完整的数据。详细内容请参考工程代码。
从DDR读出数据,然后将场方向缩小至280,这样视频从输入的720x576变为了320x240,刚好在640x480的屏幕上能放下4路图像;
图像输出:
输出HDMI视频,很简单,不多说。
8、vivado工程详解
开发板:Xilinx Artix7-100T
开发环境:vivado2019.1;
输入:4路PAL摄像头;
输出:HDMI,640x480;
工程代码架构如下:
顶层源码如下:
//
// Module Name : Video_TW2867.v
// Project Name : Video_TW2867
// Target Devices: XC7A100T-2FGG484
// Tool Versions : vivado2019.1
// Description :
// Dependencies :
// Revision :1.0 - File Created
// Additional Comments:
//
`timescale 1ns / 1ps
`include "system_parameter.h"
module Video_TW2867 (//************************clock port**********************//input i_clk //25MHz //************************DDR ports*************************//,inout [31:0] io_ddr3_dq,inout [3:0] io_ddr3_dqs_n,inout [3:0] io_ddr3_dqs_p,output [13:0] o_ddr3_addr,output [2:0] o_ddr3_ba,output o_ddr3_ras_n,output o_ddr3_cas_n,output o_ddr3_we_n,output o_ddr3_reset_n,output o_ddr3_ck_p,output o_ddr3_ck_n,output o_ddr3_cke,output o_ddr3_cs_n,output [3:0] o_ddr3_dm,output o_ddr3_odt//************************TW2867 ports*************************//,output o_TW2867_i2c_scl ,inout io_TW2867_i2c_sda,output o_TW2867_rst_n ,input i_video_clk_108m,input i_video_clk_27m,input [7:0] i_video_data //************************HDMI ports***************************//,output o_tmds_clk_p ,output o_tmds_clk_n ,output [2:0] o_tmds_data_p,output [2:0] o_tmds_data_n ,output o_hdmi_en ); //signal for clock and reset wire w_clk_25MHz ;wire w_clk_125MHz ;wire w_clk_100MHz ; wire w_clk_200MHz ;wire w_clk_200MHz_loeked ;wire w_sys_rst_n ;wire w_sys_clk ; //signal for TW2867 wire w_tw2867_init_done ; wire w_ID_error ; reg [9:0] r_TW2867_init_cnt ;reg r_TW2867_init_en ; //video CH1 data wire w_ch1_axis_tvalid ;wire w_ch1_axis_tready ;wire [31: 0] w_ch1_axis_tdata ;wire [3 : 0] w_ch1_axis_tkeep ;wire w_ch1_axis_tlast ;wire [3 : 0] w_ch1_axis_tuser ;//video CH2 data wire w_ch2_axis_tvalid ;wire w_ch2_axis_tready ;wire [31: 0] w_ch2_axis_tdata ;wire [3 : 0] w_ch2_axis_tkeep ;wire w_ch2_axis_tlast ;wire [3 : 0] w_ch2_axis_tuser ;//video CH3 data wire w_ch3_axis_tvalid ;wire w_ch3_axis_tready ;wire [31: 0] w_ch3_axis_tdata ;wire [3 : 0] w_ch3_axis_tkeep ;wire w_ch3_axis_tlast ;wire [3 : 0] w_ch3_axis_tuser ;//video CH4 data wire w_ch4_axis_tvalid ;wire w_ch4_axis_tready ;wire [31: 0] w_ch4_axis_tdata ;wire [3 : 0] w_ch4_axis_tkeep ;wire w_ch4_axis_tlast ;wire [3 : 0] w_ch4_axis_tuser ; //signal for Write DDRwire [31 : 0] w_DDR_wr_dma_baseaddr ; wire [15 : 0] w_DDR_wr_dma_vsize ; wire [15 : 0] w_DDR_wr_dma_hsize ; wire [15 : 0] w_DDR_wr_dma_stridesize ; wire w_DDR_wr_dma_start ; wire w_DDR_wr_dma_pause ; wire w_DDR_wr_dma_force_stop ; wire w_DDR_wr_dma_busy ; wire w_DDR_wr_dma_done ; wire [1 : 0] w_DDR_wr_dma_inter_err ; wire w_DDR_wr_axi_noack_err ; wire [3 : 0] w_DDR_wr_dma_parameter_err; wire w_DDR_wr_clk ; wire w_DDR_wr_en ; wire [31:0] w_DDR_wr_din ; wire w_DDR_wr_full ; wire w_DDR_wr_almost_full ; wire [10:0] w_DDR_wr_wr_data_count ; //signal for DDR wire w_ddr_init_done ;//signal for read image from ddrwire w_rd_vsync ;wire w_rd_hsync ;wire w_rd_active ; wire [31:0] w_image_data ;wire [15:0] w_DDR_rd_dma_hsize ; wire [15:0] w_DDR_rd_dma_vsize ;wire [15:0] w_DDR_rd_dma_stridesize ;wire w_DDR_rd_dma_start ;wire [31:0] w_DDR_rd_dma_base_addr ;wire w_DDR_rd_dma_busy ;wire w_DDR_rd_dma_done ;wire [1:0] w_ch1_frame_cnt ;wire [1:0] w_ch2_frame_cnt ;wire [1:0] w_ch3_frame_cnt ;wire [1:0] w_ch4_frame_cnt ;wire w_frame_start ;//signal for HDMI display wire [23:0] w_HDMI_data ;//*****************************************************************************// //part: Clock and Reset //*****************************************************************************// Clock_Unit_v1_0 helai_Clock_Unit (.i_clk (i_clk )//25MHz外部时钟,.o_clk_25MHz (w_clk_25MHz )//for VGA,.o_clk_125MHz (w_clk_125MHz ) ,.o_clk_100MHz ( ),.o_clk_200MHz (w_clk_200MHz )//for DDR,.o_clk_200MHz_loeked(w_clk_200MHz_loeked)//for DDR); //*****************************************************************************////part: TW2867 初始化 //*****************************************************************************// //控制启动TW2867的初始化启动时间,等复位稳定后即可启动always @ (posedge w_sys_clk ) beginif(w_sys_rst_n == 1'b0) r_TW2867_init_cnt <= 10'd0;else if(r_TW2867_init_cnt == 10'd1000) r_TW2867_init_cnt <= r_TW2867_init_cnt;else r_TW2867_init_cnt <= r_TW2867_init_cnt + 1'b1;end always @ (posedge w_sys_clk ) beginif(r_TW2867_init_cnt == 16'd800) r_TW2867_init_en <= 1'b1 ;else r_TW2867_init_en <= 1'b0 ;endTW2867_Init_Top_v1_0 #(.P_SYS_CLK (100_000_000 ) ,.P_I2C_CLK (200_000 )//200KHz,.P_ID_WR_ADDR (8'h50 ),.P_ID_RD_ADDR (8'h51 ),.P_SIMULATION (1'b0 ))helai_TW2867_Init( .i_sys_clk (w_sys_clk ) ,.i_reset_n (w_sys_rst_n ),.i_init_en (r_TW2867_init_en ) ,.o_i2c_sclk (o_TW2867_i2c_scl ),.io_i2c_sdat (io_TW2867_i2c_sda ),.o_tw2867_rst_n (o_TW2867_rst_n ),.o_ch_status_valid( )//通道状态数据有效 ,.o_ch_number ( )//通道号 ,.o_ch_status ( )//通道状态数据 ,.o_init_done (w_tw2867_init_done),.o_ID_error (w_ID_error ),.o_bir_en ( ) ); //*****************************************************************************// //part: TW2867 视频解码、采集 //*****************************************************************************// TW2867_Decode_v1_0 helai_TW2867_Decode (.i_clk_108M (i_video_clk_108m )//w_video_clk_108MHz,.i_clk_27M (i_video_clk_27m )//w_video_clk_27MHz ,.i_rst_n (w_tw2867_init_done)//w_sys_rst_n ,.i_mux_data (i_video_data )//------------------video CH1------------------ ,.i_ch1_s_aresetn (w_sys_rst_n ) ,.i_ch1_m_aclk (w_sys_clk ) ,.o_ch1_m_axis_tvalid(w_ch1_axis_tvalid ) ,.i_ch1_m_axis_tready(w_ch1_axis_tready ) ,.o_ch1_m_axis_tdata (w_ch1_axis_tdata ) ,.o_ch1_m_axis_tkeep (w_ch1_axis_tkeep ) ,.o_ch1_m_axis_tlast (w_ch1_axis_tlast ),.o_ch1_m_axis_tuser (w_ch1_axis_tuser )//------------------video CH2------------------ ,.i_ch2_s_aresetn (w_sys_rst_n ),.i_ch2_m_aclk (w_sys_clk ),.o_ch2_m_axis_tvalid(w_ch2_axis_tvalid ),.i_ch2_m_axis_tready(w_ch2_axis_tready ),.o_ch2_m_axis_tdata (w_ch2_axis_tdata ),.o_ch2_m_axis_tkeep (w_ch2_axis_tkeep ),.o_ch2_m_axis_tlast (w_ch2_axis_tlast ),.o_ch2_m_axis_tuser (w_ch2_axis_tuser )//------------------video CH3------------------ ,.i_ch3_s_aresetn (w_sys_rst_n ),.i_ch3_m_aclk (w_sys_clk ),.o_ch3_m_axis_tvalid(w_ch3_axis_tvalid ),.i_ch3_m_axis_tready(w_ch3_axis_tready ),.o_ch3_m_axis_tdata (w_ch3_axis_tdata ),.o_ch3_m_axis_tkeep (w_ch3_axis_tkeep ),.o_ch3_m_axis_tlast (w_ch3_axis_tlast ),.o_ch3_m_axis_tuser (w_ch3_axis_tuser )//------------------video CH4------------------,.i_ch4_s_aresetn (w_sys_rst_n ),.i_ch4_m_aclk (w_sys_clk ),.o_ch4_m_axis_tvalid(w_ch4_axis_tvalid ),.i_ch4_m_axis_tready(w_ch4_axis_tready ),.o_ch4_m_axis_tdata (w_ch4_axis_tdata ),.o_ch4_m_axis_tkeep (w_ch4_axis_tkeep ),.o_ch4_m_axis_tlast (w_ch4_axis_tlast ),.o_ch4_m_axis_tuser (w_ch4_axis_tuser )); //*******************************************************************************//part: DDR//*******************************************************************************WR_Frame_Buffer_Ctl_v1_0 helai_WR_FBC(.i_axi_rst_n (w_sys_rst_n ) ,.i_axi_clk (w_sys_clk )//--------------CH1 AXIS Port ----------------------/ ,.i_ch1_s_axis_tvalid (w_ch1_axis_tvalid ),.o_ch1_s_axis_tready (w_ch1_axis_tready ),.i_ch1_s_axis_tdata (w_ch1_axis_tdata ),.i_ch1_s_axis_tkeep (w_ch1_axis_tkeep ),.i_ch1_s_axis_tlast (w_ch1_axis_tlast ),.i_ch1_s_axis_tuser (w_ch1_axis_tuser )//--------------CH2 AXIS Port ----------------------/ ,.i_ch2_s_axis_tvalid (w_ch2_axis_tvalid ) ,.o_ch2_s_axis_tready (w_ch2_axis_tready ) ,.i_ch2_s_axis_tdata (w_ch2_axis_tdata ) ,.i_ch2_s_axis_tkeep (w_ch2_axis_tkeep ) ,.i_ch2_s_axis_tlast (w_ch2_axis_tlast ) ,.i_ch2_s_axis_tuser (w_ch2_axis_tuser ) //--------------CH3 AXIS Port ----------------------/ ,.i_ch3_s_axis_tvalid (w_ch3_axis_tvalid ) ,.o_ch3_s_axis_tready (w_ch3_axis_tready ) ,.i_ch3_s_axis_tdata (w_ch3_axis_tdata ) ,.i_ch3_s_axis_tkeep (w_ch3_axis_tkeep ) ,.i_ch3_s_axis_tlast (w_ch3_axis_tlast ) ,.i_ch3_s_axis_tuser (w_ch3_axis_tuser ) //--------------CH4 AXIS Port ----------------------// ,.i_ch4_s_axis_tvalid (w_ch4_axis_tvalid ) ,.o_ch4_s_axis_tready (w_ch4_axis_tready ) ,.i_ch4_s_axis_tdata (w_ch4_axis_tdata ) ,.i_ch4_s_axis_tkeep (w_ch4_axis_tkeep ) ,.i_ch4_s_axis_tlast (w_ch4_axis_tlast ) ,.i_ch4_s_axis_tuser (w_ch4_axis_tuser )//--------------Write DDR port --------------------//,.o_wr_dma_baseaddr (w_DDR_wr_dma_baseaddr ) ,.o_wr_dma_vsize (w_DDR_wr_dma_vsize ),.o_wr_dma_hsize (w_DDR_wr_dma_hsize ),.o_wr_dma_stridesize (w_DDR_wr_dma_stridesize ),.o_wr_dma_start (w_DDR_wr_dma_start ),.o_wr_dma_pause (w_DDR_wr_dma_pause ),.o_wr_dma_force_stop (w_DDR_wr_dma_force_stop ),.i_wr_dma_busy (w_DDR_wr_dma_busy ),.i_wr_dma_done (w_DDR_wr_dma_done ),.i_wr_dma_inter_err (w_DDR_wr_dma_inter_err ),.i_wr_axi_noack_err (w_DDR_wr_axi_noack_err ),.i_wr_dma_parameter_err(w_DDR_wr_dma_parameter_err),.o_wr_en (w_DDR_wr_en ),.o_wr_din (w_DDR_wr_din ),.i_wr_full (w_DDR_wr_full ),.i_wr_almost_full (w_DDR_wr_almost_full ),.i_wr_wr_data_count (w_DDR_wr_wr_data_count ),.o_ch1_frame_cnt (w_ch1_frame_cnt ),.o_ch2_frame_cnt (w_ch2_frame_cnt ),.o_ch3_frame_cnt (w_ch3_frame_cnt ),.o_ch4_frame_cnt (w_ch4_frame_cnt ));DDR_Top_v1_0 helai_DDR_Top(//globle signal.i_rst (~w_clk_200MHz_loeked ) ,.i_ddr_clk_i (w_clk_200MHz ) ,.o_sys_clk (w_sys_clk )//目前是100MHz,.o_sys_rst ( )// DDR port ,.ddr3_dq (io_ddr3_dq ) ,.ddr3_dqs_n (io_ddr3_dqs_n ) ,.ddr3_dqs_p (io_ddr3_dqs_p ) ,.ddr3_addr (o_ddr3_addr ) ,.ddr3_ba (o_ddr3_ba ) ,.ddr3_ras_n (o_ddr3_ras_n ) ,.ddr3_cas_n (o_ddr3_cas_n ) ,.ddr3_we_n (o_ddr3_we_n ) ,.ddr3_reset_n (o_ddr3_reset_n ) ,.ddr3_ck_p (o_ddr3_ck_p ) ,.ddr3_ck_n (o_ddr3_ck_n ) ,.ddr3_cke (o_ddr3_cke ) ,.ddr3_cs_n (o_ddr3_cs_n ) ,.ddr3_dm (o_ddr3_dm ) ,.ddr3_odt (o_ddr3_odt ) ,.init_calib_complete (w_ddr_init_done )// Read port ,.i_rd_dma_start (w_DDR_rd_dma_start ) ,.i_rd_dma_base_addr (w_DDR_rd_dma_base_addr ),.o_rd_dma_busy (w_DDR_rd_dma_busy ),.o_rd_dma_done (w_DDR_rd_dma_done ),.i_rd_dma_hsize (w_DDR_rd_dma_hsize ) ,.i_rd_dma_vsize (w_DDR_rd_dma_vsize ) ,.i_rd_dma_stridesize (w_DDR_rd_dma_stridesize ),.i_rd_frame_start (w_frame_start ) ,.i_rd_clk (w_clk_25MHz ),.i_rd_en (w_rd_active ),.o_rd_data_out (w_image_data ),.o_rd_data_valid ( ),.o_rd_empty ( ),.o_rd_almost_empty ( ),.o_rd_rd_data_count ( ),.o_rd_fifo_wcount ( )//Write port ,.i_wr_dma_baseaddr (w_DDR_wr_dma_baseaddr ) ,.i_wr_dma_vsize (w_DDR_wr_dma_vsize ) ,.i_wr_dma_hsize (w_DDR_wr_dma_hsize ) ,.i_wr_dma_stridesize (w_DDR_wr_dma_stridesize ) ,.i_wr_dma_start (w_DDR_wr_dma_start ) ,.i_wr_dma_pause (w_DDR_wr_dma_pause ) ,.i_wr_dma_force_stop (w_DDR_wr_dma_force_stop ) ,.o_wr_dma_busy (w_DDR_wr_dma_busy ) ,.o_wr_dma_done (w_DDR_wr_dma_done ) ,.o_wr_dma_inter_err (w_DDR_wr_dma_inter_err ) ,.o_wr_axi_noack_err (w_DDR_wr_axi_noack_err ) ,.o_wr_dma_parameter_err(w_DDR_wr_dma_parameter_err) ,.i_wr_clk (w_sys_clk ) ,.i_wr_en (w_DDR_wr_en ) ,.i_wr_din (w_DDR_wr_din ) ,.o_wr_full (w_DDR_wr_full ) ,.o_wr_almost_full (w_DDR_wr_almost_full ) ,.o_wr_wr_data_count (w_DDR_wr_wr_data_count ) );assign w_sys_rst_n = w_ddr_init_done ; //DDR 初始化完成后,系统其它部分再开始工作 //*******************************************************************************/ //part: 读DDR // ******************************************************************************/ //从DDR中读取图像Image_Output_IF_Timing_v2_2 #( .P_H_FRONT_PORCH (`P_VGA_H_FRONT ),.P_H_SYNC_PULSE (`P_VGA_H_SYNC ),.P_H_BACK_PORCH (`P_VGA_H_BACK ),.P_H_ACT_SIZE (`P_VGA_H_ACTIVE ),.P_V_FRONT_PORCH (`P_VGA_V_FRONT ),.P_V_SYNC_PULSE (`P_VGA_V_SYNC ),.P_V_BACK_PORCH (`P_VGA_V_BACK ),.P_V_ACT_SIZE (`P_VGA_V_ACTIVE ) ,.P_FIFO_RCW (12 )) helai_read_Image( .i_clk (w_clk_25MHz )//w_sys_clk ,.i_resetn (w_clk_200MHz_loeked ) ,.i_timing_en (w_clk_200MHz_loeked ) ,.o_frame_start (w_frame_start ) ,.o_frame_done ( ) ,.o_vsync (w_rd_vsync ) ,.o_hsync (w_rd_hsync ) ,.o_active (w_rd_active ) ,.o_fvld ( ) ,.o_sol ( ) ,.i_axi_clk (w_sys_clk ),.i_axi_rst_n (w_sys_rst_n ),.o_dma_start (w_DDR_rd_dma_start ),.o_dma_base_addr (w_DDR_rd_dma_base_addr ),.o_dma_hsize (w_DDR_rd_dma_hsize ),.o_dma_vsize (w_DDR_rd_dma_vsize ),.o_dma_stridesize(w_DDR_rd_dma_stridesize),.i_rd_dma_busy (w_DDR_rd_dma_busy ),.i_rd_dma_done (w_DDR_rd_dma_done ),.i_ch1_frame_cnt (w_ch1_frame_cnt ),.i_ch2_frame_cnt (w_ch2_frame_cnt ),.i_ch3_frame_cnt (w_ch3_frame_cnt ),.i_ch4_frame_cnt (w_ch4_frame_cnt )); //*******************************************************************************/ //part: HDMI display // ******************************************************************************/ rgb2dvi #( .kGenerateSerialClk(1'b0) ,.kClkRange (1 ) ,.kRstActiveHigh (1'b1) )helai_HDMI( // DVI 1.0 TMDS video interface .TMDS_Clk_p (o_tmds_clk_p ) ,.TMDS_Clk_n (o_tmds_clk_n ) ,.TMDS_Data_p(o_tmds_data_p) ,.TMDS_Data_n(o_tmds_data_n) //Auxiliary signals ,.aRst (1'b0 ) ,.aRst_n (1'b1 ) // Video in ,.vid_pData (w_HDMI_data )//RBG {8'd255,8'd0,8'd0} ,.vid_pVDE (w_rd_active ) ,.vid_pHSync(w_rd_hsync ) ,.vid_pVSync(w_rd_vsync ) ,.PixelClk (w_clk_25MHz ) ,.SerialClk (w_clk_125MHz )// 5x PixelClk ); //assign w_HDMI_data = {w_image_data[23:16],w_image_data[7:0],w_image_data[15:8]};//RBG888输出模式assign w_HDMI_data = {w_image_data[23:19],w_image_data[21:19], //上位机显示的图像是由RGB565转换成的RGB888,此处为了做一样的颜色补偿,w_image_data[7:3] ,w_image_data[5:3] , //采用了这种输出显示的方式 w_image_data[15:10],w_image_data[11:10]};assign o_hdmi_en = 1'b1 ; endmodule
资源消耗和功耗预估如下:
9、上板调试验证
由于某些保密因素,暂无法展示输出,请见谅。。。
10、福利:工程代码的获取
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下:
相关文章:

FPGA实现模拟视频BT656解码 TW2867四路PAL采集拼接显示 提供工程源码和技术支持
目录1、前言2、模拟视频概述3、模拟视频颜色空间4、逐行与隔行5、BT656数据与解码BT656数据格式BT656数据解码6、TW2867芯片解读与配置TW2867芯片解读TW2867芯片配置TW2867时序分析7、设计思路与框架8、vivado工程详解9、上板调试验证10、福利:工程代码的获取1、前言…...

【建议收藏】超详细的Canal入门,看这篇就够了!!!
概述 canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB)。 背景 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部…...

KubeSphere 社区双周报 | OpenFunction v1.0.0-rc.0 发布
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为:2023.02.17-2023.…...

查漏补缺3月
SPI扩展序列化方式 分布式ID的相关问题 TCP的流量控制,避免浪费网络资源的滑动平均法也可以用在其他可能会出现资源浪费的情况等 讲一讲对自己这个 RPC 项目的想法,你是怎么设计这个项目的,想要实现那些功能? 你认为一个好的 RPC…...

如何使用Java实现类似Windows域登录
什么是域登录? 域登录是一种集中式身份验证和授权方法,用于访问企业内部网络和资源。在Windows环境中,域是一组计算机和用户帐户的集合,受到单个安全管理的控制。域登录允许用户在访问域资源时使用单个帐户名和密码进行身份验证&…...

生成模型与判别模型
生成模型与判别模型 一、决策函数Yf(X)或者条件概率分布P(Y|X) 监督学习的任务就是从数据中学习一个模型(也叫分类器),应用这一模型,对给定的输入X预测相应的输出Y。这个模型的一般形式为决策函数Yf(X)或者条件概率分布P(Y|X)。 …...

Kotlin lateinit 和 lazy 之间的区别 (翻译)
Kotlin 中的属性是使用var或val关键字声明的。Late init 和 lazy 都是用来初始化以后要用到的属性。 由于这两个关键字都用于声明稍后将要使用的属性,因此让我们看一下它们以及它们的区别。 Late Init 在下面的示例中,我们有一个变量 myClass࿰…...

Golang alpine Dockerfile 最小打包
最近在ubantu 上进行了 iris项目的alpine 版本打包,过程遇到了一些问题,记录一下。 golang版本 :1.18 系统:ubantu 代码结构 Dockfile内容 FROM alpine:latest MAINTAINER Si Wei<3320376695qq.com> ENV VERSION 1.1 ENV G…...

在NVIDIA JetBot Nano小车上更新WIFI驱动
前言:树莓派上的WIFI驱动类型比较多,经常有更好驱动的需求本文给出RealTek的无线WIFI模组,8821CU的驱动更新办法步骤第一 通过其他方式连接网络小车通过网线或者老的WIFI连接到网络上第二 构建驱动模块并下载驱动首先,我们需要打开一个ubuntu…...

2023年网络安全最应该看的书籍,弯道超车,拒绝看烂书
学习的方法有很多种,看书就是一种不错的方法,但为什么总有人说:“看书是学不会技术的”。 其实就是书籍没选对,看的书不好,你学不下去是很正常的。 一本好书其实不亚于一套好的视频教程,尤其是经典的好书…...

VSYNC研究
Vsync信号是SurfaceFlinger进程中核心的一块逻辑,我们主要从以下几个方面着手讲解。软件Vsync是怎么实现的,它是如何保持有效性的?systrace中看到的VSYNC信号如何解读,这些脉冲信号是在哪里打印的?为什么VSYNC-sf / VS…...

python gRPC:根据.protobuf文件生成py代码、grpc转换为http协议对外提供服务
文章目录python GRPC:根据.protobuf文件生成py代码grpcio-tools安装和使用python GRPC的官网示例grpc转换为http协议对外提供服务工作问题总结grpc-ecosystem/grpc-gateway/third_party/googleapis: warning: directory does not exist.python GRPC:根据…...

Allegro如何输出ODB文件操作指导
Allegro如何输出ODB文件操作指导 在PCB设计完成之后,需要输出生产文件用于生产加工,除了gerber文件可以用生产制造,ODB文件同样也可以用于生产,如下图 用Allegro如何输出ODB文件,具体操作如下 首先确保电脑上已经安装了ODB这个插件,版本不受限制点击File...

koa-vue的分页实现
1.引言 最近确实体会到了前端找工作的难处,不过大家还是要稳住心态,毕竟有一些前端大神说的有道理,前端发展了近20年,诞生了很多leader级别的大神,这些大神可能都没有合适的坑位,我们新手入坑自然难一些&am…...

安全开发基础 -- DAST,SAST,IAST简单介绍
安全开发基础-- DAST,SAST,IAST 简介 DAST 动态应用程序安全测试(Dynamic Application Security Testing)技术在测试或运行阶段分析应用程序的动态运行状态。它模拟黑客行为对应用程序进行动态攻击,分析应用程序的反…...

网络安全之暴力破解介绍及暴力破解Tomcat
网络安全之暴力破解介绍及应用场景一、暴力破解介绍1.1 暴力破解介绍1.2 暴力破解应用场景一、暴力破解Tomcat一、暴力破解介绍 1.1 暴力破解介绍 暴力破解字典:https://github.com/k8gege/PasswordDic 1.2 暴力破解应用场景 一、暴力破解Tomcat 登录Tomcat后台&a…...

Elasticsearch:使用 Logstash 构建从 Kafka 到 Elasticsearch 的管道 - Nodejs
在我之前的文章 “Elastic:使用 Kafka 部署 Elastic Stack”,我构建了从 Beats > Kafka > Logstash > Elasticsearch 的管道。在今天的文章中,我将描述从 Nodejs > Kafka > Logstash > Elasticsearch 这样的一个数据流。在…...

记录一次es的性能调优
文章目录es性能调优启用g1垃圾回收器es性能调优 成都的es集群经常出现告警,查看日志发现 [gc][11534155] overhead, spent [38.3s] collecting in the last [38.6s]这是 JVM 垃圾回收过程中的一条日志,表示在最近 38.6 秒内,JVM 进行了一次…...

内核性能评估测试及具体修改操作步骤记录
步骤记录前言一、查看环境配置二、LRU缓存空间调整三、进程扫描时间间隔四、与其他内核对比的工作负载测试(另一个内核的编译)总结前言 记录的相关操作有:查看服务器硬件环境、LRU缓存大小修改、内核命名、内核编译以及进程执行周期的设置。…...

S7-200smart远程无线模拟量信号采集案例
本参考方案使用西门子PLCS7-200SMART 结合无线通讯终端DTD434MC和DTD433F实现 PLC对远端设备模拟量的远程无线输入输出查询控制。所使用到的设备:西门子S7-200smartPLC无线数据终端DTD434MC无线模拟量信号测控终端DTD433F所使用的协议:ModbusRTU协议方案…...

Blender Python材质处理入门
本文介绍在 Blender 中如何使用 Python API 获取材质及其属性。 推荐:用 NSDT场景设计器 快速搭建3D场景。 1、如何获取材质 方法1、 获取当前激活的材质 激活材质是当前在材质槽中选择的材料。 如果你选择一个面,则活动材料将更改为分配给选定面的材质…...

ChatGPT后劲很大,问题也是
ChatGPT亮相即封神,最初的访客是程序员、工程师、AI从业者、投资人,最后是无数懵懂又好奇的普通人:ChatGPT是什么?自己会被ChatGPT取代吗?看待ChatGPT的立场也是两个极端: 快乐,是因为ChatGPT太…...

世界那么大,你哪都别去了,来我带你了解CSS3 (二)
文章目录❤️🔥CSS文档流❤️🔥CSS浮动❤️🔥CSS定位❤️🔥CSS媒体查询❤️🔥CSS文档流 文档流是文档中可显示对象在排列时所占用的位置/空间。 例如:块元素自上而下摆放,内…...

2023年再不会Redis,就要被淘汰了
目录专栏导读一、同样是缓存,用map不行吗?二、Redis为什么是单线程的?三、Redis真的是单线程的吗?四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…...

Java SPI机制了解与应用
1. 了解SPI机制 我们在平时学习和工作中总是会听到Java SPI机制,特别是使用第三方框架的时候,那么什么是SP机制呢?SPI 全称 Service Provider Interface,是 Java 提供的一套用来被第三方实现或者扩展的接口,它可以用来…...

vue实现输入框中输完后光标自动跳到下一个输入框中
前言 最近接到这么一个需求,做一个安全码的输入框,限制为6位数,但是每一个写入的值都是一个输入框,共计6个输入框,当前输入框写入值后,光标自动跳到下一个输入框中,删除当前输入框写入的值后再自…...

如何构建 C 语言编译环境?
C语言是一种通用的编程语言,它是由Dennis Ritchie于20世纪70年代初在贝尔实验室开发的。C语言的设计目标是提供一种结构化、高效、可移植的编程语言,以支持系统编程和应用程序开发。C语言广泛用于开发操作系统、网络设备、游戏、嵌入式系统、桌面应用程序…...

电子台账:模板制作之一——列过滤(水平过滤)
1 简介列过滤即水平过滤。一般情况下,企业数据源文件中有很多数据列,其中大部分数据列中的数据对电子台账来说是没有用的。列过滤就是确定企业数据文件的哪几列有用,以及有用的列分别对应到台账(模板)的哪一列。列过滤…...

【java】Java连接mysql数据库及mysql驱动jar包下载和使用
文章目录JDBCJDBC本质:JDBC作用:跟数据库建立连接发送 SQL 语句返回处理结果操作流程和具体的连接步骤如下:操作步骤:需要导入驱动jar包 mysql-connector-java-8.0.22.jar注册驱动获取数据库连接对象 Connection定义sql获取执行sq…...

Mysql八股文
Mysql八股文 数据库的三范式是什么 第一范式:列不可再分第二范式:行可以唯一区分,主键约束第三范式:表的非主属性不能依赖与 其他表的非主属性 外键约束且三大范式是一级一级依赖的,第二范式建立在第一范式上&#x…...