文章目录
- 一、前言
- 二、verilog代码实现
- 三、仿真以及结果分析
一、前言
TPG(video_test_pattern generator) 视频测试模式发生器用于产生测试数据,对视频数据通路测试。根据视频输出时序产生相应的图像数据
二、verilog代码实现
`timescale 1ns / 1nsmodule tpg
(
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)begintpg_vs_r <= I_tpg_vs; //对vs信号寄存一次tpg_hs_r <= I_tpg_hs; //对hs信号寄存一次
endreg [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=0else 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)begingrid_data <= ((v_cnt[4]==1'b1) ^ (h_cnt[4]==1'b1)) ? 8'h00 : 8'hff; //方格大小16*16,黑白交替
end//RGB彩条发生器
always @(posedge I_tpg_clk)
beginif(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;//黑elsecolor_bar <= color_bar;
end//测试图形输出
always @(posedge I_tpg_clk)begincase(dis_mode[10:7])//截取高位,控制切换显示速度4'd0:beginr_reg <= 0; b_reg <= 0;g_reg <= 0;end4'd1:beginr_reg <= 8'b11111111; //白g_reg <= 8'b11111111;b_reg <= 8'b11111111;end4'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;end4'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];end4'd10,4'd11:begin //连续两个状态输出相同图形r_reg <= v_cnt[7:0]; //垂直渐变g_reg <= v_cnt[7:0];b_reg <= v_cnt[7:0];end4'd12:begin r_reg <= v_cnt[7:0]; //红垂直渐变g_reg <= 0;b_reg <= 0;end4'd13:begin r_reg <= 0; //绿垂直渐变g_reg <= h_cnt[7:0];b_reg <= 0;end4'd14:begin r_reg <= 0; //蓝垂直渐变g_reg <= 0;b_reg <= h_cnt[7:0]; end4'd15:begin r_reg <= color_bar[23:16]; //彩条g_reg <= color_bar[15:8];b_reg <= color_bar[7:0]; end endcase
endassign 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
三、仿真以及结果分析
tb代码如下:
`timescale 1ns / 1ns//仿真时间刻度/精度module video_test_tb;localparam SYS_TIME = 20;//系统时钟周期10nsreg I_vid_rstn,I_vid_clk;
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_clk(I_vid_clk),
.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 beginI_vid_clk = 1'b0;I_vid_rstn = 1'b0;#100;//产生100ns的系统复位I_vid_rstn = 1'b1;//复位完成
end
//产生仿真时钟
always #(SYS_TIME/2) I_vid_clk= ~I_vid_clk;endmodule
结果分析: