本帖最后由 FPGA课程 于 2024-9-2 10:41 编辑
软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
1概述TPG(video_test_pattern generator) 视频测试模式发生器用于产生测试数据,对视频数据通路测试。 2 TPG视频测试模式发生器2.1系统框图I_tpg_ck:视频格式的像素时钟 I_tpg_vs:视频格式的场同步信号 I_tpg_hs:视频格式的行同步信号 I_tpg_de:视频格式的有效数据阶段
O_tpg_vs:同I_tpg_vs O_tpg_hs:同I_tpg_hs O_tpg_de:同I_tpg_de O_tpg_data:rgb格式数据输出
2.2时序设计视频数据的有效区域如下图所示:视频数据在H_AcitiveSize和V_AcitiveSize同时有效时候有效
3 TPG源码产生彩条、纯色、黑白棋方格测试数据,用于视频测试。 - `timescale 1ns / 1ns//仿真时间刻度/精度
- module uitpg
- (
- input I_tpg_clk, //系统时钟
- input I_tpg_rstn,//系统复位
- input I_tpg_vs, //场同步输入
- input I_tpg_hs, //行同步输入
- input I_tpg_de, //视频数据有效输入
- output O_tpg_vs, //场同步输出
- output O_tpg_hs, //行同步输出
- output O_tpg_de, //视频数据有效输出
- output [23:0] O_tpg_data //有效测试数据
- );
- reg tpg_vs_r = 1'b0; //对vs信号寄存
- reg tpg_hs_r = 1'b0; //对hs信号寄存
- reg [7 :0] grid_data = 8'd0; //grid棋方格寄存器
- reg [23:0] color_bar = 24'd0;//RGB 彩条寄存器
- reg [10:0] dis_mode = 11'd0;//显示模式寄存器
- reg [7 :0] r_reg = 8'd0; //红寄存器
- reg [7 :0] g_reg = 8'd0; //绿寄存器
- reg [7 :0] b_reg = 8'd0; //蓝寄存器
- always @(posedge I_tpg_clk)begin
- tpg_vs_r <= I_tpg_vs; //对vs信号寄存一次
- tpg_hs_r <= I_tpg_hs; //对hs信号寄存一次
- end
- reg [11:0]v_cnt = 12'd0; //视频垂直方向,行计数器
- reg [11:0]h_cnt = 12'd0; //视频水平方向,列计数器
- //h_cnt计数器模块
- always @(posedge I_tpg_clk)
- h_cnt <= I_tpg_de ? h_cnt + 1'b1 : 12'd0; //计数行有效像素,当de无效,重置 h_cnt=0
- //v_cnt计数器模块
- always @(posedge I_tpg_clk)
- if(I_tpg_vs) //通过vs产生同步复位
- v_cnt <= 12'd0; //重置v_cnt=0
- else
- v_cnt <= ((!tpg_hs_r)&&I_tpg_hs) ? v_cnt + 1'b1 : v_cnt; //hs信号的上升沿,v_cnt计数,这种方式可以不管hs有效是高电平还是低电平的情况,v_cnt 视频垂直方向,行计数器,计数行数量
- //显示模式切换
- always @(posedge I_tpg_clk)
- if(I_tpg_rstn==1'b0)
- dis_mode <= 0;
- else
- dis_mode <= ((!tpg_vs_r)&&I_tpg_vs) ? dis_mode + 1'b1 : dis_mode;
- //grid_data发生器
- always @(posedge I_tpg_clk)begin
- grid_data <= ((v_cnt[4]==1'b1) ^ (h_cnt[4]==1'b1)) ? 8'h00 : 8'hff; //方格大小16*16,黑白交替
- end
- //RGB彩条发生器
- always @(posedge I_tpg_clk)
- begin
- if(h_cnt==260)
- color_bar <= 24'hff0000;//红
- else if(h_cnt==420)
- color_bar <= 24'h00ff00;//绿
- else if(h_cnt==580)
- color_bar <= 24'h0000ff;//蓝
- else if(h_cnt==740)
- color_bar <= 24'hff00ff;//紫
- else if(h_cnt==900)
- color_bar <= 24'hffff00;//黄
- else if(h_cnt==1060)
- color_bar <= 24'h00ffff;//青蓝
- else if(h_cnt==1220)
- color_bar <= 24'hffffff;//白
- else if(h_cnt==1380)
- color_bar <= 24'h000000;//黑
- else
- color_bar <= color_bar;
- end
- //测试图形输出
- always @(posedge I_tpg_clk)begin
- case(dis_mode[10:7])//截取高位,控制切换显示速度
- 4'd0:begin
- r_reg <= 0;
- b_reg <= 0;
- g_reg <= 0;
- end
- 4'd1:begin
- r_reg <= 8'b11111111; //白
- g_reg <= 8'b11111111;
- b_reg <= 8'b11111111;
- end
- 4'd2,4'd3:begin//连续两个状态输出相同图形
- r_reg <= 8'b11111111; //红
- g_reg <= 0;
- b_reg <= 0;
- end
- 4'd4,4'd5:begin//连续两个状态输出相同图形
- r_reg <= 0; //绿
- g_reg <= 8'b11111111;
- b_reg <= 0;
- end
- 4'd6:begin
- r_reg <= 0; //蓝
- g_reg <= 0;
- b_reg <= 8'b11111111;
- end
- 4'd7,4'd8:begin //连续两个状态输出相同图形
- r_reg <= grid_data; //方格
- g_reg <= grid_data;
- b_reg <= grid_data;
- end
- 4'd9:begin
- r_reg <= h_cnt[7:0]; //水平渐变
- g_reg <= h_cnt[7:0];
- b_reg <= h_cnt[7:0];
- end
- 4'd10,4'd11:begin //连续两个状态输出相同图形
- r_reg <= v_cnt[7:0]; //垂直渐变
- g_reg <= v_cnt[7:0];
- b_reg <= v_cnt[7:0];
- end
- 4'd12:begin
- r_reg <= v_cnt[7:0]; //红垂直渐变
- g_reg <= 0;
- b_reg <= 0;
- end
- 4'd13:begin
- r_reg <= 0; //绿垂直渐变
- g_reg <= h_cnt[7:0];
- b_reg <= 0;
- end
- 4'd14:begin
- r_reg <= 0; //蓝垂直渐变
- g_reg <= 0;
- b_reg <= h_cnt[7:0];
- end
- 4'd15:begin
- r_reg <= color_bar[23:16]; //彩条
- g_reg <= color_bar[15:8];
- b_reg <= color_bar[7:0];
- end
- endcase
- end
- assign O_tpg_data = {r_reg,g_reg,b_reg};//测试图形RGB数据输出
- assign O_tpg_vs = I_tpg_vs; //VS同步信号
- assign O_tpg_hs = I_tpg_hs; //HS同步信号
- assign O_tpg_de = I_tpg_de; //DE数据有效信号
- endmodule
复制代码
4RTL仿真
4.1仿真激励文件
- /*************视频测试仿真文件****************************************
- *********************************************************************/
- `timescale 1ns / 1ns//仿真时间刻度/精度
- module video_test_tb;
- localparam SYS_TIME = 10;//系统时钟周期10ns
- reg I_vid_rstn,I_vid_sysclk_p,I_vid_sysclk_n;
- wire O_vid_vs,O_vid_hs,O_vid_de;
- wire [7:0]O_rgb_r,O_rgb_g,O_rgb_b;
- //例化video_test
- video_test video_test_inst
- (
- .I_vid_sysclk_p(I_vid_sysclk_p),
- .I_vid_sysclk_n(I_vid_sysclk_n),
- .I_vid_rstn(I_vid_rstn),
- .O_vid_vs(O_vid_vs),
- .O_vid_hs(O_vid_hs),
- .O_vid_de(O_vid_de),
- .O_rgb_r(O_rgb_r),
- .O_rgb_g(O_rgb_g),
- .O_rgb_b(O_rgb_b)
- );
- //初始化
- initial begin
- I_vid_sysclk_p = 1'b0;
- I_vid_sysclk_n = 1'b1;
- I_vid_rstn = 1'b0;
- #100;//产生100ns的系统复位
- I_vid_rstn = 1'b1;//复位完成
- end
- //产生仿真时钟
- always #(SYS_TIME/2) I_vid_sysclk_p= ~I_vid_sysclk_p;
- always #(SYS_TIME/2) I_vid_sysclk_n= ~I_vid_sysclk_n;
- endmodule
复制代码
为简化仿真,这里模拟的视频格式为320*5 即一行的有效数据为350个像素,一帧数据有5行像素数据。
4.2仿真结果
|