VTC视频时序控制器原理以及Verilog实现

文章目录

  • 一、前言
  • 二、视频时序控制原理
  • 三、Verilog实现
    • 3.1 代码
    • 3.2 仿真以及分析


一、前言

  VTC(Video Timing Controller)是一种用于产生视频时序的控制器,在FPGA图像领域经常用到。Xilinx Vivado 也有专门用于生成视频时序的 IP,叫做 Video Timing Controller 核,简称为 VTC,官方的说明在 PG016,本文使用Verilog实现VTC的功能模块。

二、视频时序控制原理

  在《VGA接口时序以及FPGA实现》一问中,我们产生了VGA的视频时序并且成功在显示器上实现。VTC原理和VGA类似:

在这里插入图片描述
  显示器显示图像主要由行同步信号场同步信号构成,只要用正确的时钟产生正确的行场同步信号就能正确的输出画面时序。
  不同分辨率所对应的时序表如下:

显示模式时钟/Mhz行同步hsync行后沿行有效行前沿行总共场同步vsync场后沿场有效场前沿场总共
640×480@60Hz25.296486401680023348010525
800×600@60Hz40128888004010564236001628
1024×768@60Hz6513616010242413446297683806
1280×720@60Hz74.2540220128011016505207205750
1280×1024@60Hz1081122481280481688338102411066
1920×1080@60Hz148.5441481920882200536108041125
3840×2160@60Hz59488296384019644001072216082250

三、Verilog实现

3.1 代码

