[X]关闭

1-4-07 RGB转HDMI显示方案

文档创建者:uisrc
浏览次数:323
最后更新:2023-12-27
文档课程分类
AMD: FPGA部分(2024样板资料) » 1_START(适配所有型号) » 4-硬件功能案例
软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA
登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!
1 概述
本实验通过FPGA内部资源实现HDMI协议,使用HDMI直接驱动HDMI接口显示器,这是成本非常低廉的一种方案,可以实现HDMI输出1080P@60fps的视频图像。本实验需要用到VTC模块产生视频时序,以及TPG模块产生测试图形。
2 硬件电路分析
硬件接口和子卡模块请阅读"附录 1"
配套工程的 FPGA PIN 脚定义路径为 fpga_prj/uisrc/04_pin/ fpga_pin.xdc。
3 系统框图
2504661-20231227191412407-1807240649.jpg
4 代码分析4.1 VTC控制器4.1.1 VTC控制器系统框图
VTC控制器通过hcnt和vcnt计数器实现hs时序vs时序以及de时序。
2504661-20231227191412940-1482729296.jpg
4.1.2 VTC控制器时序设计
视频数据在H_AcitiveSize和V_AcitiveSize同时有效时候有效,显示屏上的显示效果如下图所示。
2504661-20231227191413329-2145175223.jpg
4.1.3 VTC源码
/*************uivtc(video timing controller)视频时序控制器*************
--版本号1.1
--以下是米联客设计的uivtc(video timing controller)视频时序控制器
--1.代码简洁,占用极少逻辑资源,代码结构清晰,逻辑设计严谨
--2.使用方便,只需要输入6个参数既可以实现对不同视频分辨率时序的控制
--3.该视频时序控制,一个时钟对应一个像素
--4.通常我们说的像素,比如1080P代表了1920*1080是指视频的有效显示区域,实际的视频还包含不能显示的区域,比如行同步,场同步时间
--5.通常我们说的行视频信号,也称之为视频的水平像素信号;场视频信号,也称之为视频的垂直像素信号;
*********************************************************************/

