功能分析
VTC包含三个部分,时序检测、时序生成、中断控制器。时序检测或时序生成功能可以在不使用时禁用以节省资源。
很多时候视频输入的时序是由产品方案决定的,甚至是写在技术协议中的,按照相应的时序做后续处理即可。但有时视频输入的时序是不确定的,或者需要支持两种或以上的时序,例如常规的720P、1080P,60FPS、50FPS、30FPS,时序检测功能可以帮助我们确定时序信息,方便我们后续的处理。
时序生成功能并不复杂,几个计数器就能搞定。但是在实际的使用中,我们肯定会遇到很多问题,例如在跨时域时需要可设置的延时、在需要改变时序时还要考虑帧数据完整性等。经过长时间努力,我们肯定能造出一个适合我们已走过的道路的轮子。但是如果你还没有开始造轮子,那有一个量产的轮子也不错,毕竟重复造轮子并不总是值得的。
中断控制器的作用就是使用一组信号来表示当前状态,有时是脉冲,有时是电平,这在软核或者PS中配置中断触发模式时需要注意。VTC对应的中断信号如下图所示。
注:此处的时序与每时钟的像素数无关,仅可表示传输了多少次数据,而非传输了多少数据。例如常用的1080P数据,每行有效像素1920个,如果每个时钟传输4像素数据,则时序检测或时序生成对应的active line应为1920 / 4 = 480。
时序检测
时序检测有6个可选的输入:垂直消隐、垂直同步、水平消隐、水平同步、有效视频、有效色度。至少应该包含如下组合:垂直消隐、水平消隐、有效视频,或者垂直同步、水平同步、有效视频。如果输入信号未连接或驱动,相应的检测功能必须被禁用。在GUI中取消选择相应的选项即可。要使能时序检测功能,除了在IP配置的GUI中勾选使能项外,还要将控制寄存器的比特1置位。
极性检测的结果可以在对应寄存器中查看。检测极性寄存器(0x2C)的比特0-5对应了6个可选输入的极性,1表示高有效,0对应低有效。比特8对应了色度采样行间隔,1对应行间隔采样(4:2:0),0表示非隔行采样。比特9为1表示像素间隔采样,0表示非像素间隔采样。
将时序检测用于时序生成时,可以使用有效色度信号结合下面列出的两种信号组合来生成垂直消隐、水平消隐、有效视频:
- 垂直同步、水平同步、有效视频
- 垂直消隐、水平消隐、垂直同步、水平同步、有效视频
时序生成
时序生成可以生成垂直消隐、垂直同步、水平消隐、水平同步、有效视频、有效色度。在GUI中勾选相应的信号,并在控制寄存器中置位比特0或比特2。时序生成极性以及色度采样间隔在对应寄存器冲设置即可。
控制寄存器中的Source Select可以选择使用时序检测寄存器(需使能时序检测功能)或外部输入的生成寄存器来控制时序生成。
时序生成不支持在帧结束时同时结束行消隐和场消隐信号,通常在最后一行的行消隐生效时取消场消隐。最接近同时结束的情况是,设置场消隐提前最后一行的行消隐一个时钟结束。设置如下:F0_VBLANK_HEND = HFRAME_SIZE - 1。
配置和使用
下图显示了IP配置界面GUI,可以大致分为3部分,1部分是通用配置,2是时序生成配置,3是时序检测配置。
IP核的配置
第一部分为通用配置,根据不同的使用方式会产生不同的配置组合。
- Include AXI4-Lite Interface 此选项确定是否包含AXI4-Lite接口,使能之后可以通过带有AXI4 Master接口的模块或者软核对VTC进行灵活控制和信息获取。当禁用此接口时,用户无法获取时序信息,在GUI中仅使能时序检测并取消此选择时,会自动勾选上Include INTC interface选项。
- Include INTC Interface 包含中断控制器接口,在包含AXI4-Lite接口时,此选项为可选项,否则为必选项。
- Interlaced Video Support 是否支持隔行视频
- Synchronize Generator to Detector or to fsync_in使用时序检测器或帧同步来同步生成时序
- Max Clocks Per Line/Max Lines Per Frame 每帧最大宽高
- Fram Syncs 帧同步输出的数量
生成选项
Auto Generation Mode 仅在时序生成和时序检测均启用时可选,此时时序生成可使用时序检测的时序或寄存器配置时序,取决于第一次锁定时的状态。
其余部分很直白,按需勾选即可。
检测选项
这部分很直白,按需勾选即可。
默认/固定时序
在使能时序生成后,可以在默认/固定时序界面设置默认(当使用AXI4-Lite接口时,相应寄存器的默认值)或固定时序。其中预设了标准的480P、720P、1080P时序,选择Custom则可以自定义。此页面也包含了极性设置。
帧同步信号输出位置
当使能时序生成时,会有帧同步信号输出选项,最多支持16路同步信号输出。这里可以设置同步信号输出的时机(在帧中的位置,第几行的第几个时钟周期)。
IP核的使用
不同的使用方式会影响IP核的配置,我们验证几种常用的场景。
仅生成时序,时序固定
我们首先使用预设的时序来生成视频时序,也方便后续的测试。IP核的GUI配置界面如下图。
时序我们选择预设480P。
TestBench代码如下,为了方便观察,这里延长了复位和时钟使能信号。
`timescale 1ns / 1ns
//
// Company:
// Engineer:
//
// Create Date: 2024/07/16 13:34:52
// Design Name:
// Module Name: vtc_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module vtc_tb(
);
reg clk;
reg resetn;
reg clken;
reg gen_clken;
wire hsync;
wire vsync;
wire active_video;
wire fsync;
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
initial begin
resetn = 1'b0;
#20000 resetn = 1'b1;
end
initial begin
clken = 1'b0;
#10000 clken = 1'b1;
end
initial begin
gen_clken = 1'b0;
#30000 gen_clken = 1'b1;
end
v_tc_0 v_tc_0_u0 (
.clk(clk), // input wire clk
.resetn(resetn), // input wire resetn
.clken(clken), // input wire clken
.gen_clken(gen_clken), // input wire gen_clken
.sof_state(), // input wire sof_state
.hsync_out(hsync), // output wire hsync_out
.vsync_out(vsync), // output wire vsync_out
.active_video_out(active_video), // output wire active_video_out
.fsync_out(fsync) // output wire [0 : 0] fsync_out
);
endmodule
仿真波形如下
展开起始部分,可以看到帧同步信号以及有效视频信号相对于gen_clken的延迟。帧同步信号早于有效视频信号一个时钟周期。
仿真时钟周期10ns,视频有效信号宽度6.4us,有效信号持续640个周期。视频有效信号周期8us,帧宽度800个时钟。行同步信号出现在视频有效信号拉低后的0.16us,结束于视频有效信号拉低后的1.12us,持续时间0.96us,与设置中起始于656,结束于752一致。
场同步信号与视频有效信号间隔9个行同步信号,持续2个行同步信号,与设置一致。同时,我们注意到,场同步信号确实是在行同步信号置位时被拉低了。
使用AXI4-Lite接口配置时序
我们总是希望IP的使用可以更灵活,至少不需要每次变动都要重新配置IP、综合、布局布线,这个时候AXI4-Lite接口结合软核或者PS就可以满足我们的需求。
我们使能时序生成器,勾选Include AXI4-Lite Interface选项。默认时序设置为480P,非隔行模式。
添加MicroBlaze软核,这里我们使用默认配置。VIVADO提供自动生成软核相关模块,连接AXI4接口的功能。
我们在不设置时序寄存器的情况下使能时序生成功能,查看默认配置。然后关闭时序生成功能,配置时序寄存器,再使能时序生成功能,查看输出时序是否生效。软核代码如下:
#include "xvtc.h"
#include "xparameters.h"
#include <string.h>
XVtc vtc;
XVtc_Signal signal_cfg;
XVtc_Polarity signal_polarity;
XVtc_SourceSelect source;
int main(void)
{
XVtc_Config *vtc_cfg_ptr;
vtc_cfg_ptr = XVtc_LookupConfig(XPAR_XVTC_0_BASEADDR);
XVtc_CfgInitialize(&vtc, vtc_cfg_ptr, vtc_cfg_ptr->BaseAddress);
/* Use pre-set */
XVtc_EnableGenerator(&vtc);
/* VTC source, 1-Generator registers, 0-Detector registers */
memset((void *)&source, 0, sizeof(source));
source.VSyncPolSrc = 1;
source.HSyncPolSrc = 1;
source.ActiveVideoPolSrc = 1;
source.VActiveSrc = 1;
source.VBackPorchSrc = 1;
source.VSyncSrc = 1;
source.VFrontPorchSrc = 1;
source.VTotalSrc = 1;
source.HActiveSrc = 1;
source.HBackPorchSrc = 1;
source.HFrontPorchSrc = 1;
source.HTotalSrc = 1;
/* VTC Polarity */
memset((void *)&signal_polarity, 0, sizeof(signal_polarity));
signal_polarity.ActiveVideoPol = 1;
signal_polarity.VSyncPol = 1;
signal_polarity.HSyncPol = 1;
/* VTC timing */
memset((void *)&signal_cfg, 0, sizeof(signal_cfg));
signal_cfg.OriginMode = 1;
signal_cfg.HTotal = 8;
signal_cfg.HActiveStart = 0;
signal_cfg.HFrontPorchStart = 4;
signal_cfg.HSyncStart = 5;
signal_cfg.HBackPorchStart = 7;
signal_cfg.V0Total = 6;
signal_cfg.V0ActiveStart = 0;
signal_cfg.V0FrontPorchStart = 3;
signal_cfg.V0SyncStart = 4;
signal_cfg.V0BackPorchStart = 5;
/* Stop generator */
XVtc_DisableGenerator(&vtc);
/* Write VTC reg */
XVtc_RegUpdate(&vtc);
XVtc_SetPolarity(&vtc, &signal_polarity);
XVtc_SetGenerator(&vtc, &signal_cfg);
XVtc_SetSource(&vtc, &source);
/* Enable VTC generator */
XVtc_EnableGenerator(&vtc);
while(1) {
}
}
默认时序输出如下图,与480P一致。
按照新的时序配置后输出如下二图,与设置一致。
时序检测,使用AXI-Lite读取时序
我们再生成一个VTC,使能时序检测功能和时序生成功能,使用带有AXI4接口的软核读取检测到的时序信息,并将其用于时序生成。
当同时使能VTC的时序检测功能和时序生成功能时,时序生成的source(配置信息来源)有两种选择,检测器寄存器中的、生成器寄存器中的。我们可以根据需要将检测到的信息写入生成器的寄存器,也可以简单的将source设置为检测器寄存器。
下图是生成器生成的时序
检测器检测到的时序如下图,与生成器生成时序一致(未使用的信号不会产生有效值)。
使用检测器时序重新生成时序,运行结果如下图。可见输出时序与检测时序一致。同时也可以发现,两组时序间是没有同步的。
当我们使能生成器与检测器的同步后,即可得到同步的信号。可惜,帧同步输出出现了两次,有效视频信号出现了断裂。
我们试着加入2行延迟 ,帧起始部分正常了,虽然延迟了两个时钟。但是两行之后,帧同步信号又出现了。再看帧尾,多出了两行~
肯定有哪里不对,再看看手册!好家伙,我可以让生成器与检测器或者fsync_in同步,但我不能选择哪个同步~
之前连线的时候我们将fsync_in接入,同时又使能了检测器,两个信号都被作为同步源了?先将fsync_in断开试试,完美~下面分别是无延时和延时两行的信号输出。
如果我们不使能生成器,仅接入fsync_in呢?使用fsync_in时有两个时钟的延迟,当我们设置两行延时时,此延时不生效。
至此,VTC的基本使用已经了解了,更多的细节还是留在涉及到的时候再探索吧。