`timescale 1ns / 1ns 

module vtc#
(
parameter H_ActiveSize  =   1980,               //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
parameter H_FrameSize   =   1920+88+44+148,     //视频时间参数,行视频信号,一行视频信号总计占用的时钟数
parameter H_SyncStart   =   1920+88,            //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号 
parameter H_SyncEnd     =   1920+88+44,         //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分

parameter V_ActiveSize  =   1080,               //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
parameter V_FrameSize   =   1080+4+5+36,        //视频时间参数,场视频信号,一帧视频信号总计占用的行数量
parameter V_SyncStart   =   1080+4,             //视频时间参数,场同步开始,即多少行数后开始产生场同步信号 
parameter V_SyncEnd     =   1080+4+5            //视频时间参数,场同步结束,即多少场数后停止产生场同步信号,之后就是场有效数据部分
)
(
input           I_vtc_rstn,     //系统复位
input			I_vtc_clk,      //系统时钟
output			O_vtc_vs,       //场同步输出
output          O_vtc_hs,       //行同步输出
output          O_vtc_de_valid, //视频数据有效	
output          O_vtc_user,     //满足stream时序产生 user 信号,用于帧同步
output          O_vtc_last      //满足stream时序产生 later 信号,用于每行结束
);




reg [11:0] hcnt = 12'd0;    //视频水平方向,列计数器,寄存器
reg [11:0] vcnt = 12'd0;    //视频垂直方向,行计数器,寄存器   
reg [2 :0] rst_cnt = 3'd0;  //复位计数器,寄存器
wire rst_sync = rst_cnt[2]; //同步复位

always @(posedge I_vtc_clk or negedge I_vtc_rstn)begin //通过计数器产生同步复位
    if(I_vtc_rstn == 1'b0)
        rst_cnt <= 3'd0;
    else if(rst_cnt[2] == 1'b0)
        rst_cnt <= rst_cnt + 1'b1;
end    


//视频水平方向,列计数器
always @(posedge I_vtc_clk)begin
    if(rst_sync == 1'b0) //复位
        hcnt <= 12'd0;
    else if(hcnt < (H_FrameSize - 1'b1))//计数范围从0 ~ H_FrameSize-1
        hcnt <= hcnt + 1'b1;
    else 
        hcnt <= 12'd0;
end         

//视频垂直方向,行计数器,用于计数已经完成的行视频信号
always @(posedge I_vtc_clk)begin
    if(rst_sync == 1'b0)
        vcnt <= 12'd0;
    else if(hcnt == (H_ActiveSize  - 1'b1)) begin//视频水平方向,是否一行结束
           vcnt <= (vcnt == (V_FrameSize - 1'b1)) ? 12'd0 : vcnt + 1'b1;//视频垂直方向,行计数器加1,计数范围0~V_FrameSize - 1
    end
end 

wire hs_valid  =  hcnt < H_ActiveSize; //行信号有效像素部分
wire vs_valid  =  vcnt < V_ActiveSize; //场信号有效像素部分
wire vtc_hs    =  (hcnt >= H_SyncStart && hcnt < H_SyncEnd);//产生hs,行同步信号
wire vtc_vs	   =  (vcnt > V_SyncStart && vcnt <= V_SyncEnd);//产生vs,场同步信号      
wire vtc_de    =  hs_valid && vs_valid;//只有当视频水平方向,列有效和视频垂直方向,行同时有效,视频数据部分才是有效

//**********************  video stream video rgb  ***************************
reg   vtc_vs_r1  ;
reg   vtc_hs_r1  ;
reg   vtc_de_r1  ;
reg   vtc_user_r1 ,vtc_user_r2;
reg   vtc_valid_r1,vtc_valid_r2;
reg   vtc_last_r2;
reg   vs_start;
 
always @(posedge I_vtc_clk )begin
    if(rst_sync == 1'b0) //复位
        vs_start <= 1'b0;
    else if(vtc_user_r1)//清除VS帧同步
        vs_start <= 1'b0;
    else if(vtc_vs && vtc_vs_r1==1'b0)//当vtc_vs发生上升沿跳变代表一帧开始
        vs_start <= 1'b1;
end  
      
always @(posedge I_vtc_clk  )begin
    vtc_vs_r1    <= vtc_vs;
    vtc_hs_r1    <= vtc_hs;
    vtc_user_r1  <= ~vtc_user_r1 & vs_start & vtc_de;//vtc_user延迟1拍
    vtc_last_r2  <= ~vtc_de & vtc_valid_r1; //产生stream video last 延迟于数据输入2拍
    vtc_valid_r1 <= vtc_de;//vtc_valid延迟1拍
    vtc_valid_r2 <= vtc_valid_r1;//vtc_valid对输入信号延迟2拍,以和vtc_last_r2信号配套同步
    vtc_user_r2  <= vtc_user_r1; //vtc_user 对输入信号延迟2拍,以和vtc_last_r2信号配套同步    
end    

assign O_vtc_vs       =  vtc_vs_r1;
assign O_vtc_hs       =  vtc_hs_r1;
assign O_vtc_de_valid =  vtc_valid_r2;
assign O_vtc_user     =  vtc_user_r2;
assign O_vtc_last     =  vtc_last_r2;

endmodule

3.2 仿真以及分析

  tb文件编写

`timescale 1ns / 1ns //仿真时间刻度/精度


module vtc_tb;

localparam SYS_TIME = 20;//系统时钟周期20ns

reg I_vtc_rstn,I_vtc_clk;
wire O_vid_vs,O_vid_hs,O_vtc_de_valid,O_vtc_user,O_vtc_last;

//例化视频时序产生模块
vtc#
(
.H_ActiveSize(320),         //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素,设置320个像素
.H_FrameSize(320+88+44+239),//视频时间参数,行视频信号,一行视频信号总计占用的时钟数 
.H_SyncStart(320+88),       //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
.H_SyncEnd(320+88+44),      //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行数据有效数据部分
.V_ActiveSize(5),           //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
.V_FrameSize(5+4+5+28),     //视频时间参数,场视频信号,一帧视频信号总计占用的行数量
.V_SyncStart(5+4),          //视频时间参数,场同步开始,即多少行数后开始产生场同步信号 
.V_SyncEnd (5+4+5)          //视频时间参数,场同步结束,即多少行数后停止产生场同步信号,之后就是场有效数据部分
)
uivtc_inst
(
.I_vtc_clk(I_vtc_clk),  //系统时钟
.I_vtc_rstn(I_vtc_rstn),//系统复位
.O_vtc_vs(O_vid_vs),    //图形的vs信号
.O_vtc_hs(O_vid_hs),    //图形的hs信号
.O_vtc_de_valid(O_vtc_de_valid),	  //de数据有效信号
.O_vtc_user(O_vtc_user),     //满足stream时序产生 user 信号,用于帧同步
.O_vtc_last(O_vtc_last)      //满足stream时序产生 later 信号,用于每行结束
);


