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

news2025/3/15 1:57:41

文章目录

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


一、前言

  VTC(Video Timing Controller)是一种用于产生视频时序的控制器,在图像领域经常会输出各种分辨率和帧率的视频格式。因此为了方便,设置一个VTC控制模块,只需要在顶层修改一下需要输出的视频格式,就能自动的产生对应的时序,这样能方便处理一点。Xilinx Vivado 也有专门用于生成视频时序的 IP,叫做 Video Timing Controller 核,官方的说明在 PG016,本文使用Verilog实现VTC的基本功能。

二、视频时序控制原理

  在《VGA接口时序以及FPGA实现》文章中,我们实现了1080P的时序并且成功的在显示器上显示出来了。VTC原理和VGA一样,只需要在给正确的时钟频率产生出正确的VS和HS信号即可。视频显示原理如下:

在这里插入图片描述

  显示器显示图像主要由行同步信号场同步信号构成:

  • 每一行又分为:行同步信号H_SYNC;行后沿信号H_BACK_PORCH;行数据有效信号H_ACTIVE;行前沿信号 H_FRONT_PORCH。
  • 每一列同样分为:场同步信号V_SYNC;场后沿信号V_BACK_PORCH;场数据有效信号V_ACTIVE;场前沿信号V_FRONT_PORCH。
  • 只有在行数据有效信号H_ACTIVE和场数据有效信号V_ACTIVE都有效时,才输出de信号。

  常见分辨率视频所对应的各信号长度如下:

显示模式时钟/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_SYNC                  = 96,   //行同步信号
    parameter                                           H_BACK_PORCH            = 48,   //行后沿
    parameter                                           H_ACTIVE                = 640,  //行有效数据
    parameter                                           H_FRONT_PORCH           = 16,   //行前沿
    parameter                                           V_SYNC                  = 2,    //场同步信号
    parameter                                           V_BACK_PORCH            = 33,   //场后沿
    parameter                                           V_ACTIVE                = 480,  //场有效信号
    parameter                                           V_FRONT_PORCH           = 10    //场前沿
) 
(
    input                                               clk ,                   
    input                                               rst_n   ,
    output  reg                                         vs  ,                   //输出vs信号
    output  reg                                         hs  ,                   //输出hs信号
    output  reg                                         de  ,                   //输出de信号
    output  reg                                         h_end                   //每一行结束信号
);
    
    localparam                                          hcnt_max    = H_SYNC + H_BACK_PORCH + H_ACTIVE + H_FRONT_PORCH;     //行扫描最大计数值
    localparam                                          vcnt_max    = V_SYNC + V_BACK_PORCH + V_ACTIVE + V_FRONT_PORCH;     //列扫描最大计数值

    reg             [12:0]                              h_cnt = 13'd0  ;        //行扫描器,对列计数
    reg             [11:0]                              v_cnt = 12'd0  ;        //列扫描器,对行计数
    reg             [3:0]                               rst_cnt = 4'd0 ;        //复位计数器
    reg                                                 rst_sync = 1'b0  ;      //同步复位信号

    reg                                                 data_valid = 1'b0  ;          //输出数据有效信号
    reg                                                 data_valid_reg1 =1'b0  ;
    reg                                                 data_valid_reg2 =1'b0  ;
    reg                                                 hs_valid = 1'b0  ;           //行同步有效信号
    reg                                                 hs_valid_reg1 =1'b0  ;
    reg                                                 hs_valid_reg2 =1'b0  ;
    reg                                                 vs_valid = 1'b0  ;           //行同步有效信号
    reg                                                 vs_valid_reg1 =1'b0  ;
    reg                                                 vs_valid_reg2 =1'b0  ;
 