`timescale 1ns / 1ns //仿真时间刻度/精度

module uivtc#
(
parameter H_ActiveSize  =   1980,               //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
parameter H_FrameSize   =   1920+88+44+148,     //视频时间参数,行视频信号,一行视频信号总计占用的时钟数
parameter H_SyncStart   =   1920+88,            //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
parameter H_SyncEnd     =   1920+88+44,         //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分

parameter V_ActiveSize  =   1080,               //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
parameter V_FrameSize   =   1080+4+5+36,        //视频时间参数,场视频信号,一帧视频信号总计占用的行数量
parameter V_SyncStart   =   1080+4,             //视频时间参数,场同步开始,即多少行数后开始产生场同步信号
parameter V_SyncEnd     =   1080+4+5            //视频时间参数,场同步结束,即多少场数后停止产生场同步信号,之后就是场有效数据部分
)
(
input           I_vtc_rstn,     //系统复位
input           I_vtc_clk,      //系统时钟
output          O_vtc_vs,       //场同步输出
output          O_vtc_hs,       //行同步输出
output          O_vtc_de_valid, //视频数据有效   
output          O_vtc_user,     //满足stream时序产生 user 信号,用于帧同步
output          O_vtc_last      //满足stream时序产生 later 信号,用于每行结束
);

reg [11:0] hcnt = 12'd0;    //视频水平方向,列计数器,寄存器
reg [11:0] vcnt = 12'd0;    //视频垂直方向,行计数器,寄存器  
reg [2 :0] rst_cnt = 3'd0;  //复位计数器,寄存器
wire rst_sync = rst_cnt[2]; //同步复位

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

//视频水平方向,列计数器
always @(posedge I_vtc_clk)begin
    if(rst_sync == 1'b0) //复位
        hcnt <= 12'd0;
    else if(hcnt < (H_FrameSize - 1'b1))//计数范围从0 ~ H_FrameSize-1
        hcnt <= hcnt + 1'b1;
    else
        hcnt <= 12'd0;
end        

//视频垂直方向,行计数器,用于计数已经完成的行视频信号
always @(posedge I_vtc_clk)begin
    if(rst_sync == 1'b0)
        vcnt <= 12'd0;
    else if(hcnt == (H_ActiveSize  - 1'b1)) begin//视频水平方向,是否一行结束
           vcnt <= (vcnt == (V_FrameSize - 1'b1)) ? 12'd0 : vcnt + 1'b1;//视频垂直方向,行计数器加1,计数范围0~V_FrameSize - 1
    end
end

wire hs_valid  =  hcnt < H_ActiveSize; //行信号有效像素部分
wire vs_valid  =  vcnt < V_ActiveSize; //场信号有效像素部分
wire vtc_hs    =  (hcnt >= H_SyncStart && hcnt < H_SyncEnd);//产生hs,行同步信号
wire vtc_vs    =  (vcnt > V_SyncStart && vcnt <= V_SyncEnd);//产生vs,场同步信号      
wire vtc_de    =  hs_valid && vs_valid;//只有当视频水平方向,列有效和视频垂直方向,行同时有效,视频数据部分才是有效

//**********************  video stream video rgb  ***************************
//如果是输入RGB时序,那么转为stream时序
reg   vtc_vs_r1  ;
reg   vtc_hs_r1  ;
reg   vtc_de_r1  ;
reg   vtc_user_r1 ,vtc_user_r2;
reg   vtc_valid_r1,vtc_valid_r2;
reg   vtc_last_r2;
reg   vs_start;

always @(posedge I_vtc_clk )begin
    if(rst_sync == 1'b0) //复位
        vs_start <= 1'b0;
    else if(vtc_user_r1)//清除VS帧同步
        vs_start <= 1'b0;
    else if(vtc_vs && vtc_vs_r1==1'b0)//当vtc_vs发生上升沿跳变代表一帧开始
        vs_start <= 1'b1;
end  

always @(posedge I_vtc_clk  )begin
    vtc_vs_r1    <= vtc_vs;
    vtc_hs_r1    <= vtc_hs;
    vtc_user_r1  <= ~vtc_user_r1 & vs_start & vtc_de;//vtc_user延迟1拍
    vtc_last_r2  <= ~vtc_de & vtc_valid_r1; //产生stream video last 延迟于数据输入2拍
    vtc_valid_r1 <= vtc_de;//vtc_valid延迟1拍
    vtc_valid_r2 <= vtc_valid_r1;//vtc_valid对输入信号延迟2拍,以和vtc_last_r2信号配套同步
    vtc_user_r2  <= vtc_user_r1; //vtc_user 对输入信号延迟2拍,以和vtc_last_r2信号配套同步   
end   

assign O_vtc_vs       =  vtc_vs_r1;
assign O_vtc_hs       =  vtc_hs_r1;
assign O_vtc_de_valid =  vtc_valid_r2;
assign O_vtc_user     =  vtc_user_r2;
assign O_vtc_last     =  vtc_last_r2;

endmodule



4.1.4 分辨率以及时钟计算方法
如果是标准分辨率,建议大家以标准分辨率参数直接填入,如果不是标准分辨率则根据实际情况可以用接近标准分辨率的参数去修改相关参数。
比如对于标准分辨率1080*1920*60的分辨率通常采用148.5MHZ的像素时钟。此时我们可以给出以下参数设置:
H_ActiveSize    =1920
H_SyncStart     =1920+88
H_SyncEnd       =1920+88+44
H_FrameSize     =1920+88+44+148
V_ActiveSize    =1080
V_SyncStart     =1080+4
V_SyncEnd       =1080+4+5
V_FrameSize     =1080+4+5+36


计算分辨率和时钟的推断可以用一个关键公式 像素时钟= H_FrameSize* V_FrameSize*帧率,但是通常我们只会知道,H_ActiveSize、V_ActiveSize以及帧率,而像素时钟和其他参数都需要我们自己设置。
    可以先以以上标准1080*1920*60的分辨率计算下:
H_FrameSize* V_FrameSize*帧率 = 2,200* 1,125*60= 148,500,000,在时钟晶振足够精确的情况下,可以确保帧率以恒定60fps输出。
但是很多时候如果某个参数不能满足要求,比如系统时钟只能提供140MHZ的情况,那么我们也可以重新调整参数,尽量来接近标准分辨率。
比如当以140MHZ输出1080*1920*60fps的视频时,我们给出以下参数:
H_ActiveSize    =1920
H_SyncStart     =1920+88
H_SyncEnd       =1920+88+44
H_FrameSize     =1920+88+44+71

V_ActiveSize    =1080
V_SyncStart     =1080+4
V_SyncEnd       =1080+4+5
V_FrameSize     =1080+4+5+16


H_FrameSize* V_FrameSize *帧率=2,123*1099*60=139,990,620 这样每一帧的精确度误差为0.000067。对于140MHZ的时钟输出帧率会稍微快点。
4.1.5 常用系统分辨率
对于148.5MHZ像素时钟,输出1080*1920*60
H_ActiveSize    =1920
H_SyncStart     =1920+88
H_SyncEnd       =1920+88+44
H_FrameSize     =1920+88+44+148
V_ActiveSize    =1080
V_SyncStart     =1080+4
V_SyncEnd       =1080+4+5
V_FrameSize     =1080+4+5+36


对于74.25MHZ像素时钟,输出1280*720*60
H_ActiveSize    =1280
H_SyncStart     =1280+110
H_SyncEnd       =1280+110+ 40
H_FrameSize     =1280+110+ 40+220
V_ActiveSize    =720
V_SyncStart     =720+4
V_SyncEnd       =720+4+5
V_FrameSize     =720+4+5+21


对于42MHZ像素时钟,输出640*480*60
H_ActiveSize    =640
H_SyncStart     =640+16
H_SyncEnd       =640+16+96
H_FrameSize     =640+16+96+48
V_ActiveSize    =480
V_SyncStart     =480+9
V_SyncEnd       =480+9+2
V_FrameSize     =480+9+2+34


对于非标准分辨率,用户可以以上面介绍的方法计算相近参数。
比如对于非标准140MHZ像素时钟,输出1080*1920*60
H_ActiveSize    =1920
H_SyncStart     =1920+88
H_SyncEnd       =1920+88+44
H_FrameSize     =1920+88+44+71

V_ActiveSize    =1080
V_SyncStart     =1080+4
V_SyncEnd       =1080+4+5
V_FrameSize     =1080+4+5+16


比如对于非标准75MHZ像素时钟,输出1280*720*60
H_ActiveSize    =1280
H_SyncStart     =1280+88
H_SyncEnd       =1280+88+44
H_FrameSize     =1280+88+44+239

V_ActiveSize    =720
V_SyncStart     =720+4
V_SyncEnd       =720+4+5
V_FrameSize     =720+4+5+28



4.2 TPG视频测试模式发生器4.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格式数据输出
2504661-20231227191418717-1014114656.jpg
4.2.2 时序设计
视频数据的有效区域如下图所示:视频数据在H_AcitiveSize和V_AcitiveSize同时有效时候有效
2504661-20231227191419098-4531951.jpg
/*********uitpg(video test Pattern Generator)测试视频发生器***********
--版本号1.1
--以下是米联客设计的uitpg(video test Pattern Generator)测试视频发生器
--1.代码简洁,占用极少逻辑资源,代码结构清晰,逻辑设计严谨
--2.该测试视频发生器通过产生彩条、渐变、纯色、棋方格,产生测试图形
*********************************************************************/

`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


