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


一、前言

  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 代码

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                                              vs  ,       //场同步输出
    output                                              hs  ,       //行同步输出
    output                                              de         //视频数据有效	
);

    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             [11:0]                              hcnt        = 12'd0;    //视频水平方向,列计数器
    reg             [11:0]                              vcnt        = 12'd0;    //视频垂直方向,行计数器 
    reg             [2 :0]                              rst_cnt     = 3'd0;  //复位计数器,寄存器
    wire                                                rst_sync    ; //同步复位
    wire                                                hs_valid    ;
    wire                                                vs_valid    ;

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

assign rst_sync = rst_cnt[2];

//视频水平方向,列计数器
always @(posedge clk)begin
    if(rst_sync == 1'b0) 
        hcnt <= 12'd0;
    else if(hcnt < (hcnt_max - 1'b1))
        hcnt <= hcnt + 1'b1;
    else 
        hcnt <= 12'd0;
end         

//视频垂直方向,行计数器,用于计数已经完成的行视频信号
always @(posedge clk)begin
    if(rst_sync == 1'b0)
        vcnt <= 12'd0;
    else if(hcnt == (hcnt_max - 1'b1)) begin
            if(vcnt == (vcnt_max - 1'b1))
                vcnt <= 12'd0;
            else
                vcnt <= vcnt + 1'b1;
    end
    else 
        vcnt <= vcnt;
end 

assign hs_valid    =  ((hcnt >= H_SYNC +H_BACK_PORCH)&&(hcnt < H_SYNC +H_BACK_PORCH +H_ACTIVE))? 1'b1 : 1'b0; //行信号有效像素部分
assign vs_valid    =  ((vcnt >=V_SYNC + V_BACK_PORCH)&&(vcnt<V_SYNC+V_BACK_PORCH+V_ACTIVE))? 1'b1 : 1'b0; //场信号有效像素部分
assign hs  =  (hcnt < H_SYNC) ? 1'b1 : 1'b0;//产生hs,行同步信号
assign vs  =  (vcnt < V_SYNC) ? 1'b1 : 1'b0;//产生vs,场同步信号      
assign de  =  hs_valid && vs_valid;//只有当视频水平方向,列有效和视频垂直方向,行同时有效,视频数据部分才是有效

endmodule

3.2 仿真以及分析

  tb文件编写

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

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

    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            	) 
);

endmodule

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

  由上图可以看出,V_SYNC信号共占2个v_cnt周期。

在这里插入图片描述

  由上图可以看出,H_SYNC信号共有1920ns,1920/20=96个h_cnt周期。

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱奔跑的虎子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值