//异步复位,同步释放
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)
        rst_cnt <= 3'd0;
    else if (rst_cnt[3] == 1'b1) 
        rst_cnt <= rst_cnt;
    else
        rst_cnt <= rst_cnt + 1'b1;   
end

always @(posedge clk) begin
    if(rst_cnt[3] == 1'b0)
        rst_sync <= 1'b0;
    else
        rst_sync <= 1'b1;
end

//水平方向扫描,对列计数
always @(posedge clk) begin
    if(rst_sync == 1'b0)
        h_cnt <= 13'd0;
    else if(h_cnt == hcnt_max - 1)
        h_cnt <= 13'd0;
    else
        h_cnt <= h_cnt + 1'b1;
end

//垂直方向,对行计数
always @(posedge clk) begin
    if(rst_sync == 1'b0)
        v_cnt <= 12'd0;
    else if((v_cnt == vcnt_max - 1) && (h_cnt == hcnt_max - 1))
        v_cnt <= 12'd0;
    else if(h_cnt == hcnt_max - 1)
        v_cnt <= v_cnt + 1'b1;
    else
        v_cnt <= v_cnt;
end

//行同步信号
always @(posedge clk) begin
    if(rst_sync == 1'b0)
        hs_valid <= 1'b0;
    else if(h_cnt <= H_SYNC - 1)
        hs_valid <= 1'b1;
    else
        hs_valid <= 1'b0; 
end

always @(posedge clk) begin
    if(rst_sync == 1'b0)begin
        hs_valid_reg1 <= 1'b0;
        hs_valid_reg2 <= 1'b0;
    end
    else begin
        hs_valid_reg1 <= hs_valid;
        hs_valid_reg2 <= hs_valid_reg1;
    end
end

//场同步信号
always @(posedge clk) begin
    if(rst_sync == 1'b0)
        vs_valid <= 1'b0;
    else if(v_cnt <= V_SYNC - 1)
        vs_valid <= 1'b1;
    else
        vs_valid <= 1'b0;
end

always @(posedge clk) begin
    if(rst_sync == 1'b0)begin
        vs_valid_reg1 <= 1'b0;
        vs_valid_reg2 <= 1'b0;
    end
    else begin
        vs_valid_reg1 <= vs_valid;
        vs_valid_reg2 <= vs_valid_reg1;
    end
end

//数据有效信号
always @(posedge clk) begin
     if(rst_sync == 1'b0)
        data_valid <= 1'b0;
    else if(((h_cnt >= H_SYNC + H_BACK_PORCH)&&(h_cnt < hcnt_max - H_FRONT_PORCH))&&((v_cnt >= V_SYNC + V_BACK_PORCH)&&(v_cnt < vcnt_max - V_FRONT_PORCH)))
        data_valid <= 1'b1;
    else
        data_valid <= 1'b0;  
end

always @(posedge clk) begin
    if(rst_sync == 1'b0)begin
        data_valid_reg1 <= 1'b0;
        data_valid_reg2 <= 1'b0;
    end
    else begin
        data_valid_reg1 <= data_valid;
        data_valid_reg2 <= data_valid_reg1;
    end
end

//输出信号
always @(posedge clk) begin
    if(rst_sync == 1'b0)
        h_end <= 1'b0;
    else if(~data_valid_reg1 & data_valid_reg2)
        h_end <= 1'b1;
    else
        h_end <= 1'b0;
end

always @(posedge clk) begin
    if(rst_sync == 1'b0)begin
        de <= 1'b0;
        vs <= 1'b0;
        hs <= 1'b0;
    end
    else begin
        de <= data_valid_reg2;
        vs <= vs_valid_reg2;
        hs <= hs_valid_reg2;
    end
end
endmodule

3.2 仿真以及分析

  tb文件编写

`timescale 1ns / 1ps
module tb_vtc();

    reg                                                 clk ;
    reg                                                 rst_n   ;
    wire                                                de  ;
    wire                                                hs  ;
    wire                                                vs  ;
    wire                                                h_end   ;

    initial begin
        clk = 0;
        rst_n = 0;
        #200;
        rst_n = 1;
    end

always # 10 clk     = ~clk;

vtc#(
    .H_SYNC        ( 96 ),
    .H_BACK_PORCH  ( 48 ),
    .H_ACTIVE      ( 640 ),
    .H_FRONT_PORCH ( 16 ),
    .V_SYNC        ( 2 ),
    .V_BACK_PORCH  ( 33 ),
    .V_ACTIVE      ( 480 ),
    .V_FRONT_PORCH ( 10 )
)u_vtc(
    .clk           ( clk           ),
    .rst_n         ( rst_n         ),
    .vs            ( vs            ),
    .hs            ( hs            ),
    .de            ( de            ),
    .h_end         ( h_end         )
);

endmodule

仿真结果如下:
在这里插入图片描述
  由上图可以看出,V_SYNC信号共占2个v_cnt周期。

在这里插入图片描述
  由上图可以看出,H_SYNC信号共有1920ns,1920/20=96个h_cnt周期。

在这里插入图片描述  由上图可以看出,de信号共有12800ns,12800/20=640个h_cnt周期。综上,本次仿真符合640*480@60hz的视频时序

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++: IO流

目录 1、C语言输入输出 流的概念&#xff1a; 2、CIO流 3、C文件IO流 1、C语言输入输出 C语言中我们用到的最频繁的输入输出方式就是scanf () 与 printf() 。 scanf(): 从标准输入设备 ( 键 盘 ) 读取数据&#xff0c;并将值存放在变量中 。 printf(): 将指定的文…

C语言入门课程学习笔记2

C语言入门课程学习笔记2 第8课 - 四则运算与关系运算第9课 - 逻辑运算与位运算第10课 - 深度剖析位运算第11课 - 程序中的选择结构 本文学习自狄泰软件学院 唐佐林老师的 C语言入门课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 第8课 - 四则运算与关系…

pycharm安装AI写代码插件

在IDE安装特慢&#xff08;可能找不到插件&#xff09; 去官网搜一下 对应安装包 下载zip在IDE解压 插件--已安装齿轮图标--从磁盘里安装 选择下载的插件 应用 --重启OK

在ubuntu上安装mysql(在线安装需要)

安装环境 虚拟机系统&#xff1a; Ubuntu 打开虚拟机 安装步骤 (1) 安装 将系统中的所有软件包都升为最新版本 sudo apt update 安装 MySQL sudo apt install mysql-server查询 MySQL 版本 mysql --version(2) MySQL 安全设置 进入 MySQL Shell sudo mysql设置 …

window平台C#实现软件升级功能(控制台)

window平台C#实现软件升级功能 之前用window窗体实现过一个升级功能&#xff0c;后来发现多个项目都需要升级功能&#xff0c;现改成可接收参数实现一种通用的exe.改用控制台方式实现这个升级功能&#xff0c;这样不仅实现了接收参数&#xff0c;升级程序体积也比原来的窗体形式…

java自动生成pojo,springboot自动生成pojo

第一步 pom引入依赖 <dependencies><!-- mybatis-generator --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.7</version></dependency>&…

开源电商小程序源码+搭建 支持全平台端口+商家自营+多商户入驻 带分销功能 可自用DIY界面

开源电商小程序源码系统为商家提供了一个快速搭建和部署电商平台的解决方案。商家可以利用该系统&#xff0c;在较短的时间内构建出功能齐全、界面美观的电商小程序&#xff0c;无需从零开始编写代码&#xff0c;从而大大节省了开发成本和时间。 分享一个开源电商小程序源码系…

OpenUI在windows下部署使用

OpenUI OpenUI是一个基于Python的AI对话平台&#xff0c;支持接入多种AI模型。 通过聊天的方式来进行UI设计&#xff0c;你可以通过文字来描述你想要的UI界面&#xff0c;OpenUI可以帮你实时进行渲染出效果 安装OpenUI 这里预设你的电脑上已安装git、Python和pip&#xff0…

Nginx 搭建Web服务

题目&#xff1a; 1.web服务器的主机ip&#xff1a;192.168.78.128 2.web服务器的默认访问目录为/var/www/html 默认发布内容为default‘s page 3.站点news.timinglee.org默认发布目录 为/var/www/virtual/timinglee.org/news 默认发布内容为 news.timinglee.org 4.站点login.t…

Power BI 如何解决月份排序错误/乱序问题(自定义顺序/正确排序)

问题描述 在创建图标时&#xff0c;月份标签没有按照正确的顺序排列。 解决方案&#xff1a; Sort by Column 单击选中排序错误的列&#xff08;MMM&#xff09;根据列排序 (sort by Column)选择需要根据哪一列排序。 这里选择的是Month列&#xff0c;这一列有月份的序号1-…

如何通过香港站群服务器提升跨境电商交易效率?

如何通过香港站群服务器提升跨境电商交易效率? 在全球电子商务迅速发展的今天&#xff0c;跨境电商已成为企业拓展国际市场、获取更多商机的重要途径。然而&#xff0c;跨境电商面临的挑战也不容小觑&#xff0c;尤其是在交易效率方面。利用香港站群服务器&#xff0c;不仅可…

做抖音小店如何选品?这几个技巧,精准“锁定”爆品!

哈喽~我是电商月月 做抖音小店最重要的就是选品&#xff0c;这点大家都知道 一个店铺商品选的好&#xff0c;顾客喜欢&#xff0c;质量完好&#xff0c;销量和售后都不用操心&#xff0c;和达人合作时&#xff0c;爆单的机会也就越高 那这种商品是什么样的&#xff0c;新手开…

快速了解-BTP

名词了解 BTP&#xff1a;SAP Business Technology Platform 是一个技术和业务的平台ETWEAVER &#xff08;SAP NW&#xff09;&#xff1a;NetWeaver本质上是SAP一系列技术产品的集成平台PAAS Cloud Foundry&#xff08;云原生&#xff09;&#xff1a;开源云服务平台烟囱式…

通配符/泛域名证书的五大优势

在数字化时代&#xff0c;网络安全成为企业及个人关注的焦点。为了确保在线信息传输的安全性与私密性&#xff0c;SSL/TLS证书成为网站加密通信的重要工具。其中&#xff0c;通配符证书作为一种特殊类型的SSL证书&#xff0c;以其独特的优势在众多证书类型中脱颖而出&#xff0…

Python程序设计教案

文章目录&#xff1a; 一&#xff1a;软件环境安装 第一个软件&#xff1a;pycharm 第二个软件&#xff1a;thonny 第三个软件&#xff1a;IDIE&#xff08;自带的集成开发环境&#xff09; 二&#xff1a;相关 1.规范 2.关键字 3.Ascll码表 三&#xff1a;语法基础…

LeetCode-2007. 从双倍数组中还原原数组【贪心 数组 哈希表 排序】

LeetCode-2007. 从双倍数组中还原原数组【贪心 数组 哈希表 排序】 题目描述&#xff1a;解题思路一&#xff1a;排序 哈希表解题思路二&#xff1a;排序 队列解题思路三&#xff1a;消消乐 题目描述&#xff1a; 一个整数数组 original 可以转变成一个 双倍 数组 changed &…

使用Spring 完成转账业务添加日志功能

(完整的代码在文章附带文件中 , 文章里的代码仅作展示 , 可能有部分不完善 代码地址 :下载:https://javazhang.lanzn.com/i5oLI1vyiile 密码:1234 ) 任务目标 具体实现方法和心得 步骤1. 导入依赖项Spring依赖 , aop依赖,德鲁伊依赖,mybatis依赖 , mysql驱动 , mybatis-sprin…

jar包做成Windows Service 服务,不能访问网络映射磁盘

在Windows操作系统中&#xff0c;系统服务&#xff08;Services&#xff09;、计划任务&#xff08;Scheduled Tasks&#xff09;以及很多系统调用都是以SYSTEM系统账号进行操作的。用 net use 挂载&#xff0c;或者在文件管理器上直接挂载&#xff0c;挂载卷是以 Administrato…

在 ingress-nginx 负载均衡器上阻止特定路径

背景&#xff1a; 安全临时通知生产环境swagger的路径没屏蔽&#xff0c;正常思路是通过以下配置才能起作用&#xff0c;但是重启才能生效&#xff0c;又会影响用户使用。 springfox: documentation: # 总开关&#xff08;同时设置auto-startupfalse&#xff0c;否则/v3…

2020年海南职业院校技能大赛高职组

2020年海南职业院校技能大赛高职组“信息安全管理与评估”赛项任务书 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu5488233 赛项时间…