4.3 HDMI输出IP
为了能够输出测试图像,需要调用HDMI IP,这个IP是开源的。由于本文不计划对HDMI IP进行分析,这里只给出调用方法。
2504661-20231227191424454-1206254897.jpg
在参数接口中,输入"7FAMILY"代表支持7系列的FPGA,如果输入"UFAMILY"代表支持ultrascale或者ultrascale+的FPGA.
PCLKX1_i代表像素时钟;
PCLKX2_5_i代表2.5倍的像素时钟,这个时钟仅在使用ultrascale或者ultrascale+的FPGA的时候需要配置;
PCLKX5_i代表5倍的像素时钟;
//例化HDMI输出IP,把TPG产生的测试图像经过HDMI输出
uihdmitx #
(
.FAMILY("7FAMILY")  //选择芯片所支持的系列"7FAMILY" "UFAMILY"   
)
uihdmitx_inst
(
.I_rstn(locked),//复位
.I_hs(vtc_hs), //hs信号
.I_vs(vtc_vs), //vs信号
.I_de(vtc_de),//de信号
.I_rgb({rgb_r,rgb_g,rgb_b}), //RGB数据
.I_pclkx1(pclkx1), //像素时钟
.I_pclkx2_5(1'b0), //2.5倍像素时钟,只有UFAMILY需要
.I_pclkx5(pclkx5), //5倍像素时钟
.O_hdmi_tx_clk_p(O_hdmi_clk_p), //HDMI时钟输出P端
.O_hdmi_tx_clk_n(O_hdmi_clk_n), //HDMI时钟输出N端
.O_hdmi_tx_p(O_hdmi_tx_p),      //HDMI输出数据P端
.O_hdmi_tx_n(O_hdmi_tx_n)       //HDMI输出数据N端
);



5 顶层调用接口源码
这里我们主要看下顶层调用接口以及PLL部分设置。
/*************HDMI 视频输出测试*************
--版本号1.1
--使用VTC产生视频时序
--使用TPG产生测试图像数据
--使用HDMI输出IP,把RGB数据转为HDMI数据输出
*********************************************************************/
`timescale 1ns / 1ns //仿真时间刻度/精度

module display
(
input  I_sysclk,       //系统时钟输入
output O_hdmi_clk_p,     //HDMI输出时钟P端
output O_hdmi_clk_n,     //HDMI输出时钟N端
output [2:0]O_hdmi_tx_p, //HDMI输出数据P端
output [2:0]O_hdmi_tx_n  //HDMI输出数据N端
);
wire vtc_rstn,vtc_clk,vtc_vs,vtc_hs,vtc_de;//vid 视频相关信号
wire pclkx1,pclkx5,locked;//HDMI输出需要2个时钟,pclkx1是和内部视频同步的时钟,pclkx5是HDMI IP内部用于产生输出数据和输出时钟
wire [7 :0] rgb_r ,rgb_g ,rgb_b;// 定义寄存器保存图像的颜色数据
assign vtc_clk = pclkx1; // 内部像素时钟
assign vtc_rstn = locked; //用PLL 的LOCK信号复位

//MMCM/PLL时钟管理IP 输出 pclkx1和pclkx5以及locked信号
clk_wiz_0 clk_wiz0_inst(.clk_out1(pclkx1),.clk_out2(pclkx5),.locked(locked),.clk_in1(I_sysclk));

//例化HDMI输出IP,把TPG产生的测试图像经过HDMI输出
uihdmitx #
(
.FAMILY("7FAMILY")  //选择芯片所支持的系列"7FAMILY" "UFAMILY"   
)
uihdmitx_inst
(
.I_rstn(locked),//复位
.I_hs(vtc_hs), //hs信号
.I_vs(vtc_vs), //vs信号
.I_de(vtc_de),//de信号
.I_rgb({rgb_r,rgb_g,rgb_b}), //RGB数据
.I_pclkx1(pclkx1), //像素时钟
.I_pclkx2_5(1'b0), //2.5倍像素时钟,只有UFAMILY需要
.I_pclkx5(pclkx5), //5倍像素时钟
.O_hdmi_tx_clk_p(O_hdmi_clk_p), //HDMI时钟输出P端
.O_hdmi_tx_clk_n(O_hdmi_clk_n), //HDMI时钟输出N端
.O_hdmi_tx_p(O_hdmi_tx_p),      //HDMI输出数据P端
.O_hdmi_tx_n(O_hdmi_tx_n)       //HDMI输出数据N端
);

uivtc#
(
.H_ActiveSize(1280),          //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
.H_FrameSize(1280+88+44+239), //视频时间参数,行视频信号,一行视频信号总计占用的时钟数
.H_SyncStart(1280+88),        //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
.H_SyncEnd(1280+88+44),       //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分
.V_ActiveSize(720),           //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
.V_FrameSize(720+4+5+28),     //视频时间参数,场视频信号,一帧视频信号总计占用的行数量
.V_SyncStart(720+4),          //视频时间参数,场同步开始,即多少行数后开始产生场同步信号
.V_SyncEnd (720+4+5)          //视频时间参数,场同步结束,即多少行数后停止产生场同步信号,之后就是场有效数据部分
)
uivtc_inst
(
.I_vtc_clk(vtc_clk),  //系统时钟
.I_vtc_rstn(vtc_rstn),//系统复位
.O_vtc_vs(vtc_vs),    //场同步输出
.O_vtc_hs(vtc_hs),    //行同步输出
.O_vtc_de_valid(vtc_de),      //视频数据有效
.O_vtc_user(),     //满足stream时序产生 user 信号,用于帧同步
.O_vtc_last()      //满足stream时序产生 later 信号,用于每行结束
);

uitpg uitpg_inst   
(
.I_tpg_clk(vtc_clk),   //系统时钟
.I_tpg_rstn(vtc_rstn), //系统复位
.I_tpg_vs(vtc_vs),     //图像的vs信号
.I_tpg_hs(vtc_hs),     //图像的hs信号
.I_tpg_de(vtc_de),     //de数据有效信号
.O_tpg_vs(),//和vtc_vs信号一样
.O_tpg_hs(),//和vtc_hs信号一样
.O_tpg_de(),//和vtc_de信号一样      
.O_tpg_data({rgb_r,rgb_g,rgb_b})//测试图像数据输出         
);

endmodule


以上源码中,关键有2个地方需要设置好
5.1 PLL时钟设置
对于PLL的设置需要产生1:5的时钟,对于演示demo中720P的设置如下:
2504661-20231227191429904-220412539.jpg
5.2 VTC参数设置
关于VTC参数设置具体阅读前面video timing controller相关内容,这里针对75M的PCLK参数如下:
.H_ActiveSize(1280),
.H_FrameSize(1280+88+44+239),
.H_SyncStart(1280+88),
.H_SyncEnd(1280+88+44),
.V_ActiveSize(720),
.V_FrameSize(720+4+5+28),
.V_SyncStart(720+4),
.V_SyncEnd (720+4+5)


6 FPGA工程
fpga工程的创建过程不再重复,如有不清楚的请看前面实验
2504661-20231227191430389-91247745.jpg
米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹
01_rtl:放用户编写的rtl代码
02_sim:仿真文件或者工程
03_ip:放使用到的ip文件
04_pin:放fpga的pin脚约束文件或者时序约束文件
05_boot:放编译好的bit或者bin文件(一般为空)
06_doc:放本一些相关文档(一般为空)
2504661-20231227191430727-289052444.jpg


7 下载演示
下载程序前,先确保FPGA工程已经编译。
7.1 硬件连接
请确保下载器和开发板已经正确连接,并且开发板已经上电(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)
2504661-20231227191431253-292820489.jpg
7.2 运行结果
显示器循环输出测试图形
2504661-20231227191436719-2128318470.jpg

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则