initial begin
    I_vtc_clk  = 1'b0;
    I_vtc_rstn = 1'b0;
    #100;
    I_vtc_rstn = 1'b1;
end

always #(SYS_TIME/2) I_vtc_clk= ~I_vtc_clk;

endmodule

仿真结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/562830.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

垃圾收集器ParNewCMS与底层三色标记算法详解

垃圾收集算法 分代收集理论 当前虚拟机的垃圾收集都是采用分代收集算法,这种算法没有什么新思想,只是依据对象的存活周期不同将内存分为几块.一般将Java堆分为新生代和老年代,这样就可以根据各个年代的特点选择合适的垃圾收集算法. 比如在新生代中,每次收集都会有大量对象(近…

安信可 ESP_01SWIFI模块的使用 (电脑通过usb转tll模块连接wifi模块进行调试)

一&#xff1a;需要用到的模块 &#xff08;1&#xff09;安信可的ESP_01wifi模块 ESP-01是深圳安信可科技基于ESP8266芯片开发的串口wifi模块&#xff0c;模组集成了透传功能&#xff0c;即买即用&#xff0c;支持串口指令集&#xff0c;用户通过串口即可实现网络访问…

如何使用JSONB类型在PostgreSQL中存储和查询复杂的数据结构?

文章目录 解决方案1. 创建包含JSONB列的表2. 插入JSONB数据3. 查询JSONB数据4. 创建索引以优化查询性能 示例代码结论 在PostgreSQL中&#xff0c;JSONB是一种二进制格式的JSON数据类型&#xff0c;它允许你在数据库中存储和查询复杂的JSON数据结构。与普通的JSON类型相比&…

【Hadoop】- MapReduce YARN 初体验[9]

目录 提交MapReduce程序至YARN运行 1、提交wordcount示例程序 1.1、先准备words.txt文件上传到hdfs&#xff0c;文件内容如下&#xff1a; 1.2、在hdfs中创建两个文件夹&#xff0c;分别为/input、/output 1.3、将创建好的words.txt文件上传到hdfs中/input 1.4、提交MapR…

量子城域网系列(六):关于量子信道

下图是“墨子号”卫星与兴隆地面站量子密钥分发的实验现场图&#xff0c;是不是很酷。星地高速量子密钥分发是“墨子号”量子卫星的科学目标之一。量子密钥分发实验采用卫星发射量子信号&#xff0c;地面接收的方式&#xff0c;“墨子号”量子卫星过境时&#xff0c;与河北兴隆…

性能监控(本地、服务器)

CPU、内存、磁盘等的监控 一、mac本地性能监控 1. top 终端&#xff1a; top load Avg: 平均负载(1分钟&#xff0c;5 分钟&#xff0c;15 分钟)值不能超过 4&#xff0c;要不然就是超负荷运行 Tasks: 进程数 %Cpu(s): idle :剩余百分比 KiB Mem: free:剩余内存&#xff0…

Mac电池管理软件 Batteries for Mac v2.2.9直装版

Batteries for Mac&#xff0c;作为一款专为Mac用户设计的电池管理软件&#xff0c;以其强大的功能和智能的监测机制&#xff0c;为用户提供了便捷、高效的电池使用体验。 Batteries for Mac(Mac电池)v2.2.9直装版下载 首先&#xff0c;Batteries for Mac具备实时电池监测功能&…

使用Python进行云计算:AWS、Azure、和Google Cloud的比较

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python进行云计算&#xff1a;AWS、Azure、和Google Cloud的比较 随着云计算的普及&am…

[Kubernetes] etcd的集群基石作用

文章目录 1. 配置存储2. 数据一致性3. 服务发现与协调4. 集群状态中枢5. 集群稳定性 1. 配置存储 etcd作为一个高度可靠的分布式键值存储系统&#xff0c;存储了Kubernetes集群的完整配置和状态数据。集群的元数据&#xff0c;包括节点信息、命名空间、部署、副本集、服务、持…

Modern CSV for Mac:强大的CSV文件编辑器

Modern CSV for Mac是一款功能强大的CSV文件编辑器&#xff0c;专为Mac用户设计&#xff0c;提供直观易用的界面和丰富的功能&#xff0c;使用户能够轻松编辑和管理CSV文件。 Modern CSV for Mac v2.0.6激活版下载 这款软件支持快速导入和导出CSV文件&#xff0c;方便用户与其他…

Java之类和对象

一面向对象的初步认知 1.什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的思想…

【Linux】MySQL的安装及配置(Ubuntu-18.04)

一、安装MySQL 分别安装MySQL服务器、MySQL客户端、C/C开发库 sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev 二、配置MySQL 1.查看默认配置文件&#xff0c;此处的user和password为默认提供的&#xff0c;…

强固型工业电脑在码头智能闸口、OCR(箱号识别)、集装箱卡车车载电脑行业应用

集装箱卡车车载电脑应用 背景介绍 针对码头集装箱卡车的调度运用, 结合码头TOS系统设计出了各种平台的车载电脑(VT系列)和车载LED显示屏(VLD系列)&#xff0c;同时提供各种安装支架&#xff0c;把车载电脑固定到狭小的驾驶室中&#xff1b;同时提供了各种天线选择&#xff08;…

【AI开发:音频】二、GPT-SoVITS使用方法和过程中出现的问题(GPU版)

1.FileNotFoundError: [Errno 2] No such file or directory: logs/guanshenxxx/2-name2text-0.txt 这个问题中包含了两个&#xff1a; 第一个&#xff1a;No module named pyopenjtalk 我的电脑出现的就是这个 解决&#xff1a;pip install pyopenjtalk 第二个&#xff1a…

Golang | Leetcode Golang题解之第42题接雨水

题目&#xff1a; 题解: func trap(height []int) (ans int) {n : len(height)if n 0 {return}leftMax : make([]int, n)leftMax[0] height[0]for i : 1; i < n; i {leftMax[i] max(leftMax[i-1], height[i])}rightMax : make([]int, n)rightMax[n-1] height[n-1]for i…

【深度学习】DragGAN

基于StyleGAN的图像拖拽编辑新范式 一、StyleGAN与DragGAN&#xff1a;图像生成与编辑的桥梁二、DragGAN的实现原理三、实例与代码展示四、总结与展望 在深度学习和计算机视觉领域&#xff0c;图像生成和编辑技术一直是研究的热点。StyleGAN作为一种强大的图像生成模型&#xf…

Linux基本命令之正则表达式(转义字符)

一&#xff1a;查看二进制文件 strings 命令&#xff1a;strings 文件名 生成链接文件 ln 命令&#xff1a;ln 选项 源文件(f1) 链接文件&#xff08;f2&#xff09; 软连接&#xff1a;eg:ln -s f1 f2 软链接不能跨分区链接&#xff0c;但可以在同一分区的不同目录下链接…

【python】启动一个公司级项目的完整报错和解决方案

启动一个项目对于新手都是不容易的事情 操作 打开项目 使用pyCharm打开python项目以后&#xff0c;先找main方法&#xff0c;一般在根目录有一个.py的文件 点进去以后会让你配置Python解释器 每个项目都有自己的一个虚拟环境&#xff0c;配置自己的解释器&#xff0c;可能…

【信号处理】基于CNN自编码器的心电信号异常检测识别(tensorflow)

关于 本项目主要实现卷积自编码器对于异常心电ECG信号的检测和识别&#xff0c;属于无监督学习中的生理信号检测的典型方法之一。 工具 方法实现 读取心电信号 normal_df pd.read_csv("/heartbeat/ptbdb_normal.csv").iloc[:, :-1] anomaly_df pd.read_csv(&quo…

MultiHeadAttention在Tensorflow中的实现原理

前言 通过这篇文章&#xff0c;你可以学习到Tensorflow实现MultiHeadAttention的底层原理。 一、MultiHeadAttention的本质内涵 1.Self_Atention机制 MultiHeadAttention是Self_Atention的多头堆嵌&#xff0c;有必要对Self_Atention机制进行一次深入浅出的理解&#xff0c;这…